8f15fe900f
Update all .py source files by $ pyupgrade --py3-only $(git ls-files | grep ".py$") to modernize the code according to Python 3 syntaxes. Also add the pyupgrade hook to pre-commit to avoid merging additional Python 2 syntaxes. Change-Id: I9fe7d07fe6184833e1fbb228efc7d7308430782a
204 lines
6.8 KiB
Python
204 lines
6.8 KiB
Python
# Copyright 2012 Red Hat, Inc.
|
|
# Copyright 2013 IBM Corp.
|
|
# All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
"""Translation function factory
|
|
"""
|
|
|
|
import gettext
|
|
import os
|
|
|
|
from oslo_i18n import _lazy
|
|
from oslo_i18n import _locale
|
|
from oslo_i18n import _message
|
|
|
|
|
|
__all__ = [
|
|
'TranslatorFactory',
|
|
]
|
|
|
|
# magic gettext number to separate context from message
|
|
CONTEXT_SEPARATOR = _message.CONTEXT_SEPARATOR
|
|
|
|
|
|
class TranslatorFactory:
|
|
"Create translator functions"
|
|
|
|
def __init__(self, domain, 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 localedir: Directory with translation catalogs.
|
|
:type localedir: str
|
|
"""
|
|
self.domain = domain
|
|
if localedir is None:
|
|
variable_name = _locale.get_locale_dir_variable_name(domain)
|
|
localedir = os.environ.get(variable_name)
|
|
self.localedir = localedir
|
|
|
|
def _make_translation_func(self, domain=None):
|
|
"""Return a translation function ready for use with messages.
|
|
|
|
The returned function takes a single value, the unicode string
|
|
to be translated. The return type varies depending on whether
|
|
lazy translation is being done. When lazy translation is
|
|
enabled, :class:`Message` objects are returned instead of
|
|
regular :class:`unicode` strings.
|
|
|
|
The domain argument 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
|
|
t = gettext.translation(domain,
|
|
localedir=self.localedir,
|
|
fallback=True)
|
|
# Use the appropriate method of the translation object based
|
|
# on the python version.
|
|
m = t.gettext
|
|
|
|
def f(msg):
|
|
"""oslo_i18n.gettextutils translation function."""
|
|
if _lazy.USE_LAZY:
|
|
return _message.Message(msg, domain=domain)
|
|
return m(msg)
|
|
return f
|
|
|
|
def _make_contextual_translation_func(self, domain=None):
|
|
"""Return a translation function ready for use with context messages.
|
|
|
|
The returned function takes two values, the context of
|
|
the unicode string, the unicode string to be translated.
|
|
The returned type is the same as
|
|
:method:`TranslatorFactory._make_translation_func`.
|
|
|
|
The domain argument is the same as
|
|
:method:`TranslatorFactory._make_translation_func`.
|
|
|
|
"""
|
|
if domain is None:
|
|
domain = self.domain
|
|
t = gettext.translation(domain,
|
|
localedir=self.localedir,
|
|
fallback=True)
|
|
# Use the appropriate method of the translation object based
|
|
# on the python version.
|
|
m = t.gettext
|
|
|
|
def f(ctx, msg):
|
|
"""oslo.i18n.gettextutils translation with context function."""
|
|
if _lazy.USE_LAZY:
|
|
msgid = (ctx, msg)
|
|
return _message.Message(msgid, domain=domain,
|
|
has_contextual_form=True)
|
|
|
|
msgctx = "{}{}{}".format(ctx, CONTEXT_SEPARATOR, msg)
|
|
s = m(msgctx)
|
|
if CONTEXT_SEPARATOR in s:
|
|
# Translation not found
|
|
return msg
|
|
return s
|
|
return f
|
|
|
|
def _make_plural_translation_func(self, domain=None):
|
|
"""Return a plural translation function ready for use with messages.
|
|
|
|
The returned function takes three values, the single form of
|
|
the unicode string, the plural form of the unicode string,
|
|
the count of items to be translated.
|
|
The returned type is the same as
|
|
:method:`TranslatorFactory._make_translation_func`.
|
|
|
|
The domain argument is the same as
|
|
:method:`TranslatorFactory._make_translation_func`.
|
|
|
|
"""
|
|
if domain is None:
|
|
domain = self.domain
|
|
t = gettext.translation(domain,
|
|
localedir=self.localedir,
|
|
fallback=True)
|
|
# Use the appropriate method of the translation object based
|
|
# on the python version.
|
|
m = t.ngettext
|
|
|
|
def f(msgsingle, msgplural, msgcount):
|
|
"""oslo.i18n.gettextutils plural translation function."""
|
|
if _lazy.USE_LAZY:
|
|
msgid = (msgsingle, msgplural, msgcount)
|
|
return _message.Message(msgid, domain=domain,
|
|
has_plural_form=True)
|
|
return m(msgsingle, msgplural, msgcount)
|
|
return f
|
|
|
|
@property
|
|
def primary(self):
|
|
"The default translation function."
|
|
return self._make_translation_func()
|
|
|
|
@property
|
|
def contextual_form(self):
|
|
"""The contextual translation function.
|
|
|
|
The returned function takes two values, the context of
|
|
the unicode string, the unicode string to be translated.
|
|
|
|
.. versionadded:: 2.1.0
|
|
|
|
"""
|
|
return self._make_contextual_translation_func()
|
|
|
|
@property
|
|
def plural_form(self):
|
|
"""The plural translation function.
|
|
|
|
The returned function takes three values, the single form of
|
|
the unicode string, the plural form of the unicode string,
|
|
the count of items to be translated.
|
|
|
|
.. versionadded:: 2.1.0
|
|
|
|
"""
|
|
return self._make_plural_translation_func()
|
|
|
|
def _make_log_translation_func(self, level):
|
|
return self._make_translation_func(self.domain + '-log-' + level)
|
|
|
|
@property
|
|
def log_info(self):
|
|
"Translate info-level log messages."
|
|
return self._make_log_translation_func('info')
|
|
|
|
@property
|
|
def log_warning(self):
|
|
"Translate warning-level log messages."
|
|
return self._make_log_translation_func('warning')
|
|
|
|
@property
|
|
def log_error(self):
|
|
"Translate error-level log messages."
|
|
return self._make_log_translation_func('error')
|
|
|
|
@property
|
|
def log_critical(self):
|
|
"Translate critical-level log messages."
|
|
return self._make_log_translation_func('critical')
|