295 Zeilen
10 KiB
Python
295 Zeilen
10 KiB
Python
"""
|
|
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 |