ciyidogan commited on
Commit
a413a10
·
verified ·
1 Parent(s): 70a05b4

Upload locale_manager.py

Browse files
Files changed (1) hide show
  1. config/locale_manager.py +163 -0
config/locale_manager.py ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # locale_manager.py
2
+ """
3
+ Locale Manager - Manages locale files for the system
4
+ """
5
+
6
+ import json
7
+ from pathlib import Path
8
+ from typing import Dict, List, Optional
9
+ from datetime import datetime
10
+ import sys
11
+ from logger import log_info, log_error, log_debug, log_warning
12
+
13
+ class LocaleManager:
14
+ """Manages locale files for TTS preprocessing and system-wide language support"""
15
+
16
+ _cache: Dict[str, Dict] = {}
17
+ _available_locales: Optional[List[Dict[str, str]]] = None
18
+
19
+ @classmethod
20
+ def get_locale(cls, language: str) -> Dict:
21
+ """Get locale data with caching"""
22
+ if language not in cls._cache:
23
+ cls._cache[language] = cls._load_locale(language)
24
+ return cls._cache[language]
25
+
26
+ @classmethod
27
+ def _load_locale(cls, language: str) -> Dict:
28
+ """Load locale from file - accepts both 'tr' and 'tr-TR' formats"""
29
+ base_path = Path(__file__).parent / "locales"
30
+
31
+ # First try exact match
32
+ locale_file = base_path / f"{language}.json"
33
+
34
+ # If not found and has region code, try without region (tr-TR -> tr)
35
+ if not locale_file.exists() and '-' in language:
36
+ language_code = language.split('-')[0]
37
+ locale_file = base_path / f"{language_code}.json"
38
+
39
+ if locale_file.exists():
40
+ try:
41
+ with open(locale_file, 'r', encoding='utf-8') as f:
42
+ data = json.load(f)
43
+ log_debug(f"✅ Loaded locale file: {locale_file.name}")
44
+ return data
45
+ except Exception as e:
46
+ log_error(f"Failed to load locale file {locale_file}", e)
47
+
48
+ # Try English fallback
49
+ fallback_file = base_path / "en.json"
50
+ if fallback_file.exists():
51
+ try:
52
+ with open(fallback_file, 'r', encoding='utf-8') as f:
53
+ data = json.load(f)
54
+ log_warning(f"⚠️ Using English fallback for locale: {language}")
55
+ return data
56
+ except:
57
+ pass
58
+
59
+ # Minimal fallback if no locale files exist
60
+ log_warning(f"⚠️ No locale files found, using minimal fallback")
61
+ return {
62
+ "code": "tr",
63
+ "locale_tag": "tr-TR",
64
+ "name": "Türkçe",
65
+ "english_name": "Turkish"
66
+ }
67
+
68
+ @classmethod
69
+ def list_available_locales(cls) -> List[str]:
70
+ """List all available locale files"""
71
+ base_path = Path(__file__).parent / "locales"
72
+ if not base_path.exists():
73
+ return ["en", "tr"] # Default locales
74
+ return [f.stem for f in base_path.glob("*.json")]
75
+
76
+ @classmethod
77
+ def get_available_locales_with_names(cls) -> List[Dict[str, str]]:
78
+ """Get list of all available locales with their display names"""
79
+ if cls._available_locales is not None:
80
+ return cls._available_locales
81
+
82
+ cls._available_locales = []
83
+ base_path = Path(__file__).parent / "locales"
84
+
85
+ if not base_path.exists():
86
+ # Return default locales if directory doesn't exist
87
+ cls._available_locales = [
88
+ {
89
+ "code": "tr-TR",
90
+ "name": "Türkçe",
91
+ "english_name": "Turkish"
92
+ },
93
+ {
94
+ "code": "en-US",
95
+ "name": "English",
96
+ "english_name": "English (US)"
97
+ }
98
+ ]
99
+ return cls._available_locales
100
+
101
+ # Load all locale files
102
+ for locale_file in base_path.glob("*.json"):
103
+ try:
104
+ locale_code = locale_file.stem
105
+ locale_data = cls.get_locale(locale_code)
106
+
107
+ cls._available_locales.append({
108
+ "code": locale_code,
109
+ "name": locale_data.get("name", locale_code),
110
+ "english_name": locale_data.get("english_name", locale_code)
111
+ })
112
+
113
+ log_info(f"✅ Loaded locale: {locale_code} - {locale_data.get('name', 'Unknown')}")
114
+
115
+ except Exception as e:
116
+ log_error(f"❌ Failed to load locale {locale_file}", e)
117
+
118
+ # Sort by name for consistent ordering
119
+ cls._available_locales.sort(key=lambda x: x['name'])
120
+
121
+ return cls._available_locales
122
+
123
+ @classmethod
124
+ def get_locale_details(cls, locale_code: str) -> Optional[Dict]:
125
+ """Get detailed info for a specific locale"""
126
+ try:
127
+ locale_data = cls.get_locale(locale_code)
128
+ # Ensure code is in the data
129
+ locale_data['code'] = locale_code
130
+ return locale_data
131
+ except:
132
+ return None
133
+
134
+ @classmethod
135
+ def is_locale_supported(cls, locale_code: str) -> bool:
136
+ """Check if a locale is supported system-wide"""
137
+ available_codes = [locale['code'] for locale in cls.get_available_locales_with_names()]
138
+ return locale_code in available_codes
139
+
140
+ @classmethod
141
+ def validate_project_languages(cls, languages: List[str]) -> List[str]:
142
+ """Validate that all languages are system-supported, return invalid ones"""
143
+ available_codes = [locale['code'] for locale in cls.get_available_locales_with_names()]
144
+ invalid_languages = [
145
+ lang for lang in languages
146
+ if lang not in available_codes
147
+ ]
148
+ return invalid_languages
149
+
150
+ @classmethod
151
+ def get_default_locale(cls) -> str:
152
+ """Get system default locale"""
153
+ available_locales = cls.get_available_locales_with_names()
154
+
155
+ # Priority: tr-TR, en-US, first available
156
+ for preferred in ["tr-TR", "en-US"]:
157
+ if any(locale['code'] == preferred for locale in available_locales):
158
+ return preferred
159
+
160
+ # Return first available or fallback
161
+ if available_locales:
162
+ return available_locales[0]['code']
163
+ return "en-US"