import builtins from collections import defaultdict import json5 from loguru import logger from . import utils log = logger.bind(module="i18n", prefix="init") log_load = logger.bind(module="i18n", prefix="load") class I18N: def __init__(self, locale_dir, load_lang, encoding): """ Load the language file and set the locale directory. Use JSON5 format for the language file. :param locale_dir: {BASE_DIR}/resources/{locale_dir} :param load_lang: some.lang """ self._locale_dir = utils.get_file(locale_dir) # {BASE_DIR}/resources/{locale_dir} self._lang = load_lang self._encoding = encoding self._locale = {} log.debug("Injecting to builtins") builtins.i18n = self builtins.i10n = self log.debug("Ready") self._load() def _load(self): if not self._locale_dir: raise FileNotFoundError(f"Locale directory not found: {self._locale_dir}") if (locale_file:=self._locale_dir / f"{self._lang}.json5").exists(): log_load.debug(f"Loading locale file: {locale_file}") with open(locale_file, "r", encoding=self._encoding) as f: data = json5.load(f) self._locale = utils.flatten_dict(data) log_load.debug("Loaded and flattened.") else: raise FileNotFoundError(f"Locale file not found: {locale_file}") def set_lang(self, lang, encoding=None): """ Set the language and encoding for the locale file. :param lang: Use the language file with the given language. :param encoding: Encoding of the language file. :return: None """ self._lang = lang self._encoding = encoding or self._encoding self._load() def get_phrase(self, key: str, **kwargs) -> str: """ Get the phrase from the locale file. If the phrase is not found, return the key in uppercase. :param key: Key to search in the locale file. :param kwargs: Arguments to format the phrase. :return: The phrase from the locale file. """ # key: some.key.here phrase = self._locale.get(key) if not phrase: return key.upper() return phrase.format_map(defaultdict(lambda: '???', kwargs)) def __call__(self, key: str, **kwargs): return self.get_phrase(key, **kwargs) def __getitem__(self, key: str): return self.get_phrase(key)