Dieser Commit ist enthalten in:
Claude Project Manager
2025-08-01 23:50:28 +02:00
Commit 04585e95b6
290 geänderte Dateien mit 64086 neuen und 0 gelöschten Zeilen

Datei anzeigen

@ -0,0 +1,295 @@
"""
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