196 lines
5.3 KiB
Markdown
196 lines
5.3 KiB
Markdown
|
|
# Blake2b-Hash-Implementierung für XML-Dateien
|
||
|
|
|
||
|
|
## Übersicht
|
||
|
|
|
||
|
|
Diese Dokumentation beschreibt die Implementierung der automatischen blake2b-Hash-Berechnung für XML-Dateien in der XSL-Validator-Anwendung.
|
||
|
|
|
||
|
|
## Funktionalität
|
||
|
|
|
||
|
|
### Automatische Hash-Berechnung beim Projektladen
|
||
|
|
|
||
|
|
Beim Laden eines Projekts in der `MainWindow`-Klasse werden automatisch alle XML-Dateien auf fehlende `hashsum`-Eigenschaften geprüft. Für Dateien ohne Hash-Wert wird dieser asynchron im Hintergrund berechnet.
|
||
|
|
|
||
|
|
### Hash-Algorithmus
|
||
|
|
|
||
|
|
- **Algorithmus**: blake2b (aus Python's `hashlib`)
|
||
|
|
- **Präfix**: `blake2b:`
|
||
|
|
- **Format**: `blake2b:<64-stelliger-hex-hash>`
|
||
|
|
|
||
|
|
### Beispiel
|
||
|
|
|
||
|
|
```
|
||
|
|
blake2b:c0d6043a79e953f31921a68f008d20ef3bce5bc7f9613d0f53c3a3d3f0a5879e4a18b955f1741ddf190cf7769c1be47d4cf48246f455fa9f84e6599ce5b45119
|
||
|
|
```
|
||
|
|
|
||
|
|
## Technische Implementierung
|
||
|
|
|
||
|
|
### Erweiterte XmlFile-Klasse
|
||
|
|
|
||
|
|
Die `conf.XmlFile`-Klasse wurde um die optionale `hashsum`-Eigenschaft erweitert:
|
||
|
|
|
||
|
|
```python
|
||
|
|
class XmlFile(BaseModel):
|
||
|
|
xml: Path
|
||
|
|
hashsum: str | None = None # Neue Eigenschaft
|
||
|
|
```
|
||
|
|
|
||
|
|
### Asynchrone Hash-Berechnung
|
||
|
|
|
||
|
|
#### XmlHashCalculatorThread
|
||
|
|
|
||
|
|
Eine spezialisierte `QThread`-Klasse für die asynchrone Hash-Berechnung:
|
||
|
|
|
||
|
|
```python
|
||
|
|
class XmlHashCalculatorThread(QThread):
|
||
|
|
hash_calculated = pyqtSignal(object, str)
|
||
|
|
calculation_finished = pyqtSignal(int, int)
|
||
|
|
error_occurred = pyqtSignal(str, str)
|
||
|
|
```
|
||
|
|
|
||
|
|
**Hauptmethoden:**
|
||
|
|
- `_calculate_blake2b_hash()`: Berechnet den blake2b-Hash einer Datei
|
||
|
|
- `run()`: Hauptschleife für die asynchrone Verarbeitung
|
||
|
|
|
||
|
|
#### Integration in MainWindow
|
||
|
|
|
||
|
|
**Automatischer Start:**
|
||
|
|
```python
|
||
|
|
def load_project_from_file(self, file_path: Path):
|
||
|
|
# ... Projekt laden ...
|
||
|
|
# Starte Hash-Berechnung für alle XML-Dateien
|
||
|
|
self._start_xml_hash_calculation()
|
||
|
|
```
|
||
|
|
|
||
|
|
**Kern-Methoden:**
|
||
|
|
- `_start_xml_hash_calculation()`: Startet die asynchrone Hash-Berechnung
|
||
|
|
- `_collect_all_xml_files()`: Sammelt alle XML-Dateien rekursiv
|
||
|
|
- `_on_hash_calculated()`: Signal-Handler für berechnete Hashes
|
||
|
|
- `_calculate_hash_for_xml_file()`: Synchrone Hash-Berechnung für neue Dateien
|
||
|
|
|
||
|
|
### Rekursive Datensammlung
|
||
|
|
|
||
|
|
Die Implementierung durchsucht rekursiv alle `TreeNode`- und `XslFile`-Strukturen:
|
||
|
|
|
||
|
|
```python
|
||
|
|
def _collect_all_xml_files(self, node: TreeNode) -> list[XmlFile]:
|
||
|
|
xml_files = []
|
||
|
|
|
||
|
|
# Sammle XML-Dateien aus XSL-Dateien
|
||
|
|
for xsl_file in node.xsl_files:
|
||
|
|
xml_files.extend(xsl_file.xml_files)
|
||
|
|
|
||
|
|
# Rekursiv durch Kindknoten
|
||
|
|
for child in node.children:
|
||
|
|
xml_files.extend(self._collect_all_xml_files(child))
|
||
|
|
|
||
|
|
return xml_files
|
||
|
|
```
|
||
|
|
|
||
|
|
## Verwendung
|
||
|
|
|
||
|
|
### Automatische Hash-Berechnung
|
||
|
|
|
||
|
|
Die Hash-Berechnung erfolgt automatisch beim Laden von Projekten. Keine manuelle Intervention erforderlich.
|
||
|
|
|
||
|
|
### Neue XML-Dateien
|
||
|
|
|
||
|
|
Beim Hinzufügen neuer XML-Dateien wird der Hash synchron berechnet:
|
||
|
|
|
||
|
|
```python
|
||
|
|
def add_xml_file(self, xml_file: XmlFile):
|
||
|
|
if xml_file.hashsum is None:
|
||
|
|
xml_file.hashsum = self._calculate_hash_for_xml_file(xml_file)
|
||
|
|
```
|
||
|
|
|
||
|
|
## Fehlerbehandlung
|
||
|
|
|
||
|
|
### Nicht existierende Dateien
|
||
|
|
|
||
|
|
```python
|
||
|
|
def _calculate_blake2b_hash(self, file_path: Path) -> str | None:
|
||
|
|
try:
|
||
|
|
if not file_path.exists():
|
||
|
|
return None
|
||
|
|
# ... Hash-Berechnung ...
|
||
|
|
except Exception as e:
|
||
|
|
self.error_occurred.emit(str(file_path), str(e))
|
||
|
|
return None
|
||
|
|
```
|
||
|
|
|
||
|
|
### Thread-Sicherheit
|
||
|
|
|
||
|
|
- Verwendung von Qt-Signalen für Thread-Kommunikation
|
||
|
|
- Keine direkten UI-Updates aus Worker-Thread
|
||
|
|
- Graceful handling von Thread-Fehlern
|
||
|
|
|
||
|
|
## Performance-Optimierung
|
||
|
|
|
||
|
|
### Asynchrone Verarbeitung
|
||
|
|
|
||
|
|
- Hash-Berechnung läuft im Hintergrund
|
||
|
|
- UI bleibt responsiv während der Berechnung
|
||
|
|
- Batch-Verarbeitung mehrerer Dateien
|
||
|
|
|
||
|
|
### Selektive Berechnung
|
||
|
|
|
||
|
|
- Nur Dateien ohne bestehende `hashsum` werden verarbeitet
|
||
|
|
- Vermeidung redundanter Berechnungen
|
||
|
|
- Effiziente Speichernutzung
|
||
|
|
|
||
|
|
## Testen
|
||
|
|
|
||
|
|
### Test-Skript
|
||
|
|
|
||
|
|
Ein umfassendes Test-Skript (`test_hash_implementation.py`) validiert:
|
||
|
|
|
||
|
|
- Korrekte Hash-Berechnung
|
||
|
|
- XmlFile-Modell-Funktionalität
|
||
|
|
- Hash-Konsistenz
|
||
|
|
- Fehlerbehandlung
|
||
|
|
|
||
|
|
### Ausführung
|
||
|
|
|
||
|
|
```bash
|
||
|
|
uv run python test_hash_implementation.py
|
||
|
|
```
|
||
|
|
|
||
|
|
## Wartung und Erweiterung
|
||
|
|
|
||
|
|
### Hinzufügung neuer Hash-Algorithmen
|
||
|
|
|
||
|
|
Die Implementierung kann einfach erweitert werden:
|
||
|
|
|
||
|
|
```python
|
||
|
|
def _calculate_hash(self, file_path: Path, algorithm: str = "blake2b") -> str | None:
|
||
|
|
if algorithm == "blake2b":
|
||
|
|
return self._calculate_blake2b_hash(file_path)
|
||
|
|
elif algorithm == "sha256":
|
||
|
|
return self._calculate_sha256_hash(file_path)
|
||
|
|
# ... weitere Algorithmen
|
||
|
|
```
|
||
|
|
|
||
|
|
### Konfiguration
|
||
|
|
|
||
|
|
Hash-Einstellungen können über die Anwendungskonfiguration gesteuert werden:
|
||
|
|
|
||
|
|
```python
|
||
|
|
class HashConfig:
|
||
|
|
algorithm: str = "blake2b"
|
||
|
|
prefix_format: str = "{algorithm}:"
|
||
|
|
async_calculation: bool = True
|
||
|
|
```
|
||
|
|
|
||
|
|
## Bekannte Einschränkungen
|
||
|
|
|
||
|
|
1. **Dateigröße**: Sehr große XML-Dateien können die Hash-Berechnung verlangsamen
|
||
|
|
2. **Netzwerk-Dateien**: Dateien auf Netzlaufwerken werden möglicherweise langsamer verarbeitet
|
||
|
|
3. **Encoding**: Binärer Dateizugriff für konsistente Hash-Berechnung
|
||
|
|
|
||
|
|
## Changelog
|
||
|
|
|
||
|
|
### Version 1.0.0
|
||
|
|
- Initiale Implementierung der blake2b-Hash-Berechnung
|
||
|
|
- Asynchrone Verarbeitung mit QThread
|
||
|
|
- Integration in Projektlade-Prozess
|
||
|
|
- Umfassende Fehlerbehandlung
|
||
|
|
- Test-Suite für Validierung
|