lib.i18n
Internacionalización: función _() para CLI y GUI.
Prioridad de idioma: config (~/.config/temario/temario.yaml) → TEMARIO_LANG (variable de entorno) → LANG del sistema → fallback (español, idioma fuente)
Uso:
from lib.i18n import _ # en cualquier módulo import lib.i18n as i18n; i18n.setup() # una vez al inicio de la app (main.py / __main__) print(_("hola"))
1""" 2Internacionalización: función _() para CLI y GUI. 3 4Prioridad de idioma: config (~/.config/temario/temario.yaml) 5 → TEMARIO_LANG (variable de entorno) 6 → LANG del sistema 7 → fallback (español, idioma fuente) 8 9Uso: 10 from lib.i18n import _ # en cualquier módulo 11 import lib.i18n as i18n; i18n.setup() # una vez al inicio de la app (main.py / __main__) 12 print(_("hola")) 13""" 14 15import builtins 16import gettext 17import os 18from pathlib import Path 19 20_LOCALES_DIR = Path(__file__).parent.parent / 'locales' 21_DOMAIN = 'escriba' 22 23_gettext_func = lambda s: s # identidad hasta que setup() se llame 24 25 26def _(s: str) -> str: # noqa: E743 (nombre corto intencionado) 27 """Traduce s al idioma activo. No-op hasta que setup() sea llamado.""" 28 return _gettext_func(s) 29 30 31def _detect_lang() -> str | None: 32 """Detecta el idioma a usar: config → ESCRIBA_LANG → LANG del sistema.""" 33 try: 34 from lib.slides_config import get_language 35 lang = get_language() 36 if lang: 37 return lang 38 except Exception: 39 pass 40 if env := os.environ.get('ESCRIBA_LANG', '').strip(): 41 return env 42 system = os.environ.get('LANG', '').split('_')[0].split('.')[0].lower() 43 return system or None 44 45 46def setup(lang: str | None = None) -> None: 47 """Activa la traducción. Llamar una vez al inicio de la app.""" 48 global _gettext_func 49 if lang is None: 50 lang = _detect_lang() 51 t = gettext.translation( 52 _DOMAIN, 53 localedir=str(_LOCALES_DIR), 54 languages=[lang] if lang else None, 55 fallback=True, 56 ) 57 _gettext_func = t.gettext 58 builtins._ = _ # disponible globalmente para módulos que no importen i18n 59 60 61# Instalar identidad en builtins como fallback (antes de setup()) 62if not hasattr(builtins, '_'): 63 builtins._ = _
def
setup(lang: str | None = None) -> None:
47def setup(lang: str | None = None) -> None: 48 """Activa la traducción. Llamar una vez al inicio de la app.""" 49 global _gettext_func 50 if lang is None: 51 lang = _detect_lang() 52 t = gettext.translation( 53 _DOMAIN, 54 localedir=str(_LOCALES_DIR), 55 languages=[lang] if lang else None, 56 fallback=True, 57 ) 58 _gettext_func = t.gettext 59 builtins._ = _ # disponible globalmente para módulos que no importen i18n
Activa la traducción. Llamar una vez al inicio de la app.