From e6ffab1c10a03ab3265c8818a9b9d3c78d681e27 Mon Sep 17 00:00:00 2001 From: daniel Date: Fri, 13 Feb 2026 21:39:12 +0100 Subject: [PATCH] =?UTF-8?q?Angefangen,=20DataGrabber=20anzulegen=20(Grundl?= =?UTF-8?q?agen=20gelegt,=20noch=20nicht=20lauff=C3=A4hig)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/datagrabber.jpeg | Bin 0 -> 102043 bytes assets/datagrabber.md | 38 +++++ assets/datagrabber.pdf | Bin 0 -> 32398 bytes functions/qt_wrapper.py | 68 +++++++- functions/test.md | 14 ++ modules/DataGrabber.py | 324 ++++++++++++++++++++++++++++++++++++++ modules/Dateipruefer.py | 4 +- modules/Pruefmanager.py | 282 +++++++++++++++++++-------------- modules/excel_importer.py | 91 +++++++++++ modules/layerpruefer.py | 4 +- modules/linkpruefer.py | 4 +- modules/pruef_ergebnis.py | 54 ++++--- 12 files changed, 733 insertions(+), 150 deletions(-) create mode 100644 assets/datagrabber.jpeg create mode 100644 assets/datagrabber.md create mode 100644 assets/datagrabber.pdf create mode 100644 functions/test.md create mode 100644 modules/DataGrabber.py create mode 100644 modules/excel_importer.py diff --git a/assets/datagrabber.jpeg b/assets/datagrabber.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..e38d84b899667b99d16f6076254e4a5a4b07cbfd GIT binary patch literal 102043 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 literal 0 HcmV?d00001 diff --git a/assets/datagrabber.md b/assets/datagrabber.md new file mode 100644 index 0000000..a3161f6 --- /dev/null +++ b/assets/datagrabber.md @@ -0,0 +1,38 @@ +```mermaid +flowchart TD + subgraph Plugin + P[sn_plan41 Fachplugin] + A[Adapter Plan41LinklistAdapter] + PM[Pruefmanager] + LP[Layerpruefer] + KP[Linkpruefer] + SP[Stilpruefer] + end + + subgraph Core + DG[DataGrabber] + NL[normalized entries] + LL[Layer Loader Provider Dispatch] + SM[Spatial Matcher] + ST[Storage GPKG / PostGIS] + PR[Project QGIS - addMapLayer] + LOG[Log / Ergebnisstruktur] + end + + P -->|gibt Adapter, Prüfer, Pruefmanager| DG + A -->|load liefert Rohdaten| DG + DG -->|adapter.normalize| NL + NL --> DG + DG -->|für jeden Eintrag: _check_link -> KP.check| KP + DG -->|für jeden Eintrag: _check_style -> SP.check| SP + DG -->|prüfe vorhandene Layer| LP + DG -->|lade Layer via provider| LL + LL -->|Features| SM + SM -->|Abgleich| DG + DG -->|speichern| ST + ST --> PR + DG --> PR + DG -->|Ergebnis/Fehler| LOG + LOG --> PM + DG --> PM +``` \ No newline at end of file diff --git a/assets/datagrabber.pdf b/assets/datagrabber.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f79edb2131f8d9333a36f716b720626ab45bd9a0 GIT binary patch literal 32398 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 S@(~w@052yh4GmCH>VE;ie;=d( literal 0 HcmV?d00001 diff --git a/functions/qt_wrapper.py b/functions/qt_wrapper.py index 9e116dc..8346f8b 100644 --- a/functions/qt_wrapper.py +++ b/functions/qt_wrapper.py @@ -32,6 +32,7 @@ QTabWidget: type QToolButton: Type[Any] QSizePolicy: Type[Any] Qt: Type[Any] +ComboBox: Type[Any] YES: Optional[Any] = None NO: Optional[Any] = None @@ -68,6 +69,7 @@ try: QTabWidget as _QTabWidget,# type: ignore QToolButton as _QToolButton,#type:ignore QSizePolicy as _QSizePolicy,#type:ignore + QComboBox as _QComboBox, ) @@ -107,6 +109,7 @@ try: QTabWidget = _QTabWidget QToolButton=_QToolButton QSizePolicy=_QSizePolicy + QComboBox=_QComboBox YES = QMessageBox.StandardButton.Yes NO = QMessageBox.StandardButton.No @@ -148,7 +151,7 @@ try: except Exception: try: - from PyQt5.QtWidgets import ( + from PyQt5.QtWidgets import (# type: ignore QMessageBox as _QMessageBox, QFileDialog as _QFileDialog, QWidget as _QWidget, @@ -166,18 +169,20 @@ except Exception: QTabWidget as _QTabWidget, QToolButton as _QToolButton, QSizePolicy as _QSizePolicy, + QComboBox as _QComboBox, ) - from PyQt5.QtCore import ( + from PyQt5.QtCore import (# type: ignore QEventLoop as _QEventLoop, QUrl as _QUrl, QCoreApplication as _QCoreApplication, Qt as _Qt, ) - from PyQt5.QtNetwork import ( + from PyQt5.QtNetwork import (# type: ignore QNetworkRequest as _QNetworkRequest, QNetworkReply as _QNetworkReply, ) + QMessageBox = _QMessageBox QFileDialog = _QFileDialog QEventLoop = _QEventLoop @@ -203,6 +208,7 @@ except Exception: QTabWidget = _QTabWidget QToolButton=_QToolButton QSizePolicy=_QSizePolicy + ComboBox=_QComboBox YES = QMessageBox.Yes NO = QMessageBox.No @@ -210,6 +216,8 @@ except Exception: ICON_QUESTION = QMessageBox.Question QT_VERSION = 5 + + # then try next backend # --------------------------------------------------------- # Qt5 Enum-Aliase (vereinheitlicht) # --------------------------------------------------------- @@ -246,7 +254,7 @@ except Exception: QT_VERSION = 0 class FakeEnum(int): - def __or__(self, other: "FakeEnum") -> "FakeEnum": + def __or__(self, other: int) -> "FakeEnum": return FakeEnum(int(self) | int(other)) YES = FakeEnum(1) @@ -518,3 +526,55 @@ except Exception: self._tabs.append((widget, title)) QTabWidget = _MockTabWidget + # ------------------------- + # Mock ComboBox Implementation + # ------------------------- + class _MockSignal: + def __init__(self): + self._slots = [] + + def connect(self, cb): + self._slots.append(cb) + + def emit(self, value): + for s in list(self._slots): + try: + s(value) + except Exception: + pass + + class _MockComboBox: + def __init__(self, parent=None): + self._items = [] + self._index = -1 + self.currentTextChanged = _MockSignal() + + def addItem(self, text: str) -> None: + self._items.append(text) + + def addItems(self, items): + for it in items: + self.addItem(it) + + def findText(self, text: str) -> int: + try: + return self._items.index(text) + except ValueError: + return -1 + + def setCurrentIndex(self, idx: int) -> None: + if 0 <= idx < len(self._items): + self._index = idx + self.currentTextChanged.emit(self.currentText()) + + def setCurrentText(self, text: str) -> None: + idx = self.findText(text) + if idx >= 0: + self.setCurrentIndex(idx) + + def currentText(self) -> str: + if 0 <= self._index < len(self._items): + return self._items[self._index] + return "" + + ComboBox = _MockComboBox diff --git a/functions/test.md b/functions/test.md new file mode 100644 index 0000000..84240dc --- /dev/null +++ b/functions/test.md @@ -0,0 +1,14 @@ +mermaid´´´ +flowchart TD + A[Projekt] + + subgraph children[ ] + direction TB + B[src] + C[docs] + D[README.md] + end + + A --> B + A --> C + A --> D diff --git a/modules/DataGrabber.py b/modules/DataGrabber.py new file mode 100644 index 0000000..85ba2fe --- /dev/null +++ b/modules/DataGrabber.py @@ -0,0 +1,324 @@ +# sn_basis/modules/DataGrabber.py +""" +DataGrabber module +================== + +Leichter Orchestrator, der eine Quelle (Datei, Einzellink, Datenbank) +analysiert, passende Prüfer aufruft und die Ergebnisse an den +:class:`sn_basis.modules.Pruefmanager.Pruefmanager` delegiert. + +Dieses vereinfachte Modul geht davon aus, dass alle benötigten Prüfer +und der ExcelImporter vorhanden und importierbar sind. Es enthält +keine Fallbacks oder defensive Exception-Handling-Pfade für fehlende +Prüfer-Module — fehlende Komponenten führen zu Import- oder Laufzeitfehlern, +die bewusst nicht unterdrückt werden. +""" + +from __future__ import annotations + +from typing import ( + Optional, + Any, + Mapping, + Iterable, + Dict, + Protocol, + Literal, + Tuple, + List, +) +from pathlib import Path +import sqlite3 + +from sn_basis.modules.Pruefmanager import Pruefmanager +from sn_basis.modules.pruef_ergebnis import pruef_ergebnis, PruefAktion + +# In dieser vereinfachten Variante werden die Prüfer und der ExcelImporter +# direkt importiert. Fehlende Module führen zu ImportError (gewollt). +from sn_basis.modules.Dateipruefer import Dateipruefer +from sn_basis.modules.linkpruefer import Linkpruefer +from sn_basis.modules.layerpruefer import Layerpruefer +from sn_basis.modules.stilpruefer import Stilpruefer +from sn_basis.modules.excel_importer import ExcelImporter + + +SourceType = Literal["file", "link", "database", "unknown"] + + +class LinklistAdapter(Protocol): + """ + Minimal-Protokoll für Adapter, die Linklisten liefern/normalisieren. + + Implementierende Klassen sollten: + - load() -> Iterable[Mapping[str, Any]] + - normalize(raw_item) -> Mapping[str, Any] + """ + def load(self) -> Iterable[Mapping[str, Any]]: + ... + def normalize(self, raw_item: Mapping[str, Any]) -> Mapping[str, Any]: + ... + + +class DataGrabber: + """ + DataGrabber orchestriert das Einlesen einer Quelle und die Übergabe an Prüfer. + + Diese vereinfachte Implementierung erwartet, dass alle Prüferklassen und + der ExcelImporter vorhanden sind. Es gibt keine defensive Logik für + fehlende Komponenten. + + Konstruktor-Parameter + -------------------- + :param pruefmanager: Instanz des Pruefmanagers (verpflichtend). + :param datei_pruefer_cls: Klasse des Dateipruefers (Standard: Dateipruefer). + :param link_pruefer: Instanz des Linkpruefers. + :param layer_pruefer: Instanz des Layerpruefers. + :param stil_pruefer: Instanz des Stilpruefers. + """ + + def __init__( + self, + pruefmanager: Pruefmanager, + *, + datei_pruefer_cls=Dateipruefer, + link_pruefer: Linkpruefer, + layer_pruefer: Layerpruefer, + stil_pruefer: Stilpruefer, + ) -> None: + # Pruefmanager ist verpflichtend + self.pruefmanager: Pruefmanager = pruefmanager + + # Dateipruefer-Klasse (wird zur Laufzeit mit einem Pfad instanziert) + self._datei_pruefer_cls = datei_pruefer_cls + + # Prüfer-Instanzen (werden direkt verwendet) + self.link_pruefer: Linkpruefer = link_pruefer + self.layer_pruefer: Layerpruefer = layer_pruefer + self.stil_pruefer: Stilpruefer = stil_pruefer + + # Quelle (wird später gesetzt) + self.source: Optional[str] = None + + # ------------------------------------------------------------------ # + # Source Management + # ------------------------------------------------------------------ # + def set_source(self, source: str) -> None: + """ + Setzt die Quelle für den DataGrabber. + + Die Quelle ist ein String, der entweder ein lokaler Dateipfad, + ein Einzellink (URL/URI) oder ein Pfad zu einer Datenbank/GeoPackage ist. + """ + self.source = source + + def analyze_source(self, source: str) -> SourceType: + """ + Klassifiziert die angegebene Quelle ausschließlich anhand des Dateipruefers. + + Ablauf + ------ + 1. Instanziere den Dateipruefer mit `pfad=source` und `temporaer_erlaubt=False`. + 2. Rufe `pruefe()` auf und werte das zurückgegebene :class:`pruef_ergebnis` aus. + 3. Bei `ok==True` wird anhand der Dateiendung zwischen "database" (gpkg/sqlite/db) + und "file" unterschieden. + 4. Bei `ok==False` werden typische Aktionen wie "datei_nicht_gefunden" als "link" + interpretiert; bei "falsche_endung" wird anhand der Endung klassifiziert. + """ + dp = self._datei_pruefer_cls(pfad=source, temporaer_erlaubt=False) + pe: pruef_ergebnis = dp.pruefe() + + if getattr(pe, "ok", False): + suffix = Path(source).suffix.lower() + if suffix in (".gpkg", ".sqlite", ".db"): + return "database" + return "file" + + aktion = getattr(pe, "aktion", None) + if aktion in ("datei_nicht_gefunden", "pfad_nicht_gefunden", "kein_dateipfad"): + return "link" + if aktion == "falsche_endung": + lower = source.lower() + for db_ext in (".gpkg", ".sqlite", ".db"): + if lower.endswith(db_ext): + return "database" + for file_ext in (".xlsx", ".xls", ".csv"): + if lower.endswith(file_ext): + return "file" + return "unknown" + + # ------------------------------------------------------------------ # + # Excel-Verarbeitung + #Es werden alle Werte ohne Prüfung der Links, Pfade oder Stile geladen, da verschiedene Plugins verschiedene xlsx-Strukturen haben können + # ------------------------------------------------------------------ # + def process_excel_source(self, filepath: str) -> Tuple[Optional[Dict[str, List[Mapping[str, Any]]]], pruef_ergebnis]: + """ + Liest eine Excel-Datei (.xlsx/.xls) mit dem ExcelImporter und gibt ein Dict + mit den Zeilen zurück sowie das vom Pruefmanager verarbeitete pruef_ergebnis. + + Rückgabe + ------- + - (data_dict, processed_pruef_ergebnis) + data_dict: {'rows': [Mapping,...]} oder None bei Fehlern + processed_pruef_ergebnis: das Ergebnis, nachdem der Pruefmanager das + interne pruef_ergebnis verarbeitet hat. + """ + importer = ExcelImporter(filepath=filepath, pruefmanager=self.pruefmanager) + rows = importer.import_xlsx() # erwartet: List[Mapping[str, Any]] + data = {"rows": rows} + pe_ok = pruef_ergebnis(ok=True, meldung="Excel erfolgreich gelesen", aktion="ok", kontext=filepath) + processed = self.pruefmanager.verarbeite(pe_ok) + return data, processed + + # ------------------------------------------------------------------ # + # Einzellink-Verarbeitung + # ------------------------------------------------------------------ # + def process_single_link(self, link: str) -> Tuple[Optional[Dict[str, List[Mapping[str, Any]]]], pruef_ergebnis]: + """ + Verarbeitet einen Einzellink. + + Ablauf + ------ + 1. Führt die fachliche Prüfung über self.link_pruefer.pruefe(link) aus. + 2. Übergibt das Ergebnis an den Pruefmanager (self.pruefmanager.verarbeite). + 3. Wenn die Prüfung nicht OK ist, wird nur das verarbeitete pruef_ergebnis zurückgegeben. + 4. Wenn die Prüfung OK ist, erwartet diese Implementierung, dass der Prüfer + die Link-Parameter im pruef_ergebnis.kontext als Mapping bereitstellt. + Dieses Mapping wird unverändert in ein Dict {'rows': [kontext]} überführt + und zusammen mit dem verarbeiteten pruef_ergebnis zurückgegeben. + + Hinweis + ------ + Diese Funktion enthält keine Fallbacks, keine normalize-/load-Aufrufe und + keine zusätzlichen Validierungen. Der Linkpruefer ist verantwortlich dafür, + bei OK ein geeignetes Mapping im pruef_ergebnis.kontext bereitzustellen. + """ + # 1) Fachliche Prüfung durch den Linkpruefer + pe = self.link_pruefer.pruefe(link) + + # 2) Pruefmanager verarbeiten lassen (Logging / UI / Entscheidung) + processed = self.pruefmanager.verarbeite(pe) + + # 3) Wenn Prüfung nicht OK -> nur das verarbeitete pruef_ergebnis zurückgeben + if not getattr(processed, "ok", False): + return None, processed + + # 4) Prüfung OK -> Prüfer liefert die Link-Parameter im pruef_ergebnis.kontext + kontext = getattr(pe, "kontext", None) + data = {"rows": [kontext]} + # Erwartung: kontext ist ein Mapping mit den Link-Parametern. + # Wir übergeben es unverändert in das rows-Format. + return data, processed + + + # ------------------------------------------------------------------ # + # Datenbank-Verarbeitung + # ------------------------------------------------------------------ # + #def process_database_table(self, db_path: str, table: Optional[str] = None) -> Tuple[Optional[Dict[str, List[Mapping[str, Any]]]], pruef_ergebnis]: + #noch nicht implementiert + """ + Liest eine Tabelle aus einer SQLite/GeoPackage-Datei. + + Verhalten + --------- + 1. Validiert die Datei mit dem Dateipruefer. + 2. Falls OK, versucht es, die angegebene Tabelle zu lesen; falls keine Tabelle + angegeben ist, wird nach einer typischen Metadaten-Tabelle 'layer_metadaten' + gesucht und diese gelesen. + 3. Gibt die Zeilen als Liste von Dicts zurück. + """ + dp = self._datei_pruefer_cls(pfad=db_path, temporaer_erlaubt=False) + pe = dp.pruefe() + processed = self.pruefmanager.verarbeite(pe) + if not getattr(processed, "ok", False): + return None, processed + + conn = sqlite3.connect(db_path) + cur = conn.cursor() + if table: + cur.execute(f"SELECT * FROM {table}") + cols = [d[0] for d in cur.description] + rows = [dict(zip(cols, r)) for r in cur.fetchall()] + else: + cur.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='layer_metadaten'") + if cur.fetchone(): + cur.execute("SELECT * FROM layer_metadaten") + cols = [d[0] for d in cur.description] + rows = [dict(zip(cols, r)) for r in cur.fetchall()] + else: + rows = [] + conn.close() + + pe_ok = pruef_ergebnis(ok=True, meldung="DB gelesen", aktion="ok", kontext=db_path) + processed_ok = self.pruefmanager.verarbeite(pe_ok) + return {"rows": rows}, processed_ok + + # ------------------------------------------------------------------ # + # Hauptlauf / Dispatch + # ------------------------------------------------------------------ # + def run(self) -> Dict[str, Any]: + """ + Hauptmethode des DataGrabbers. + + Ablauf + ------ + 1. Prüft, ob eine Quelle gesetzt ist. + 2. Klassifiziert die Quelle via :meth:`analyze_source`. + 3. Dispatch: + - file (.xlsx/.xls) -> :meth:`process_excel_source` + - link -> :meth:`process_single_link` + - database -> :meth:`process_database_table` + - unknown -> Fehler + 4. Aggregiert geladene Einträge in einem Ergebnis-Dict und gibt dieses zurück. + + Rückgabeformat + ------------- + Ein Dict mit den Schlüsseln: + - 'geladen' : Liste der geladenen Themen/Namen + - 'fehler' : Mapping Thema -> Fehlermeldung + - 'ausserhalb': Liste der als ausserhalb klassifizierten Themen + - 'relevant' : Liste der relevanten Themen + - 'details' : zusätzliche Detailinformationen (z. B. Anzahl Zeilen) + """ + result: Dict[str, Any] = {"geladen": [], "fehler": {}, "ausserhalb": [], "relevant": [], "details": {}} + + if not self.source: + pe = pruef_ergebnis(ok=False, meldung="Keine Quelle gesetzt", aktion="kein_dateipfad", kontext=None) + processed = self.pruefmanager.verarbeite(pe) + result["fehler"]["source"] = getattr(processed, "meldung", "Keine Quelle") + return result + + src_type = self.analyze_source(self.source) + + if src_type == "file": + suffix = Path(self.source).suffix.lower() + if suffix in (".xlsx", ".xls"): + data_dict, pe = self.process_excel_source(self.source) + else: + pe = pruef_ergebnis(ok=False, meldung="Dateityp nicht unterstützt", aktion="falsche_endung", kontext=self.source) + pe = self.pruefmanager.verarbeite(pe) + data_dict = None + + elif src_type == "link": + data_dict, pe = self.process_single_link(self.source) + + #elif src_type == "database": + #data_dict, pe = self.process_database_table(self.source, table=None) + + else: + pe = pruef_ergebnis(ok=False, meldung="Quelle unbekannt", aktion="kein_dateipfad", kontext=self.source) + pe = self.pruefmanager.verarbeite(pe) + data_dict = None + + # Falls Daten vorhanden: fülle result['geladen'] und details + if data_dict and "rows" in data_dict: + rows = data_dict["rows"] + for r in rows: + thema = r.get("Inhalt") or r.get("ident") or r.get("Link") or "unbenannt" + result["geladen"].append(thema) + result["details"]["source_rows"] = len(rows) + + # Falls das letzte pruef_ergebnis einen Fehler enthält, übernehme es + if not getattr(pe, "ok", False): + result["fehler"]["source"] = getattr(pe, "meldung", "Fehler bei Quelle") + + return result diff --git a/modules/Dateipruefer.py b/modules/Dateipruefer.py index cb4e6af..31e5c25 100644 --- a/modules/Dateipruefer.py +++ b/modules/Dateipruefer.py @@ -39,7 +39,7 @@ class Dateipruefer: def _pfad(self, relativer_pfad: str) -> Path: """ - Erzeugt einen OS‑unabhängigen Pfad relativ zum Basisverzeichnis. + Erzeugt einen OS-unabhängigen Pfad relativ zum Basisverzeichnis. """ return join_path(self.basis_pfad, relativer_pfad) @@ -119,7 +119,7 @@ class Dateipruefer: ok=False, meldung=( "Es wurde keine Datei angegeben. " - "Soll eine temporäre Datei erzeugt werden?" + "Sollen temporäre Layer erzeugt werden?" ), aktion="temporaer_erlaubt", kontext=None, diff --git a/modules/Pruefmanager.py b/modules/Pruefmanager.py index 4a0a85c..a7a8910 100644 --- a/modules/Pruefmanager.py +++ b/modules/Pruefmanager.py @@ -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 diff --git a/modules/excel_importer.py b/modules/excel_importer.py new file mode 100644 index 0000000..50f8913 --- /dev/null +++ b/modules/excel_importer.py @@ -0,0 +1,91 @@ +# sn_plan41/modules/excel_importer.py +import os +from typing import Optional, Iterable, Mapping, Any, List, cast + +from openpyxl import load_workbook +from openpyxl.workbook.workbook import Workbook +from openpyxl.worksheet.worksheet import Worksheet + +from sn_basis.modules.Dateipruefer import Dateipruefer +from sn_basis.modules.Pruefmanager import Pruefmanager +from sn_basis.modules.pruef_ergebnis import pruef_ergebnis + + +class ExcelImporter: + """ + Excel-Importer für Linklisten, verwendet Dateipruefer und Pruefmanager zur Meldungsbehandlung. + + - Der Aufrufer übergibt einen konkreten Dateipfad. + - Vor dem Öffnen wird der Pfad mit Dateipruefer geprüft. + - Link- und Stilprüfungen erfolgen nicht hier, sondern im DataGrabber. + - Nach dem Ladevorgang wird die Arbeitsmappe geschlossen, damit die Datei vom OS freigegeben wird. + """ + + def __init__(self, filepath: str, pruefmanager: Pruefmanager): + if not filepath: + raise ValueError("ExcelImporter benötigt einen gültigen Dateipfad.") + if pruefmanager is None: + raise ValueError("ExcelImporter benötigt einen Pruefmanager.") + self.filepath = filepath + self.pruefmanager = pruefmanager + + def import_xlsx(self) -> List[Mapping[str, Any]]: + """ + Liest die Excel-Datei und gibt eine Liste von Dicts (Zeilen) zurück. + Bei Prüf- oder Leseproblemen wird der Pruefmanager zur Verarbeitung des pruef_ergebnis aufgerufen. + Im Fehlerfall wird eine leere Liste zurückgegeben. + """ + # 1) Dateiprüfung über Dateipruefer + datei_pruefer = Dateipruefer(pfad=self.filepath, temporaer_erlaubt=False) + ergebnis: pruef_ergebnis = datei_pruefer.pruefe() + ergebnis = self.pruefmanager.verarbeite(ergebnis) + + if not ergebnis.ok: + return [] + + workbook: Optional[Workbook] = None + try: + workbook = load_workbook(filename=self.filepath, data_only=True) + + # workbook.active kann typmäßig als Optional angesehen werden; cast/prüfen, damit Pylance weiß, dass sheet ein Worksheet ist + sheet = workbook.active + if sheet is None: + pe = pruef_ergebnis(ok=False, meldung=f"Kein aktives Blatt in der Arbeitsmappe: {self.filepath}", aktion="kein_arbeitsblatt", kontext=self.filepath) + self.pruefmanager.verarbeite(pe) + return [] + + # Typengranularität für den Linter + sheet = cast(Worksheet, sheet) + + # Header aus erster Zeile (als Werte) + header_row = next(sheet.iter_rows(min_row=1, max_row=1, values_only=True), None) + if not header_row: + pe = pruef_ergebnis(ok=False, meldung=f"Excel-Datei enthält keine Header-Zeile: {self.filepath}", aktion="kein_header", kontext=self.filepath) + self.pruefmanager.verarbeite(pe) + return [] + + header = list(header_row) + if not header or all(h is None for h in header): + pe = pruef_ergebnis(ok=False, meldung=f"Excel-Header ist leer oder ungültig: {self.filepath}", aktion="kein_header", kontext=self.filepath) + self.pruefmanager.verarbeite(pe) + return [] + + ergebnis_list: List[Mapping[str, Any]] = [] + # Werte-only lesen für Performance und Einfachheit + for row in sheet.iter_rows(min_row=2, values_only=True): + if row is None: + continue + # zip stoppt bei kürzerer Länge; das ist beabsichtigt + attributes = dict(zip(header, row)) + ergebnis_list.append(attributes) + + return ergebnis_list + + except Exception as exc: + pe = pruef_ergebnis(ok=False, meldung=f"Fehler beim Lesen der Excel-Datei '{self.filepath}': {exc}", aktion="read_error", kontext=self.filepath) + self.pruefmanager.verarbeite(pe) + return [] + + finally: + if workbook is not None: + workbook.close() diff --git a/modules/layerpruefer.py b/modules/layerpruefer.py index 164f9cf..3718a31 100644 --- a/modules/layerpruefer.py +++ b/modules/layerpruefer.py @@ -2,7 +2,7 @@ sn_basis/modules/layerpruefer.py – Prüfung von QGIS-Layern. Verwendet ausschließlich Wrapper und gibt pruef_ergebnis zurück. """ - +from typing import Optional, Any from sn_basis.functions import ( layer_exists, get_layer_geometry_type, @@ -26,7 +26,7 @@ class Layerpruefer: def __init__( self, - layer, + layer:Optional[Any]=None, erwarteter_geotyp: str | None = None, muss_sichtbar_sein: bool = False, erwarteter_layertyp: str | None = None, diff --git a/modules/linkpruefer.py b/modules/linkpruefer.py index 6f59306..a94e863 100644 --- a/modules/linkpruefer.py +++ b/modules/linkpruefer.py @@ -32,7 +32,7 @@ class Linkpruefer: def _pfad(self, relativer_pfad: str) -> Path: """ - Erzeugt einen OS‑unabhängigen Pfad relativ zum Basisverzeichnis. + Erzeugt einen OS-unabhängigen Pfad relativ zum Basisverzeichnis. """ if not self.basis: return Path(relativer_pfad) @@ -79,7 +79,7 @@ class Linkpruefer: def _pruefe_url(self, url: str) -> pruef_ergebnis: """ - Prüft eine URL über einen HEAD‑Request. + Prüft eine URL über einen HEAD-Request. """ reply = network_head(url) diff --git a/modules/pruef_ergebnis.py b/modules/pruef_ergebnis.py index 084f314..c7313be 100644 --- a/modules/pruef_ergebnis.py +++ b/modules/pruef_ergebnis.py @@ -1,14 +1,8 @@ -""" -sn_basis/modules/pruef_ergebnis.py – Ergebnisobjekt für alle Prüfer. -""" - +from __future__ import annotations from dataclasses import dataclass -from pathlib import Path from typing import Any, Optional, Literal - -# Alle möglichen Aktionen, die ein Prüfer auslösen kann. -# Erweiterbar ohne Umbau der Klasse. +# Erweitertes Literal mit allen erlaubten Aktionen (PruefAktion) PruefAktion = Literal[ "ok", "leer", @@ -16,34 +10,52 @@ PruefAktion = Literal[ "leereingabe_nicht_erlaubt", "standarddatei_vorschlagen", "temporaer_erlaubt", + "temporaer_erzeugen", "datei_nicht_gefunden", "kein_dateipfad", "pfad_nicht_gefunden", "url_nicht_erreichbar", "netzwerkfehler", - "falscher_layertyp", + "layer_nicht_gefunden", + "layer_unsichtbar", "falscher_geotyp", "layer_leer", + "falscher_layertyp", "falsches_crs", "felder_fehlen", "datenquelle_unerwartet", "layer_nicht_editierbar", - "temporaer_erzeugen", - "stil_nicht_anwendbar", - "layer_unsichtbar", - "layer_nicht_gefunden", - "unbekannt", - "stil_anwendbar", "falsche_endung", + # Excel / Import-spezifische Aktionen + "kein_header", + "kein_arbeitsblatt", + "read_error", + "open_error", + # Generische Prüf-/Speicher-Aktionen + "pruefe_exception", + "save_exception", + "save_not_implemented", + "stil_not_implemented", + "datei_unbekannt", + "needs_user_action", ] - - -@dataclass(slots=True) +@dataclass class pruef_ergebnis: + """ + Einheitliches Ergebnisobjekt für Prüfer. + - ok: True wenn Prüfung bestanden + - meldung: menschenlesbare Meldung + - aktion: maschinenlesbarer Aktionscode (PruefAktion) + - kontext: optionaler Zusatzkontext (z. B. Pfad, Layer-Objekt) + """ ok: bool - meldung: str - aktion: PruefAktion + meldung: Optional[str] = None + aktion: Optional[PruefAktion] = None kontext: Optional[Any] = None - + def __init__(self, ok: bool, meldung: Optional[str] = None, aktion: Optional[PruefAktion] = None, kontext: Optional[Any] = None): + self.ok = ok + self.meldung = meldung + self.aktion = aktion + self.kontext = kontext