Add File
This commit is contained in:
57
backend/common/utils/locale.py
Normal file
57
backend/common/utils/locale.py
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
import json
|
||||||
|
from typing import Dict, Optional, Any
|
||||||
|
from fastapi import Request
|
||||||
|
|
||||||
|
class I18n:
|
||||||
|
def __init__(self, locale_dir: str = "locales"):
|
||||||
|
self.locale_dir = Path(locale_dir)
|
||||||
|
self.translations: Dict[str, Dict[str, Any]] = {}
|
||||||
|
self.load_translations()
|
||||||
|
|
||||||
|
def load_translations(self):
|
||||||
|
if not self.locale_dir.exists():
|
||||||
|
self.locale_dir.mkdir()
|
||||||
|
return
|
||||||
|
|
||||||
|
for lang_file in self.locale_dir.glob("*.json"):
|
||||||
|
with open(lang_file, 'r', encoding='utf-8') as f:
|
||||||
|
self.translations[lang_file.stem.lower()] = json.load(f)
|
||||||
|
|
||||||
|
def get_language(self, request: Request) -> str:
|
||||||
|
accept_language = request.headers.get('accept-language', 'en')
|
||||||
|
primary_lang = accept_language.split(',')[0].lower()
|
||||||
|
|
||||||
|
return primary_lang if primary_lang in self.translations else 'zh-cn'
|
||||||
|
|
||||||
|
def __call__(self, request: Request) -> 'I18nHelper':
|
||||||
|
return I18nHelper(self, request)
|
||||||
|
|
||||||
|
class I18nHelper:
|
||||||
|
def __init__(self, i18n: I18n, request: Request):
|
||||||
|
self.i18n = i18n
|
||||||
|
self.request = request
|
||||||
|
self.lang = i18n.get_language(request)
|
||||||
|
|
||||||
|
def _get_nested_translation(self, data: Dict[str, Any], key_path: str) -> str:
|
||||||
|
keys = key_path.split('.')
|
||||||
|
current = data
|
||||||
|
|
||||||
|
for key in keys:
|
||||||
|
if isinstance(current, dict) and key in current:
|
||||||
|
current = current[key]
|
||||||
|
else:
|
||||||
|
return key_path # 如果找不到,返回原键
|
||||||
|
|
||||||
|
return current if isinstance(current, str) else key_path
|
||||||
|
|
||||||
|
def __call__(self, arg_key: str, **kwargs) -> str:
|
||||||
|
lang_data = self.i18n.translations.get(self.lang, {})
|
||||||
|
text = self._get_nested_translation(lang_data, arg_key)
|
||||||
|
|
||||||
|
if kwargs:
|
||||||
|
try:
|
||||||
|
return text.format(**kwargs)
|
||||||
|
except (KeyError, ValueError):
|
||||||
|
return text
|
||||||
|
return text
|
||||||
Reference in New Issue
Block a user