Files
AccountForger-neuerUpload/controllers/platform_controllers/base_controller.py
2025-11-27 21:17:32 +01:00

313 Zeilen
11 KiB
Python

"""
Basis-Controller für Plattform-spezifische Funktionalität.
"""
import logging
from PyQt5.QtCore import QObject
from typing import Dict, Any, Optional, Tuple
import random
from views.tabs.generator_tab_factory import GeneratorTabFactory
from views.tabs.accounts_tab import AccountsTab
# SettingsTab import entfernt - wird nicht mehr verwendet
class BasePlatformController(QObject):
"""Basis-Controller-Klasse für Plattformspezifische Logik."""
# Konstanten auf Klassen-Ebene
MOBILE_PROBABILITY = {
'instagram': 0.7,
'tiktok': 0.9,
'facebook': 0.5
}
MIN_AGE = 13
DEFAULT_EMAIL_DOMAIN = "z5m7q9dk3ah2v1plx6ju.com"
def __init__(self, platform_name, db_manager, proxy_rotator, email_handler, language_manager=None):
super().__init__()
self.platform_name = platform_name
self.logger = logging.getLogger(f"{platform_name.lower()}_controller")
# Modelle
self.db_manager = db_manager
self.proxy_rotator = proxy_rotator
self.email_handler = email_handler
self.language_manager = language_manager
# Tabs
self._generator_tab = None
self._accounts_tab = None
# Worker Thread
self.worker_thread = None
# Optional: Session Controller (Clean Architecture)
self.session_controller = None
# Optional: Forge Dialog
self.forge_dialog = None
# Plattformspezifische Initialisierungen
self.init_platform()
def set_tabs(self, generator_tab, accounts_tab):
"""
Setzt die Tab-Referenzen.
Args:
generator_tab: Generator-Tab
accounts_tab: Accounts-Tab
"""
self._generator_tab = generator_tab
self._accounts_tab = accounts_tab
def init_platform(self):
"""
Initialisiert plattformspezifische Komponenten.
Diese Methode sollte von Unterklassen überschrieben werden.
"""
pass
def get_generator_tab(self):
"""Gibt den Generator-Tab zurück oder erstellt ihn bei Bedarf."""
if not self._generator_tab:
self._generator_tab = self.create_generator_tab()
return self._generator_tab
def get_accounts_tab(self):
"""Gibt den Accounts-Tab zurück oder erstellt ihn bei Bedarf."""
if not self._accounts_tab:
self._accounts_tab = self.create_accounts_tab()
return self._accounts_tab
# get_settings_tab Methode entfernt - Settings-Tab wird nicht mehr verwendet
def create_generator_tab(self):
"""
Erstellt den Generator-Tab mit der Factory.
Unterklassen können diese Methode überschreiben für spezielle Anforderungen.
Returns:
QWidget: Plattform-spezifischer oder generischer Generator-Tab
"""
return GeneratorTabFactory.create_tab(self.platform_name, self.language_manager)
def create_accounts_tab(self):
"""
Erstellt den Accounts-Tab.
Diese Methode sollte von Unterklassen überschrieben werden.
"""
return AccountsTab(self.platform_name, self.db_manager, self.language_manager)
# create_settings_tab Methode entfernt - Settings-Tab wird nicht mehr verwendet
def start_account_creation(self, params):
"""
Startet die Account-Erstellung.
Diese Methode sollte von Unterklassen überschrieben werden.
Args:
params: Parameter für die Account-Erstellung
"""
# Feature 5: Process Guard - Prüfe ob Prozess starten darf
from utils.process_guard import get_guard
guard = get_guard()
can_start, error_msg = guard.can_start("Account-Erstellung", self.platform_name)
if not can_start:
# Zeige Fehlermeldung
generator_tab = self.get_generator_tab()
generator_tab.show_error(error_msg)
return
# Guard Lock setzen
guard.start("Account-Erstellung", self.platform_name)
self.logger.info(f"Account-Erstellung für {self.platform_name} gestartet")
# In Unterklassen implementieren
def validate_inputs(self, inputs):
"""
Validiert die Eingaben für die Account-Erstellung.
Args:
inputs: Eingaben für die Account-Erstellung
Returns:
(bool, str): (Ist gültig, Fehlermeldung falls nicht gültig)
"""
# Basis-Validierungen
if not inputs.get("full_name"):
return False, "Bitte geben Sie einen vollständigen Namen ein."
# Alter prüfen
age_text = inputs.get("age_text", "")
if not age_text:
return False, "Bitte geben Sie ein Alter ein."
# Alter muss eine Zahl sein
try:
age = int(age_text)
inputs["age"] = age # Füge das konvertierte Alter zu den Parametern hinzu
except ValueError:
return False, "Das Alter muss eine ganze Zahl sein."
# Alter-Bereich prüfen
if age < 13 or age > 99:
return False, "Das Alter muss zwischen 13 und 99 liegen."
# Telefonnummer prüfen, falls erforderlich
if inputs.get("registration_method") == "phone" and not inputs.get("phone_number"):
return False, "Telefonnummer erforderlich für Registrierung via Telefon."
return True, ""
def _determine_profile_type(self) -> str:
"""Bestimmt den Profil-Typ basierend auf Platform-Wahrscheinlichkeiten"""
mobile_prob = self.MOBILE_PROBABILITY.get(self.platform_name.lower(), 0.5)
return 'mobile' if random.random() < mobile_prob else 'desktop'
def _generate_fingerprint_for_platform(self) -> Optional[Any]:
"""Generiert Fingerprint mit Fehlerbehandlung"""
try:
if not hasattr(self, 'session_controller') or not self.session_controller:
return None
profile_type = self._determine_profile_type()
# Prüfe ob fingerprint_service existiert
if hasattr(self.session_controller, 'fingerprint_service'):
return self.session_controller.fingerprint_service.generate_fingerprint(
profile_type=profile_type,
platform=self.platform_name.lower()
)
except Exception as e:
self.logger.warning(f"Fingerprint-Generierung fehlgeschlagen: {e}")
return None
def _setup_ui_for_creation(self):
"""Bereitet die UI für die Account-Erstellung vor"""
generator_tab = self.get_generator_tab()
generator_tab.set_running(True)
generator_tab.clear_log()
generator_tab.set_progress(0)
def _connect_worker_signals(self):
"""Verbindet Worker-Signals mit UI-Elementen"""
if not self.worker_thread:
return
generator_tab = self.get_generator_tab()
# Forge-Dialog Signals
if self.forge_dialog:
self.worker_thread.update_signal.connect(self.forge_dialog.set_status)
self.worker_thread.log_signal.connect(self.forge_dialog.add_log)
self.worker_thread.progress_signal.connect(self.forge_dialog.set_progress)
# Generator-Tab Signals (Backup)
self.worker_thread.log_signal.connect(lambda msg: generator_tab.add_log(msg))
self.worker_thread.progress_signal.connect(lambda value: generator_tab.set_progress(value))
# Error und Finished Handling
self.worker_thread.error_signal.connect(self._handle_error)
self.worker_thread.finished_signal.connect(self._handle_finished)
def _show_forge_dialog(self):
"""Zeigt den Forge-Animation Dialog"""
try:
from views.widgets.forge_animation_widget import ForgeAnimationDialog
generator_tab = self.get_generator_tab()
parent_widget = generator_tab.window()
self.forge_dialog = ForgeAnimationDialog(parent_widget)
self.forge_dialog.cancel_clicked.connect(self.stop_account_creation)
self.forge_dialog.closed.connect(self.stop_account_creation)
self.forge_dialog.start_animation()
self.forge_dialog.show()
except Exception as e:
self.logger.warning(f"Konnte Forge-Dialog nicht anzeigen: {e}")
def _handle_error(self, error_msg: str):
"""Gemeinsame Fehlerbehandlung"""
# Forge-Dialog schließen
if hasattr(self, 'forge_dialog') and self.forge_dialog:
self.forge_dialog.close()
self.forge_dialog = None
# Fehler anzeigen
generator_tab = self.get_generator_tab()
generator_tab.show_error(error_msg)
generator_tab.set_running(False)
def _handle_finished(self, result: dict):
"""Gemeinsame Behandlung bei Abschluss"""
# Forge-Dialog schließen
if hasattr(self, 'forge_dialog') and self.forge_dialog:
self.forge_dialog.close()
self.forge_dialog = None
# Normale Verarbeitung
self.handle_account_created(result)
def stop_account_creation(self):
"""Stoppt die Account-Erstellung"""
if self.worker_thread and self.worker_thread.isRunning():
self.worker_thread.stop()
generator_tab = self.get_generator_tab()
generator_tab.add_log(f"{self.platform_name}-Account-Erstellung wurde abgebrochen")
generator_tab.set_running(False)
generator_tab.set_progress(0)
# Forge-Dialog schließen falls vorhanden
if hasattr(self, 'forge_dialog') and self.forge_dialog:
self.forge_dialog.close()
self.forge_dialog = None
def handle_account_created(self, result):
"""
Verarbeitet erfolgreich erstellte Accounts.
Sollte von Unterklassen überschrieben werden für spezifische Logik.
"""
generator_tab = self.get_generator_tab()
generator_tab.set_running(False)
# Standard-Implementierung - kann von Unterklassen erweitert werden
self.logger.info(f"Account erfolgreich erstellt für {self.platform_name}")
def stop_account_creation(self):
"""
Stoppt die Account-Erstellung (Default-Implementierung).
Diese Methode kann von Unterklassen überschrieben werden für spezielle Anforderungen.
Sie stellt sicher dass:
1. Der Process Guard freigegeben wird
2. Der Worker-Thread gestoppt wird
3. Die UI zurückgesetzt wird
4. Dialoge geschlossen werden
"""
# Guard-Freigabe (wichtig: VOR Worker-Stop)
from utils.process_guard import get_guard
guard = get_guard()
if guard.is_locked():
guard.end(success=False)
self.logger.info("Guard freigegeben bei Stop (BaseController)")
# Worker stoppen falls vorhanden
if self.worker_thread and self.worker_thread.isRunning():
self.worker_thread.stop()
generator_tab = self.get_generator_tab()
generator_tab.add_log(f"{self.platform_name}-Account-Erstellung wurde abgebrochen")
generator_tab.set_running(False)
generator_tab.set_progress(0)
# Forge-Dialog schließen falls vorhanden
if hasattr(self, 'forge_dialog') and self.forge_dialog:
self.forge_dialog.close()
self.forge_dialog = None