Auf Wrapper umgestellt, Prüfarchitektur QT6-kompatibel gemacht (Nicht lauffähig)

This commit is contained in:
2025-12-18 22:00:31 +01:00
parent f64d56d4bc
commit e8fea163b5
31 changed files with 2791 additions and 889 deletions

View File

@@ -1,100 +1,126 @@
#Modul zur Prüfung und zum Exception Handling für Dateieingaben
#Dateipruefer.py
"""
sn_basis/modulesdateipruefer.py Prüfung von Dateieingaben für das Plugin.
Verwendet syswrapper und gibt pruef_ergebnis an den Pruefmanager zurück.
"""
import os
from enum import Enum, auto
from sn_basis.functions.syswrapper import (
file_exists,
is_file,
join_path,
)
from sn_basis.modules.Pruefmanager import pruef_ergebnis
# -------------------------------
# ENUMS
# -------------------------------
class LeererPfadModus(Enum):#legt die modi fest, die für Dateipfade möglich sind
VERBOTEN = auto() #ein leeres Eingabefeld stellt einen Fehler dar
NUTZE_STANDARD = auto() #ein leeres Eingabefeld fordert zur Entscheidung auf: nutze Standard oder brich ab
TEMPORAER_ERLAUBT = auto() #ein leeres Eingabefeld fordert zur Entscheidung auf: arbeite temporär oder brich ab.
class DateiEntscheidung(Enum):#legt die Modi fest, wie mit bestehenden Dateien umgegangen werden soll (hat das das QGSFile-Objekt schon selbst?)
ERSETZEN = auto()#Ergebnis der Nutzerentscheidung: bestehende Datei ersetzen
ANHAENGEN = auto()#Ergebnis der Nutzerentscheidung: an bestehende Datei anhängen
ABBRECHEN = auto()#bricht den Vorgang ab. (muss das eine definierte Option sein? oder geht das auch mit einem normalen Abbruch-Button)
# -------------------------------
# RÜCKGABEOBJEKT
# -------------------------------
#Das Dateiprüfergebnis wird an den Prüfmanager übergeben. Alle GUI-Abfragen werden im Prüfmanager behandelt.
class DateipruefErgebnis:
#Definition der Parameter und Festlegung auf den Parametertyp,bzw den Standardwert
def __init__(self, erfolgreich: bool, pfad: str = None, temporär: bool = False,
entscheidung: DateiEntscheidung = None, fehler: list = None):
self.erfolgreich = erfolgreich
self.pfad = pfad
self.temporär = temporär
self.entscheidung = entscheidung
self.fehler = fehler or []
def __repr__(self):
return (f"DateipruefErgebnis(erfolgreich={self.erfolgreich}, "
f"pfad={repr(self.pfad)}, temporär={self.temporär}, "
f"entscheidung={repr(self.entscheidung)}, fehler={repr(self.fehler)})")
# -------------------------------
# DATEIPRÜFER
# -------------------------------
class Dateipruefer:
def pruefe(self, pfad: str,
leer_modus: LeererPfadModus,
standardname: str = None,
plugin_pfad: str = None,
vorhandene_datei_entscheidung: DateiEntscheidung = None) -> DateipruefErgebnis: #Rückgabetypannotation; "Die Funktion "pruefe" gibt ein Objekt vom Typ "DateipruefErgebnis" zurück
"""
Prüft Dateieingaben und liefert ein pruef_ergebnis zurück.
Die eigentliche Nutzerinteraktion übernimmt der Pruefmanager.
"""
# 1. Prüfe, ob das Eingabefeld leer ist
if not pfad or pfad.strip() == "":#wenn der angegebene Pfad leer oder ungültig ist:
if leer_modus == LeererPfadModus.VERBOTEN: #wenn der Modus "verboten" vorgegeben ist, gib zurück, dass der Test fehlgeschlagen ist
return DateipruefErgebnis(
erfolgreich=False,
fehler=["Kein Pfad angegeben."]
)
elif leer_modus == LeererPfadModus.NUTZE_STANDARD:#wenn der Modus "Nutze_Standard" vorgegeben ist...
if not plugin_pfad or not standardname:#wenn kein gültiger Pluginpfad angegeben ist oder die Standarddatei fehlt...
return DateipruefErgebnis(
erfolgreich=False,
fehler=["Standardpfad oder -name fehlen."]#..gib zurück, dass der Test fehlgeschlagen ist
)
pfad = os.path.join(plugin_pfad, standardname)#...wenn es Standarddatei und Pluginpfad gibt...setze sie zum Pfad zusammen...
elif leer_modus == LeererPfadModus.TEMPORAER_ERLAUBT:#wenn der Modus "temporär" vorgegeben ist,...
return DateipruefErgebnis(#...gib zurück, dass das Prüfergebnis erfolgreich ist (Entscheidung, ob temporör gearbeitet werden soll oder nicht, kommt woanders)
erfolgreich=True,
pfad=None
)
def __init__(
self,
pfad: str,
basis_pfad: str = "",
leereingabe_erlaubt: bool = False,
standarddatei: str | None = None,
temporaer_erlaubt: bool = False,
):
self.pfad = pfad
self.basis_pfad = basis_pfad
self.leereingabe_erlaubt = leereingabe_erlaubt
self.standarddatei = standarddatei
self.temporaer_erlaubt = temporaer_erlaubt
# 2. Existiert die Datei bereits?
if os.path.exists(pfad):#wenn die Datei vorhanden ist...
if not vorhandene_datei_entscheidung:#aber noch keine Entscheidung getroffen ist...
return DateipruefErgebnis(
erfolgreich=True,#ist die Prüfung erfolgreich, aber es muss noch eine Entscheidung verlangt werden
pfad=pfad,
entscheidung=None,
fehler=["Datei existiert bereits Entscheidung ausstehend."]
)
if vorhandene_datei_entscheidung == DateiEntscheidung.ABBRECHEN:
return DateipruefErgebnis(#...der Nutzer aber abgebrochen hat...
erfolgreich=False,#ist die Prüfung fehlgeschlagen ISSUE: ergibt das Sinn?
pfad=pfad,
fehler=["Benutzer hat abgebrochen."]
)
# ---------------------------------------------------------
# Hilfsfunktion
# ---------------------------------------------------------
return DateipruefErgebnis(
erfolgreich=True,
def _pfad(self, relativer_pfad: str) -> str:
"""Erzeugt einen OSunabhängigen Pfad relativ zum Basisverzeichnis."""
return join_path(self.basis_pfad, relativer_pfad)
# ---------------------------------------------------------
# Hauptfunktion
# ---------------------------------------------------------
def pruefe(self) -> pruef_ergebnis:
"""
Prüft eine Dateieingabe und liefert ein pruef_ergebnis zurück.
Der Pruefmanager entscheidet später, wie der Nutzer gefragt wird.
"""
# -----------------------------------------------------
# 1. Fall: Eingabe ist leer
# -----------------------------------------------------
if not self.pfad:
return self._handle_leere_eingabe()
# -----------------------------------------------------
# 2. Fall: Eingabe ist nicht leer → Datei prüfen
# -----------------------------------------------------
pfad = self._pfad(self.pfad)
if not file_exists(pfad) or not is_file(pfad):
return pruef_ergebnis(
ok=False,
meldung=f"Die Datei '{self.pfad}' wurde nicht gefunden.",
aktion="datei_nicht_gefunden",
pfad=pfad,
entscheidung=vorhandene_datei_entscheidung
)
# 3. Pfad gültig und Datei nicht vorhanden
#wenn alle Varianten NICHT zutreffen, weil ein gültiger Pfad eingegeben wurde und die Datei noch nicht vorhanden ist:
return DateipruefErgebnis(
erfolgreich=True,
pfad=pfad
# -----------------------------------------------------
# 3. Datei existiert → Erfolg
# -----------------------------------------------------
return pruef_ergebnis(
ok=True,
meldung="Datei gefunden.",
aktion="ok",
pfad=pfad,
)
# ---------------------------------------------------------
# Behandlung leerer Eingaben
# ---------------------------------------------------------
def _handle_leere_eingabe(self) -> pruef_ergebnis:
"""
Liefert ein pruef_ergebnis für den Fall, dass das Dateifeld leer ist.
Der Pruefmanager fragt später den Nutzer.
"""
# 1. Leereingabe erlaubt → Nutzer fragen, ob das beabsichtigt war
if self.leereingabe_erlaubt:
return pruef_ergebnis(
ok=False,
meldung="Das Dateifeld ist leer. Soll ohne Datei fortgefahren werden?",
aktion="leereingabe_erlaubt",
pfad=None,
)
# 2. Standarddatei verfügbar → Nutzer fragen, ob sie verwendet werden soll
if self.standarddatei:
return pruef_ergebnis(
ok=False,
meldung=f"Es wurde keine Datei angegeben. Soll die Standarddatei '{self.standarddatei}' verwendet werden?",
aktion="standarddatei_vorschlagen",
pfad=self._pfad(self.standarddatei),
)
# 3. Temporäre Datei erlaubt → Nutzer fragen, ob temporär gearbeitet werden soll
if self.temporaer_erlaubt:
return pruef_ergebnis(
ok=False,
meldung="Es wurde keine Datei angegeben. Soll eine temporäre Datei erzeugt werden?",
aktion="temporaer_erlaubt",
pfad=None,
)
# 4. Leereingabe nicht erlaubt → Fehler
return pruef_ergebnis(
ok=False,
meldung="Es wurde keine Datei angegeben.",
aktion="leereingabe_nicht_erlaubt",
pfad=None,
)