""" Controller für OK.ru (Odnoklassniki)-spezifische Funktionalität. """ import logging from PyQt5.QtCore import QThread, pyqtSignal from controllers.platform_controllers.base_controller import BasePlatformController from controllers.platform_controllers.base_worker_thread import BaseAccountCreationWorkerThread from views.tabs.generator_tab import GeneratorTab from views.widgets.forge_animation_widget import ForgeAnimationDialog from social_networks.ok_ru.ok_ru_automation import OkRuAutomation from utils.logger import setup_logger logger = setup_logger("ok_ru_controller") class OkRuWorkerThread(BaseAccountCreationWorkerThread): """Worker Thread für OK.ru Account-Erstellung""" def __init__(self, params, session_controller=None, generator_tab=None): super().__init__(params, "OK.ru", session_controller, generator_tab) def get_automation_class(self): """Gibt die OK.ru-Automation-Klasse zurück""" return OkRuAutomation def get_error_interpretations(self): """OK.ru-spezifische Fehlerinterpretationen""" return { "phone": "Diese Telefonnummer wird bereits verwendet.", "captcha": "Bitte lösen Sie das Captcha.", "age": "Sie müssen mindestens 14 Jahre alt sein.", "blocked": "Zu viele Versuche. Bitte versuchen Sie es später erneut." } class OkRuController(BasePlatformController): """Controller für OK.ru (Odnoklassniki)-spezifische Funktionalität.""" def __init__(self, db_manager, proxy_rotator, email_handler, language_manager=None): super().__init__("OK.ru", db_manager, proxy_rotator, email_handler, language_manager) self.worker_thread = None self.platform_icon = "ok_ru.png" # Spezifisches Icon für OK.ru def create_generator_tab(self): """Erstellt den Generator-Tab für OK.ru.""" generator_tab = GeneratorTab(self.platform_name, self.language_manager) # OK.ru verwendet nur Telefon-Registrierung # Keine spezielle Konfiguration nötig, da GeneratorTab standardmäßig alle Felder hat return generator_tab def start_account_creation(self, params): """Startet die OK.ru-Account-Erstellung.""" logger.info(f"Starte OK.ru Account-Erstellung mit Parametern: {params}") # Validiere Eingaben is_valid, error_msg = self.validate_inputs(params) if not is_valid: self.get_generator_tab().show_error(error_msg) return # UI aktualisieren generator_tab = self.get_generator_tab() generator_tab.set_running(True) generator_tab.clear_log() generator_tab.set_progress(0) # Schmiedeanimation-Dialog erstellen und anzeigen parent_widget = generator_tab.window() self.forge_dialog = ForgeAnimationDialog(parent_widget, "OK.ru") self.forge_dialog.cancel_clicked.connect(self.stop_account_creation) self.forge_dialog.closed.connect(self.stop_account_creation) # Fensterposition vom Hauptfenster holen if parent_widget: window_pos = parent_widget.pos() params["window_position"] = (window_pos.x(), window_pos.y()) # Fingerprint VOR Account-Erstellung generieren try: from infrastructure.services.fingerprint.fingerprint_generator_service import FingerprintGeneratorService from domain.entities.browser_fingerprint import BrowserFingerprint import uuid fingerprint_service = FingerprintGeneratorService() # Generiere einen neuen Fingerprint für diesen Account fingerprint_data = fingerprint_service.generate_fingerprint() # Erstelle BrowserFingerprint Entity mit allen notwendigen Daten fingerprint = BrowserFingerprint.from_dict(fingerprint_data) fingerprint.fingerprint_id = str(uuid.uuid4()) fingerprint.account_bound = True fingerprint.rotation_seed = str(uuid.uuid4()) # Konvertiere zu Dictionary für Übertragung params["fingerprint"] = fingerprint.to_dict() logger.info(f"Fingerprint für neue Account-Erstellung generiert: {fingerprint.fingerprint_id}") except Exception as e: logger.error(f"Fehler beim Generieren des Fingerprints: {e}") # Fortfahren ohne Fingerprint - wird später generiert # Worker-Thread starten session_controller = getattr(self, 'session_controller', None) generator_tab_ref = generator_tab if hasattr(generator_tab, 'store_created_account') else None self.worker_thread = OkRuWorkerThread( params, session_controller=session_controller, generator_tab=generator_tab_ref ) # Updates an Forge-Dialog weiterleiten 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.error_signal.connect(self._handle_error) self.worker_thread.finished_signal.connect(self._handle_finished) self.worker_thread.progress_signal.connect(self.forge_dialog.set_progress) # Auch an Generator-Tab für 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)) self.worker_thread.start() # Dialog anzeigen und Animation starten self.forge_dialog.start_animation() self.forge_dialog.show() def stop_account_creation(self): """Stoppt die OK.ru-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("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 validate_inputs(self, inputs): """ Validiert die Eingaben für die Account-Erstellung. """ # Basis-Validierungen von BasePlatformController verwenden valid, error_msg = super().validate_inputs(inputs) if not valid: return valid, error_msg # OK.ru-spezifische Validierungen age = inputs.get("age", 0) if age < 14: return False, "Das Alter muss mindestens 14 sein (OK.ru-Anforderung)." # Telefonnummer-Validierung für OK.ru - vorerst deaktiviert für Tests # TODO: Telefonnummern-Feld in UI hinzufügen # phone_number = inputs.get("phone_number", "") # if not phone_number: # return False, "Telefonnummer ist erforderlich für OK.ru-Registrierung." # # # Einfache Telefonnummern-Validierung # if len(phone_number) < 10: # return False, "Telefonnummer muss mindestens 10 Ziffern haben." return True, "" def _handle_error(self, error_msg: str): """Behandelt Fehler während der Account-Erstellung""" # 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): """Behandelt das Ende der Account-Erstellung""" # 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)