""" Gmail Automatisierung - Hauptklasse """ import logging import time import random from typing import Dict, Optional, Tuple, Any from playwright.sync_api import Page from social_networks.base_automation import BaseAutomation from social_networks.gmail import gmail_selectors as selectors from social_networks.gmail.gmail_ui_helper import GmailUIHelper from social_networks.gmail.gmail_registration import GmailRegistration from social_networks.gmail.gmail_login import GmailLogin from social_networks.gmail.gmail_verification import GmailVerification from social_networks.gmail.gmail_utils import GmailUtils logger = logging.getLogger("gmail_automation") class GmailAutomation(BaseAutomation): """ Gmail/Google Account-spezifische Automatisierung """ def __init__(self, **kwargs): """ Initialisiert die Gmail-Automatisierung """ super().__init__(**kwargs) self.platform_name = "gmail" self.ui_helper = None self.registration = None self.login_helper = None self.verification = None self.utils = None def _initialize_helpers(self, page: Page): """ Initialisiert die Hilfsklassen """ self.ui_helper = GmailUIHelper(page, self.screenshots_dir, self.save_screenshots) self.registration = GmailRegistration(page, self.ui_helper, self.screenshots_dir, self.save_screenshots) self.login_helper = GmailLogin(page, self.ui_helper, self.screenshots_dir, self.save_screenshots) self.verification = GmailVerification(page, self.ui_helper, self.email_handler, self.screenshots_dir, self.save_screenshots) self.utils = GmailUtils() def register_account(self, full_name: str, age: int, registration_method: str = "email", phone_number: str = None, **kwargs) -> Dict[str, any]: """ Erstellt einen neuen Gmail/Google Account Args: full_name: Vollständiger Name für den Account age: Alter des Benutzers registration_method: Registrierungsmethode (nur "email" für Gmail) phone_number: Telefonnummer (optional, aber oft erforderlich) **kwargs: Weitere optionale Parameter """ try: logger.info(f"[GMAIL AUTOMATION] register_account aufgerufen") logger.info(f"[GMAIL AUTOMATION] full_name: {full_name}") logger.info(f"[GMAIL AUTOMATION] age: {age}") logger.info(f"[GMAIL AUTOMATION] phone_number: {phone_number}") logger.info(f"[GMAIL AUTOMATION] kwargs: {kwargs}") # Erstelle account_data aus den Parametern account_data = { "full_name": full_name, "first_name": kwargs.get("first_name", full_name.split()[0] if full_name else ""), "last_name": kwargs.get("last_name", full_name.split()[-1] if full_name and len(full_name.split()) > 1 else ""), "age": age, "birthday": kwargs.get("birthday", self._generate_birthday(age)), "gender": kwargs.get("gender", random.choice(["male", "female"])), "username": kwargs.get("username", ""), "password": kwargs.get("password", ""), "phone": phone_number, "recovery_email": kwargs.get("recovery_email", "") } # Initialisiere Browser, falls noch nicht geschehen logger.info(f"[GMAIL AUTOMATION] Prüfe Browser-Status...") logger.info(f"[GMAIL AUTOMATION] self.browser: {self.browser}") if self.browser: logger.info(f"[GMAIL AUTOMATION] hasattr(self.browser, 'page'): {hasattr(self.browser, 'page')}") if not self.browser or not hasattr(self.browser, 'page'): logger.info(f"[GMAIL AUTOMATION] Browser muss initialisiert werden") if not self._initialize_browser(): logger.error(f"[GMAIL AUTOMATION] Browser-Initialisierung fehlgeschlagen!") return { "success": False, "error": "Browser konnte nicht initialisiert werden", "message": "Browser-Initialisierung fehlgeschlagen" } logger.info(f"[GMAIL AUTOMATION] Browser erfolgreich initialisiert") # Page-Objekt holen page = self.browser.page self._initialize_helpers(page) # Direkt zur Registrierungs-URL navigieren logger.info("Navigiere zur Gmail Registrierungsseite") page.goto(selectors.REGISTRATION_URL, wait_until="networkidle") # Warte auf vollständiges Laden der Seite logger.info("Warte auf vollständiges Laden der Seite...") time.sleep(random.uniform(5, 7)) # Prüfe ob wir auf der richtigen Seite sind current_url = page.url logger.info(f"Aktuelle URL nach Navigation: {current_url}") # Screenshot der Startseite self.ui_helper.take_screenshot("gmail_start_page") # Finde und klicke auf "Konto erstellen" Button (Dropdown) try: # Warte bis die Seite interaktiv ist logger.info("Warte auf vollständiges Laden der Gmail Workspace Seite...") page.wait_for_load_state("networkidle") time.sleep(2) # Debug: Alle sichtbaren Links/Buttons mit "Konto" ausgeben try: konto_elements = page.locator("*:has-text('Konto')").all() logger.info(f"Gefundene Elemente mit 'Konto': {len(konto_elements)}") for i, elem in enumerate(konto_elements[:5]): # Erste 5 Elemente try: tag = elem.evaluate("el => el.tagName") text = elem.inner_text() logger.info(f"Element {i}: <{tag}> - {text}") except: pass except Exception as e: logger.debug(f"Debug-Ausgabe fehlgeschlagen: {e}") # Schritt 1: Klicke auf "Konto erstellen" Dropdown create_account_selectors = [ "[aria-label='Konto erstellen']", "div[aria-label='Konto erstellen']", "[data-g-action='create an account']", "button:has-text('Konto erstellen')", "a:has-text('Konto erstellen')", "*:has-text('Konto erstellen')", # Beliebiges Element mit dem Text "[slot='label']:has-text('Konto erstellen')" # Spezifisch für Web Components ] clicked_dropdown = False for selector in create_account_selectors: try: elements = page.locator(selector).all() logger.info(f"Selector {selector}: {len(elements)} Elemente gefunden") if page.locator(selector).is_visible(timeout=3000): # Versuche normale Klick-Methode try: page.locator(selector).first.click() logger.info(f"Dropdown 'Konto erstellen' geklickt mit: {selector}") clicked_dropdown = True break except: # Versuche JavaScript-Klick als Fallback page.locator(selector).first.evaluate("el => el.click()") logger.info(f"Dropdown 'Konto erstellen' via JS geklickt mit: {selector}") clicked_dropdown = True break except Exception as e: logger.debug(f"Fehler mit Selector {selector}: {e}") continue if not clicked_dropdown: logger.error("Konnte 'Konto erstellen' Dropdown nicht finden") self.ui_helper.take_screenshot("konto_erstellen_not_found") return { "success": False, "error": "Konto erstellen Dropdown nicht gefunden", "message": "Navigation fehlgeschlagen" } # Kurz warten bis Dropdown geöffnet ist time.sleep(1) # Schritt 2: Klicke auf "Für die private Nutzung" private_use_selectors = [ "a[aria-label='Gmail - Für die private Nutzung']", "a:has-text('Für die private Nutzung')", "[data-g-action='für die private nutzung']", "span:has-text('Für die private Nutzung')" ] clicked_private = False for selector in private_use_selectors: try: if page.locator(selector).is_visible(timeout=2000): page.locator(selector).click() logger.info(f"'Für die private Nutzung' geklickt mit: {selector}") clicked_private = True break except: continue if not clicked_private: logger.error("Konnte 'Für die private Nutzung' nicht finden") self.ui_helper.take_screenshot("private_nutzung_not_found") return { "success": False, "error": "Für die private Nutzung Option nicht gefunden", "message": "Navigation fehlgeschlagen" } # Warte auf die Registrierungsseite time.sleep(random.uniform(3, 5)) except Exception as e: logger.error(f"Fehler beim Navigieren zur Registrierung: {e}") # Screenshot der Registrierungsseite self.ui_helper.take_screenshot("gmail_registration_page") # Registrierungsprozess starten registration_result = self.registration.start_registration_flow(account_data) if not registration_result["success"]: return registration_result # Nach erfolgreicher Registrierung logger.info("Gmail Account-Registrierung erfolgreich abgeschlossen") return { "success": True, "username": registration_result.get("username"), "password": account_data.get("password"), "email": registration_result.get("email"), "phone": account_data.get("phone"), "recovery_email": account_data.get("recovery_email"), "message": "Account erfolgreich erstellt" } except Exception as e: logger.error(f"Fehler bei der Gmail-Registrierung: {str(e)}") return { "success": False, "error": str(e), "message": f"Registrierung fehlgeschlagen: {str(e)}" } finally: self._close_browser() def login(self, username: str, password: str) -> Dict[str, any]: """ Meldet sich bei einem bestehenden Gmail/Google Account an """ try: logger.info(f"Starte Gmail Login für {username}") # Initialisiere Browser, falls noch nicht geschehen if not self.browser or not hasattr(self.browser, 'page'): if not self._initialize_browser(): return { "success": False, "error": "Browser konnte nicht initialisiert werden", "message": "Browser-Initialisierung fehlgeschlagen" } # Page-Objekt holen page = self.browser.page self._initialize_helpers(page) # Login durchführen return self.login_helper.login(username, password) except Exception as e: logger.error(f"Fehler beim Gmail Login: {str(e)}") return { "success": False, "error": str(e), "message": f"Login fehlgeschlagen: {str(e)}" } finally: self._close_browser() def get_account_info(self) -> Dict[str, any]: """ Ruft Informationen über den aktuellen Account ab """ # TODO: Implementierung return { "success": False, "message": "Noch nicht implementiert" } def logout(self) -> bool: """ Meldet sich vom aktuellen Account ab """ # TODO: Implementierung return False def login_account(self, username_or_email: str, password: str, **kwargs) -> Dict[str, Any]: """ Meldet sich bei einem bestehenden Gmail Account an. Implementiert die abstrakte Methode aus BaseAutomation. """ return self.login(username_or_email, password) def verify_account(self, verification_code: str, **kwargs) -> Dict[str, Any]: """ Verifiziert einen Gmail Account mit einem Bestätigungscode. Implementiert die abstrakte Methode aus BaseAutomation. """ try: if self.verification: return self.verification.verify_with_code(verification_code) else: return { "success": False, "error": "Verification helper nicht initialisiert", "message": "Verifizierung kann nicht durchgeführt werden" } except Exception as e: return { "success": False, "error": str(e), "message": f"Verifizierung fehlgeschlagen: {str(e)}" } def _generate_birthday(self, age: int) -> str: """ Generiert ein Geburtsdatum basierend auf dem Alter """ from datetime import datetime, timedelta today = datetime.now() birth_year = today.year - age # Zufälliger Tag im Jahr random_days = random.randint(0, 364) birthday = datetime(birth_year, 1, 1) + timedelta(days=random_days) return birthday.strftime("%Y-%m-%d")