Philipp Hörist pushed to branch master at gajim / gajim
Commits: ae5ac2d3 by Philipp Hörist at 2023-05-29T11:43:30+02:00 refactor: Rename main application entry points
- - - - - 32601f1c by Philipp Hörist at 2023-05-29T11:43:30+02:00 fix: Init plugin translation module later
the plugins_i18n module needs to be imported after configpaths.init() has been called, otherwise the correct locale dir is not found
- - - - - c45fbdd8 by Philipp Hörist at 2023-05-29T11:43:30+02:00 refactor: Allow to import i18n module without side effects
- Add new method for translation - Remove stderr if translations are missing
- - - - -
9 changed files:
- gajim/common/app.py - gajim/common/application.py - gajim/common/i18n.py - gajim/gtk/message_input.py - gajim/gajim.py → gajim/main.py - gajim/gajim_remote.py → gajim/remote.py - launch.py - pyproject.toml - win/misc/create-launcher.py
Changes:
===================================== gajim/common/app.py ===================================== @@ -49,7 +49,7 @@ from gajim.common import ged as ged_module from gajim.common import types from gajim.common.const import Display -from gajim.common.i18n import LANG +from gajim.common.i18n import get_default_lang
if typing.TYPE_CHECKING: from gajim.common.call_manager import CallManager @@ -294,7 +294,7 @@ def detect_dependencies() -> None: for dep, val in _dependencies.items(): log('gajim').info('%-13s %s', dep, val)
- log('gajim').info('Used language: %s', LANG) + log('gajim').info('Used language: %s', get_default_lang())
def detect_desktop_env() -> str | None:
===================================== gajim/common/application.py ===================================== @@ -58,8 +58,6 @@ from gajim.common.storage.events import EventStorage from gajim.common.task_manager import TaskManager from gajim.common.util.http import create_http_request -from gajim.plugins.pluginmanager import PluginManager -from gajim.plugins.repository import PluginRepository
class CoreApplication(ged.EventHelper): @@ -120,6 +118,9 @@ def _init_core(self) -> None: app.nicks[account] = app.settings.get_account_setting(account, 'name')
+ from gajim.plugins.pluginmanager import PluginManager + from gajim.plugins.repository import PluginRepository + app.plugin_manager = PluginManager() app.plugin_manager.init_plugins() app.plugin_repository = PluginRepository()
===================================== gajim/common/i18n.py ===================================== @@ -33,39 +33,23 @@ DOMAIN = 'gajim'
-def get_win32_default_lang() -> str: - import ctypes - windll = ctypes.windll.kernel32 - return locale.windows_locale[windll.GetUserDefaultUILanguage()] - - -def get_darwin_default_lang() -> str: - from AppKit import NSLocale - - # FIXME: This returns a two letter language code (en, de, fr) - # We need a way to get en_US, de_DE etc. - return NSLocale.currentLocale().languageCode() +def init() -> None: + _trans.init()
def get_default_lang() -> str: - if sys.platform == 'win32': - return get_win32_default_lang() - - if sys.platform == 'darwin': - return get_darwin_default_lang() - - return locale.getdefaultlocale()[0] or 'en' + return _trans.get_default_lang()
def get_rfc5646_lang(lang: str | None = None) -> str: if lang is None: - lang = LANG + lang = _trans.get_default_lang() return lang.replace('_', '-')
def get_short_lang_code(lang: str | None = None) -> str: if lang is None: - lang = LANG + lang = _trans.get_default_lang() return lang[:2]
@@ -84,10 +68,6 @@ def is_rtl_text(text: str) -> bool: return False
-def p_(context: str, message: str) -> str: - return _translation.pgettext(context, message) - - def ngettext(s_sing: str, s_plural: str, n: int, @@ -100,7 +80,7 @@ def ngettext(s_sing: str,
In other words this is a hack to ngettext() to support %s %d etc.. ''' - text = _translation.ngettext(s_sing, s_plural, n) + text = _trans.translation.ngettext(s_sing, s_plural, n) if n == 1 and replace_sing is not None: return text % replace_sing
@@ -109,29 +89,69 @@ def ngettext(s_sing: str, return text
-try: - locale.setlocale(locale.LC_ALL, '') -except locale.Error as error: - print(error, file=sys.stderr) - -LANG = get_default_lang() -if sys.platform == 'win32': - # Set the env var on Windows because gettext.find() uses it to - # find the translation - # Use LANGUAGE instead of LANG, LANG sets LC_ALL and thus - # doesn't retain other region settings like LC_TIME - os.environ['LANGUAGE'] = LANG - - -package_dir = cast(Path, importlib.resources.files('gajim')) -locale_dir = package_dir / 'data' / 'locale' - -try: - _translation = gettext.translation(DOMAIN, locale_dir) - _ = _translation.gettext - if hasattr(locale, 'bindtextdomain'): - locale.bindtextdomain(DOMAIN, locale_dir) -except OSError: - _translation = gettext.NullTranslations() - _ = _translation.gettext - print('No translations found for', LANG, file=sys.stderr) +class Translation: + def __init__(self) -> None: + self.translation = gettext.NullTranslations() + self._default_lang = None + + def get_default_lang(self) -> str: + assert self._default_lang is not None + return self._default_lang + + @staticmethod + def _get_win32_default_lang() -> str: + import ctypes + windll = ctypes.windll.kernel32 + return locale.windows_locale[windll.GetUserDefaultUILanguage()] + + @staticmethod + def _get_darwin_default_lang() -> str: + from AppKit import NSLocale + + # FIXME: This returns a two letter language code (en, de, fr) + # We need a way to get en_US, de_DE etc. + return NSLocale.currentLocale().languageCode() + + def _get_default_lang(self) -> str: + if sys.platform == 'win32': + return self._get_win32_default_lang() + + if sys.platform == 'darwin': + return self._get_darwin_default_lang() + + return locale.getdefaultlocale()[0] or 'en' + + def init(self) -> None: + try: + locale.setlocale(locale.LC_ALL, '') + except locale.Error as error: + print(error, file=sys.stderr) + + self._default_lang = self._get_default_lang() + if sys.platform == 'win32': + # Set the env var on Windows because gettext.find() uses it to + # find the translation + # Use LANGUAGE instead of LANG, LANG sets LC_ALL and thus + # doesn't retain other region settings like LC_TIME + os.environ['LANGUAGE'] = self._default_lang + + package_dir = cast(Path, importlib.resources.files('gajim')) + locale_dir = package_dir / 'data' / 'locale' + + try: + self.translation = gettext.translation(DOMAIN, locale_dir) + if hasattr(locale, 'bindtextdomain'): + locale.bindtextdomain(DOMAIN, locale_dir) + except OSError: + pass + + self.install() + + def install(self) -> None: + global _, g_, p_ + _ = self.translation.gettext + g_ = self.translation.gettext + p_ = self.translation.pgettext + + +_trans = Translation()
===================================== gajim/gtk/message_input.py ===================================== @@ -34,7 +34,7 @@ from gajim.common.events import MessageSent from gajim.common.ged import EventHelper from gajim.common.i18n import _ -from gajim.common.i18n import LANG +from gajim.common.i18n import get_default_lang from gajim.common.styling import PlainBlock from gajim.common.styling import process from gajim.common.types import ChatContactT @@ -219,7 +219,7 @@ def _get_spell_checker_language(self, # use the default one lang = app.settings.get('speller_language') if not lang: - lang = LANG + lang = get_default_lang()
assert isinstance(lang, str) lang = Gspell.language_lookup(lang)
===================================== gajim/gajim.py → gajim/main.py ===================================== @@ -95,6 +95,11 @@ def _check_required_deps() -> None: check_version('sqlite', sqlite3.sqlite_version, _MIN_SQLITE_VER)
+def _init_translations() -> None: + import gajim.common.i18n + gajim.common.i18n.init() + + def _init_gui(gui: str) -> None: if gui == 'GTK': _init_gtk() @@ -154,7 +159,7 @@ def _set_proc_title() -> None: libc.setproctitle('gajim')
-def main() -> None: +def run() -> None: if sys.platform != 'win32': if os.geteuid() == 0: sys.exit('You must not launch gajim as root, it is insecure.') @@ -162,5 +167,6 @@ def main() -> None: _check_required_deps() _set_proc_title() _set_env_vars() + _init_translations() _init_gui('GTK') _run_app()
===================================== gajim/gajim_remote.py → gajim/remote.py ===================================== @@ -133,7 +133,7 @@ def create_arg_parser() -> argparse.ArgumentParser: return parser
-def main() -> None: +def run() -> None: args = create_arg_parser().parse_args() try: result = call_method(args)
===================================== launch.py ===================================== @@ -3,7 +3,7 @@ import subprocess
import gajim -from gajim.gajim import main +import gajim.main
try: res = subprocess.check_output( @@ -12,4 +12,4 @@ except Exception: pass
-main() +gajim.main.run()
===================================== pyproject.toml ===================================== @@ -55,10 +55,10 @@ dev = [ ]
[project.scripts] -gajim-remote = "gajim.gajim_remote:main" +gajim-remote = "gajim.remote:run"
[project.gui-scripts] -gajim = "gajim.gajim:main" +gajim = "gajim.main:run"
[tool.setuptools.packages.find] include = ["gajim*"] @@ -146,8 +146,8 @@ include = [ "gajim/common/styling.py", "gajim/common/task_manager.py", "gajim/common/util/*", - "gajim/gajim.py", - "gajim/gajim_remote.py", + "gajim/main.py", + "gajim/remote.py", "gajim/gtk/*", "gajim/plugins/*", "test/*",
===================================== win/misc/create-launcher.py ===================================== @@ -98,8 +98,8 @@ def get_launcher_code(*, debug: bool) -> str: "root_path = Path(sys.executable).parents[1];" "from ctypes import windll;" "windll.kernel32.SetDllDirectoryW(str(root_path / 'bin'));" - "from gajim import gajim;" - "gajim.main();"); + "import gajim.main;" + "gajim.main.run();"); Py_Finalize(); return result; }
View it on GitLab: https://dev.gajim.org/gajim/gajim/-/compare/bbc6c55d85362de5cbc2aab65680e952...