Neues Modul quellen/ki_hilfe.py (konsistent zum dedup-LLM-Muster): - Struktur-Erkennung: bei verdächtig leerem Parser-Ergebnis schlägt das LLM Pagination-/Filter-Folge-URLs vor; hart gefiltert auf gleiche Domain, max. 20 je Seite, nicht erreichbare Vorschläge brechen den Lauf nicht ab. - Feld-Extraktion: nur unsichere Treffer (fehlender Verlag, verdächtiger Titel); korrigiert ausschließlich titel/verlag/autor, niemals die URL. - Env-Konfiguration SPIELE_NEUHEITEN_KI_* (AKTIV default 0, KONFIDENZ_MIN default 0.7), OpenAI-kompatible Chat-Completions via httpx mit Timeout und genau einem Retry. - Fallback-Pflicht: ohne Konfiguration oder bei jedem Fehler läuft exakt der klassische Crawler; KI-Fehler blockieren den Sync nie. - Audit: KI-Eingriffe je Quelle und Lauf ins audit-log (Modell, Konfidenz, korrigierte Felder, verfolgte Folge-URLs). 20 neue Tests (gemocktes HTTP/LLM): Fallback-Fälle, Konfidenz-Schwelle, Domain-Filter, Max-20-Grenze, URL-Unveränderbarkeit, Audit.
90 lines
3.3 KiB
Python
90 lines
3.3 KiB
Python
"""Zugriff auf die neuheiten-Plugin-Module über den vom Plugin-Loader
|
|
verwendeten Modulnamen (`spiele_redaktion_plugins.neuheiten`).
|
|
|
|
Der Kern teilt sich eine SQLAlchemy-MetaData; deshalb darf es pro Prozess
|
|
nur eine Modul-Identität geben. Tests importieren das Plugin daher über
|
|
diesen Helper statt direkt über `plugins.neuheiten`.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
from redaktionskern.plugin_loader import discover_plugins
|
|
|
|
_PROJEKT_WURZEL = Path(__file__).resolve().parents[1]
|
|
|
|
if "spiele_redaktion_plugins.neuheiten" not in sys.modules:
|
|
discover_plugins(
|
|
_PROJEKT_WURZEL / "plugins",
|
|
entry_point_group="spiele_redaktion.tests.keine_entry_points",
|
|
)
|
|
|
|
_neuheiten = sys.modules["spiele_redaktion_plugins.neuheiten"]
|
|
|
|
bgg = _neuheiten.bgg
|
|
sync_modul = _neuheiten.sync
|
|
models = _neuheiten.models
|
|
|
|
BggClient = bgg.BggClient
|
|
BggFehler = bgg.BggFehler
|
|
BggAuthFehler = bgg.BggAuthFehler
|
|
MELDUNG_401 = bgg.MELDUNG_401
|
|
SuchTreffer = bgg.SuchTreffer
|
|
BggSpiel = bgg.BggSpiel
|
|
parse_suche = bgg.parse_suche
|
|
parse_things = bgg.parse_things
|
|
|
|
SyncService = sync_modul.SyncService
|
|
SyncErgebnis = sync_modul.SyncErgebnis
|
|
ist_moeglicher_prototyp = sync_modul.ist_moeglicher_prototyp
|
|
speichere_oder_aktualisiere = sync_modul.speichere_oder_aktualisiere
|
|
|
|
Neuheit = models.Neuheit
|
|
STATUS_NEUHEIT = models.STATUS_NEUHEIT
|
|
|
|
# ---------- Web-Quellen (Adapter + Sync-Orchestrierung) ----------
|
|
|
|
quellen_basis = _neuheiten.quellen.basis
|
|
quellen_sync_modul = _neuheiten.quellen_sync
|
|
models = _neuheiten.models # neu mit QuellenStatus
|
|
|
|
USER_AGENT = quellen_basis.USER_AGENT
|
|
QuellenAdapter = quellen_basis.QuellenAdapter
|
|
QuellenFehler = quellen_basis.QuellenFehler
|
|
QuellenTreffer = quellen_basis.QuellenTreffer
|
|
SammelErgebnis = quellen_basis.SammelErgebnis
|
|
WebQuellenClient = quellen_basis.WebQuellenClient
|
|
jahr_aus_datumsangabe = quellen_basis.jahr_aus_datumsangabe
|
|
titel_aehnlichkeit = quellen_basis.titel_aehnlichkeit
|
|
titel_normalisieren = quellen_basis.titel_normalisieren
|
|
|
|
ki_hilfe_modul = _neuheiten.quellen.ki_hilfe
|
|
KiHilfe = ki_hilfe_modul.KiHilfe
|
|
KiKonfiguration = ki_hilfe_modul.KiKonfiguration
|
|
lade_ki_konfiguration = ki_hilfe_modul.lade_konfiguration
|
|
extrahiere_ki_json = ki_hilfe_modul.extrahiere_json
|
|
struktur_verdaechtig = ki_hilfe_modul.struktur_verdaechtig
|
|
treffer_ist_unsicher = ki_hilfe_modul.treffer_ist_unsicher
|
|
titel_ist_verdaechtig = ki_hilfe_modul.titel_ist_verdaechtig
|
|
validiere_url_vorschlaege = ki_hilfe_modul.validiere_url_vorschlaege
|
|
validiere_feld_antwort = ki_hilfe_modul.validiere_feld_antwort
|
|
MAX_FOLGE_URLS = ki_hilfe_modul.MAX_FOLGE_URLS
|
|
|
|
SpielboxQuelle = _neuheiten.quellen.spielbox.SpielboxQuelle
|
|
BrettspielboxQuelle = _neuheiten.quellen.brettspielbox.BrettspielboxQuelle
|
|
SpielEssenQuelle = _neuheiten.quellen.spielessen.SpielEssenQuelle
|
|
CliquenabendQuelle = _neuheiten.quellen.cliquenabend.CliquenabendQuelle
|
|
|
|
ADAPTER_KLASSEN = quellen_sync_modul.ADAPTER_KLASSEN
|
|
WebQuellenSyncService = quellen_sync_modul.WebQuellenSyncService
|
|
QuellenLaufZeile = quellen_sync_modul.QuellenLaufZeile
|
|
quelle_aktiv = quellen_sync_modul.quelle_aktiv
|
|
TITEL_FUZZY_SCHWELLE = quellen_sync_modul.TITEL_FUZZY_SCHWELLE
|
|
QuellenStatus = models.QuellenStatus
|
|
|
|
|
|
def sys_modules_plugin():
|
|
"""Die geladene NeuheitenPlugin-Instanz (für Migrationen im Test)."""
|
|
return sys.modules["spiele_redaktion_plugins.neuheiten"].plugin
|