63 lines
2.0 KiB
Python
63 lines
2.0 KiB
Python
import logging
|
|
from typing import Optional
|
|
|
|
from yaml import safe_load
|
|
|
|
|
|
class I18N:
|
|
def __init__(self, logger: logging.Logger,
|
|
path: str = "i18n.yaml",
|
|
lang: Optional[str] = None,
|
|
fallback_lang: str = "en"):
|
|
self.logger = logger
|
|
self._path = path
|
|
self._fallback_lang = fallback_lang
|
|
self._lang = lang or self.fallback_lang
|
|
self._dict = dict()
|
|
self.load()
|
|
|
|
@property
|
|
def path(self):
|
|
return self._path
|
|
|
|
@property
|
|
def fallback_lang(self):
|
|
return self._fallback_lang
|
|
|
|
def set_lang(self, lang: Optional[str] = None):
|
|
if lang in self._dict:
|
|
self._lang = lang
|
|
else:
|
|
self._lang = self.fallback_lang
|
|
|
|
@property
|
|
def lang(self):
|
|
return self._lang
|
|
|
|
def load(self):
|
|
self._dict.clear()
|
|
with open(self._path) as f:
|
|
self._dict = safe_load(f)
|
|
if self.fallback_lang not in self._dict:
|
|
raise RuntimeError("I18N file doesn't contain fallback language section")
|
|
|
|
def get(self, phrase: str, lang: Optional[str] = None):
|
|
lang = lang or self.lang
|
|
if lang not in self._dict:
|
|
self.logger.warning(f"Language '{lang}' not found in i18n, using fallback")
|
|
lang = self.fallback_lang
|
|
lang_dict = self._dict.get(lang)
|
|
result = lang_dict.get(phrase)
|
|
if result is None:
|
|
self.logger.error(f"Phrase '{phrase}' not found in language '{lang}'")
|
|
result = f"<Phrase '{phrase}' not found in language '{lang}'>"
|
|
return result
|
|
|
|
def __call__(self, phrase: str, lang: Optional[str] = None, *args, **kwargs):
|
|
return self.get(phrase, lang).format(*args, **kwargs)
|
|
|
|
def customized_call(self, preset_lang: Optional[str] = None, **preset_kwargs):
|
|
def wrapper(phrase: str, lang: Optional[str] = None, *args, **kwargs):
|
|
return self(phrase, lang or preset_lang, *args, **preset_kwargs, **kwargs)
|
|
return wrapper
|