""" Login Process Modal - Spezialisiertes Modal für Login-Prozesse """ import logging from typing import Optional, Dict, Any from PyQt5.QtCore import QTimer, pyqtSignal from PyQt5.QtWidgets import QHBoxLayout, QLabel from PyQt5.QtGui import QFont, QPixmap from PyQt5.QtCore import Qt from views.widgets.progress_modal import ProgressModal logger = logging.getLogger("login_process_modal") class LoginProcessModal(ProgressModal): """ Spezialisiertes Modal für Login-Prozesse mit Session-Wiederherstellung. """ # Signale login_completed = pyqtSignal(bool, str) # success, message session_restored = pyqtSignal(str) # platform def __init__(self, parent=None, platform: str = "Social Media", language_manager=None): self.platform = platform self.login_method = "session" # "session" oder "credentials" self.account_username = "" super().__init__(parent, "login_process", language_manager) # Erweitere UI für Login-spezifische Anzeige self.setup_login_ui() def setup_login_ui(self): """Erweitert die UI um Login-spezifische Elemente""" container_layout = self.modal_container.layout() # Platform/Account Info (zwischen Titel und Animation) self.account_info_widget = QLabel() self.account_info_widget.setVisible(False) self.account_info_widget.setAlignment(Qt.AlignCenter) info_font = QFont("Inter", 13) info_font.setBold(True) self.account_info_widget.setFont(info_font) self.account_info_widget.setStyleSheet(""" QLabel { color: #2D3748; font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: rgba(66, 153, 225, 0.1); border-radius: 8px; padding: 8px 16px; margin: 4px 0px; } """) # Füge nach Titel ein (Index 1) container_layout.insertWidget(1, self.account_info_widget) # Login-Methode Indicator (nach Animation Widget) self.method_label = QLabel() self.method_label.setVisible(False) self.method_label.setAlignment(Qt.AlignCenter) method_font = QFont("Inter", 11) self.method_label.setFont(method_font) self.method_label.setStyleSheet(""" QLabel { color: #4A5568; font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; font-style: italic; margin: 4px 0px; } """) # Füge nach Animation Widget ein (Index 3, wegen account_info_widget) container_layout.insertWidget(3, self.method_label) def show_session_login(self, account_username: str, platform: str = None): """ Zeigt Session-basiertes Login an. Args: account_username: Benutzername des Accounts platform: Optional - Platform überschreibung """ if platform: self.platform = platform self.account_username = account_username self.login_method = "session" # UI aktualisieren self._update_login_display() # Modal anzeigen self.show_process("login_process") logger.info(f"Session Login Modal angezeigt für: {account_username} @ {self.platform}") def show_credentials_login(self, account_username: str, platform: str = None): """ Zeigt Credential-basiertes Login an. Args: account_username: Benutzername des Accounts platform: Optional - Platform überschreibung """ if platform: self.platform = platform self.account_username = account_username self.login_method = "credentials" # UI aktualisieren self._update_login_display() # Modal anzeigen self.show_process("login_process") logger.info(f"Credentials Login Modal angezeigt für: {account_username} @ {self.platform}") def _update_login_display(self): """Aktualisiert die Anzeige basierend auf Login-Methode""" # Titel anpassen title = f"🔐 {self.platform} Login" self.title_label.setText(title) # Account Info anzeigen if self.account_username: account_info = f"👤 {self.account_username}" self.account_info_widget.setText(account_info) self.account_info_widget.setVisible(True) # Methode anzeigen if self.login_method == "session": method_text = "🔄 Session wird wiederhergestellt" status_text = "Gespeicherte Anmeldedaten werden geladen..." else: method_text = "🔑 Anmeldedaten werden eingegeben" status_text = "Benutzername und Passwort werden verwendet..." self.method_label.setText(method_text) self.method_label.setVisible(True) # Status setzen self.update_status(status_text) def update_login_progress(self, step: str, detail: str = None): """ Aktualisiert den Login-Fortschritt. Args: step: Aktueller Schritt detail: Optional - Detail-Information """ step_emojis = { 'browser_init': '🌐', 'page_load': '📄', 'session_restore': '🔄', 'credential_input': '✍️', 'verification': '🔐', 'success_check': '✅', 'finalizing': '🏁' } emoji = step_emojis.get(step, '⏳') status_text = f"{emoji} {step.replace('_', ' ').title()}" self.update_status(status_text, detail) logger.debug(f"Login Progress: {step} - {detail or 'No detail'}") def show_session_restored(self, platform_data: Dict[str, Any] = None): """ Zeigt erfolgreiche Session-Wiederherstellung an. Args: platform_data: Optional - Platform-spezifische Daten """ self.update_status("✅ Session erfolgreich wiederhergestellt", "Anmeldung abgeschlossen") # Session restored Signal self.session_restored.emit(self.platform) # Auto-Close nach 2 Sekunden QTimer.singleShot(2000, lambda: self._complete_login(True, "Session wiederhergestellt")) logger.info(f"Session erfolgreich wiederhergestellt für: {self.account_username} @ {self.platform}") def show_credentials_success(self): """Zeigt erfolgreiche Credential-Anmeldung an""" self.update_status("✅ Anmeldung erfolgreich", "Account ist bereit") # Auto-Close nach 2 Sekunden QTimer.singleShot(2000, lambda: self._complete_login(True, "Anmeldung erfolgreich")) logger.info(f"Credential-Login erfolgreich für: {self.account_username} @ {self.platform}") def show_login_failed(self, reason: str, retry_available: bool = False): """ Zeigt fehlgeschlagene Anmeldung an. Args: reason: Grund für Fehlschlag retry_available: Ob Retry möglich ist """ # Animation stoppen self.animation_widget.stop_animation() error_title = "❌ Anmeldung fehlgeschlagen" if self.login_method == "session": error_detail = "Session ist abgelaufen oder ungültig" else: error_detail = "Benutzername oder Passwort falsch" self.title_label.setText(error_title) self.update_status(reason, error_detail) # Auto-Close nach 4 Sekunden auto_close_time = 4000 QTimer.singleShot(auto_close_time, lambda: self._complete_login(False, reason)) logger.error(f"Login fehlgeschlagen für: {self.account_username} @ {self.platform} - {reason}") def show_session_expired(self): """Zeigt abgelaufene Session an""" self.show_login_failed("Session ist abgelaufen", retry_available=True) # Spezielle Behandlung für Session-Ablauf self.method_label.setText("⚠️ Manuelle Anmeldung erforderlich") def show_captcha_required(self): """Zeigt an, dass Captcha erforderlich ist""" self.update_status("🤖 Captcha-Verifizierung erforderlich", "Bitte manuell lösen...") # Längere Auto-Close Zeit für Captcha QTimer.singleShot(10000, lambda: self._complete_login(False, "Captcha erforderlich")) def show_two_factor_required(self): """Zeigt an, dass Zwei-Faktor-Authentifizierung erforderlich ist""" self.update_status("📱 Zwei-Faktor-Authentifizierung", "Code wird benötigt...") # Längere Auto-Close Zeit für 2FA QTimer.singleShot(8000, lambda: self._complete_login(False, "2FA erforderlich")) def _complete_login(self, success: bool, message: str): """ Schließt den Login-Prozess ab. Args: success: Ob Login erfolgreich war message: Abschließende Nachricht """ # Signal senden self.login_completed.emit(success, message) # Modal verstecken self.hide_process() logger.info(f"Login-Prozess abgeschlossen: {success} - {message}") def get_platform_icon_path(self) -> Optional[str]: """ Gibt den Pfad zum Platform-Icon zurück. Returns: Optional[str]: Icon-Pfad oder None """ try: import os current_dir = os.path.dirname(os.path.abspath(__file__)) parent_dir = os.path.dirname(os.path.dirname(os.path.dirname(current_dir))) icons_dir = os.path.join(parent_dir, "resources", "icons") platform_name = self.platform.lower().replace('.', '').replace(' ', '') if platform_name == "x": platform_name = "twitter" elif platform_name == "okru": platform_name = "ok" icon_path = os.path.join(icons_dir, f"{platform_name}.svg") if os.path.exists(icon_path): return icon_path except Exception as e: logger.warning(f"Konnte Platform-Icon nicht laden: {e}") return None