Feat: Interaktiver XSL-Abhängigkeitsgraph mit vis.js und THIRD_PARTY_LICENSES aktualisiert
XslDependencyDialog mit zwei Tabs: Baumansicht (vorwärts/rückwärts-Abhängigkeiten) und interaktiver Netzwerkgraph (vis.js in QWebEngineView mit Physics-Simulation, Hover-Tooltips, Nachbar-Hervorhebung). Graceful Fallback wenn WebEngine fehlt. THIRD_PARTY_LICENSES um psutil, PyInstaller, Pillow, vis-network ergänzt und Versionen aktualisiert. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
# Transformation ohne Force — Entscheidungslogik
|
||||
|
||||
Die zentrale Methode ist `is_up_to_date()` in transform.py:155-180. Sie basiert auf Modifikationszeiten (mtime), nicht auf Hashes.
|
||||
|
||||
## Ablauf
|
||||
Die Prüfung erfolgt an zwei Stellen in der Pipeline:
|
||||
1. Vor Saxon-Transformation (`transform_saxon()`) — transform.py:192-194
|
||||
2. Vor PDF-Build (`build_pdf()`) — transform.py:322-324
|
||||
|
||||
Beide rufen `is_up_to_date()` auf, die prüft:
|
||||
- Existiert die New-PDF?
|
||||
- Ist die XML-Datei neuer als die New-PDF?
|
||||
- Ist die XSL-Datei neuer als die New-PDF?
|
||||
|
||||
Wenn die New-PDF existiert und älter als alle Inputs ist → Transformation wird übersprungen mit `(True, "Übersprungen (aktuell)")`.
|
||||
|
||||
## Mermaid-Diagramm
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["Transformation gestartet<br/>(force=False)"] --> B{"force == True?"}
|
||||
B -- Ja --> EXEC["Transformation ausführen"]
|
||||
B -- Nein --> C{"New-PDF existiert?"}
|
||||
C -- Nein --> EXEC
|
||||
C -- Ja --> D["mtime der New-PDF ermitteln"]
|
||||
D --> E{"XML-Datei neuer<br/>als New-PDF?"}
|
||||
E -- Ja --> EXEC
|
||||
E -- Nein --> F{"XSL-Datei neuer<br/>als New-PDF?"}
|
||||
F -- Ja --> EXEC
|
||||
F -- Nein --> SKIP["Übersprungen (aktuell)<br/>return (True, 'Übersprungen')"]
|
||||
|
||||
EXEC --> S1["Schritt 1: Saxon<br/>XML → FO"]
|
||||
S1 --> S1OK{"Saxon erfolgreich?"}
|
||||
S1OK -- Nein --> FAIL["Pipeline abgebrochen"]
|
||||
S1OK -- Ja --> S2CHECK{"force == True?<br/>(erneute Prüfung<br/>für build_pdf)"}
|
||||
S2CHECK -- Ja --> S2["Schritt 2: FOP<br/>FO → PDF"]
|
||||
S2CHECK -- Nein --> S2UP{"is_up_to_date()?"}
|
||||
S2UP -- Ja --> S2SKIP["PDF-Build übersprungen"]
|
||||
S2UP -- Nein --> S2
|
||||
S2 --> S3["Schritt 3: diff-pdf<br/>PDF-Vergleich"]
|
||||
S3 --> DONE["Pipeline abgeschlossen"]
|
||||
|
||||
style SKIP fill:#4CAF50,color:#fff
|
||||
style EXEC fill:#2196F3,color:#fff
|
||||
style FAIL fill:#f44336,color:#fff
|
||||
style DONE fill:#4CAF50,color:#fff
|
||||
style S2SKIP fill:#4CAF50,color:#fff
|
||||
```
|
||||
## Wichtige Details
|
||||
- Keine Hash-basierte Prüfung: Die Skip-Logik nutzt ausschließlich `mtime`-Vergleiche, nicht die blake2b-Hashes (die werden nur für Änderungsverfolgung in der UI verwendet).
|
||||
- Doppelte Prüfung: `is_up_to_date()` wird sowohl vor Saxon als auch vor FOP aufgerufen — theoretisch könnte Saxon ausgeführt, aber der PDF-Build übersprungen werden.
|
||||
- Skip = Erfolg: Ein übersprungener Schritt gilt als erfolgreich `(True, ...)`, die Pipeline läuft weiter.
|
||||
- Force-Aufruf: Über das Kontextmenü gibt es explizite Force-Methoden wie `_transform_all_xml_files_force()` in transformation.py.
|
||||
|
||||
|
||||
## Erweiterung
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
LOAD["Projekt geladen"] --> BUILD["XSL-Abhängigkeitsgraph aufbauen<br/>dict[Path, set[Path]]"]
|
||||
BUILD --> CACHE["Im Speicher halten"]
|
||||
|
||||
TRANSFORM["is_up_to_date() aufgerufen"] --> CHECK{"Graph-Eintrag<br/>vorhanden?"}
|
||||
CHECK -- Nein --> PARSE["XSL parsen, Imports auflösen,<br/>Eintrag erstellen"]
|
||||
PARSE --> MTIME
|
||||
CHECK -- Ja --> STALE{"mtime der XSL<br/>geändert seit letztem Parse?"}
|
||||
STALE -- Ja --> PARSE
|
||||
STALE -- Nein --> MTIME["mtime aller Abhängigkeiten<br/>gegen New-PDF prüfen"]
|
||||
MTIME --> RESULT["Ergebnis"]
|
||||
```
|
||||
Reference in New Issue
Block a user