86 lines
2.9 KiB
Python
86 lines
2.9 KiB
Python
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
from django.core.management.base import BaseCommand, CommandError
|
|
|
|
from apps.sources.services.discovery import (
|
|
discover_from_email,
|
|
discover_from_feed,
|
|
discover_from_html,
|
|
discover_from_sitemap,
|
|
persist_discovery_candidates,
|
|
)
|
|
|
|
|
|
class Command(BaseCommand):
|
|
help = (
|
|
"Voert bronontdekking uit op lokaal aangeleverde content "
|
|
"en slaat alleen kandidaatregels op met policy review."
|
|
)
|
|
|
|
def add_arguments(self, parser):
|
|
parser.add_argument(
|
|
"mode",
|
|
choices=["html", "sitemap", "feed", "email"],
|
|
help="Bronmodus voor ontdekking",
|
|
)
|
|
parser.add_argument(
|
|
"--input",
|
|
required=True,
|
|
dest="input_path",
|
|
help="Pad naar inputbestand",
|
|
)
|
|
parser.add_argument(
|
|
"--base-url",
|
|
dest="base_url",
|
|
help="Base URL voor relativiteitsresolutie",
|
|
)
|
|
parser.add_argument(
|
|
"--dry-run",
|
|
action="store_true",
|
|
help="Geen database-write; toon alleen ontdekte kandidaten",
|
|
)
|
|
|
|
def handle(self, *args, **options):
|
|
mode = options["mode"]
|
|
input_path = Path(options["input_path"]).resolve()
|
|
base_url = (options["base_url"] or "").strip()
|
|
if mode in {"html", "sitemap", "feed"} and not base_url:
|
|
raise CommandError("--base-url is verplicht voor html/sitemap/feed")
|
|
|
|
if not input_path.is_file():
|
|
raise CommandError(f"Inputbestand niet gevonden: {input_path}")
|
|
|
|
if mode in {"html", "sitemap", "feed"}:
|
|
content = input_path.read_text(encoding="utf-8")
|
|
else:
|
|
content = input_path.read_bytes()
|
|
|
|
if mode == "html":
|
|
candidates = discover_from_html(content, base_url=base_url)
|
|
elif mode == "sitemap":
|
|
candidates = discover_from_sitemap(content, base_url=base_url)
|
|
elif mode == "feed":
|
|
candidates = discover_from_feed(content, base_url=base_url)
|
|
else:
|
|
candidates = discover_from_email(content)
|
|
|
|
self.stdout.write(f"Ontdekt {len(candidates)} kandidaten (mode={mode}).")
|
|
if not candidates:
|
|
self.stdout.write(self.style.WARNING("Geen bruikbare kandidaten gevonden."))
|
|
return
|
|
|
|
if options["dry_run"]:
|
|
self.stdout.write(self.style.WARNING("Dry-run modus: er wordt niet geschreven."))
|
|
for candidate in candidates:
|
|
self.stdout.write(f"- {candidate.source_type} {candidate.url} [{candidate.reason}]")
|
|
return
|
|
|
|
created, updated, skipped = persist_discovery_candidates(candidates)
|
|
self.stdout.write(
|
|
self.style.SUCCESS(
|
|
f"Persist result: {created} nieuw, {updated} bijgewerkt, {skipped} ongewijzigd."
|
|
)
|
|
)
|