From 877cfdaf8beadae951c0c95183446d7c31b4cbb4 Mon Sep 17 00:00:00 2001 From: Claude Project Manager Date: Sat, 11 Oct 2025 22:40:30 +0200 Subject: [PATCH] Rollbackpoint - Overlay kein Emoji --- .../base_worker_thread.py | 20 ++++- .../facebook_controller.py | 78 ++---------------- database/accounts.db | Bin 376832 -> 380928 bytes social_networks/base_automation.py | 52 +++++++++--- .../facebook/facebook_automation.py | 42 +++++++--- 5 files changed, 97 insertions(+), 95 deletions(-) diff --git a/controllers/platform_controllers/base_worker_thread.py b/controllers/platform_controllers/base_worker_thread.py index 8246e10..4c92caf 100644 --- a/controllers/platform_controllers/base_worker_thread.py +++ b/controllers/platform_controllers/base_worker_thread.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- """ Basis-Klasse für alle Platform Worker Threads zur Eliminierung von Code-Duplikation """ @@ -91,17 +92,24 @@ class BaseAccountCreationWorkerThread(QThread): automation_params["window_position"] = self.params.get("window_position") automation = AutomationClass(**automation_params) - + # Setze Callback für kundenfreundliche Logs automation.set_customer_log_callback(lambda msg: self.log_signal.emit(msg)) - + + # Setze zusätzliche Callbacks für Facebook-Kompatibilität + # Facebook verwendet _send_status_update und _send_log_update + if hasattr(automation, 'status_update_callback'): + automation.status_update_callback = lambda msg: self.update_signal.emit(msg) + if hasattr(automation, 'log_update_callback'): + automation.log_update_callback = lambda msg: self.log_signal.emit(msg) + self.update_signal.emit(f"{self.platform_name}-Automation initialisiert") self.progress_signal.emit(20) # Browser-Schutz wird jetzt direkt in base_automation.py nach Browser-Start angewendet # Account registrieren - self.log_signal.emit(f"Registriere Account für: {self.params['full_name']}") + self.log_signal.emit(f"Registriere Account: {self.params['full_name']}") # Account registrieren mit allen Original-Parametern # Erstelle saubere Parameter für register_account @@ -111,10 +119,14 @@ class BaseAccountCreationWorkerThread(QThread): "registration_method": self.params.get("registration_method", "email"), "email_domain": self.params.get("email_domain", "z5m7q9dk3ah2v1plx6ju.com") } - + # Füge optionale Parameter hinzu wenn vorhanden if "phone_number" in self.params: register_params["phone_number"] = self.params["phone_number"] + + # Gender für Facebook (optional) + if "gender" in self.params: + register_params["gender"] = self.params["gender"] # Additional params separat behandeln if "additional_params" in self.params: diff --git a/controllers/platform_controllers/facebook_controller.py b/controllers/platform_controllers/facebook_controller.py index d669e00..0e738ec 100644 --- a/controllers/platform_controllers/facebook_controller.py +++ b/controllers/platform_controllers/facebook_controller.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- """ Controller für Facebook-spezifische Funktionalität. Mit Fingerprint-Protection und Anti-Bot Features. @@ -21,16 +22,16 @@ from utils.logger import setup_logger logger = setup_logger("facebook_controller") class FacebookWorkerThread(BaseAccountCreationWorkerThread): - """Worker-Thread für die Facebook-Account-Erstellung.""" + """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 { @@ -40,73 +41,10 @@ class FacebookWorkerThread(BaseAccountCreationWorkerThread): "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 + + # WICHTIG: Keine eigene run() Methode mehr! + # Facebook nutzt jetzt die zentrale run() aus BaseAccountCreationWorkerThread + # Dies ermöglicht zentrale Callback-Verwaltung und konsistentes Verhalten class FacebookController(BasePlatformController): """Controller für die Facebook-Plattform.""" diff --git a/database/accounts.db b/database/accounts.db index 2f20744c3148559d44116eb4d605472bee22af6f..b871c753def8d272d934ec19fda8bd1a6ec2d74b 100644 GIT binary patch delta 1491 zcmb7^ZA=_R7{_;KXSo;dh2wxLt-w*zS||&%voE(pTMOkSf(^7b2d5F~-rb56xVv%? z#n`}M+J3QU)08Jsla{1@XiZTx&81PJ#uzm*Mw^%#jj>Hkuo{!L(a*X^OEnq|e%RT` zGyi$!zt3-;ot+KMo(;XYNj%MQ+~CRZZvOQ0!86VLlW!8->a6qcx5M1vDNm*Y`S-sS zAjpp%8+fjNCf`59FJ&5H{0+|e8#+W(fDbzE{ zag!sXlj+fvHDyhhiNw&fIc^RahT7TPH!4pyCmxQjEfrRvFNW@$>Afosw`C`-2}-CY z$wZRnFqK<0rA21zscWujxP+^bwIOc%nw61McG4W4Fvr)99Ll7}$E_hEE7qa0M0>0! z`E>2!Ohr%oa5h7x=$dR*MNWNDy{T(06z(zq=}pmFG`b#?`Q3-ak2;-5Sm9i^gcZAR z-wIvNI|gc^xw>5YoH)1rSg5Wo7roz^3$$^8W93pM=j2@LNe$OuMZp?MHG}D@Mh#8T znQBBD!<(~~mE7DC)>Nv&2erZ$n0XCVz#EHbBfPs}58v4np@QsMyhN zj*Y}8Mj-GG3Rd@96G<~=ZnkqBu!hrCINDv9x2IFt^q2`3ucB6%J&Flr&SNh$ZNa|$ zz6D&x!{D=cE8P4Xjl%DMx0O&DQM8DxYg9J~BMQ`BLK{jHCfk>v7@FM)ln@;jpAws) zp&acjy9a-@z)hN}844U;!i_NhxcDf1--J8hl?VUTc+Gzs&%(kGt_M;lc;Lu+yaB>5 zVP{1oNe!afZL7sC+bg-#2>Dx=MSqdoYhP{NHO;xEZFFf@*9jaepqu08lsV~GeQi}P zs-U^%0y@VXbnCgX(DpGZt0oH7WSKFY+A~%83pvC7f!rh4D^Qg|?gDOrpD&0mn0g(T zf|N(a&|D@~LHI}Hb?+G&4!4`xv2+T|Gq@a%TtRL)n@3w0PK%xJ-pk@9xK@gS`PQ#+ zkcUP|d}aZ}#uEFxNyJcf`#4=;ssdmBghBzCD!NV$sxeI?G(s4(eS<UW8cPv`TC4$n+#YSIF$IqfWizhlX(hUHVYbX@;67; zZ;z~JTwS0R#$?UF@s+8Un~STTrIP;!yAhiWryO58%NO3mY^fY)SOT~nae{AC~R@KCD}XB{;e48Tg&}mhkcOCh_d#QRZ&tdctMTxd>=pC#TI^ z21#wjNCr(~kPku`7)mm;OY*aeQ;Smb6614H6Vu`?%?;8+&HXaH-Lq6pArc^Qpz!pG zu}qSR!CMptKo diff --git a/social_networks/base_automation.py b/social_networks/base_automation.py index 392ea9a..b701fb7 100644 --- a/social_networks/base_automation.py +++ b/social_networks/base_automation.py @@ -17,6 +17,28 @@ from utils.text_similarity import TextSimilarity, fuzzy_find_element, click_fuzz # Konfiguriere Logger logger = logging.getLogger("base_automation") + +def _clean_message(message: str) -> str: + """ + Entfernt Emojis und normalisiert Leerzeichen aus Log-Nachrichten. + + Diese zentrale Funktion filtert alle Emojis und Sonderzeichen aus Display-Nachrichten, + um eine konsistente und saubere Anzeige im ForgeAnimationDialog zu gewährleisten. + + Args: + message: Die zu bereinigende Nachricht + + Returns: + str: Bereinigte Nachricht ohne Emojis und normalisierte Leerzeichen + """ + import re + # Entferne alle Zeichen außer: Buchstaben, Zahlen, Leerzeichen, Satzzeichen, Umlaute + clean = re.sub(r'[^\w\s\-.,!?äöüÄÖÜß():/@]', '', message) + # Normalisiere mehrfache Leerzeichen zu einem + clean = ' '.join(clean.split()) + return clean + + class BaseAutomation(ABC): """ Abstrakte Basisklasse für die Automatisierung von sozialen Netzwerken. @@ -108,11 +130,15 @@ class BaseAutomation(ABC): def set_customer_log_callback(self, callback): """Setzt den Callback für kundenfreundliche Log-Nachrichten.""" self.customer_log_callback = callback - + def _emit_customer_log(self, message: str): - """Sendet eine kundenfreundliche Log-Nachricht.""" + """ + Sendet eine kundenfreundliche Log-Nachricht. + Filtert automatisch Emojis für saubere Anzeige. + """ + clean_message = _clean_message(message) if self.customer_log_callback: - self.customer_log_callback(message) + self.customer_log_callback(clean_message) def _initialize_browser(self) -> bool: """ @@ -240,33 +266,37 @@ class BaseAutomation(ABC): def _send_status_update(self, status: str) -> None: """ Sendet ein Status-Update über den Callback. - + Filtert automatisch Emojis für saubere Anzeige. + Args: status: Status-Nachricht """ + clean_status = _clean_message(status) if self.status_update_callback: try: - self.status_update_callback(status) + self.status_update_callback(clean_status) except Exception as e: logger.error(f"Fehler beim Senden des Status-Updates: {e}") def _send_log_update(self, message: str) -> None: """ Sendet ein Log-Update über den Callback. - + Filtert automatisch Emojis für saubere Anzeige. + Args: message: Log-Nachricht """ + clean_message = _clean_message(message) + if self.log_update_callback: try: - self.log_update_callback(message) + self.log_update_callback(clean_message) except Exception as e: logger.error(f"Fehler beim Senden des Log-Updates: {e}") - - # Auch über customer_log_callback senden für Kompatibilität - if self.customer_log_callback: + elif self.customer_log_callback: + # Fallback für Plattformen, die nur customer_log_callback setzen try: - self.customer_log_callback(message) + self.customer_log_callback(clean_message) except Exception as e: logger.error(f"Fehler beim Senden des Customer-Log-Updates: {e}") diff --git a/social_networks/facebook/facebook_automation.py b/social_networks/facebook/facebook_automation.py index 330f55a..90c4e75 100644 --- a/social_networks/facebook/facebook_automation.py +++ b/social_networks/facebook/facebook_automation.py @@ -235,31 +235,53 @@ class FacebookAutomation(BaseAutomation): except Exception as e: logger.warning(f"Fehler beim Anwenden Facebook-spezifischer Einstellungen: {e}") - def register_account(self, - first_name: str, - last_name: str, - birth_date: Dict[str, int], - gender: str, + def register_account(self, + full_name: str = None, + age: int = None, + first_name: str = None, + last_name: str = None, + birth_date: Dict[str, int] = None, + gender: str = None, + registration_method: str = "email", email: str = None, phone_number: str = None, password: str = None, **kwargs) -> Dict[str, Any]: """ Registriert einen neuen Facebook-Account. - + Unterstützt beide Aufrufmuster: Base-Pattern (full_name, age) und Legacy (first_name, last_name, birth_date). + Args: - first_name: Vorname - last_name: Nachname - birth_date: Geburtsdatum als Dict mit 'day', 'month', 'year' + full_name: Vollständiger Name (für Base-Pattern) + age: Alter (für Base-Pattern) + first_name: Vorname (Legacy, wird aus full_name extrahiert wenn nicht gegeben) + last_name: Nachname (Legacy, wird aus full_name extrahiert wenn nicht gegeben) + birth_date: Geburtsdatum als Dict (Legacy, wird aus age generiert wenn nicht gegeben) gender: Geschlecht ('male', 'female', 'custom') + registration_method: Registrierungsmethode (für Kompatibilität, immer 'email' bei Facebook) email: E-Mail-Adresse (optional, wird generiert wenn nicht angegeben) phone_number: Telefonnummer (optional, alternativ zu E-Mail) password: Passwort (optional, wird generiert wenn nicht angegeben) **kwargs: Weitere optionale Parameter - + Returns: Dict[str, Any]: Ergebnis der Registrierung """ + # Parameter-Konvertierung: Base-Pattern → Facebook-Format + if full_name and not (first_name and last_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" + logger.debug(f"Namen aus full_name extrahiert: {first_name} {last_name}") + + if age and not birth_date: + birth_date = self.birthday_generator.generate_birthday_components("facebook", age) + logger.debug(f"Geburtsdatum aus Alter generiert: {birth_date}") + + if not gender: + gender = random.choice(["male", "female"]) + logger.debug(f"Zufälliges Geschlecht gewählt: {gender}") + logger.info(f"Starte Facebook-Registrierung für {first_name} {last_name}") try: