diff --git a/CLAUDE_PROJECT_README.md b/CLAUDE_PROJECT_README.md index a0edc0f..73b5e65 100644 --- a/CLAUDE_PROJECT_README.md +++ b/CLAUDE_PROJECT_README.md @@ -5,9 +5,9 @@ ## Project Overview - **Path**: `A:\GiTea\AccountForger` -- **Files**: 1024 files -- **Size**: 184.1 MB -- **Last Modified**: 2025-10-03 01:25 +- **Files**: 1104 files +- **Size**: 211.2 MB +- **Last Modified**: 2025-10-08 22:32 ## Technology Stack @@ -195,11 +195,11 @@ logs/ │ ├── after_account_create_click_1757807105.png │ ├── after_account_create_click_1757807217.png │ ├── after_account_create_click_1757810496.png +│ ├── after_account_create_click_1759527439.png +│ ├── after_account_create_click_1759870629.png │ ├── after_code_retrieval_1757531778.png │ ├── after_code_retrieval_1757807127.png -│ ├── after_code_retrieval_1757807239.png -│ ├── after_code_retrieval_1757810517.png -│ └── after_cookie_consent_1757852739.png +│ └── after_code_retrieval_1757807239.png resources/ │ ├── icons/ │ │ ├── check-white.svg @@ -215,7 +215,6 @@ resources/ │ └── themes/ │ ├── dark.qss │ └── light.qss -screenshots scripts/ │ └── fix_x_accounts.py social_networks/ @@ -271,7 +270,6 @@ social_networks/ │ │ ├── tiktok_verification.py │ │ ├── tiktok_workflow.py │ │ └── __init__.py -│ ├── twitter │ ├── vk/ │ │ ├── vk_automation.py │ │ ├── vk_login.py @@ -429,3 +427,5 @@ This project is managed with Claude Project Manager. To work with this project: - README updated on 2025-09-21 10:31:22 - README updated on 2025-09-24 19:25:49 - README updated on 2025-10-03 20:29:19 +- README updated on 2025-10-08 22:32:21 +- README updated on 2025-10-08 22:34:43 diff --git a/controllers/platform_controllers/facebook_controller.py b/controllers/platform_controllers/facebook_controller.py index 5657bda..d669e00 100644 --- a/controllers/platform_controllers/facebook_controller.py +++ b/controllers/platform_controllers/facebook_controller.py @@ -22,9 +22,9 @@ logger = setup_logger("facebook_controller") class FacebookWorkerThread(BaseAccountCreationWorkerThread): """Worker-Thread für die Facebook-Account-Erstellung.""" - - def __init__(self, params): - super().__init__(params, "Facebook") + + 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): @@ -111,20 +111,12 @@ class FacebookWorkerThread(BaseAccountCreationWorkerThread): class FacebookController(BasePlatformController): """Controller für die Facebook-Plattform.""" - # Qt Signale für Kommunikation mit UI - status_update = pyqtSignal(str) # Status-Updates - log_message = pyqtSignal(str) # Log-Nachrichten - progress_update = pyqtSignal(int) # Fortschritt (0-100) - generation_started = pyqtSignal() # Generierung gestartet - generation_completed = pyqtSignal(dict) # Generierung abgeschlossen - generation_failed = pyqtSignal(str) # Generierung fehlgeschlagen - 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 get_generator_tab(self): + def create_generator_tab(self): """ Erstellt und konfiguriert den Generator-Tab für Facebook. Verwendet die Factory für saubere Tab-Erstellung. @@ -142,9 +134,9 @@ class FacebookController(BasePlatformController): # 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.handle_generation_request) + generator_tab.start_requested.connect(self.start_account_creation) if hasattr(generator_tab, 'stop_requested'): - generator_tab.stop_requested.connect(self.stop_generation) + generator_tab.stop_requested.connect(self.stop_account_creation) return generator_tab @@ -161,127 +153,214 @@ class FacebookController(BasePlatformController): # Behalten für Abwärtskompatibilität pass - def handle_generation_request(self, params: Dict[str, Any]): + def start_account_creation(self, params: Dict[str, Any]): """ - Behandelt eine Anfrage zur Account-Generierung mit Forge Dialog. - + Startet die Facebook-Account-Erstellung. + Args: - params: Parameter für die Generierung + params: Parameter für die Account-Erstellung """ - logger.info(f"Facebook-Account-Generierung angefordert: {params}") - - # Prüfe ob bereits ein Thread läuft - if self.worker_thread and self.worker_thread.isRunning(): - logger.warning("Ein Account wird bereits erstellt") + 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 - - # Facebook-spezifische Parameter hinzufügen - params["platform"] = "facebook" - - # Hole Generator Tab für Parent Widget + + # UI aktualisieren generator_tab = self.get_generator_tab() - - # Schmiedeanimation-Dialog erstellen und anzeigen (wie TikTok) + 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_generation) - self.forge_dialog.closed.connect(self.stop_generation) - + 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()) - - # Starte Worker-Thread - self.worker_thread = FacebookWorkerThread(params) - - # Verbinde Signale mit Forge Dialog + + # 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) - - # Zusätzlich an Controller-Signale für andere Komponenten - self.worker_thread.update_signal.connect( - lambda msg: self.status_update.emit(msg) - ) - self.worker_thread.log_signal.connect( - lambda msg: self.log_message.emit(msg) - ) - self.worker_thread.progress_signal.connect( - lambda val: self.progress_update.emit(val) - ) - self.worker_thread.finished_signal.connect( - self._handle_generation_success - ) - self.worker_thread.error_signal.connect( - self._handle_generation_error - ) - - # Starte Thread + + # 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() - self.generation_started.emit() - + # Dialog anzeigen und Animation starten self.forge_dialog.start_animation() self.forge_dialog.show() - def _handle_generation_success(self, result: Dict[str, Any]): - """ - Behandelt erfolgreiche Account-Erstellung. - - Args: - result: Ergebnis der Erstellung - """ - logger.info("Facebook-Account erfolgreich erstellt") - + 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 - - # Speichere Account in Datenbank - if self.db_manager and result.get("account_data"): - account_data = result["account_data"] - account_data["platform"] = "facebook" - - # Speichere in DB - # TODO: DB-Integration - - self.generation_completed.emit(result) + + # Fehler anzeigen + generator_tab = self.get_generator_tab() + generator_tab.show_error(error_msg) + generator_tab.set_running(False) - def _handle_generation_error(self, error_msg: str): - """ - Behandelt Fehler bei der Account-Erstellung. - - Args: - error_msg: Fehlermeldung - """ - logger.error(f"Fehler bei Facebook-Account-Erstellung: {error_msg}") - - # Forge-Dialog schließen mit Fehlerbehandlung + 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: - try: - self.forge_dialog.close() - except RuntimeError as e: - logger.warning(f"Forge Dialog bereits geschlossen: {e}") - finally: - self.forge_dialog = None - - self.generation_failed.emit(error_msg) - - def stop_generation(self): - """Stoppt die laufende Account-Generierung.""" + 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(): - logger.info("Stoppe Facebook-Account-Generierung") self.worker_thread.stop() - self.worker_thread.wait() - + 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_generation() + self.stop_account_creation() logger.info("Facebook Controller aufgeräumt") \ No newline at end of file