feat: URL-first CLI + auto-setup for new targets

- python -m scanner https://domain.de scan  (URL as first positional arg)
- On first use, the domain directory is auto-created from the
  meine-seite.de template with all paths and target URL substituted
- scanner.sh wrapper script for convenient ./scanner.sh usage
- --config syntax fully preserved (cron jobs unchanged)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-06-12 16:29:43 +02:00
commit fcbccce422
4 changed files with 104 additions and 19 deletions

View file

@ -2,7 +2,8 @@
integrity-scanner CLI entry point.
Usage:
python -m scanner <subcommand> [options]
python -m scanner <URL> <subcommand> [options]
python -m scanner --config <site>/config.yaml <subcommand> [options]
Subcommands:
init First-time crawl + baseline setup workflow
@ -16,6 +17,8 @@ Subcommands:
import argparse
import json
import logging
import re
import shutil
import sys
from datetime import datetime, timezone
from pathlib import Path
@ -1327,9 +1330,66 @@ def _build_parser() -> argparse.ArgumentParser:
# Main
# ---------------------------------------------------------------------------
def _auto_setup(url: str, domain: str) -> None:
"""Create a new target directory from the meine-seite.de template."""
project_root = Path(__file__).parent.parent
template_dir = project_root / "meine-seite.de"
target_dir = project_root / domain
if not template_dir.exists():
print(
f"[scanner] Fehler: Template-Verzeichnis '{template_dir}' nicht gefunden.\n"
f"[scanner] Bitte sicherstellen, dass 'meine-seite.de/' im Projektverzeichnis existiert.",
file=sys.stderr,
)
sys.exit(1)
target_dir.mkdir(parents=True, exist_ok=True)
config_dst = target_dir / "config.yaml"
if not config_dst.exists():
content = (template_dir / "config.yaml").read_text(encoding="utf-8")
# Absolute Pfade anpassen
content = content.replace(
str(project_root / "meine-seite.de"),
str(project_root / domain),
)
# URL und Domain ersetzen
content = content.replace("https://meine-seite.de", url.rstrip("/"))
content = content.replace("meine-seite.de", domain)
config_dst.write_text(content, encoding="utf-8")
config_src_dir = template_dir / "config"
config_dst_dir = target_dir / "config"
if config_src_dir.exists() and not config_dst_dir.exists():
shutil.copytree(config_src_dir, config_dst_dir)
print(f"[scanner] Neues Target angelegt: {target_dir}")
print(f"[scanner] Bitte .gitignore ergänzen:")
print(f"[scanner] {domain}/data/")
print(f"[scanner] {domain}/reports/")
print(f"[scanner] {domain}/logs/")
print()
def main() -> None:
argv = list(sys.argv[1:])
# URL-first syntax: scanner https://domain.de scan [options]
if argv and re.match(r"https?://", argv[0]):
url = argv.pop(0)
domain = urlparse(url).netloc
if not domain:
print(f"[scanner] Fehler: Ungültige URL: {url}", file=sys.stderr)
sys.exit(1)
if not Path(domain).exists():
_auto_setup(url, domain)
argv = ["--config", str(Path(domain) / "config.yaml")] + argv
parser = _build_parser()
args = parser.parse_args()
args = parser.parse_args(argv)
cfg = load_config(args.config)
base_dir = Path(args.config).parent.resolve()