diff --git a/DocuMentor.wxs b/DocuMentor.wxs index b41347f..af1d10c 100644 --- a/DocuMentor.wxs +++ b/DocuMentor.wxs @@ -4,7 +4,7 @@ 0: - print(f"{deleted_count} alte Log-Datei(en) gelöscht (älter als {max_age_hours} Stunden)") + logging.info(f"{deleted_count} alte Log-Datei(en) gelöscht (älter als {max_age_hours} Stunden)") def main(): @@ -53,9 +52,6 @@ def main(): log_dir = config_path.parent / "logs" log_dir.mkdir(parents=True, exist_ok=True) - # Alte Log-Dateien aufräumen - cleanup_old_logs(log_dir, max_age_hours=24) - # Log-Dateiname mit Timestamp timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") log_file = log_dir / f"documentor_{timestamp}.log" @@ -81,6 +77,9 @@ def main(): logging.info(f"Logging initialisiert: {log_file}") + # Alte Log-Dateien aufräumen (erst nach Logger-Init) + cleanup_old_logs(log_dir, max_age_hours=24) + # QApplication-Instanz erstellen app = QApplication(sys.argv) diff --git a/src/transform.py b/src/transform.py index 2b372b1..a12163c 100644 --- a/src/transform.py +++ b/src/transform.py @@ -163,12 +163,12 @@ class TransformationJob: Returns: bool: True wenn New-PDF existiert und aktueller ist als alle Inputs """ - if not self.new_pdf.exists(): + try: + output_mtime = self.new_pdf.stat().st_mtime + except FileNotFoundError: logger.debug(f"New-PDF existiert nicht: {self.new_pdf}") return False - output_mtime = self.new_pdf.stat().st_mtime - # Prüfe XML-Datei xml_abs = self.project_dir / self.xml_file if xml_abs.exists() and xml_abs.stat().st_mtime > output_mtime: @@ -384,10 +384,11 @@ class TransformationJob: # Fallback: Traditionelle subprocess-Methode (langsamer, aber robuster) # Apache FOP Kommandozeile + fop_conf_exists = self.fop_conf.exists() cmd_line = [ str(self.fop_cmd), "-c", - str(self.fop_conf) if self.fop_conf.exists() else "", + str(self.fop_conf) if fop_conf_exists else "", "-r", "-fo", str(self.temp_fo), @@ -396,7 +397,7 @@ class TransformationJob: ] # Entferne leere Config-Parameter wenn fop.xconf nicht existiert - if not self.fop_conf.exists(): + if not fop_conf_exists: cmd_line = [c for c in cmd_line if c not in ["-c", ""]] logger.info(f"Starte Apache FOP PDF-Generierung: {self.xml_file.name}") diff --git a/src/ui/mixins/database.py b/src/ui/mixins/database.py index 8270132..00ae895 100644 --- a/src/ui/mixins/database.py +++ b/src/ui/mixins/database.py @@ -72,11 +72,6 @@ class DatabaseMixin: QMessageBox.warning(self, "Warnung", "Kein Projekt geladen. Bitte öffnen Sie zuerst ein Projekt.") return - # Hole das aktuelle Projekt aus app_settings - if not self.project: - QMessageBox.warning(self, "Warnung", "Aktuelles Projekt nicht in den Einstellungen gefunden.") - return - # Hole die PostgreSQL-Datenbank-Konfiguration db_config = self._get_database_config(self.project.postgre_sql_db_id) if not db_config: diff --git a/src/ui/mixins/hash_calculation.py b/src/ui/mixins/hash_calculation.py index 3ec5f72..eb4618f 100644 --- a/src/ui/mixins/hash_calculation.py +++ b/src/ui/mixins/hash_calculation.py @@ -9,12 +9,8 @@ import shutil import time import logging from pathlib import Path -from typing import List - -from PySide6.QtWidgets import QMessageBox from conf import TreeNode, XslFile, XmlFile -from ui.XmlToXslAssignDialog import XmlToXslAssignDialog from ui.threads import XmlHashCalculatorThread from utils import calculate_blake2b_hash @@ -33,49 +29,6 @@ class HashCalculationMixin: - self._load_nodes_to_tree(): Methode zum Laden der Nodes in den Tree """ - def _handle_xml_file_drop(self, xml_file_path: Path): - """ - Verarbeitet eine einzelne XML-Datei, die per Drag&Drop hinzugefügt wurde. - DEPRECATED: Diese Methode wird durch _handle_multiple_xml_files_drop ersetzt. - - Args: - xml_file_path: Pfad zur XML-Datei - """ - try: - logger.debug(f"Verarbeite XML-Datei: {xml_file_path}") - - # Prüfe ob die Datei existiert - if not xml_file_path.exists(): - QMessageBox.critical(self, "Fehler", f"Die XML-Datei existiert nicht:\n{xml_file_path}") - return - - # Prüfe ob Projekt-Nodes verfügbar sind - if not self.pdf_project or not self.pdf_project.nodes: - QMessageBox.warning(self, "Warnung", "Keine Projekt-Nodes verfügbar für die Zuordnung.") - return - - # Öffne den Dialog zur Zuordnung zu XSL-Knoten - dialog = XmlToXslAssignDialog( - parent=self, xml_file_path=xml_file_path, project_nodes=self.pdf_project.nodes - ) - - if dialog.exec() == XmlToXslAssignDialog.DialogCode.Accepted: - # Hole die ausgewählten XSL-Knoten - selected_xsl_nodes = dialog.get_selected_xsl_nodes() - - if selected_xsl_nodes: - # Verarbeite die Zuordnung - self._assign_xml_to_xsl_nodes(xml_file_path, selected_xsl_nodes) - else: - logger.warning("Keine XSL-Knoten ausgewählt") - else: - logger.debug("Dialog abgebrochen") - - except Exception as e: - error_msg = f"Fehler beim Verarbeiten der XML-Datei '{xml_file_path}': {str(e)}" - logger.error(error_msg) - QMessageBox.critical(self, "Fehler", error_msg) - def _assign_xml_to_xsl_nodes(self, xml_file_path: Path, selected_xsl_nodes: list): """ Ordnet eine XML-Datei den ausgewählten XSL-Knoten zu. @@ -157,18 +110,19 @@ class HashCalculationMixin: except Exception as e: logger.error(f"Fehler beim Starten der Hash-Berechnung: {e}") - def _collect_all_xml_files(self) -> List[XmlFile]: + def _collect_all_xml_files(self) -> list[XmlFile]: """ Sammelt alle XmlFile-Objekte aus der Projektstruktur. Returns: - List[XmlFile]: Liste aller gefundenen XML-Dateien + list[XmlFile]: Liste aller gefundenen XML-Dateien """ - xml_files = [] + xml_files: list[XmlFile] = [] + seen_paths: set = set() try: if self.pdf_project and self.pdf_project.nodes: - self._collect_xml_files_recursive(self.pdf_project.nodes, xml_files) + self._collect_xml_files_recursive(self.pdf_project.nodes, xml_files, seen_paths) logger.debug(f"Gesammelt: {len(xml_files)} XML-Dateien") return xml_files @@ -177,15 +131,15 @@ class HashCalculationMixin: logger.error(f"Fehler beim Sammeln der XML-Dateien: {e}") return [] - def _collect_xml_files_recursive(self, nodes, xml_files: List[XmlFile]): + def _collect_xml_files_recursive(self, nodes, xml_files: list[XmlFile], seen_paths: set): """ Sammelt rekursiv alle XML-Dateien aus den Nodes. Args: nodes: Liste der zu durchsuchenden Nodes xml_files: Liste zum Sammeln der XML-Dateien + seen_paths: Set bereits gesehener Pfade (verhindert Duplikate) """ - seen_paths = {xf.xml for xf in xml_files} for node in nodes: if isinstance(node, XslFile) and node.xmls: for xml_file in node.xmls: @@ -193,7 +147,7 @@ class HashCalculationMixin: xml_files.append(xml_file) seen_paths.add(xml_file.xml) elif isinstance(node, TreeNode) and node.children: - self._collect_xml_files_recursive(node.children, xml_files) + self._collect_xml_files_recursive(node.children, xml_files, seen_paths) def _on_hash_calculated(self, xml_file: XmlFile, hash_value: str): """ @@ -266,10 +220,6 @@ class HashCalculationMixin: except Exception as e: logger.error(f"Fehler beim Berechnen des Hash für {xml_file.xml}: {e}") - def _get_all_project_xml_files(self) -> List[XmlFile]: - """Sammelt alle XmlFile-Objekte aus dem gesamten Projekt.""" - return self._collect_all_xml_files() - def _find_xml_file_by_hash(self, target_hash: str) -> XmlFile | None: """ Sucht eine XML-Datei mit dem angegebenen Hash im gesamten Projekt. @@ -284,7 +234,7 @@ class HashCalculationMixin: if not target_hash: return None - all_xml_files = self._get_all_project_xml_files() + all_xml_files = self._collect_all_xml_files() for xml_file in all_xml_files: if xml_file.hashsum == target_hash: @@ -314,7 +264,7 @@ class HashCalculationMixin: extension = original_path.suffix # ".xml" # Sammle einmalig alle verwendeten Dateinamen (Performance-Optimierung) - all_xml_files = self._get_all_project_xml_files() + all_xml_files = self._collect_all_xml_files() used_names = {xml_file.xml.name for xml_file in all_xml_files} counter = 1 @@ -351,7 +301,7 @@ class HashCalculationMixin: bool: True wenn der Dateiname bereits verwendet wird """ try: - all_xml_files = self._get_all_project_xml_files() + all_xml_files = self._collect_all_xml_files() for xml_file in all_xml_files: if xml_file.xml == relative_xml_path: @@ -508,7 +458,7 @@ class HashCalculationMixin: logger.error(error_msg) return {"status": "error", "error_msg": error_msg} - def _show_filename_selection_dialog(self, original_name: str, alternative_paths: List[Path]) -> Path | None: + def _show_filename_selection_dialog(self, original_name: str, alternative_paths: list[Path]) -> Path | None: """ Zeigt einen Dialog zur Auswahl eines alternativen Dateinamens. diff --git a/uv.lock b/uv.lock index d245999..e3663d7 100644 --- a/uv.lock +++ b/uv.lock @@ -34,7 +34,7 @@ wheels = [ [[package]] name = "documentor" -version = "1.5.0" +version = "1.5.1" source = { virtual = "." } dependencies = [ { name = "connectorx" },