forked from AG_QGIS/Plugin_SN_Basis
fix QGIS 4.0-Kompatibilität;
Linkpruefer-Eingabe als String normalisiert, falls Paf-Objekte übergeben werden
This commit is contained in:
15
metadata.txt
Normal file
15
metadata.txt
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
[general]
|
||||||
|
name=LNO Sachsen | Basisfunktionen
|
||||||
|
description=Plugin mit Basisfunktionen
|
||||||
|
author=Michael Otto
|
||||||
|
email=michael.otto@landkreis-mittelsachsen.de
|
||||||
|
homepage=https://entwicklung.flurneuordnung-sachsen.de/AG_QGIS/Plugin_SN_Basis
|
||||||
|
repository=https://entwicklung.flurneuordnung-sachsen/AG_QGIS/Repository
|
||||||
|
qgisMinimumVersion=3.40
|
||||||
|
qgisMaximumVersion=4.99
|
||||||
|
version=26.3.11
|
||||||
|
deprecated=False
|
||||||
|
experimental=true
|
||||||
|
supportsQt6=Yes
|
||||||
|
|
||||||
|
zip_folder=sn_basis
|
||||||
@@ -2,14 +2,14 @@
|
|||||||
DataGrabber module
|
DataGrabber module
|
||||||
==================
|
==================
|
||||||
|
|
||||||
UI‑freier Orchestrator für die Prüfung und Klassifikation von Datenquellen.
|
UI-freier Orchestrator für die Prüfung und Klassifikation von Datenquellen.
|
||||||
|
|
||||||
Der DataGrabber:
|
Der DataGrabber:
|
||||||
- klassifiziert die übergebene Quelle (Datei, Dienst, Datenbank, Excel),
|
- klassifiziert die übergebene Quelle (Datei, Dienst, Datenbank, Excel),
|
||||||
- ruft passende Prüfer (Dateipruefer, Linkpruefer, Layerpruefer, Stilpruefer) auf,
|
- ruft passende Prüfer (Dateipruefer, Linkpruefer, Layerpruefer, Stilpruefer) auf,
|
||||||
- sammelt alle rohen ``pruef_ergebnis``‑Objekte,
|
- sammelt alle rohen ``pruef_ergebnis``-Objekte,
|
||||||
- aggregiert diese zu einem zusammenfassenden Ergebnis,
|
- aggregiert diese zu einem zusammenfassenden Ergebnis,
|
||||||
- **löst selbst keinerlei UI‑Interaktion aus**.
|
- **löst selbst keinerlei UI-Interaktion aus**.
|
||||||
|
|
||||||
Alle Nutzerinteraktionen (MessageBar, QMessageBox, Logging) erfolgen
|
Alle Nutzerinteraktionen (MessageBar, QMessageBox, Logging) erfolgen
|
||||||
ausschließlich über den ``Pruefmanager`` im aufrufenden Kontext (UI / Pipeline).
|
ausschließlich über den ``Pruefmanager`` im aufrufenden Kontext (UI / Pipeline).
|
||||||
@@ -38,9 +38,6 @@ class DataGrabber:
|
|||||||
"""
|
"""
|
||||||
Analysiert und prüft Datenquellen für den Fachdatenabruf.
|
Analysiert und prüft Datenquellen für den Fachdatenabruf.
|
||||||
|
|
||||||
Der DataGrabber ist **UI‑frei**. Er erzeugt ausschließlich rohe
|
|
||||||
``pruef_ergebnis``‑Objekte und überlässt deren Verarbeitung
|
|
||||||
vollständig dem aufrufenden Code.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
@@ -69,19 +66,60 @@ class DataGrabber:
|
|||||||
"""Setzt die aktuell zu untersuchende Rohquelle."""
|
"""Setzt die aktuell zu untersuchende Rohquelle."""
|
||||||
self._source = source
|
self._source = source
|
||||||
|
|
||||||
def analyze_source_type(self, source: str) -> SourceType:
|
from pathlib import Path
|
||||||
"""
|
from typing import Tuple
|
||||||
Klassifiziert die Quelle.
|
|
||||||
|
|
||||||
Aktuell Platzhalter – liefert ``"unknown"``.
|
|
||||||
|
SourceType = str # "excel" | "datenbank" | "dienst" | "unbekannt"
|
||||||
|
|
||||||
|
|
||||||
|
def analyze_source_type(self, quelle: str) -> Tuple[SourceType, pruef_ergebnis]:
|
||||||
"""
|
"""
|
||||||
return "unknown"
|
Klassifiziert die Quelle und liefert das zugehörige pruef_ergebnis.
|
||||||
|
|
||||||
|
Reihenfolge:
|
||||||
|
1. Dateipruefer (Datei + Dateityp)
|
||||||
|
2. Linkpruefer (Dienst)
|
||||||
|
"""
|
||||||
|
|
||||||
|
# --------------------------------------------------
|
||||||
|
# 1. Datei prüfen (inkl. Typ-Erkennung)
|
||||||
|
# --------------------------------------------------
|
||||||
|
dateipruefer = Dateipruefer(pfad=quelle)
|
||||||
|
datei_ergebnis = dateipruefer.pruefe()
|
||||||
|
|
||||||
|
if datei_ergebnis.ok:
|
||||||
|
pfad = Path(datei_ergebnis.kontext)
|
||||||
|
suffix = pfad.suffix.lower()
|
||||||
|
|
||||||
|
if suffix == ".xlsx":
|
||||||
|
return "excel", datei_ergebnis
|
||||||
|
|
||||||
|
if suffix in (".gpkg", ".sqlite"):
|
||||||
|
return "datenbank", datei_ergebnis
|
||||||
|
|
||||||
|
return "unbekannter_dateityp", datei_ergebnis
|
||||||
|
|
||||||
|
# --------------------------------------------------
|
||||||
|
# 2. Keine Datei → Link prüfen
|
||||||
|
# --------------------------------------------------
|
||||||
|
linkpruefer = Linkpruefer()
|
||||||
|
link_ergebnis = linkpruefer.pruefe(quelle)
|
||||||
|
|
||||||
|
if link_ergebnis.ok:
|
||||||
|
return "dienst", link_ergebnis
|
||||||
|
|
||||||
|
# --------------------------------------------------
|
||||||
|
# 3. Weder Datei noch Dienst
|
||||||
|
# --------------------------------------------------
|
||||||
|
|
||||||
|
return "unbekannte_quelle", link_ergebnis
|
||||||
|
|
||||||
def run(self, source: str) -> Tuple[SourceDict, pruef_ergebnis]:
|
def run(self, source: str) -> Tuple[SourceDict, pruef_ergebnis]:
|
||||||
"""
|
"""
|
||||||
Führt die vollständige Quellprüfung aus.
|
Führt die vollständige Quellprüfung aus.
|
||||||
|
|
||||||
Diese Methode ist **UI‑frei**. Sie gibt rohe Ergebnisse zurück,
|
Diese Methode ist **UIfrei**. Sie gibt rohe Ergebnisse zurück,
|
||||||
die vom Aufrufer über den ``Pruefmanager`` verarbeitet werden.
|
die vom Aufrufer über den ``Pruefmanager`` verarbeitet werden.
|
||||||
"""
|
"""
|
||||||
self.set_source(source)
|
self.set_source(source)
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ der Anforderungen 1-2.e (leerer Pfad, fehlende Datei, bestehende Datei).
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Optional
|
from typing import Optional, Literal
|
||||||
|
|
||||||
from sn_basis.functions.sys_wrapper import join_path, file_exists
|
from sn_basis.functions.sys_wrapper import join_path, file_exists
|
||||||
from sn_basis.modules.pruef_ergebnis import pruef_ergebnis, PruefAktion
|
from sn_basis.modules.pruef_ergebnis import pruef_ergebnis, PruefAktion
|
||||||
|
DateiTyp = Literal["excel","datenbank","unbekannt"]
|
||||||
|
|
||||||
class Dateipruefer:
|
class Dateipruefer:
|
||||||
"""
|
"""
|
||||||
@@ -74,10 +74,25 @@ class Dateipruefer:
|
|||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
# Hilfsfunktionen
|
# Hilfsfunktionen
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
|
def erkenne_dateityp(self, pfad: Path) -> DateiTyp:
|
||||||
|
"""
|
||||||
|
Erkennt den Dateityp anhand der Endung.
|
||||||
|
"""
|
||||||
|
suffix = pfad.suffix.lower()
|
||||||
|
|
||||||
|
if suffix == ".xlsx":
|
||||||
|
return "excel"
|
||||||
|
|
||||||
|
if suffix in (".gpkg", ".sqlite"):
|
||||||
|
return "datenbank"
|
||||||
|
|
||||||
|
return "unbekannt"
|
||||||
|
|
||||||
def _pfad(self, relativer_pfad: str) -> Path:
|
def _pfad(self, relativer_pfad: str) -> Path:
|
||||||
"""Erzeugt OS-unabhängigen Pfad relativ zum Basisverzeichnis."""
|
"""Erzeugt OS-unabhängigen Pfad relativ zum Basisverzeichnis."""
|
||||||
return join_path(self.basis_pfad, relativer_pfad)
|
return join_path(self.basis_pfad, relativer_pfad)
|
||||||
|
|
||||||
|
|
||||||
def _ist_leer(self) -> bool:
|
def _ist_leer(self) -> bool:
|
||||||
"""
|
"""
|
||||||
Prüft robust, ob Eingabe als „leer" zu behandeln ist.
|
Prüft robust, ob Eingabe als „leer" zu behandeln ist.
|
||||||
@@ -134,6 +149,31 @@ class Dateipruefer:
|
|||||||
|
|
||||||
# 2. Pfad normalisieren
|
# 2. Pfad normalisieren
|
||||||
pfad = self._pfad(self.pfad.strip())
|
pfad = self._pfad(self.pfad.strip())
|
||||||
|
#Excel-dateien erkennen
|
||||||
|
dateityp = self.erkenne_dateityp(pfad)
|
||||||
|
|
||||||
|
if dateityp == "excel":
|
||||||
|
if not file_exists(pfad):
|
||||||
|
return pruef_ergebnis(
|
||||||
|
ok=False,
|
||||||
|
meldung=f"Excel-Datei '{self.pfad}' wurde nicht gefunden.",
|
||||||
|
aktion="datei_nicht_gefunden",
|
||||||
|
kontext=pfad,
|
||||||
|
)
|
||||||
|
|
||||||
|
return pruef_ergebnis(
|
||||||
|
ok=True,
|
||||||
|
meldung="Excel-Datei ist gültig.",
|
||||||
|
aktion="ok",
|
||||||
|
kontext=pfad,
|
||||||
|
)
|
||||||
|
if dateityp != "datenbank":
|
||||||
|
return pruef_ergebnis(
|
||||||
|
ok=False,
|
||||||
|
meldung=f"Der Pfad '{self.pfad}' ist kein unterstützter Dateityp.",
|
||||||
|
aktion="unbekannter_dateityp",
|
||||||
|
kontext=pfad,
|
||||||
|
)
|
||||||
|
|
||||||
# 🆕 2.c: Ungültiger GPKG-Pfad?
|
# 🆕 2.c: Ungültiger GPKG-Pfad?
|
||||||
if not self.verfahrens_db_modus or not self._ist_gueltiger_gpkg_pfad(pfad):
|
if not self.verfahrens_db_modus or not self._ist_gueltiger_gpkg_pfad(pfad):
|
||||||
|
|||||||
@@ -61,7 +61,8 @@ class Linkpruefer:
|
|||||||
aktion="leer",
|
aktion="leer",
|
||||||
kontext=None,
|
kontext=None,
|
||||||
)
|
)
|
||||||
|
#evtl. Pfad-Objekte in string umwandeln
|
||||||
|
eingabe = str(eingabe)
|
||||||
# -----------------------------------------------------
|
# -----------------------------------------------------
|
||||||
# 1. Fall: URL
|
# 1. Fall: URL
|
||||||
# -----------------------------------------------------
|
# -----------------------------------------------------
|
||||||
|
|||||||
@@ -43,6 +43,13 @@ PruefAktion = Literal[
|
|||||||
# Dateiendung/Format
|
# Dateiendung/Format
|
||||||
"falsche_endung",
|
"falsche_endung",
|
||||||
"pflichtfelder_fehlen",
|
"pflichtfelder_fehlen",
|
||||||
|
"unbekannter_dateityp",
|
||||||
|
"Datenbank",
|
||||||
|
"dienst",
|
||||||
|
"excel",
|
||||||
|
"unbekannte_quelle",
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Excel/Import
|
# Excel/Import
|
||||||
"kein_header",
|
"kein_header",
|
||||||
@@ -51,6 +58,8 @@ PruefAktion = Literal[
|
|||||||
"open_error",
|
"open_error",
|
||||||
"datenabruf",
|
"datenabruf",
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 🆕 VERFAHRENS-DB SPEZIFISCH (deine Anforderungen 2.d, 2.e)
|
# 🆕 VERFAHRENS-DB SPEZIFISCH (deine Anforderungen 2.d, 2.e)
|
||||||
"datei_wird_erzeugt", # 2.d: Pfad gültig, Datei fehlt → weiter
|
"datei_wird_erzeugt", # 2.d: Pfad gültig, Datei fehlt → weiter
|
||||||
"datei_existiert", # Datei vorhanden → Layer-Entscheidung
|
"datei_existiert", # Datei vorhanden → Layer-Entscheidung
|
||||||
|
|||||||
11
plugin.info
11
plugin.info
@@ -1,11 +0,0 @@
|
|||||||
name=LNO Sachsen | Basisfunktionen
|
|
||||||
description=Plugin mit Basisfunktionen
|
|
||||||
author=Daniel Helbig
|
|
||||||
email=daniel.helbig@kreis-meissen.de
|
|
||||||
qgisMinimumVersion=3.0
|
|
||||||
qgisMaximumVersion=3.99
|
|
||||||
deprecated=False
|
|
||||||
experimental=False
|
|
||||||
supportsQt6=Yes
|
|
||||||
|
|
||||||
zip_folder=sn_basis
|
|
||||||
Reference in New Issue
Block a user