Export drin noch nicht komplett

Dieser Commit ist enthalten in:
Claude Project Manager
2025-11-10 03:43:02 +01:00
Ursprung 14eefa18f6
Commit 88dc8eea5e
8 geänderte Dateien mit 1473 neuen und 4 gelöschten Zeilen

Datei anzeigen

@ -0,0 +1,234 @@
"""
Controller für Profil-Export
Orchestriert den Export-Prozess von Account-Profilen.
"""
import os
import logging
from typing import Optional, Dict, Any
from pathlib import Path
from PyQt5.QtWidgets import QFileDialog
from database.db_manager import DatabaseManager
from utils.profile_export_service import ProfileExportService
from views.dialogs.profile_export_dialog import show_export_dialog
from views.dialogs.export_success_dialog import show_export_success
from views.widgets.modern_message_box import show_error, show_warning
logger = logging.getLogger("profile_export_controller")
class ProfileExportController:
"""Controller für Account-Profil-Export"""
def __init__(self, db_manager: DatabaseManager):
"""
Initialisiert den Export-Controller.
Args:
db_manager: Datenbank-Manager
"""
self.db_manager = db_manager
self.export_service = ProfileExportService()
def export_account(self, parent_widget, account_id: int) -> bool:
"""
Startet den Export-Prozess für einen Account.
Args:
parent_widget: Parent-Widget für Dialoge
account_id: ID des zu exportierenden Accounts
Returns:
True bei Erfolg, False bei Fehler oder Abbruch
"""
try:
# 1. Account-Daten aus DB laden
logger.info(f"Starte Export für Account-ID: {account_id}")
account_data = self.db_manager.get_account(account_id)
if not account_data:
logger.error(f"Account nicht gefunden: ID {account_id}")
show_error(
parent_widget,
"Account nicht gefunden",
f"Account mit ID {account_id} konnte nicht gefunden werden."
)
return False
username = account_data.get("username", "Unbekannt")
logger.info(f"Account geladen: {username}")
# 2. Export-Dialog anzeigen
accepted, formats, password_protect = show_export_dialog(parent_widget, username)
if not accepted:
logger.info("Export abgebrochen durch Nutzer")
return False
logger.info(f"Export-Optionen: Formate={formats}, Passwort={password_protect}")
# 3. Speicherort wählen
save_directory = self._select_save_location(parent_widget, account_data, formats, password_protect)
if not save_directory:
logger.info("Kein Speicherort ausgewählt - Export abgebrochen")
return False
logger.info(f"Speicherort: {save_directory}")
# 4. Export durchführen
files_dict, password = self.export_service.export_account(
account_data,
formats,
password_protect
)
if not files_dict:
logger.error("Keine Dateien wurden generiert")
show_error(
parent_widget,
"Export fehlgeschlagen",
"Beim Export ist ein Fehler aufgetreten."
)
return False
# 5. Dateien speichern
saved_files = []
for filename, content in files_dict.items():
file_path = os.path.join(save_directory, filename)
try:
with open(file_path, 'wb') as f:
f.write(content)
saved_files.append(filename)
logger.info(f"Datei gespeichert: {filename}")
except Exception as e:
logger.error(f"Fehler beim Speichern von {filename}: {e}")
show_error(
parent_widget,
"Fehler beim Speichern",
f"Datei {filename} konnte nicht gespeichert werden:\n{str(e)}"
)
return False
# 6. Erfolgs-Dialog anzeigen
show_export_success(
parent_widget,
saved_files,
save_directory,
password
)
logger.info(f"Export erfolgreich: {len(saved_files)} Datei(en) gespeichert")
return True
except Exception as e:
logger.error(f"Fehler beim Export: {e}", exc_info=True)
# Benutzerfreundliche Fehlermeldungen
error_message = str(e)
if "reportlab" in error_message.lower():
error_message = (
"PDF-Export ist nicht verfügbar.\n\n"
"Bitte installieren Sie die erforderlichen Bibliotheken:\n"
"pip install reportlab svglib"
)
elif "pyzipper" in error_message.lower():
error_message = (
"Passwortgeschützter Export ist nicht verfügbar.\n\n"
"Bitte installieren Sie die erforderliche Bibliothek:\n"
"pip install pyzipper"
)
show_error(
parent_widget,
"Export fehlgeschlagen",
f"Beim Export ist ein Fehler aufgetreten:\n\n{error_message}"
)
return False
def _select_save_location(
self,
parent_widget,
account_data: Dict[str, Any],
formats: list,
password_protect: bool
) -> Optional[str]:
"""
Öffnet einen Datei-Dialog zur Auswahl des Speicherorts.
Args:
parent_widget: Parent-Widget
account_data: Account-Daten
formats: Liste der Export-Formate
password_protect: Ob Passwortschutz aktiviert ist
Returns:
Ausgewähltes Verzeichnis oder None bei Abbruch
"""
# Standard-Dateiname generieren
if password_protect:
# Bei Passwortschutz wird eine ZIP erstellt
default_filename = self.export_service.generate_filename(
account_data,
"zip"
)
else:
# Ohne Passwortschutz: Ersten Format als Beispiel nehmen
first_format = formats[0] if formats else "csv"
default_filename = self.export_service.generate_filename(
account_data,
first_format
)
# Standard-Speicherort: Benutzer-Downloads-Ordner
default_directory = str(Path.home() / "Downloads")
if password_protect:
# Für ZIP: File-Dialog
file_path, _ = QFileDialog.getSaveFileName(
parent_widget,
"Profil exportieren",
os.path.join(default_directory, default_filename),
"ZIP-Archiv (*.zip)"
)
if not file_path:
return None
# Verzeichnis aus Dateipfad extrahieren
return os.path.dirname(file_path)
else:
# Für mehrere Dateien: Verzeichnis-Dialog
directory = QFileDialog.getExistingDirectory(
parent_widget,
"Speicherort für Export auswählen",
default_directory
)
return directory if directory else None
def export_multiple_accounts(self, parent_widget, account_ids: list) -> bool:
"""
Exportiert mehrere Accounts gleichzeitig.
HINWEIS: Diese Funktion ist vorbereitet für zukünftige Erweiterung,
wird aber gemäß ROADMAP.md vorerst NICHT implementiert (YAGNI).
Args:
parent_widget: Parent-Widget
account_ids: Liste von Account-IDs
Returns:
True bei Erfolg, False bei Fehler
"""
show_warning(
parent_widget,
"Nicht verfügbar",
"Mehrfach-Export ist derzeit nicht verfügbar.\n"
"Bitte exportieren Sie Accounts einzeln."
)
return False