import os import json import gettext from openpilot.common.params import Params from openpilot.common.basedir import BASEDIR SYSTEM_UI_DIR = os.path.join(BASEDIR, "system", "ui") UI_DIR = os.path.join(BASEDIR, "selfdrive", "ui") TRANSLATIONS_DIR = os.path.join(UI_DIR, "translations") LANGUAGES_FILE = os.path.join(TRANSLATIONS_DIR, "languages.json") SUPPORTED_LANGUAGES = [ "en", "de", "fr", "pt-BR", "es", "tr", ] class Multilang: def __init__(self): self._params = Params() self.languages = {} self.codes = {} self._translation: gettext.NullTranslations | gettext.GNUTranslations = gettext.NullTranslations() self._load_languages() @property def language(self) -> str: lang = str(self._params.get("LanguageSetting")).strip("main_") if lang not in SUPPORTED_LANGUAGES: lang = "en" return lang def setup(self): language = self.language try: with open(os.path.join(TRANSLATIONS_DIR, f'app_{language}.mo'), 'rb') as fh: translation = gettext.GNUTranslations(fh) translation.install() self._translation = translation print(f"Loaded translations for language: {language}") except FileNotFoundError: print(f"No translation file found for language: {language}, using default.") gettext.install('app') self._translation = gettext.NullTranslations() return None def change_language(self, language_code: str) -> None: # Reinstall gettext with the selected language self._params.put("LanguageSetting", language_code) self.setup() def tr(self, text: str) -> str: return self._translation.gettext(text) def trn(self, singular: str, plural: str, n: int) -> str: return self._translation.ngettext(singular, plural, n) def _load_languages(self): with open(LANGUAGES_FILE, encoding='utf-8') as f: self.languages = {k: v for k, v in json.load(f).items() if v in SUPPORTED_LANGUAGES} self.codes = {v: k for k, v in self.languages.items() if v in SUPPORTED_LANGUAGES} multilang = Multilang() multilang.setup() tr, trn = multilang.tr, multilang.trn # no-op marker for static strings translated later def tr_noop(s: str) -> str: return s