""" Controller für Facebook-spezifische Funktionalität. Mit Fingerprint-Protection und Anti-Bot Features. """ import logging import time import random from PyQt5.QtCore import QThread, pyqtSignal from typing import Dict, Any from controllers.platform_controllers.base_controller import BasePlatformController from controllers.platform_controllers.base_worker_thread import BaseAccountCreationWorkerThread from views.tabs.generator_tab_factory import GeneratorTabFactory # Factory Pattern für Tab-Erstellung from views.widgets.forge_animation_widget import ForgeAnimationDialog # Forge Dialog für Animation from social_networks.facebook.facebook_automation import FacebookAutomation from utils.birthday_generator import BirthdayGenerator from utils.logger import setup_logger logger = setup_logger("facebook_controller") class FacebookWorkerThread(BaseAccountCreationWorkerThread): """Worker-Thread für die Facebook-Account-Erstellung.""" def __init__(self, params, session_controller=None, generator_tab=None): super().__init__(params, "Facebook", session_controller, generator_tab) self.birthday_generator = BirthdayGenerator() def get_automation_class(self): """Gibt die Facebook Automation Klasse zurück""" return FacebookAutomation def get_error_interpretations(self) -> Dict[str, str]: """Facebook-spezifische Fehlerinterpretationen""" return { "email already in use": "Diese E-Mail-Adresse wird bereits verwendet", "phone number required": "Telefonnummer erforderlich", "invalid birth date": "Ungültiges Geburtsdatum", "account suspended": "Account wurde gesperrt", "verification required": "Verifizierung erforderlich" } def run(self): """Führt die Account-Erstellung aus.""" try: self.log_signal.emit("Facebook-Account-Erstellung gestartet...") self.progress_signal.emit(10) # Facebook-Automation initialisieren (mit Anti-Bot Features wie Instagram) automation = FacebookAutomation( headless=self.params.get("headless", False), use_proxy=self.params.get("use_proxy", False), proxy_type=self.params.get("proxy_type"), save_screenshots=True, debug=self.params.get("debug", False), email_domain=self.params.get("email_domain", "z5m7q9dk3ah2v1plx6ju.com"), enhanced_stealth=True, # Anti-Bot Features aktivieren fingerprint_noise=0.5, # Fingerprint-Verschleierung language="de" # Deutsche Version ) self.update_signal.emit("Browser wird vorbereitet...") self.progress_signal.emit(20) # Namen aufteilen (falls zusammen übergeben) full_name = self.params.get("full_name", "") name_parts = full_name.split(" ", 1) first_name = name_parts[0] if name_parts else "Test" last_name = name_parts[1] if len(name_parts) > 1 else "User" # Geburtsdatum aus Alter generieren age = self.params.get("age", random.randint(18, 65)) birth_date_components = self.birthday_generator.generate_birthday_components("facebook", age) # Geschlecht aus den Parametern oder default gender = self.params.get("gender", random.choice(["male", "female"])) logger.info(f"Geschlecht: {gender}") self.log_signal.emit(f"Registriere Account für: {first_name} {last_name} (Alter: {age})") # Account registrieren result = automation.register_account( first_name=first_name, last_name=last_name, birth_date=birth_date_components, gender=gender, email=self.params.get("email"), # Wird generiert wenn nicht vorhanden phone_number=self.params.get("phone_number"), password=self.params.get("password"), # Wird generiert wenn nicht vorhanden **self.params.get("additional_params", {}) ) self.progress_signal.emit(100) if result["success"]: self.log_signal.emit("Account erfolgreich erstellt!") self.finished_signal.emit(result) else: error_msg = result.get("error", "Unbekannter Fehler") self.log_signal.emit(f"Fehler bei der Account-Erstellung: {error_msg}") self.error_signal.emit(error_msg) except Exception as e: logger.error(f"Fehler im Worker-Thread: {e}") self.log_signal.emit(f"Schwerwiegender Fehler: {str(e)}") self.error_signal.emit(str(e)) finally: self.running = False class FacebookController(BasePlatformController): """Controller für die Facebook-Plattform.""" def __init__(self, db_manager=None, proxy_rotator=None, email_handler=None, language_manager=None): super().__init__("Facebook", db_manager, proxy_rotator, email_handler, language_manager) self.worker_thread = None logger.info("Facebook Controller initialisiert") def create_generator_tab(self): """ Erstellt und konfiguriert den Generator-Tab für Facebook. Verwendet die Factory für saubere Tab-Erstellung. Returns: QWidget: Facebook-spezifischer Tab mit Geschlechtsauswahl """ # Verwende Factory Pattern für Tab-Erstellung # Die Factory entscheidet, welche Tab-Implementierung verwendet wird generator_tab = GeneratorTabFactory.create_tab( "Facebook", self.language_manager ) # Verbinde Signale unabhängig von der Tab-Implementierung # Alle Tabs müssen diese Signale unterstützen (Interface-Kontrakt) if hasattr(generator_tab, 'start_requested'): generator_tab.start_requested.connect(self.start_account_creation) if hasattr(generator_tab, 'stop_requested'): generator_tab.stop_requested.connect(self.stop_account_creation) return generator_tab def _configure_facebook_fields(self, generator_tab): """ Legacy-Methode für Abwärtskompatibilität. Die Konfiguration erfolgt jetzt in FacebookGeneratorTab. Args: generator_tab: Der zu konfigurierende Tab """ # Diese Methode ist nicht mehr nötig, da FacebookGeneratorTab # bereits alle Facebook-spezifischen Felder enthält # Behalten für Abwärtskompatibilität pass def start_account_creation(self, params: Dict[str, Any]): """ Startet die Facebook-Account-Erstellung. Args: params: Parameter für die Account-Erstellung """ super().start_account_creation(params) logger.info(f"Facebook-Account-Erstellung angefordert: {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) if hasattr(generator_tab, 'clear_log'): generator_tab.clear_log() if hasattr(generator_tab, 'set_progress'): generator_tab.set_progress(0) # Schmiedeanimation-Dialog erstellen und anzeigen parent_widget = generator_tab.window() # Hauptfenster als Parent self.forge_dialog = ForgeAnimationDialog(parent_widget, "Facebook") 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 mit optionalen Parametern session_controller = getattr(self, 'session_controller', None) generator_tab_ref = generator_tab if hasattr(generator_tab, 'store_created_account') else None self.worker_thread = FacebookWorkerThread( 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)) if hasattr(generator_tab, 'set_progress'): 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 handle_account_created(self, result: Dict[str, Any]): """Verarbeitet erfolgreich erstellte Accounts mit Clean Architecture.""" generator_tab = self.get_generator_tab() generator_tab.set_running(False) # Account-Daten aus dem Ergebnis holen account_data = result.get("account_data", {}) # Account und Session über SessionController speichern (Clean Architecture) if hasattr(self, 'session_controller') and self.session_controller: try: session_data = result.get("session_data", {}) save_result = self.session_controller.create_and_save_account( platform=self.platform_name, account_data=account_data ) if save_result.get('success'): logger.info(f"Account und Session erfolgreich gespeichert") # Erfolgsmeldung anzeigen (nur einmal!) account_info = save_result.get('account_data', {}) from PyQt5.QtWidgets import QMessageBox QMessageBox.information( generator_tab, "Erfolg", f"Account erfolgreich erstellt!\n\n" f"Benutzername: {account_info.get('username', '')}\n" f"Passwort: {account_info.get('password', '')}\n" f"E-Mail/Telefon: {account_info.get('email') or account_info.get('phone', '')}" ) # Signal senden, um zur Hauptseite zurückzukehren if hasattr(self, 'return_to_main_requested') and callable(self.return_to_main_requested): self.return_to_main_requested() else: error_msg = save_result.get('message', 'Unbekannter Fehler') logger.error(f"Fehler beim Speichern: {error_msg}") from views.widgets.modern_message_box import show_error show_error( generator_tab, "Fehler beim Speichern", f"Beim Speichern des Accounts ist ein Fehler aufgetreten:\n\n{error_msg}" ) except Exception as e: logger.error(f"Fehler beim Speichern des Accounts: {e}") from views.widgets.modern_message_box import show_critical show_critical( generator_tab, "Unerwarteter Fehler", f"Ein unerwarteter Fehler ist beim Speichern des Accounts aufgetreten:\n\n{str(e)}" ) else: # Fallback: Alte Methode falls SessionController nicht verfügbar logger.warning("SessionController nicht verfügbar, verwende alte Methode") generator_tab.account_created.emit(self.platform_name, account_data) if hasattr(self, 'return_to_main_requested') and callable(self.return_to_main_requested): self.return_to_main_requested() 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) def stop_account_creation(self): """Stoppt die Facebook-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) if hasattr(generator_tab, 'set_progress'): 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 # Facebook-spezifische Validierungen age = inputs.get("age", 0) if age < 13: return False, "Das Alter muss mindestens 13 sein (Facebook-Anforderung)." # Prüfe ob Vor- und Nachname vorhanden sind first_name = inputs.get("first_name", "") last_name = inputs.get("last_name", "") if not first_name or not last_name: return False, "Vor- und Nachname sind erforderlich." return True, "" def cleanup(self): """Räumt Ressourcen auf.""" self.stop_account_creation() logger.info("Facebook Controller aufgeräumt")