Sync gettextutils from oslo

The oslo changes necessary for delayed translation were refactored in
oslo. This patch set brings in the refactored changes, implemented
under the same change-id mentioned below.

Partially implements bp user-locale-api

Change-Id: I27640a3c8b255be51bc6396d238098bd25af61ec
This commit is contained in:
Luis A. Garcia 2013-07-29 21:43:11 +00:00
parent 1230276b36
commit 555d27c7ef

View File

@ -1,8 +1,8 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4 # vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2012 Red Hat, Inc. # Copyright 2012 Red Hat, Inc.
# All Rights Reserved.
# Copyright 2013 IBM Corp. # Copyright 2013 IBM Corp.
# All Rights Reserved.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may # 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 # not use this file except in compliance with the License. You may obtain
@ -31,17 +31,20 @@ import os
import re import re
import UserString import UserString
from babel import localedata
import six import six
_localedir = os.environ.get('neutron'.upper() + '_LOCALEDIR') _localedir = os.environ.get('neutron'.upper() + '_LOCALEDIR')
_t = gettext.translation('neutron', localedir=_localedir, fallback=True) _t = gettext.translation('neutron', localedir=_localedir, fallback=True)
_AVAILABLE_LANGUAGES = []
def _(msg): def _(msg):
return _t.ugettext(msg) return _t.ugettext(msg)
def install(domain): def install(domain, lazy=False):
"""Install a _() function using the given translation domain. """Install a _() function using the given translation domain.
Given a translation domain, install a _() function using gettext's Given a translation domain, install a _() function using gettext's
@ -51,41 +54,45 @@ def install(domain):
overriding the default localedir (e.g. /usr/share/locale) using overriding the default localedir (e.g. /usr/share/locale) using
a translation-domain-specific environment variable (e.g. a translation-domain-specific environment variable (e.g.
NOVA_LOCALEDIR). NOVA_LOCALEDIR).
:param domain: the translation domain
:param lazy: indicates whether or not to install the lazy _() function.
The lazy _() introduces a way to do deferred translation
of messages by installing a _ that builds Message objects,
instead of strings, which can then be lazily translated into
any available locale.
""" """
gettext.install(domain, if lazy:
localedir=os.environ.get(domain.upper() + '_LOCALEDIR'), # NOTE(mrodden): Lazy gettext functionality.
unicode=True) #
# The following introduces a deferred way to do translations on
# messages in OpenStack. We override the standard _() function
""" # and % (format string) operation to build Message objects that can
Lazy gettext functionality. # later be translated when we have more information.
#
The following is an attempt to introduce a deferred way # Also included below is an example LocaleHandler that translates
to do translations on messages in OpenStack. We attempt to # Messages to an associated locale, effectively allowing many logs,
override the standard _() function and % (format string) operation # each with their own locale.
to build Message objects that can later be translated when we have
more information. Also included is an example LogHandler that
translates Messages to an associated locale, effectively allowing
many logs, each with their own locale.
"""
def get_lazy_gettext(domain):
"""Assemble and return a lazy gettext function for a given domain.
Factory method for a project/module to get a lazy gettext function
for its own translation domain (i.e. nova, glance, cinder, etc.)
"""
def _lazy_gettext(msg): def _lazy_gettext(msg):
"""Create and return a Message object. """Create and return a Message object.
Message encapsulates a string so that we can translate it later when Lazy gettext function for a given domain, it is a factory method
needed. for a project/module to get a lazy gettext function for its own
translation domain (i.e. nova, glance, cinder, etc.)
Message encapsulates a string so that we can translate
it later when needed.
""" """
return Message(msg, domain) return Message(msg, domain)
return _lazy_gettext import __builtin__
__builtin__.__dict__['_'] = _lazy_gettext
else:
localedir = '%s_LOCALEDIR' % domain.upper()
gettext.install(domain,
localedir=os.environ.get(localedir),
unicode=True)
class Message(UserString.UserString, object): class Message(UserString.UserString, object):
@ -232,6 +239,45 @@ class Message(UserString.UserString, object):
return UserString.UserString.__getattribute__(self, name) return UserString.UserString.__getattribute__(self, name)
def get_available_languages(domain):
"""Lists the available languages for the given translation domain.
:param domain: the domain to get languages for
"""
if _AVAILABLE_LANGUAGES:
return _AVAILABLE_LANGUAGES
localedir = '%s_LOCALEDIR' % domain.upper()
find = lambda x: gettext.find(domain,
localedir=os.environ.get(localedir),
languages=[x])
# NOTE(mrodden): en_US should always be available (and first in case
# order matters) since our in-line message strings are en_US
_AVAILABLE_LANGUAGES.append('en_US')
# NOTE(luisg): Babel <1.0 used a function called list(), which was
# renamed to locale_identifiers() in >=1.0, the requirements master list
# requires >=0.9.6, uncapped, so defensively work with both. We can remove
# this check when the master list updates to >=1.0, and all projects udpate
list_identifiers = (getattr(localedata, 'list', None) or
getattr(localedata, 'locale_identifiers'))
locale_identifiers = list_identifiers()
for i in locale_identifiers:
if find(i) is not None:
_AVAILABLE_LANGUAGES.append(i)
return _AVAILABLE_LANGUAGES
def get_localized_message(message, user_locale):
"""Gets a localized version of the given message in the given locale."""
if (isinstance(message, Message)):
if user_locale:
message.locale = user_locale
return unicode(message)
else:
return message
class LocaleHandler(logging.Handler): class LocaleHandler(logging.Handler):
"""Handler that can have a locale associated to translate Messages. """Handler that can have a locale associated to translate Messages.