Angefangen, DataGrabber anzulegen (Grundlagen gelegt, noch nicht lauffähig)
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
"""
|
||||
sn_basis/modules/Pruefmanager.py – zentrale Verarbeitung von pruef_ergebnis-Objekten.
|
||||
Steuert die Nutzerinteraktion über Wrapper.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
from typing import Optional, Any
|
||||
|
||||
from sn_basis.functions import (
|
||||
ask_yes_no,
|
||||
@@ -11,150 +9,196 @@ from sn_basis.functions import (
|
||||
set_layer_visible,
|
||||
)
|
||||
|
||||
from sn_basis.modules.pruef_ergebnis import pruef_ergebnis
|
||||
from sn_basis.modules.pruef_ergebnis import pruef_ergebnis, PruefAktion
|
||||
|
||||
|
||||
class Pruefmanager:
|
||||
"""
|
||||
Verarbeitet pruef_ergebnis-Objekte und steuert die Nutzerinteraktion.
|
||||
Zentrale Verarbeitung von pruef_ergebnis-Objekten.
|
||||
|
||||
Erwartete öffentliche API (verwendet von Core-Komponenten wie DataGrabber):
|
||||
- report_error(thema, meldung, *, aktion: Optional[PruefAktion]=None, kontext=None) -> None
|
||||
- request_decision(pruef_res) -> str
|
||||
- report_summary(summary: dict) -> None
|
||||
- verarbeite(ergebnis: pruef_ergebnis) -> pruef_ergebnis
|
||||
"""
|
||||
|
||||
def __init__(self, ui_modus: str = "qgis"):
|
||||
def __init__(self, ui_modus: str = "qgis", parent: Optional[Any] = None):
|
||||
self.ui_modus = ui_modus
|
||||
self.parent = parent
|
||||
|
||||
# ---------------------------------------------------------
|
||||
# Hauptfunktion
|
||||
# ---------------------------------------------------------
|
||||
# ---------------------------------------------------------------------
|
||||
# Basis-API: Meldungen / Zusammenfassungen
|
||||
# ---------------------------------------------------------------------
|
||||
def report_error(self, thema: str, meldung: str, *, aktion: Optional[PruefAktion] = None, kontext: Optional[Any] = None) -> None:
|
||||
"""
|
||||
Einheitliche Meldung für Fehler/Warnungen aus dem Core.
|
||||
Keine Rückgabe; dient als zentraler Hook für Logging/UI.
|
||||
"""
|
||||
critical_actions = {
|
||||
"netzwerkfehler",
|
||||
"pruefe_exception",
|
||||
"save_exception",
|
||||
"layer_create_failed",
|
||||
"read_error",
|
||||
"open_error",
|
||||
}
|
||||
warn_actions = {
|
||||
"datei_nicht_gefunden",
|
||||
"pfad_nicht_gefunden",
|
||||
"url_nicht_erreichbar",
|
||||
"falsche_endung",
|
||||
"kein_header",
|
||||
"kein_arbeitsblatt",
|
||||
}
|
||||
|
||||
if aktion in critical_actions:
|
||||
error(thema, meldung)
|
||||
return
|
||||
|
||||
if aktion in warn_actions:
|
||||
warning(thema, meldung)
|
||||
return
|
||||
|
||||
# Default: informative Warnung
|
||||
warning(thema, meldung)
|
||||
|
||||
def report_summary(self, summary: dict) -> None:
|
||||
geladen = summary.get("geladen", [])
|
||||
fehler = summary.get("fehler", {})
|
||||
ausserhalb = summary.get("ausserhalb", [])
|
||||
relevant = summary.get("relevant", [])
|
||||
|
||||
message = (
|
||||
f"Geladene Dienste: {len(geladen)}\n"
|
||||
f"Relevante Dienste: {len(relevant)}\n"
|
||||
f"Dienste ausserhalb: {len(ausserhalb)}\n"
|
||||
f"Fehler: {len(fehler)}"
|
||||
)
|
||||
|
||||
info("DataGrabber Zusammenfassung", message)
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# Entscheidungs-API
|
||||
# ---------------------------------------------------------------------
|
||||
def request_decision(self, pruef_res: Any) -> str:
|
||||
"""
|
||||
Synchronously request a decision from the user (or return a default in headless mode).
|
||||
|
||||
Returns one of:
|
||||
- "abort"
|
||||
- "continue"
|
||||
- "temporaer_erzeugen"
|
||||
- "ignore"
|
||||
"""
|
||||
aktion = getattr(pruef_res, "aktion", None)
|
||||
meldung = getattr(pruef_res, "meldung", str(pruef_res))
|
||||
|
||||
interactive_actions = {
|
||||
"leereingabe_erlaubt",
|
||||
"standarddatei_vorschlagen",
|
||||
"temporaer_erlaubt",
|
||||
"layer_unsichtbar",
|
||||
}
|
||||
|
||||
if aktion in interactive_actions:
|
||||
if self.ui_modus == "qgis":
|
||||
title_map = {
|
||||
"leereingabe_erlaubt": "Ohne Eingabe fortfahren",
|
||||
"standarddatei_vorschlagen": "Standarddatei verwenden",
|
||||
"temporaer_erlaubt": "Temporäre Datei erzeugen",
|
||||
"layer_unsichtbar": "Layer einblenden",
|
||||
}
|
||||
title = title_map.get(aktion, "Entscheidung erforderlich")
|
||||
try:
|
||||
yes = ask_yes_no(title, meldung, default=False, parent=self.parent)
|
||||
except Exception:
|
||||
return "abort"
|
||||
if yes:
|
||||
if aktion == "temporaer_erlaubt":
|
||||
return "temporaer_erzeugen"
|
||||
return "continue"
|
||||
return "abort"
|
||||
|
||||
if self.ui_modus == "headless":
|
||||
return "abort"
|
||||
|
||||
informational_actions = {
|
||||
"leer",
|
||||
"datei_nicht_gefunden",
|
||||
"pfad_nicht_gefunden",
|
||||
"url_nicht_erreichbar",
|
||||
"netzwerkfehler",
|
||||
"falscher_geotyp",
|
||||
"layer_leer",
|
||||
"falscher_layertyp",
|
||||
"falsches_crs",
|
||||
"felder_fehlen",
|
||||
"datenquelle_unerwartet",
|
||||
"layer_nicht_editierbar",
|
||||
"kein_header",
|
||||
"kein_arbeitsblatt",
|
||||
"read_error",
|
||||
"open_error",
|
||||
}
|
||||
if aktion in informational_actions:
|
||||
return "abort"
|
||||
|
||||
return "abort"
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# Höhere Abstraktion: verarbeite
|
||||
# ---------------------------------------------------------------------
|
||||
def verarbeite(self, ergebnis: pruef_ergebnis) -> pruef_ergebnis:
|
||||
"""
|
||||
Verarbeitet ein pruef_ergebnis und führt ggf. Nutzerinteraktion durch.
|
||||
Rückgabe: neues oder unverändertes pruef_ergebnis.
|
||||
Verarbeitet ein pruef_ergebnis-Objekt und führt ggf. Nutzerinteraktion durch.
|
||||
Liefert ein ggf. modifiziertes pruef_ergebnis zurück.
|
||||
"""
|
||||
|
||||
if ergebnis.ok:
|
||||
return ergebnis
|
||||
|
||||
aktion = ergebnis.aktion
|
||||
kontext = ergebnis.kontext
|
||||
meldung = ergebnis.meldung
|
||||
|
||||
# -----------------------------------------------------
|
||||
# Allgemeine Aktionen
|
||||
# -----------------------------------------------------
|
||||
# Zentrale Meldung
|
||||
self.report_error(aktion or "pruefung", meldung or "", aktion=aktion, kontext=kontext)
|
||||
|
||||
if aktion == "leer":
|
||||
warning("Eingabe fehlt", ergebnis.meldung)
|
||||
# Interaktive Entscheidungen
|
||||
if aktion in ("leereingabe_erlaubt", "standarddatei_vorschlagen", "temporaer_erlaubt", "layer_unsichtbar"):
|
||||
decision = self.request_decision(ergebnis)
|
||||
if decision == "temporaer_erzeugen":
|
||||
return pruef_ergebnis(ok=True, meldung="Temporäre Datei soll erzeugt werden.", aktion="temporaer_erzeugen", kontext=None)
|
||||
if decision == "continue":
|
||||
return pruef_ergebnis(ok=True, meldung="Fortgefahren.", aktion="ok", kontext=kontext)
|
||||
return ergebnis # abort / unverändert
|
||||
|
||||
# Spezielle Excel/Importer-Fälle: klare Meldungen, keine interaktive Entscheidung
|
||||
if aktion == "kein_header":
|
||||
warning("Excel-Import", meldung or "")
|
||||
return ergebnis
|
||||
|
||||
if aktion == "leereingabe_erlaubt":
|
||||
if ask_yes_no("Ohne Eingabe fortfahren", ergebnis.meldung):
|
||||
return pruef_ergebnis(
|
||||
ok=True,
|
||||
meldung="Ohne Eingabe fortgefahren.",
|
||||
aktion="ok",
|
||||
kontext=None,
|
||||
)
|
||||
if aktion == "kein_arbeitsblatt":
|
||||
warning("Excel-Import", meldung or "")
|
||||
return ergebnis
|
||||
|
||||
if aktion == "leereingabe_nicht_erlaubt":
|
||||
warning("Eingabe erforderlich", ergebnis.meldung)
|
||||
return ergebnis
|
||||
|
||||
if aktion == "standarddatei_vorschlagen":
|
||||
if ask_yes_no("Standarddatei verwenden", ergebnis.meldung):
|
||||
return pruef_ergebnis(
|
||||
ok=True,
|
||||
meldung="Standarddatei wird verwendet.",
|
||||
aktion="ok",
|
||||
kontext=kontext,
|
||||
)
|
||||
return ergebnis
|
||||
|
||||
if aktion == "temporaer_erlaubt":
|
||||
if ask_yes_no("Temporäre Datei erzeugen", ergebnis.meldung):
|
||||
return pruef_ergebnis(
|
||||
ok=True,
|
||||
meldung="Temporäre Datei soll erzeugt werden.",
|
||||
aktion="temporaer_erzeugen",
|
||||
kontext=None,
|
||||
)
|
||||
if aktion in ("read_error", "open_error"):
|
||||
error("Excel-Import", meldung or "")
|
||||
return ergebnis
|
||||
|
||||
if aktion == "datei_nicht_gefunden":
|
||||
warning("Datei nicht gefunden", ergebnis.meldung)
|
||||
return ergebnis
|
||||
|
||||
if aktion == "kein_dateipfad":
|
||||
warning("Ungültiger Pfad", ergebnis.meldung)
|
||||
return ergebnis
|
||||
|
||||
if aktion == "pfad_nicht_gefunden":
|
||||
warning("Pfad nicht gefunden", ergebnis.meldung)
|
||||
return ergebnis
|
||||
|
||||
if aktion == "url_nicht_erreichbar":
|
||||
warning("URL nicht erreichbar", ergebnis.meldung)
|
||||
return ergebnis
|
||||
|
||||
if aktion == "netzwerkfehler":
|
||||
error("Netzwerkfehler", ergebnis.meldung)
|
||||
return ergebnis
|
||||
|
||||
# -----------------------------------------------------
|
||||
# Layer-Aktionen
|
||||
# -----------------------------------------------------
|
||||
|
||||
if aktion == "layer_nicht_gefunden":
|
||||
error("Layer fehlt", ergebnis.meldung)
|
||||
warning("Datei nicht gefunden", meldung or "")
|
||||
return ergebnis
|
||||
|
||||
# Spezieller Fall: layer_unsichtbar (falls nicht interaktiv behandelt)
|
||||
if aktion == "layer_unsichtbar":
|
||||
if ask_yes_no("Layer einblenden", ergebnis.meldung):
|
||||
if kontext is not None:
|
||||
try:
|
||||
set_layer_visible(kontext, True)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return pruef_ergebnis(
|
||||
ok=True,
|
||||
meldung="Layer wurde eingeblendet.",
|
||||
aktion="ok",
|
||||
kontext=kontext,
|
||||
)
|
||||
if kontext is not None:
|
||||
try:
|
||||
set_layer_visible(kontext, True)
|
||||
return pruef_ergebnis(ok=True, meldung="Layer wurde eingeblendet.", aktion="ok", kontext=kontext)
|
||||
except Exception:
|
||||
return ergebnis
|
||||
return ergebnis
|
||||
|
||||
if aktion == "falscher_geotyp":
|
||||
warning("Falscher Geometrietyp", ergebnis.meldung)
|
||||
return ergebnis
|
||||
|
||||
if aktion == "layer_leer":
|
||||
warning("Layer enthält keine Objekte", ergebnis.meldung)
|
||||
return ergebnis
|
||||
|
||||
if aktion == "falscher_layertyp":
|
||||
warning("Falscher Layertyp", ergebnis.meldung)
|
||||
return ergebnis
|
||||
|
||||
if aktion == "falsches_crs":
|
||||
warning("Falsches CRS", ergebnis.meldung)
|
||||
return ergebnis
|
||||
|
||||
if aktion == "felder_fehlen":
|
||||
warning("Fehlende Felder", ergebnis.meldung)
|
||||
return ergebnis
|
||||
|
||||
if aktion == "datenquelle_unerwartet":
|
||||
warning("Unerwartete Datenquelle", ergebnis.meldung)
|
||||
return ergebnis
|
||||
|
||||
if aktion == "layer_nicht_editierbar":
|
||||
warning("Layer nicht editierbar", ergebnis.meldung)
|
||||
return ergebnis
|
||||
|
||||
# -----------------------------------------------------
|
||||
# Fallback
|
||||
# -----------------------------------------------------
|
||||
|
||||
warning("Unbekannte Aktion", f"Unbekannte Aktion: {aktion}")
|
||||
# Standard: keine Änderung
|
||||
return ergebnis
|
||||
|
||||
Reference in New Issue
Block a user