""" Gmail Utils - Utility-Funktionen für Gmail """ import logging import random import string import time import uuid from typing import Optional, List logger = logging.getLogger("gmail_utils") class GmailUtils: """ Utility-Funktionen für Gmail/Google Accounts """ @staticmethod def generate_gmail_username(first_name: str, last_name: str) -> str: """ Generiert einen praktisch einzigartigen Gmail-kompatiblen Benutzernamen Verwendet erweiterte 2025-Strategien für bessere Akzeptanz """ # Basis aus Vor- und Nachname normalisieren first_clean = ''.join(c.lower() for c in first_name if c.isalnum())[:8] # Max 8 Zeichen last_clean = ''.join(c.lower() for c in last_name if c.isalnum())[:8] # Max 8 Zeichen # Aktuelles Jahr und Millisekunden für Einzigartigkeit from datetime import datetime current_year = datetime.now().year current_millis = str(int(time.time() * 1000))[-6:] # Letzte 6 Ziffern der Millisekunden # Erweiteter Pool von Wörtern für 2025 words = [ "tech", "pro", "dev", "web", "net", "code", "app", "data", "work", "biz", "mail", "user", "info", "zone", "live", "home", "plus", "top", "new", "max", "best", "fast", "cool", "safe", "real", "true", "blue", "gold", "star", "win", "hub", "link", "base", "core", "main", "prime", "ultra", "mega", "super", "hyper", "alpha", "beta", "gamma", "delta", "sigma", "omega", "nova", "next", "edge", "flow" ] # Wähle zufälliges Wort word = random.choice(words) # Erweiterte 2025 Strategien für maximale Einzigartigkeit und Akzeptanz strategies = [ # Strategie 1: Hochgradig einzigartig mit Millisekunden lambda: f"{first_clean}{last_clean}{current_millis}", # Strategie 2: Mit Wort und Zeitstempel lambda: f"{first_clean}{word}{current_millis}", # Strategie 3: Punkt-getrennt mit Zahlen lambda: f"{first_clean}.{last_clean}{''.join(random.choices(string.digits, k=6))}", # Strategie 4: Jahr und zufällige Zahlen lambda: f"{first_clean}{last_clean}{current_year}{''.join(random.choices(string.digits, k=5))}", # Strategie 5: Wort in der Mitte lambda: f"{first_clean}{word}{last_clean}{''.join(random.choices(string.digits, k=4))}", # Strategie 6: Komplett zufällig aber lesbar lambda: f"{random.choice(['user', 'mail', 'contact', 'account'])}{current_millis}{random.choice(words)}", # Strategie 7: Initialen mit Timestamp lambda: f"{first_clean[0]}{last_clean[0]}{word}{current_millis}", # Strategie 8: Reverse mit Zahlen lambda: f"{last_clean}{first_clean}{''.join(random.choices(string.digits, k=6))}", # Strategie 9: Ultra-einzigartig mit UUID lambda: f"{first_clean[:4]}{str(uuid.uuid4())[:12]}".replace('-', ''), # Strategie 10: Einfach aber einzigartig lambda: f"{first_clean}{''.join(random.choices(string.digits, k=8))}" ] # Wähle zufällige Strategie username = random.choice(strategies)() # Stelle sicher, dass Username Gmail-Regeln entspricht (6-30 Zeichen) if len(username) > 30: # Kürze intelligent: behalte Schlüsselteile base_part = f"{first_clean[:4]}{last_clean[:4]}" suffix_part = username[len(username)-10:] # Letzten 10 Zeichen (einzigartige Teile) username = f"{base_part}_{suffix_part}" if len(username) < 6: # Falls zu kurz, füge mehr Zufälligkeit hinzu username += ''.join(random.choices(string.digits, k=6-len(username))) # Sicherstellen, dass es nicht mit Punkt beginnt/endet username = username.strip('.') # Keine aufeinanderfolgenden Punkte while '..' in username: username = username.replace('..', '.') return username @staticmethod def generate_multiple_username_options(first_name: str, last_name: str, count: int = 5) -> List[str]: """ Generiert mehrere einzigartige Username-Optionen für Fallback-Szenarien Verwendet verschiedene Strategien für maximale Diversität """ options = [] # Zuerst einen Standard-Username options.append(GmailUtils.generate_gmail_username(first_name, last_name)) # Dann spezielle Varianten timestamp = str(int(time.time()))[-6:] # Variante 1: Einfach mit Zahlen simple = f"{first_name.lower()[:10]}{''.join(random.choices(string.digits, k=6))}" if simple not in options: options.append(simple) # Variante 2: Mit aktuellem Jahr from datetime import datetime year_variant = f"{first_name.lower()[:8]}{datetime.now().year}{''.join(random.choices(string.digits, k=4))}" if year_variant not in options: options.append(year_variant) # Variante 3: Initialen mit Timestamp initials = f"{first_name[0].lower()}{last_name[0].lower()}user{timestamp}" if initials not in options: options.append(initials) # Fülle mit weiteren zufälligen Varianten auf while len(options) < count: username = GmailUtils.generate_gmail_username(first_name, last_name) if username not in options: # Duplikate vermeiden options.append(username) return options[:count] # Gib genau 'count' Optionen zurück @staticmethod def generate_secure_password(length: int = 16) -> str: """ Generiert ein sicheres Passwort für Google-Anforderungen - Mindestens 8 Zeichen - Mischung aus Buchstaben, Zahlen und Symbolen """ # Stelle sicher dass alle Zeichentypen enthalten sind password_chars = [] # Mindestens 2 Kleinbuchstaben password_chars.extend(random.choices(string.ascii_lowercase, k=2)) # Mindestens 2 Großbuchstaben password_chars.extend(random.choices(string.ascii_uppercase, k=2)) # Mindestens 2 Zahlen password_chars.extend(random.choices(string.digits, k=2)) # Mindestens 2 Sonderzeichen special_chars = "!@#$%^&*" password_chars.extend(random.choices(special_chars, k=2)) # Fülle mit zufälligen Zeichen auf remaining_length = length - len(password_chars) all_chars = string.ascii_letters + string.digits + special_chars password_chars.extend(random.choices(all_chars, k=remaining_length)) # Mische die Zeichen random.shuffle(password_chars) return ''.join(password_chars) @staticmethod def is_valid_gmail_address(email: str) -> bool: """ Prüft ob eine Gmail-Adresse gültig ist """ if not email.endswith("@gmail.com"): return False username = email.split("@")[0] # Gmail-Regeln: # - 6-30 Zeichen # - Buchstaben, Zahlen und Punkte # - Muss mit Buchstabe oder Zahl beginnen # - Kein Punkt am Anfang oder Ende # - Keine aufeinanderfolgenden Punkte if len(username) < 6 or len(username) > 30: return False if not username[0].isalnum() or not username[-1].isalnum(): return False if ".." in username: return False # Prüfe erlaubte Zeichen for char in username: if not (char.isalnum() or char == "."): return False return True @staticmethod def format_phone_for_google(phone: str, country_code: str = "+1") -> str: """ Formatiert eine Telefonnummer für Google """ # Entferne alle nicht-numerischen Zeichen phone_digits = ''.join(c for c in phone if c.isdigit()) # Wenn die Nummer bereits mit Ländercode beginnt if phone.startswith("+"): return phone # Füge Ländercode hinzu return f"{country_code}{phone_digits}"