Initial commit
Dieser Commit ist enthalten in:
304
utils/birthday_generator.py
Normale Datei
304
utils/birthday_generator.py
Normale Datei
@ -0,0 +1,304 @@
|
||||
"""
|
||||
Geburtsdatumsgenerator für den Social Media Account Generator.
|
||||
"""
|
||||
|
||||
import random
|
||||
import datetime
|
||||
import logging
|
||||
from typing import Dict, List, Any, Optional, Tuple, Union
|
||||
|
||||
logger = logging.getLogger("birthday_generator")
|
||||
|
||||
class BirthdayGenerator:
|
||||
"""Klasse zur Generierung von realistischen Geburtsdaten für Social-Media-Accounts."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialisiert den BirthdayGenerator."""
|
||||
# Plattformspezifische Richtlinien
|
||||
self.platform_policies = {
|
||||
"instagram": {
|
||||
"min_age": 13,
|
||||
"max_age": 100,
|
||||
"date_format": "%Y-%m-%d" # ISO-Format
|
||||
},
|
||||
"facebook": {
|
||||
"min_age": 13,
|
||||
"max_age": 100,
|
||||
"date_format": "%m/%d/%Y" # US-Format
|
||||
},
|
||||
"twitter": {
|
||||
"min_age": 13,
|
||||
"max_age": 100,
|
||||
"date_format": "%Y-%m-%d" # ISO-Format
|
||||
},
|
||||
"tiktok": {
|
||||
"min_age": 13,
|
||||
"max_age": 100,
|
||||
"date_format": "%Y-%m-%d" # ISO-Format
|
||||
},
|
||||
"x": {
|
||||
"min_age": 13,
|
||||
"max_age": 100,
|
||||
"date_format": "%Y-%m-%d" # ISO-Format
|
||||
},
|
||||
"default": {
|
||||
"min_age": 18,
|
||||
"max_age": 80,
|
||||
"date_format": "%Y-%m-%d" # ISO-Format
|
||||
}
|
||||
}
|
||||
|
||||
def get_platform_policy(self, platform: str) -> Dict[str, Any]:
|
||||
"""
|
||||
Gibt die Altersrichtlinie für eine bestimmte Plattform zurück.
|
||||
|
||||
Args:
|
||||
platform: Name der Plattform
|
||||
|
||||
Returns:
|
||||
Dictionary mit der Altersrichtlinie
|
||||
"""
|
||||
platform = platform.lower()
|
||||
return self.platform_policies.get(platform, self.platform_policies["default"])
|
||||
|
||||
def set_platform_policy(self, platform: str, policy: Dict[str, Any]) -> None:
|
||||
"""
|
||||
Setzt oder aktualisiert die Altersrichtlinie für eine Plattform.
|
||||
|
||||
Args:
|
||||
platform: Name der Plattform
|
||||
policy: Dictionary mit der Altersrichtlinie
|
||||
"""
|
||||
platform = platform.lower()
|
||||
self.platform_policies[platform] = policy
|
||||
logger.info(f"Altersrichtlinie für '{platform}' aktualisiert")
|
||||
|
||||
def generate_birthday(self, platform: str = "default", age: Optional[int] = None) -> Tuple[datetime.date, str]:
|
||||
"""
|
||||
Generiert ein Geburtsdatum gemäß den Plattformrichtlinien.
|
||||
|
||||
Args:
|
||||
platform: Name der Plattform
|
||||
age: Optionales spezifisches Alter
|
||||
|
||||
Returns:
|
||||
(Geburtsdatum als datetime.date, Formatiertes Geburtsdatum als String)
|
||||
"""
|
||||
policy = self.get_platform_policy(platform)
|
||||
|
||||
# Aktuelles Datum
|
||||
today = datetime.date.today()
|
||||
|
||||
# Altersbereich bestimmen
|
||||
min_age = policy["min_age"]
|
||||
max_age = policy["max_age"]
|
||||
|
||||
# Wenn ein spezifisches Alter angegeben ist, dieses verwenden
|
||||
if age is not None:
|
||||
if age < min_age:
|
||||
logger.warning(f"Angegebenes Alter ({age}) ist kleiner als das Mindestalter "
|
||||
f"({min_age}). Verwende Mindestalter.")
|
||||
age = min_age
|
||||
elif age > max_age:
|
||||
logger.warning(f"Angegebenes Alter ({age}) ist größer als das Höchstalter "
|
||||
f"({max_age}). Verwende Höchstalter.")
|
||||
age = max_age
|
||||
else:
|
||||
# Zufälliges Alter im erlaubten Bereich
|
||||
age = random.randint(min_age, max_age)
|
||||
|
||||
# Berechne das Geburtsjahr
|
||||
birth_year = today.year - age
|
||||
|
||||
# Berücksichtige, ob der Geburtstag in diesem Jahr bereits stattgefunden hat
|
||||
has_had_birthday_this_year = random.choice([True, False])
|
||||
|
||||
if not has_had_birthday_this_year:
|
||||
birth_year -= 1
|
||||
|
||||
# Generiere Monat und Tag
|
||||
if has_had_birthday_this_year:
|
||||
# Geburtstag war bereits in diesem Jahr
|
||||
birth_month = random.randint(1, today.month)
|
||||
|
||||
if birth_month == today.month:
|
||||
# Wenn gleicher Monat, Tag muss vor oder gleich dem heutigen sein
|
||||
birth_day = random.randint(1, today.day)
|
||||
else:
|
||||
# Wenn anderer Monat, beliebiger Tag
|
||||
birth_day = random.randint(1, self._days_in_month(birth_month, birth_year))
|
||||
else:
|
||||
# Geburtstag ist noch in diesem Jahr
|
||||
birth_month = random.randint(today.month, 12)
|
||||
|
||||
if birth_month == today.month:
|
||||
# Wenn gleicher Monat, Tag muss nach dem heutigen sein
|
||||
birth_day = random.randint(today.day + 1, self._days_in_month(birth_month, birth_year))
|
||||
else:
|
||||
# Wenn anderer Monat, beliebiger Tag
|
||||
birth_day = random.randint(1, self._days_in_month(birth_month, birth_year))
|
||||
|
||||
# Erstelle und formatiere das Geburtsdatum
|
||||
birth_date = datetime.date(birth_year, birth_month, birth_day)
|
||||
formatted_date = birth_date.strftime(policy["date_format"])
|
||||
|
||||
logger.info(f"Geburtsdatum generiert: {formatted_date} (Alter: {age})")
|
||||
|
||||
return birth_date, formatted_date
|
||||
|
||||
def _days_in_month(self, month: int, year: int) -> int:
|
||||
"""
|
||||
Gibt die Anzahl der Tage in einem Monat zurück.
|
||||
|
||||
Args:
|
||||
month: Monat (1-12)
|
||||
year: Jahr
|
||||
|
||||
Returns:
|
||||
Anzahl der Tage im angegebenen Monat
|
||||
"""
|
||||
if month in [4, 6, 9, 11]:
|
||||
return 30
|
||||
elif month == 2:
|
||||
# Schaltjahr prüfen
|
||||
if year % 4 == 0 and (year % 100 != 0 or year % 400 == 0):
|
||||
return 29
|
||||
else:
|
||||
return 28
|
||||
else:
|
||||
return 31
|
||||
|
||||
def generate_birthday_components(self, platform: str = "default", age: Optional[int] = None) -> Dict[str, int]:
|
||||
"""
|
||||
Generiert die Komponenten eines Geburtsdatums (Tag, Monat, Jahr).
|
||||
|
||||
Args:
|
||||
platform: Name der Plattform
|
||||
age: Optionales spezifisches Alter
|
||||
|
||||
Returns:
|
||||
Dictionary mit den Komponenten des Geburtsdatums (year, month, day)
|
||||
"""
|
||||
birth_date, _ = self.generate_birthday(platform, age)
|
||||
|
||||
return {
|
||||
"year": birth_date.year,
|
||||
"month": birth_date.month,
|
||||
"day": birth_date.day
|
||||
}
|
||||
|
||||
def is_valid_age(self, birth_date: datetime.date, platform: str = "default") -> bool:
|
||||
"""
|
||||
Überprüft, ob ein Geburtsdatum für eine Plattform gültig ist.
|
||||
|
||||
Args:
|
||||
birth_date: Geburtsdatum
|
||||
platform: Name der Plattform
|
||||
|
||||
Returns:
|
||||
True, wenn das Alter gültig ist, sonst False
|
||||
"""
|
||||
policy = self.get_platform_policy(platform)
|
||||
|
||||
# Aktuelles Datum
|
||||
today = datetime.date.today()
|
||||
|
||||
# Alter berechnen
|
||||
age = today.year - birth_date.year
|
||||
|
||||
# Berücksichtigen, ob der Geburtstag in diesem Jahr bereits stattgefunden hat
|
||||
if today.month < birth_date.month or (today.month == birth_date.month and today.day < birth_date.day):
|
||||
age -= 1
|
||||
|
||||
return policy["min_age"] <= age <= policy["max_age"]
|
||||
|
||||
def generate_age_from_date(self, birth_date: datetime.date) -> int:
|
||||
"""
|
||||
Berechnet das Alter basierend auf einem Geburtsdatum.
|
||||
|
||||
Args:
|
||||
birth_date: Geburtsdatum
|
||||
|
||||
Returns:
|
||||
Berechnetes Alter
|
||||
"""
|
||||
# Aktuelles Datum
|
||||
today = datetime.date.today()
|
||||
|
||||
# Alter berechnen
|
||||
age = today.year - birth_date.year
|
||||
|
||||
# Berücksichtigen, ob der Geburtstag in diesem Jahr bereits stattgefunden hat
|
||||
if today.month < birth_date.month or (today.month == birth_date.month and today.day < birth_date.day):
|
||||
age -= 1
|
||||
|
||||
return age
|
||||
|
||||
def generate_date_from_components(self, year: int, month: int, day: int, platform: str = "default") -> str:
|
||||
"""
|
||||
Formatiert ein Datum aus seinen Komponenten gemäß dem Plattformformat.
|
||||
|
||||
Args:
|
||||
year: Jahr
|
||||
month: Monat
|
||||
day: Tag
|
||||
platform: Name der Plattform
|
||||
|
||||
Returns:
|
||||
Formatiertes Geburtsdatum als String
|
||||
"""
|
||||
policy = self.get_platform_policy(platform)
|
||||
|
||||
try:
|
||||
birth_date = datetime.date(year, month, day)
|
||||
formatted_date = birth_date.strftime(policy["date_format"])
|
||||
return formatted_date
|
||||
except ValueError as e:
|
||||
logger.error(f"Ungültiges Datum: {year}-{month}-{day}, Fehler: {e}")
|
||||
# Fallback: Gültiges Datum zurückgeben
|
||||
return self.generate_birthday(platform)[1]
|
||||
|
||||
def generate_random_date(self, start_year: int, end_year: int, platform: str = "default") -> str:
|
||||
"""
|
||||
Generiert ein zufälliges Datum innerhalb eines Jahresbereichs.
|
||||
|
||||
Args:
|
||||
start_year: Startjahr
|
||||
end_year: Endjahr
|
||||
platform: Name der Plattform
|
||||
|
||||
Returns:
|
||||
Formatiertes Datum als String
|
||||
"""
|
||||
policy = self.get_platform_policy(platform)
|
||||
|
||||
year = random.randint(start_year, end_year)
|
||||
month = random.randint(1, 12)
|
||||
day = random.randint(1, self._days_in_month(month, year))
|
||||
|
||||
date = datetime.date(year, month, day)
|
||||
|
||||
return date.strftime(policy["date_format"])
|
||||
|
||||
def generate_birthday(age: int = None, platform: str = "default") -> str:
|
||||
"""
|
||||
Kompatibilitätsfunktion für ältere Codeversionen.
|
||||
Generiert ein Geburtsdatum basierend auf einem Alter.
|
||||
|
||||
Args:
|
||||
age: Alter in Jahren (optional)
|
||||
platform: Name der Plattform
|
||||
|
||||
Returns:
|
||||
Generiertes Geburtsdatum im Format "TT.MM.JJJJ"
|
||||
"""
|
||||
# Logger-Warnung für Legacy-Funktion
|
||||
logger.warning("Die Funktion generate_birthday() ist für Kompatibilität, bitte verwende stattdessen die BirthdayGenerator-Klasse.")
|
||||
|
||||
# Eine Instanz der Generator-Klasse erstellen und die Methode aufrufen
|
||||
generator = BirthdayGenerator()
|
||||
|
||||
# Geburtsdatum generieren
|
||||
_, formatted_date = generator.generate_birthday(platform, age)
|
||||
|
||||
return formatted_date
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren