Dieser Commit ist enthalten in:
Claude Project Manager
2025-08-01 23:50:28 +02:00
Commit 04585e95b6
290 geänderte Dateien mit 64086 neuen und 0 gelöschten Zeilen

Datei anzeigen

@ -0,0 +1,160 @@
"""
Timezone Location Service - Manages timezone and location consistency.
"""
import random
from typing import Dict, Optional, Tuple, Any
class TimezoneLocationService:
"""Service for managing timezone and location relationships."""
TIMEZONE_MAPPING = {
"de": {
"timezones": ["Europe/Berlin", "Europe/Munich"],
"offset": -60, # UTC+1
"dst_offset": -120 # UTC+2 during DST
},
"us": {
"timezones": ["America/New_York", "America/Chicago", "America/Los_Angeles", "America/Denver"],
"offset": 300, # UTC-5 (New York)
"dst_offset": 240 # UTC-4 during DST
},
"uk": {
"timezones": ["Europe/London"],
"offset": 0, # UTC
"dst_offset": -60 # UTC+1 during DST
},
"jp": {
"timezones": ["Asia/Tokyo"],
"offset": -540, # UTC+9
"dst_offset": -540 # No DST
},
"au": {
"timezones": ["Australia/Sydney", "Australia/Melbourne"],
"offset": -600, # UTC+10
"dst_offset": -660 # UTC+11 during DST
}
}
CITY_TO_TIMEZONE = {
"Berlin": "Europe/Berlin",
"Munich": "Europe/Munich",
"Frankfurt": "Europe/Berlin",
"Hamburg": "Europe/Berlin",
"New York": "America/New_York",
"Los Angeles": "America/Los_Angeles",
"Chicago": "America/Chicago",
"London": "Europe/London",
"Tokyo": "Asia/Tokyo",
"Sydney": "Australia/Sydney"
}
LANGUAGE_TO_LOCATION = {
"de-DE": ["de", "at", "ch"],
"en-US": ["us"],
"en-GB": ["uk"],
"ja-JP": ["jp"],
"en-AU": ["au"],
"fr-FR": ["fr"],
"es-ES": ["es"],
"it-IT": ["it"]
}
def get_timezone_for_location(self, location: Optional[str] = None) -> Tuple[str, int]:
"""Get timezone and offset for a location."""
if not location:
location = random.choice(list(self.TIMEZONE_MAPPING.keys()))
location_lower = location.lower()
# Check if it's a city
for city, tz in self.CITY_TO_TIMEZONE.items():
if city.lower() in location_lower:
# Find the offset from the mapping
for country, data in self.TIMEZONE_MAPPING.items():
if tz in data["timezones"]:
return tz, data["offset"]
return tz, 0
# Check if it's a country code
if location_lower in self.TIMEZONE_MAPPING:
data = self.TIMEZONE_MAPPING[location_lower]
timezone = random.choice(data["timezones"])
return timezone, data["offset"]
# Default to Berlin
return "Europe/Berlin", -60
def get_location_for_language(self, language: str) -> str:
"""Get a suitable location for a language."""
if language in self.LANGUAGE_TO_LOCATION:
locations = self.LANGUAGE_TO_LOCATION[language]
return random.choice(locations)
# Extract base language
base_lang = language.split('-')[0]
for lang, locations in self.LANGUAGE_TO_LOCATION.items():
if lang.startswith(base_lang):
return random.choice(locations)
# Default
return "us"
def validate_timezone_consistency(self, timezone: str, language: str) -> bool:
"""Validate if timezone is consistent with language."""
expected_location = self.get_location_for_language(language)
# Get timezones for the expected location
if expected_location in self.TIMEZONE_MAPPING:
expected_timezones = self.TIMEZONE_MAPPING[expected_location]["timezones"]
return timezone in expected_timezones
# If we can't determine, assume it's valid
return True
def get_locale_for_timezone(self, timezone: str) -> str:
"""Get appropriate locale for a timezone."""
tz_to_locale = {
"Europe/Berlin": "de-DE",
"Europe/Munich": "de-DE",
"America/New_York": "en-US",
"America/Los_Angeles": "en-US",
"America/Chicago": "en-US",
"Europe/London": "en-GB",
"Asia/Tokyo": "ja-JP",
"Australia/Sydney": "en-AU"
}
return tz_to_locale.get(timezone, "en-US")
def calculate_timezone_offset(self, timezone: str, is_dst: bool = False) -> int:
"""Calculate timezone offset in minutes from UTC."""
# Find the timezone in our mapping
for country, data in self.TIMEZONE_MAPPING.items():
if timezone in data["timezones"]:
return data["dst_offset"] if is_dst else data["offset"]
# Default to UTC
return 0
def get_consistent_location_data(self, proxy_location: Optional[str] = None) -> Dict[str, Any]:
"""Get consistent location data including timezone, locale, and language."""
timezone, offset = self.get_timezone_for_location(proxy_location)
locale = self.get_locale_for_timezone(timezone)
# Extract language from locale
language = locale.split('-')[0]
languages = [locale, language]
# Add fallback languages
if language != "en":
languages.extend(["en-US", "en"])
return {
"timezone": timezone,
"timezone_offset": offset,
"locale": locale,
"language": language,
"languages": languages
}