Problem bei X gelöst

Dieser Commit ist enthalten in:
Claude Project Manager
2025-08-12 00:38:23 +02:00
Ursprung 5d169ba517
Commit 3101e41451
16 geänderte Dateien mit 3142 neuen und 12 gelöschten Zeilen

Datei anzeigen

@ -0,0 +1,293 @@
# social_networks/facebook/facebook_utils.py
"""
Facebook Utils - Hilfsfunktionen für Facebook-Automatisierung
"""
import logging
import random
import re
from typing import Optional, List, Dict, Any
from utils.logger import setup_logger
logger = setup_logger("facebook_utils")
class FacebookUtils:
"""
Hilfsklasse mit Utility-Funktionen für Facebook.
"""
def __init__(self, automation):
"""
Initialisiert die Utils-Klasse.
Args:
automation: Referenz auf die Hauptautomatisierungsklasse
"""
self.automation = automation
logger.debug("Facebook Utils initialisiert")
@staticmethod
def validate_email(email: str) -> bool:
"""
Validiert eine E-Mail-Adresse.
Args:
email: E-Mail-Adresse
Returns:
bool: True wenn gültig
"""
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
return bool(re.match(pattern, email))
@staticmethod
def validate_phone(phone: str) -> bool:
"""
Validiert eine Telefonnummer.
Args:
phone: Telefonnummer
Returns:
bool: True wenn gültig
"""
# Entferne alle Nicht-Ziffern
digits_only = re.sub(r'\D', '', phone)
# Prüfe Länge (international 7-15 Ziffern)
return 7 <= len(digits_only) <= 15
@staticmethod
def generate_username_from_name(first_name: str, last_name: str) -> str:
"""
Generiert einen Benutzernamen aus Vor- und Nachname.
Args:
first_name: Vorname
last_name: Nachname
Returns:
str: Generierter Benutzername
"""
# Bereinige Namen
first_clean = re.sub(r'[^a-zA-Z]', '', first_name.lower())
last_clean = re.sub(r'[^a-zA-Z]', '', last_name.lower())
# Verschiedene Formate
formats = [
f"{first_clean}.{last_clean}",
f"{first_clean}{last_clean}",
f"{first_clean}_{last_clean}",
f"{first_clean[0]}{last_clean}",
f"{last_clean}.{first_clean}",
]
username = random.choice(formats)
# Füge optional Zahlen hinzu
if random.random() > 0.5:
username += str(random.randint(1, 999))
return username
@staticmethod
def format_phone_number(phone: str, country_code: str = "+49") -> str:
"""
Formatiert eine Telefonnummer.
Args:
phone: Telefonnummer
country_code: Ländervorwahl
Returns:
str: Formatierte Telefonnummer
"""
# Entferne alle Nicht-Ziffern
digits = re.sub(r'\D', '', phone)
# Füge Ländervorwahl hinzu wenn nicht vorhanden
if not phone.startswith('+'):
return f"{country_code}{digits}"
return f"+{digits}"
@staticmethod
def is_valid_password(password: str) -> bool:
"""
Prüft ob ein Passwort den Facebook-Anforderungen entspricht.
Facebook-Anforderungen:
- Mindestens 6 Zeichen
- Kombination aus Buchstaben, Zahlen und/oder Sonderzeichen empfohlen
Args:
password: Zu prüfendes Passwort
Returns:
bool: True wenn gültig
"""
if len(password) < 6:
return False
# Prüfe auf verschiedene Zeichentypen (empfohlen, nicht erforderlich)
has_letter = bool(re.search(r'[a-zA-Z]', password))
has_digit = bool(re.search(r'\d', password))
has_special = bool(re.search(r'[!@#$%^&*(),.?":{}|<>]', password))
# Mindestens 2 verschiedene Zeichentypen empfohlen
char_types = sum([has_letter, has_digit, has_special])
if char_types < 2:
logger.warning("Passwort sollte mindestens 2 verschiedene Zeichentypen enthalten")
return True
def detect_language(self) -> str:
"""
Erkennt die aktuelle Sprache der Facebook-Seite.
Returns:
str: Sprachcode ("de", "en", etc.)
"""
try:
# Prüfe HTML lang-Attribut
lang = self.automation.browser.page.get_attribute("html", "lang")
if lang:
return lang[:2] # Erste 2 Zeichen (de, en, etc.)
# Prüfe Meta-Tags
meta_lang = self.automation.browser.page.get_attribute(
"meta[property='og:locale']", "content"
)
if meta_lang:
return meta_lang[:2]
# Fallback: Prüfe Text-Inhalte
page_content = self.automation.browser.page.content().lower()
german_keywords = ["anmelden", "registrieren", "passwort", "konto"]
english_keywords = ["login", "register", "password", "account"]
german_count = sum(1 for kw in german_keywords if kw in page_content)
english_count = sum(1 for kw in english_keywords if kw in page_content)
if german_count > english_count:
return "de"
else:
return "en"
except Exception as e:
logger.error(f"Fehler bei Spracherkennung: {e}")
return "en" # Fallback zu Englisch
def extract_error_message(self) -> Optional[str]:
"""
Extrahiert Fehlermeldungen von der Seite.
Returns:
Optional[str]: Fehlermeldung oder None
"""
try:
# Verschiedene Fehler-Selektoren
error_selectors = [
"div[role='alert']",
"div.uiContextualLayer",
"div._5v-0._53im",
"div[data-testid='error']",
"span.error",
"div.error-message"
]
for selector in error_selectors:
try:
error_elem = self.automation.browser.page.query_selector(selector)
if error_elem and error_elem.is_visible():
error_text = error_elem.inner_text().strip()
if error_text:
logger.info(f"Fehlermeldung gefunden: {error_text}")
return error_text
except:
continue
# Prüfe auf bekannte Fehler-Keywords im Seiteninhalt
page_content = self.automation.browser.page.content()
error_patterns = [
r"(Fehler|Error):\s*([^<\n]+)",
r"(Problem|Issue):\s*([^<\n]+)",
r"class=\"error[^\"]*\"[^>]*>([^<]+)",
]
for pattern in error_patterns:
match = re.search(pattern, page_content, re.IGNORECASE)
if match:
error_text = match.group(1) if len(match.groups()) == 1 else match.group(2)
logger.info(f"Fehler-Pattern gefunden: {error_text}")
return error_text.strip()
return None
except Exception as e:
logger.error(f"Fehler beim Extrahieren der Fehlermeldung: {e}")
return None
@staticmethod
def parse_facebook_url(url: str) -> Dict[str, Any]:
"""
Parst eine Facebook-URL und extrahiert Informationen.
Args:
url: Facebook-URL
Returns:
Dict mit URL-Komponenten
"""
parsed = {
"is_facebook": "facebook.com" in url,
"is_login": "/login" in url or "/accounts/login" in url,
"is_registration": "/r.php" in url or "/reg" in url,
"is_checkpoint": "/checkpoint" in url,
"is_confirmation": "/confirmemail" in url,
"is_home": url.endswith("facebook.com/") or "/home" in url,
"has_error": "error=" in url or "err=" in url
}
# Extrahiere Query-Parameter
if "?" in url:
query_string = url.split("?")[1]
params = {}
for param in query_string.split("&"):
if "=" in param:
key, value = param.split("=", 1)
params[key] = value
parsed["params"] = params
return parsed
def take_debug_screenshot(self, name: str = "debug") -> str:
"""
Nimmt einen Debug-Screenshot auf.
Args:
name: Name für den Screenshot
Returns:
str: Pfad zum Screenshot
"""
return self.automation._take_screenshot(f"facebook_{name}")
@staticmethod
def get_random_user_agent() -> str:
"""
Gibt einen zufälligen User-Agent zurück.
Returns:
str: User-Agent String
"""
user_agents = [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
]
return random.choice(user_agents)