From e2383fd7a4cfd8d1dc38ca51fb74f97e7a657ccf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20H=C3=B6rist?= Date: Tue, 24 Apr 2018 22:54:18 +0200 Subject: [PATCH] Refactor i18n module - Move everything translation related from gajim.py to i18n.py --- gajim/common/app.py | 10 --- gajim/common/i18n.py | 166 +++++++++++++++++++++++++++++----------- gajim/gajim.py | 41 +--------- gajim/gtkgui_helpers.py | 2 +- 4 files changed, 125 insertions(+), 94 deletions(-) diff --git a/gajim/common/app.py b/gajim/common/app.py index d9d63e153..69938fb65 100644 --- a/gajim/common/app.py +++ b/gajim/common/app.py @@ -80,16 +80,6 @@ MY_CERT_DIR = configpaths.get('MY_CERT') RecentGroupchat = namedtuple('RecentGroupchat', ['room', 'server', 'nickname']) -try: - LANG = locale.getdefaultlocale()[0] # en_US, fr_FR, el_GR etc.. -except (ValueError, locale.Error): - # unknown locale, use en is better than fail - LANG = None -if LANG is None: - LANG = 'en' -else: - LANG = LANG[:2] # en, fr, el etc.. - os_info = None # used to cache os information transport_type = {} # list the type of transport diff --git a/gajim/common/i18n.py b/gajim/common/i18n.py index 038cec1cd..b1af9b22c 100644 --- a/gajim/common/i18n.py +++ b/gajim/common/i18n.py @@ -5,6 +5,7 @@ ## Copyright (C) 2004 Vincent Hanquez ## Copyright (C) 2005-2006 Nikos Kouremenos ## Copyright (C) 2009 Benjamin Richter
+## Copyright (C) 2018 Philipp Hörist ## ## This file is part of Gajim. ## @@ -26,8 +27,120 @@ import gettext import os import unicodedata -# May be changed after GTK is imported +DOMAIN = 'gajim' +LANG = 'en' direction_mark = '\u200E' +_translations = None + + +def initialize(): + global _translations + + locale.setlocale(locale.LC_ALL, '') + # initialize_win_translation() broken + initialize_lang() + set_i18n_env() + + localedir = get_locale_dir() + if hasattr(locale, 'bindtextdomain'): + locale.bindtextdomain(DOMAIN, localedir) + + gettext.install(DOMAIN, localedir) + if gettext._translations: + _translations = list(gettext._translations.values())[0] + else: + _translations = gettext.NullTranslations() + + +def set_i18n_env(): + if os.name == 'nt': + lang = os.getenv('LANG') + if lang is None: + default_lang = locale.getdefaultlocale()[0] + if default_lang: + lang = default_lang + + if lang: + os.environ['LANG'] = lang + + +def initialize_lang(): + global LANG + try: + # en_US, fr_FR, el_GR etc.. + LANG = locale.getdefaultlocale()[0] + LANG = LANG[:2] + except (ValueError, locale.Error): + pass + + +def get_locale_dir(): + if os.name == 'nt': + return "../po" + + # try to find domain in localedir + path = gettext.find(DOMAIN) + if path: + # extract localedir from localedir/language/LC_MESSAGES/domain.mo + path, tail = os.path.split(path) + path, tail = os.path.split(path) + localedir, tail = os.path.split(path) + else: + # fallback to user locale + base = os.getenv('XDG_DATA_HOME') + if base is None or base[0] != '/': + base = os.path.expanduser('~/.local/share') + localedir = os.path.join(base, "locale") + return localedir + + +def initialize_win_translation(): + # broken for now + return + + if os.name != 'nt': + return + + # needed for docutils + # sys.path.append('.') + APP = 'gajim' + DIR = '../po' + lang = locale.getdefaultlocale()[0] + os.environ['LANG'] = lang + gettext.bindtextdomain(APP, DIR) + gettext.textdomain(APP) + gettext.install(APP, DIR) + + # This is for Windows translation which is currently not + # working on GTK 3.18.9 + # locale.setlocale(locale.LC_ALL, '') + # import ctypes + # import ctypes.util + # libintl_path = ctypes.util.find_library('intl') + # if libintl_path == None: + # local_intl = os.path.join('gtk', 'bin', 'intl.dll') + # if os.path.exists(local_intl): + # libintl_path = local_intl + # if libintl_path == None: + # raise ImportError('intl.dll library not found') + # libintl = ctypes.cdll.LoadLibrary(libintl_path) + # libintl.bindtextdomain(APP, DIR) + # libintl.bind_textdomain_codeset(APP, 'UTF-8') + # plugins_locale_dir = os.path.join(common.configpaths[ + # 'PLUGINS_USER'], 'locale').encode(locale.getpreferredencoding()) + # libintl.bindtextdomain('gajim_plugins', plugins_locale_dir) + # libintl.bind_textdomain_codeset('gajim_plugins', 'UTF-8') + + +def initialize_direction_mark(): + import gi + from gi.repository import Gtk + + global direction_mark + + if Gtk.Widget.get_default_direction() == Gtk.TextDirection.RTL: + direction_mark = '\u200F' + def paragraph_direction_mark(text): """ @@ -45,47 +158,6 @@ def paragraph_direction_mark(text): return '\u200E' -APP = 'gajim' - -# set '' so each part of the locale that should be modified is set -# according to the environment variables -locale.setlocale(locale.LC_ALL, '') - -## For windows: set, if needed, a value in LANG environmental variable ## -if os.name == 'nt': - lang = os.getenv('LANG') - if lang is None: - default_lang = locale.getdefaultlocale()[0] # en_US, fr_FR, el_GR etc.. - if default_lang: - lang = default_lang - - if lang: - os.environ['LANG'] = lang - - localedir = "../po" -else: - # try to find domain in localedir - path = gettext.find(APP) - if path: - # extract localedir from localedir/language/LC_MESSAGES/domain.mo - path, tail = os.path.split(path) - path, tail = os.path.split(path) - localedir, tail = os.path.split(path) - else: # fallback to user locale - base = os.getenv('XDG_DATA_HOME') - if base is None or base[0] != '/': - base = os.path.expanduser('~/.local/share') - localedir = os.path.join(base, "locale") - - if hasattr(locale, 'bindtextdomain'): - locale.bindtextdomain(APP, localedir) - -gettext.install(APP, localedir) - -if gettext._translations: - _translation = list(gettext._translations.values())[0] -else: - _translation = gettext.NullTranslations() def Q_(text): """ @@ -107,16 +179,20 @@ def Q_(text): qualifier, text = text.split(':', 1) return text -def ngettext(s_sing, s_plural, n, replace_sing = None, replace_plural = None): + +def ngettext(s_sing, s_plural, n, replace_sing=None, replace_plural=None): """ Use as: - i18n.ngettext('leave room %s', 'leave rooms %s', len(rooms), 'a', 'a, b, c') + i18n.ngettext('leave room %s', 'leave rooms %s', len(rooms), 'a', 'a, b, c') In other words this is a hack to ngettext() to support %s %d etc.. """ - text = _translation.ngettext(s_sing, s_plural, n) + text = _translations.ngettext(s_sing, s_plural, n) if n == 1 and replace_sing is not None: text = text % replace_sing elif n > 1 and replace_plural is not None: text = text % replace_plural return text + + +initialize() diff --git a/gajim/gajim.py b/gajim/gajim.py index 08a1b8954..dd88acb04 100644 --- a/gajim/gajim.py +++ b/gajim/gajim.py @@ -40,7 +40,6 @@ import sys import os import signal -import locale from urllib.parse import unquote import gi @@ -156,6 +155,7 @@ class GajimApplication(Gtk.Application): # Create and initialize Application Paths & Databases from gajim.common import app + i18n.initialize_direction_mark() app.detect_dependencies() configpaths.create_paths() from gajim.common import exceptions @@ -176,41 +176,6 @@ class GajimApplication(Gtk.Application): dlg.destroy() sys.exit() - if os.name == 'nt': - import gettext - # needed for docutils - sys.path.append('.') - APP = 'gajim' - DIR = '../po' - lang = locale.getdefaultlocale()[0] - os.environ['LANG'] = lang - gettext.bindtextdomain(APP, DIR) - gettext.textdomain(APP) - gettext.install(APP, DIR) - - # This is for Windows translation which is currently not - # working on GTK 3.18.9 - # locale.setlocale(locale.LC_ALL, '') - # import ctypes - # import ctypes.util - # libintl_path = ctypes.util.find_library('intl') - # if libintl_path == None: - # local_intl = os.path.join('gtk', 'bin', 'intl.dll') - # if os.path.exists(local_intl): - # libintl_path = local_intl - # if libintl_path == None: - # raise ImportError('intl.dll library not found') - # libintl = ctypes.cdll.LoadLibrary(libintl_path) - # libintl.bindtextdomain(APP, DIR) - # libintl.bind_textdomain_codeset(APP, 'UTF-8') - # plugins_locale_dir = os.path.join(common.configpaths[ - # 'PLUGINS_USER'], 'locale').encode(locale.getpreferredencoding()) - # libintl.bindtextdomain('gajim_plugins', plugins_locale_dir) - # libintl.bind_textdomain_codeset('gajim_plugins', 'UTF-8') - - if Gtk.Widget.get_default_direction() == Gtk.TextDirection.RTL: - i18n.direction_mark = '\u200F' - from ctypes import CDLL, byref, create_string_buffer from ctypes.util import find_library import platform @@ -242,7 +207,7 @@ class GajimApplication(Gtk.Application): app.app = self path = os.path.join(configpaths.get('GUI'), 'application_menu.ui') builder = Gtk.Builder() - builder.set_translation_domain(i18n.APP) + builder.set_translation_domain(i18n.DOMAIN) builder.add_from_file(path) menubar = builder.get_object("menubar") appmenu = builder.get_object("appmenu") @@ -319,7 +284,7 @@ class GajimApplication(Gtk.Application): remote_commands = ['ipython', 'show-next-pending-event', 'start-chat', - ] + ] remaining = options.lookup_value(GLib.OPTION_REMAINING, GLib.VariantType.new('as')) diff --git a/gajim/gtkgui_helpers.py b/gajim/gtkgui_helpers.py index 7f7405a28..7289f7a6e 100644 --- a/gajim/gtkgui_helpers.py +++ b/gajim/gtkgui_helpers.py @@ -124,7 +124,7 @@ def get_image_button(icon_name, tooltip, toggle=False): def get_gtk_builder(file_name, widget=None): file_path = os.path.join(configpaths.get('GUI'), file_name) builder = Gtk.Builder() - builder.set_translation_domain(i18n.APP) + builder.set_translation_domain(i18n.DOMAIN) if widget: builder.add_objects_from_file(file_path, [widget]) else: