Refactor i18n module

- Move everything translation related from gajim.py to i18n.py
This commit is contained in:
Philipp Hörist 2018-04-24 22:54:18 +02:00
parent 21d4d0cb1e
commit e2383fd7a4
4 changed files with 125 additions and 94 deletions

View File

@ -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

View File

@ -5,6 +5,7 @@
## Copyright (C) 2004 Vincent Hanquez <tab AT snarc.org>
## Copyright (C) 2005-2006 Nikos Kouremenos <kourem AT gmail.com>
## Copyright (C) 2009 Benjamin Richter <br AT waldteufel-online.net>
## Copyright (C) 2018 Philipp Hörist <philipp AT hoerist.com>
##
## 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()

View File

@ -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'))

View File

@ -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: