""" OK.ru (Odnoklassniki) Automatisierung - Hauptklasse für OK.ru-Automatisierungsfunktionalität """ import time import random from typing import Dict, List, Any, Optional, Tuple from browser.playwright_manager import PlaywrightManager from browser.playwright_extensions import PlaywrightExtensions from social_networks.base_automation import BaseAutomation from utils.password_generator import PasswordGenerator from utils.username_generator import UsernameGenerator from utils.birthday_generator import BirthdayGenerator from utils.human_behavior import HumanBehavior from utils.logger import setup_logger # Importiere Helferklassen from .ok_ru_registration import OkRuRegistration from .ok_ru_login import OkRuLogin from .ok_ru_verification import OkRuVerification from .ok_ru_ui_helper import OkRuUIHelper from .ok_ru_utils import OkRuUtils # Konfiguriere Logger logger = setup_logger("ok_ru_automation") class OkRuAutomation(BaseAutomation): """ Hauptklasse für die OK.ru (Odnoklassniki) Automatisierung. Implementiert die Registrierung und Anmeldung bei OK.ru. """ def __init__(self, headless: bool = False, use_proxy: bool = False, proxy_type: str = None, save_screenshots: bool = True, screenshots_dir: str = None, slowmo: int = 0, debug: bool = False, email_domain: str = "z5m7q9dk3ah2v1plx6ju.com", enhanced_stealth: bool = True, fingerprint_noise: float = 0.5, window_position = None, fingerprint = None, auto_close_browser: bool = False): """ Initialisiert die OK.ru-Automatisierung. Args: headless: Ob der Browser im Headless-Modus ausgeführt werden soll use_proxy: Ob ein Proxy verwendet werden soll proxy_type: Proxy-Typ ("ipv4", "ipv6", "mobile") oder None für zufälligen Typ save_screenshots: Ob Screenshots gespeichert werden sollen screenshots_dir: Verzeichnis für Screenshots slowmo: Verzögerung zwischen Aktionen in Millisekunden (nützlich für Debugging) debug: Ob Debug-Informationen angezeigt werden sollen email_domain: Domain für generierte E-Mail-Adressen enhanced_stealth: Ob erweiterter Stealth-Modus aktiviert werden soll fingerprint_noise: Menge an Rauschen für Fingerprint-Verschleierung (0.0-1.0) window_position: Optional - Fensterposition als Tuple (x, y) fingerprint: Optional - Vordefinierter Browser-Fingerprint auto_close_browser: Ob Browser automatisch geschlossen werden soll (Standard: False) """ # Initialisiere die Basisklasse super().__init__( headless=headless, use_proxy=use_proxy, proxy_type=proxy_type, save_screenshots=save_screenshots, screenshots_dir=screenshots_dir, slowmo=slowmo, debug=debug, email_domain=email_domain, window_position=window_position, auto_close_browser=auto_close_browser ) # Stealth-Modus-Einstellungen self.enhanced_stealth = enhanced_stealth self.fingerprint_noise = max(0.0, min(1.0, fingerprint_noise)) # Initialisiere Helferklassen self.registration = OkRuRegistration(self) self.login = OkRuLogin(self) self.verification = OkRuVerification(self) self.ui_helper = OkRuUIHelper(self) self.utils = OkRuUtils(self) # Zusätzliche Hilfsklassen self.password_generator = PasswordGenerator() self.username_generator = UsernameGenerator() self.birthday_generator = BirthdayGenerator() self.human_behavior = HumanBehavior(speed_factor=0.8, randomness=0.6) # Nutze übergebenen Fingerprint wenn vorhanden self.provided_fingerprint = fingerprint logger.info("OK.ru-Automatisierung initialisiert") def _initialize_browser(self) -> bool: """ Initialisiert den Browser mit den entsprechenden Einstellungen. Returns: bool: True bei Erfolg, False bei Fehler """ try: # Proxy-Konfiguration, falls aktiviert proxy_config = None if self.use_proxy: proxy_config = self.proxy_rotator.get_proxy(self.proxy_type) if not proxy_config: logger.warning(f"Kein Proxy vom Typ '{self.proxy_type}' verfügbar, verwende direkten Zugriff") # Browser initialisieren self.browser = PlaywrightManager( headless=self.headless, proxy=proxy_config, browser_type="chromium", screenshots_dir=self.screenshots_dir, slowmo=self.slowmo ) # Browser starten self.browser.start() # Erweiterten Fingerprint-Schutz aktivieren, wenn gewünscht if self.enhanced_stealth: # Erstelle Extensions-Objekt extensions = PlaywrightExtensions(self.browser) # Methoden anhängen extensions.hook_into_playwright_manager() # Fingerprint-Schutz aktivieren mit angepasster Konfiguration if self.provided_fingerprint: # Nutze den bereitgestellten Fingerprint logger.info("Verwende bereitgestellten Fingerprint für Account-Erstellung") # Konvertiere Dict zu BrowserFingerprint wenn nötig if isinstance(self.provided_fingerprint, dict): from domain.entities.browser_fingerprint import BrowserFingerprint fingerprint_obj = BrowserFingerprint.from_dict(self.provided_fingerprint) else: fingerprint_obj = self.provided_fingerprint # Wende Fingerprint über FingerprintProtection an from browser.fingerprint_protection import FingerprintProtection protection = FingerprintProtection( context=self.browser.context, fingerprint_config=fingerprint_obj ) protection.apply_to_context(self.browser.context) logger.info(f"Fingerprint {fingerprint_obj.fingerprint_id} angewendet") else: # Fallback: Zufällige Fingerprint-Konfiguration fingerprint_config = { "noise_level": self.fingerprint_noise, "canvas_noise": True, "audio_noise": True, "webgl_noise": True, "hardware_concurrency": random.choice([4, 6, 8]), "device_memory": random.choice([4, 8]), "timezone_id": "Europe/Moscow" # Russische Zeitzone für OK.ru } success = self.browser.enable_enhanced_fingerprint_protection(fingerprint_config) if success: logger.info("Erweiterter Fingerprint-Schutz erfolgreich aktiviert") else: logger.warning("Erweiterter Fingerprint-Schutz konnte nicht aktiviert werden") logger.info("Browser erfolgreich initialisiert") return True except Exception as e: logger.error(f"Fehler bei der Browser-Initialisierung: {e}") self.status["error"] = f"Browser-Initialisierungsfehler: {str(e)}" return False def register_account(self, full_name: str, age: int, registration_method: str = "phone", phone_number: str = None, **kwargs) -> Dict[str, Any]: """ Registriert einen neuen OK.ru-Account. Args: full_name: Vollständiger Name für den Account age: Alter des Benutzers registration_method: "phone" (OK.ru unterstützt hauptsächlich Telefon-Registrierung) phone_number: Telefonnummer (erforderlich) **kwargs: Weitere optionale Parameter Returns: Dict[str, Any]: Ergebnis der Registrierung mit Status und Account-Daten """ logger.info(f"Starte OK.ru-Account-Registrierung für '{full_name}'") self._emit_customer_log(f"📱 OK.ru-Account wird erstellt für: {full_name}") try: # 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"} # Rotiere Fingerprint vor der Registrierung if self.enhanced_stealth and hasattr(self.browser, 'rotate_fingerprint'): self.browser.rotate_fingerprint() logger.info("Browser-Fingerprint vor der Registrierung rotiert") # Delegiere die Hauptregistrierungslogik an die Registration-Klasse result = self.registration.register_account( full_name=full_name, age=age, registration_method=registration_method, phone_number=phone_number, **kwargs ) # Nehme Abschlussfoto auf self._take_screenshot(f"registration_finished_{int(time.time())}") # Aktualisiere Status self.status.update(result) return result except Exception as e: error_msg = f"Unerwarteter Fehler bei der Registrierung: {str(e)}" logger.error(error_msg, exc_info=True) # Fehler-Screenshot self._take_screenshot(f"registration_error_{int(time.time())}") # Aktualisiere Status self.status.update({ "success": False, "error": error_msg, "stage": "exception" }) return self.status finally: # Browser schließen self._close_browser() def login_account(self, username_or_email: str, password: str, **kwargs) -> Dict[str, Any]: """ Meldet sich bei einem bestehenden OK.ru-Account an. Args: username_or_email: Benutzername, E-Mail oder Telefonnummer password: Passwort **kwargs: Weitere optionale Parameter Returns: Dict[str, Any]: Ergebnis der Anmeldung mit Status """ logger.info(f"Starte OK.ru-Login für '{username_or_email}'") try: # 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"} # Rotiere Fingerprint vor dem Login if self.enhanced_stealth and hasattr(self.browser, 'rotate_fingerprint'): self.browser.rotate_fingerprint() logger.info("Browser-Fingerprint vor dem Login rotiert") # Delegiere die Hauptlogin-Logik an die Login-Klasse result = self.login.login_account(username_or_email, password, **kwargs) # Nehme Abschlussfoto auf self._take_screenshot(f"login_finished_{int(time.time())}") # Aktualisiere Status self.status.update(result) return result except Exception as e: error_msg = f"Unerwarteter Fehler beim Login: {str(e)}" logger.error(error_msg, exc_info=True) # Fehler-Screenshot self._take_screenshot(f"login_error_{int(time.time())}") # Aktualisiere Status self.status.update({ "success": False, "error": error_msg, "stage": "exception" }) return self.status finally: # Browser schließen wenn auto_close aktiviert if self.auto_close_browser: self._close_browser()