def changeLanguage(self, language):
"""Change the language."""
try:
lang = gettext.translation(
'messages', localedir='locales', languages=[language])
lang.install()
except:
lang = gettext.NullTranslations()
self.app.removeTranslator(self.translator)
self.translator = PyQt5.QtCore.QTranslator(self.app)
self.translator.load(PyQt5.QtCore.QLocale(language),
"qtbase", "_", scctool.settings.getAbsPath('locales'), ".qm")
self.app.installTranslator(self.translator)
scctool.settings.config.parser.set("SCT", "language", language)
self.restart()
python类translation()的实例源码
def __resource_exists(name):
"""Return true if the given resource exists"""
try:
open_resource(name).close()
return True
except IOError:
return False
# Enable this when we get some translations?
# We want an i18n API that is useful to programs using Python's gettext
# module, as well as the Zope3 i18n package. Perhaps we should just provide
# the POT file and translations, and leave it up to callers to make use
# of them.
#
# t = gettext.translation(
# 'pytz', os.path.join(os.path.dirname(__file__), 'locales'),
# fallback=True
# )
# def _(timezone_name):
# """Translate a timezone name using the current locale, returning Unicode"""
# return t.ugettext(timezone_name)
def __init__(self, language):
"""Create a GNUTranslations() using many locale directories"""
gettext_module.GNUTranslations.__init__(self)
self.set_output_charset('utf-8') # For Python 2 gettext() (#25720)
self.__language = language
self.__to_language = to_language(language)
self.__locale = to_locale(language)
self._catalog = None
self._init_translation_catalog()
self._add_installed_apps_translations()
self._add_local_translations()
if self.__language == settings.LANGUAGE_CODE and self._catalog is None:
# default lang should have at least one translation file available.
raise IOError("No translation files found for default language %s." % settings.LANGUAGE_CODE)
self._add_fallback()
if self._catalog is None:
# No catalogs found for this language, set an empty catalog.
self._catalog = {}
def activateLanguage(self, index):
try:
lang = self.lang[index]
print "Activating language " + lang[0]
self.catalog = gettext.translation('enigma2', resolveFilename(SCOPE_LANGUAGE, ""), languages=[index], fallback=True)
self.catalog.install(names=("ngettext", "pgettext"))
self.activeLanguage = index
for x in self.callbacks:
if x:
x()
except:
print "Selected language does not exist!"
# NOTE: we do not use LC_ALL, because LC_ALL will not set any of the categories, when one of the categories fails.
# We'd rather try to set all available categories, and ignore the others
for category in [locale.LC_CTYPE, locale.LC_COLLATE, locale.LC_TIME, locale.LC_MONETARY, locale.LC_MESSAGES, locale.LC_NUMERIC]:
try:
locale.setlocale(category, (self.getLanguage(), 'UTF-8'))
except:
pass
# HACK: sometimes python 2.7 reverts to the LC_TIME environment value, so make sure it has the correct value
os.environ["LC_TIME"] = self.getLanguage() + '.UTF-8'
os.environ["LANGUAGE"] = self.getLanguage() + '.UTF-8'
os.environ["GST_SUBTITLE_ENCODING"] = self.getGStreamerSubtitleEncoding()
def updateLanguageCache(self):
t = localtime(time())
createdate = strftime("%d.%m.%Y %H:%M:%S", t)
f = open('/usr/lib/enigma2/python/Components/Language_cache.py','w')
f.write('# -*- coding: UTF-8 -*-\n')
f.write('# date: ' + createdate + '\n#\n\n')
f.write('LANG_TEXT = {\n')
for lang in self.langlist:
catalog = gettext.translation('enigma2', resolveFilename(SCOPE_LANGUAGE, ""), languages=[str(lang)], fallback=True)
T1 = catalog.gettext("Please use the UP and DOWN keys to select your language. Afterwards press the OK button.")
T2 = catalog.gettext("Language selection")
T3 = catalog.gettext("Cancel")
T4 = catalog.gettext("Save")
f.write('"' + lang + '"' + ': {\n')
f.write('\t "T1"' + ': "' + T1 + '",\n')
f.write('\t "T2"' + ': "' + T2 + '",\n')
f.write('\t "T3"' + ': "' + T3 + '",\n')
f.write('\t "T4"' + ': "' + T4 + '",\n')
f.write('},\n')
f.write('}\n')
f.close
catalog = None
lang = None
def get_translations(languages=None, getter=get_builtin_gnu_translations):
"""
Get a WTForms translation object which wraps a low-level translations object.
:param languages:
A sequence of languages to try, in order.
:param getter:
A single-argument callable which returns a low-level translations object.
"""
translations = getter(languages)
if hasattr(translations, 'ugettext'):
return DefaultTranslations(translations)
else:
# Python 3 has no ugettext/ungettext, so just return the translations object.
return translations
def get_translations(languages=None, getter=get_builtin_gnu_translations):
"""
Get a WTForms translation object which wraps a low-level translations object.
:param languages:
A sequence of languages to try, in order.
:param getter:
A single-argument callable which returns a low-level translations object.
"""
translations = getter(languages)
if hasattr(translations, 'ugettext'):
return DefaultTranslations(translations)
else:
# Python 3 has no ugettext/ungettext, so just return the translations object.
return translations
def resource_exists(name):
"""Return true if the given resource exists"""
try:
open_resource(name).close()
return True
except IOError:
return False
# Enable this when we get some translations?
# We want an i18n API that is useful to programs using Python's gettext
# module, as well as the Zope3 i18n package. Perhaps we should just provide
# the POT file and translations, and leave it up to callers to make use
# of them.
#
# t = gettext.translation(
# 'pytz', os.path.join(os.path.dirname(__file__), 'locales'),
# fallback=True
# )
# def _(timezone_name):
# """Translate a timezone name using the current locale, returning Unicode"""
# return t.ugettext(timezone_name)
def check_available_translations(self, locale):
"""
Test a locale for having a translation available
locale -- string with standard language code, locale code, or name
"""
if not self.localedir:
return None
#Note that this isn't a typo for self.language; self.languages
#is cached so we don't have to query the file system every
#time this function is called.
if not hasattr(self, 'languages'):
self.languages = self.get_available_translations()
if not locale:
return None
if locale[:5] in self.languages:
return locale[:5]
#US English is the outlier, all other English locales want real English:
if locale[:2] == 'en' and locale[:5] != 'en_US':
return 'en_GB'
if locale[:2] in self.languages:
return locale[:2]
return None
def ngettext(self, singular, plural, num):
"""
The translation of singular/plural is returned unless the translation is
not available and the singular contains the separator. In that case,
the returned value is the singular.
:param singular: The singular form of the string to be translated.
may contain a context seperator
:type singular: unicode
:param plural: The plural form of the string to be translated.
:type plural: unicode
:param num: the amount for which to decide the translation
:type num: int
:returns: Translation or the original.
:rtype: unicode
"""
return gettext.GNUTranslations.ngettext(self, singular, plural, num)
def sgettext(self, msgid, sep='|'):
"""
Strip the context used for resolving translation ambiguities.
The translation of msgid is returned unless the translation is
not available and the msgid contains the separator. In that case,
the returned value is the portion of msgid following the last
separator. Default separator is '|'.
:param msgid: The string to translated.
:type msgid: unicode
:param sep: The separator marking the context.
:type sep: unicode
:returns: Translation or the original with context stripped.
:rtype: unicode
"""
msgval = self.gettext(msgid)
if msgval == msgid:
sep_idx = msgid.rfind(sep)
msgval = msgid[sep_idx+1:]
return msgval
def __init__(self, domain, lazy=False, localedir=None):
"""Establish a set of translation functions for the domain.
:param domain: Name of translation domain,
specifying a message catalog.
:type domain: str
:param lazy: Delays translation until a message is emitted.
Defaults to False.
:type lazy: Boolean
:param localedir: Directory with translation catalogs.
:type localedir: str
"""
self.domain = domain
self.lazy = lazy
if localedir is None:
localedir = os.environ.get(domain.upper() + '_LOCALEDIR')
self.localedir = localedir
def _make_translation_func(self, domain=None):
"""Return a new translation function ready for use.
Takes into account whether or not lazy translation is being
done.
The domain can be specified to override the default from the
factory, but the localedir from the factory is always used
because we assume the log-level translation catalogs are
installed in the same directory as the main application
catalog.
"""
if domain is None:
domain = self.domain
if self.lazy:
return functools.partial(Message, domain=domain)
t = gettext.translation(
domain,
localedir=self.localedir,
fallback=True,
)
if six.PY3:
return t.gettext
return t.ugettext
def _translate_msgid(msgid, domain, desired_locale=None):
if not desired_locale:
system_locale = locale.getdefaultlocale()
# If the system locale is not available to the runtime use English
if not system_locale[0]:
desired_locale = 'en_US'
else:
desired_locale = system_locale[0]
locale_dir = os.environ.get(domain.upper() + '_LOCALEDIR')
lang = gettext.translation(domain,
localedir=locale_dir,
languages=[desired_locale],
fallback=True)
if six.PY3:
translator = lang.gettext
else:
translator = lang.ugettext
translated_message = translator(msgid)
return translated_message
def _sanitize_mod_params(self, other):
"""Sanitize the object being modded with this Message.
- Add support for modding 'None' so translation supports it
- Trim the modded object, which can be a large dictionary, to only
those keys that would actually be used in a translation
- Snapshot the object being modded, in case the message is
translated, it will be used as it was when the Message was created
"""
if other is None:
params = (other,)
elif isinstance(other, dict):
# Merge the dictionaries
# Copy each item in case one does not support deep copy.
params = {}
if isinstance(self.params, dict):
for key, val in self.params.items():
params[key] = self._copy_param(val)
for key, val in other.items():
params[key] = self._copy_param(val)
else:
params = self._copy_param(other)
return params
def set_locale(self, locales, trans_dir=None):
if locales[0] is None or "en" in locales[0].lower():
self.trans = NullTranslations()
return
if "cn" in locales[0].lower():
locales = ["zh_Hans_CN"]
try:
if trans_dir is None:
trans_dir = os.path.join(
os.path.dirname(
os.path.abspath(
__file__,
),
),
"translations"
)
self.trans = translation(
domain="messages",
localedir=trans_dir,
languages=locales,
)
except Exception as e:
system_log.debug(e)
self.trans = NullTranslations()
def set_locale(self, locales, trans_dir=None):
if locales[0] is None or "en" in locales[0].lower():
self.trans = NullTranslations()
return
if "cn" in locales[0].lower():
locales = ["zh_Hans_CN"]
try:
if trans_dir is None:
trans_dir = os.path.join(
os.path.dirname(
os.path.abspath(
__file__,
),
),
"translations"
)
self.trans = translation(
domain="messages",
localedir=trans_dir,
languages=locales,
)
except Exception as e:
system_log.debug(e)
self.trans = NullTranslations()
def findtranslation(self):
"Find the translation for the document language."
self.langcodes = None
if not DocumentParameters.language:
Trace.error('No language in document')
return
if not DocumentParameters.language in TranslationConfig.languages:
Trace.error('Unknown language ' + DocumentParameters.language)
return
if TranslationConfig.languages[DocumentParameters.language] == 'en':
return
langcodes = [TranslationConfig.languages[DocumentParameters.language]]
try:
self.translation = gettext.translation('elyxer', None, langcodes)
except IOError:
Trace.error('No translation for ' + unicode(langcodes))
def resource_exists(name):
return loader.resource_exists(name)
# Enable this when we get some translations?
# We want an i18n API that is useful to programs using Python's gettext
# module, as well as the Zope3 i18n package. Perhaps we should just provide
# the POT file and translations, and leave it up to callers to make use
# of them.
#
# t = gettext.translation(
# 'pytz', os.path.join(os.path.dirname(__file__), 'locales'),
# fallback=True
# )
# def _(timezone_name):
# """Translate a timezone name using the current locale, returning Unicode"""
# return t.ugettext(timezone_name)
def findtranslation(self):
"Find the translation for the document language."
self.langcodes = None
if not DocumentParameters.language:
Trace.error('No language in document')
return
if not DocumentParameters.language in TranslationConfig.languages:
Trace.error('Unknown language ' + DocumentParameters.language)
return
if TranslationConfig.languages[DocumentParameters.language] == 'en':
return
langcodes = [TranslationConfig.languages[DocumentParameters.language]]
try:
self.translation = gettext.translation('elyxer', None, langcodes)
except IOError:
Trace.error('No translation for ' + unicode(langcodes))
def get_translations(languages=None, getter=get_builtin_gnu_translations):
"""
Get a WTForms translation object which wraps a low-level translations object.
:param languages:
A sequence of languages to try, in order.
:param getter:
A single-argument callable which returns a low-level translations object.
"""
translations = getter(languages)
if hasattr(translations, 'ugettext'):
return DefaultTranslations(translations)
else:
# Python 3 has no ugettext/ungettext, so just return the translations object.
return translations
def set_language_code(code, gettext_install=False):
"""Set the BCP-47 language code that the speech systems should use.
Args:
gettext_install: if True, gettext's _() will be installed in as a builtin.
As this has global effect, it should only be done by applications.
"""
global _language_code
_language_code = code.replace('_', '-')
if gettext_install:
if not _locale_dir:
raise ValueError('locale_dir is not set. Please call set_locale_dir().')
language_id = code.replace('-', '_')
t = gettext.translation(_LOCALE_DOMAIN, _locale_dir, [language_id], fallback=True)
t.install()
def get_translations(languages=None, getter=get_builtin_gnu_translations):
"""
Get a WTForms translation object which wraps a low-level translations object.
:param languages:
A sequence of languages to try, in order.
:param getter:
A single-argument callable which returns a low-level translations object.
"""
translations = getter(languages)
if hasattr(translations, 'ugettext'):
return DefaultTranslations(translations)
else:
# Python 3 has no ugettext/ungettext, so just return the translations object.
return translations
def activateLanguage(self, index):
try:
lang = self.lang[index]
print "Activating language " + lang[0]
self.catalog = gettext.translation('enigma2', resolveFilename(SCOPE_LANGUAGE, ""), languages=[index], fallback=True)
self.catalog.install(names=("ngettext", "pgettext"))
self.activeLanguage = index
for x in self.callbacks:
x()
except:
print "Selected language does not exist!"
# NOTE: we do not use LC_ALL, because LC_ALL will not set any of the categories, when one of the categories fails.
# We'd rather try to set all available categories, and ignore the others
for category in [locale.LC_CTYPE, locale.LC_COLLATE, locale.LC_TIME, locale.LC_MONETARY, locale.LC_MESSAGES, locale.LC_NUMERIC]:
try:
locale.setlocale(category, (self.getLanguage(), 'UTF-8'))
except:
pass
# HACK: sometimes python 2.7 reverts to the LC_TIME environment value, so make sure it has the correct value
os.environ["LC_TIME"] = self.getLanguage() + '.UTF-8'
os.environ["LANGUAGE"] = self.getLanguage() + '.UTF-8'
os.environ["GST_SUBTITLE_ENCODING"] = self.getGStreamerSubtitleEncoding()
def errormsg(msg):
"""Intended for end-user-visible error messages.
(Currently just writes to stderr with an appended newline, but could do
something better in future: e.g. could add markup to distinguish error
messages from status messages or debugging output.)
Note that this should always be combined with translation:
import inkex
...
inkex.errormsg(_("This extension requires two selected paths."))
"""
if isinstance(msg, unicode):
sys.stderr.write(msg.encode("utf-8") + "\n")
else:
sys.stderr.write((unicode(msg, "utf-8", errors='replace') + "\n").encode("utf-8"))
def resource_exists(name):
"""Return true if the given resource exists"""
try:
open_resource(name).close()
return True
except IOError:
return False
# Enable this when we get some translations?
# We want an i18n API that is useful to programs using Python's gettext
# module, as well as the Zope3 i18n package. Perhaps we should just provide
# the POT file and translations, and leave it up to callers to make use
# of them.
#
# t = gettext.translation(
# 'pytz', os.path.join(os.path.dirname(__file__), 'locales'),
# fallback=True
# )
# def _(timezone_name):
# """Translate a timezone name using the current locale, returning Unicode"""
# return t.ugettext(timezone_name)
def test_the_alternative_interface(self):
eq = self.assertEqual
# test the alternative interface
with open(self.mofile, 'rb') as fp:
t = gettext.GNUTranslations(fp)
# Install the translation object
t.install()
eq(_('nudge nudge'), 'wink wink')
# Try unicode return type
t.install()
eq(_('mullusk'), 'bacon')
# Test installation of other methods
import builtins
t.install(names=["gettext", "lgettext"])
eq(_, t.gettext)
eq(builtins.gettext, t.gettext)
eq(lgettext, t.lgettext)
del builtins.gettext
del builtins.lgettext
def test_cache(self):
self.localedir = os.curdir
self.mofile = MOFILE
self.assertEqual(len(gettext._translations), 0)
t = gettext.translation('gettext', self.localedir)
self.assertEqual(len(gettext._translations), 1)
t = gettext.translation('gettext', self.localedir,
class_=DummyGNUTranslations)
self.assertEqual(len(gettext._translations), 2)
self.assertEqual(t.__class__, DummyGNUTranslations)
# Calling it again doesn't add to the cache
t = gettext.translation('gettext', self.localedir,
class_=DummyGNUTranslations)
self.assertEqual(len(gettext._translations), 2)
self.assertEqual(t.__class__, DummyGNUTranslations)
def get_translations(languages=None, getter=get_builtin_gnu_translations):
"""
Get a WTForms translation object which wraps a low-level translations object.
:param languages:
A sequence of languages to try, in order.
:param getter:
A single-argument callable which returns a low-level translations object.
"""
translations = getter(languages)
if hasattr(translations, 'ugettext'):
return DefaultTranslations(translations)
else:
# Python 3 has no ugettext/ungettext, so just return the translations object.
return translations
def errormsg(msg):
"""Intended for end-user-visible error messages.
(Currently just writes to stderr with an appended newline, but could do
something better in future: e.g. could add markup to distinguish error
messages from status messages or debugging output.)
Note that this should always be combined with translation:
import inkex
inkex.localize()
...
inkex.errormsg(_("This extension requires two selected paths."))
"""
if isinstance(msg, unicode):
sys.stderr.write(msg.encode("UTF-8") + "\n")
else:
sys.stderr.write((unicode(msg, "utf-8", errors='replace') + "\n").encode("UTF-8"))