sysmon_pytk.app_locale
Locale management.
1# SPDX-FileCopyrightText: © 2024 Stacey Adams <stacey.belle.rose@gmail.com> 2# SPDX-License-Identifier: MIT 3 4""" 5Locale management. 6""" 7 8from __future__ import annotations 9 10import gettext 11import importlib 12import inspect 13from configparser import ConfigParser, Error 14from pathlib import Path 15from typing import TYPE_CHECKING 16 17from .file_utils import settings_path 18 19if TYPE_CHECKING: 20 from .callables import GettextCallable 21 22LANGUAGES = { 23 "English": "en", 24 "Español": "es", 25 "Deutsch": "de", 26 "Norsk Bokmål": "nb_NO" 27} 28"""The list of language translations available.""" 29 30__i18n_domain__ = "app" 31 32TRANSLATED_MODULES: list = [] 33""" 34List of modules which have requested translated strings. 35 36When the translation is changed, these modules will be reloaded. 37""" 38 39 40def get_translator( 41 *, forced_lang: str | None = None, domain: str = __i18n_domain__ 42) -> GettextCallable: 43 """ 44 Load the selected translation. 45 46 Parameters 47 ---------- 48 forced_lang : str, optional 49 The language to force-load. If not set, read the language from Settings 50 and load that one. 51 domain : str, optional 52 The gettext domain to use. Default is set by `__i18n_domain__`. Useful 53 for loading translation files for other modules, such as `argparse.py`. 54 55 Returns 56 ------- 57 GettextCallable 58 a Callable with the signature: func(message: str) -> str: 59 """ 60 current_lang = forced_lang if forced_lang else _get_lang_from_config() 61 frm = inspect.stack()[1] # get caller 62 mod = inspect.getmodule(frm.frame) 63 if mod not in TRANSLATED_MODULES: 64 TRANSLATED_MODULES.append(mod) 65 TRANSLATED_MODULES.sort(key=lambda x: x.__name__) 66 _localedir = Path.resolve(Path(__file__).parent) / "locale" 67 translation = gettext.translation( 68 domain, _localedir, fallback=True, languages=[current_lang] 69 ) 70 return translation.gettext 71 72 73def reload_translated_modules() -> None: 74 """ 75 Reload any modules that have requested translations. 76 77 This should be called when the user selects a new translation. 78 """ 79 for mod in TRANSLATED_MODULES: 80 importlib.reload(mod) 81 82 83def _get_lang_from_config() -> str: 84 current_lang = "en" 85 try: 86 _filename = settings_path() 87 _config = ConfigParser() 88 _config.read(_filename) 89 if "general" in _config.sections(): 90 current_lang = _config["general"].get("language", fallback="en") 91 except Error: 92 pass 93 return current_lang
LANGUAGES =
{'English': 'en', 'Español': 'es', 'Deutsch': 'de', 'Norsk Bokmål': 'nb_NO'}
The list of language translations available.
TRANSLATED_MODULES: list = []
List of modules which have requested translated strings.
When the translation is changed, these modules will be reloaded.
def
get_translator( *, forced_lang: str | None = None, domain: str = 'app') -> 'GettextCallable':
41def get_translator( 42 *, forced_lang: str | None = None, domain: str = __i18n_domain__ 43) -> GettextCallable: 44 """ 45 Load the selected translation. 46 47 Parameters 48 ---------- 49 forced_lang : str, optional 50 The language to force-load. If not set, read the language from Settings 51 and load that one. 52 domain : str, optional 53 The gettext domain to use. Default is set by `__i18n_domain__`. Useful 54 for loading translation files for other modules, such as `argparse.py`. 55 56 Returns 57 ------- 58 GettextCallable 59 a Callable with the signature: func(message: str) -> str: 60 """ 61 current_lang = forced_lang if forced_lang else _get_lang_from_config() 62 frm = inspect.stack()[1] # get caller 63 mod = inspect.getmodule(frm.frame) 64 if mod not in TRANSLATED_MODULES: 65 TRANSLATED_MODULES.append(mod) 66 TRANSLATED_MODULES.sort(key=lambda x: x.__name__) 67 _localedir = Path.resolve(Path(__file__).parent) / "locale" 68 translation = gettext.translation( 69 domain, _localedir, fallback=True, languages=[current_lang] 70 ) 71 return translation.gettext
Load the selected translation.
Parameters
- forced_lang (str, optional): The language to force-load. If not set, read the language from Settings and load that one.
- domain (str, optional):
The gettext domain to use. Default is set by
__i18n_domain__. Useful for loading translation files for other modules, such asargparse.py.
Returns
- GettextCallable: a Callable with the signature: func(message: str) -> str:
def
reload_translated_modules() -> None:
74def reload_translated_modules() -> None: 75 """ 76 Reload any modules that have requested translations. 77 78 This should be called when the user selects a new translation. 79 """ 80 for mod in TRANSLATED_MODULES: 81 importlib.reload(mod)
Reload any modules that have requested translations.
This should be called when the user selects a new translation.