/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
1
# -*- coding: utf-8 -*-
2
#
3
# Copyright (C) 2007 Lukáš Lalinský <lalinsky@gmail.com>
4
# Copyright (C) 2007,2009 Alexander Belchenko <bialix@ukr.net>
5
# Copyright (C) 2011 Canonical Ltd
6
#
5875.2.11 by Vincent Ladeuil
Slightly different wrapping of the GPL header broke test_source :-/
7
# This program is free software; you can redistribute it and/or modify
8
# it under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 2 of the License, or
10
# (at your option) any later version.
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
11
#
12
# This program is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with this program; if not, write to the Free Software
5875.2.11 by Vincent Ladeuil
Slightly different wrapping of the GPL header broke test_source :-/
19
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
20
21
# This module is copied from Bazaar Explorer and modified for bzr.
22
6379.6.7 by Jelmer Vernooij
Move importing from future until after doc string, otherwise the doc string will disappear.
23
"""i18n and l10n support for Bazaar."""
24
6379.6.3 by Jelmer Vernooij
Use absolute_import.
25
from __future__ import absolute_import
26
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
27
import gettext as _gettext
28
import os
29
import sys
30
6162.4.7 by Jonathan Riddell
two empty lines between top level items
31
6133.3.10 by Jonathan Riddell
default _translations back to None so we can tell if it gets installed
32
_translations = None
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
33
34
5875.2.7 by INADA Naoki
Change order of functions.
35
def gettext(message):
36
    """Translate message. 
5875.2.9 by Vincent Ladeuil
Cleanup some PEP8 issues and move test code in test module, test_multiline still failing.
37
    
38
    :returns: translated message as unicode.
39
    """
6131.2.1 by Jonathan Riddell
install translations whenever they are used
40
    install()
6621.2.26 by Martin
Misc set of changes to get started with selftest on Python 3
41
    try:
42
        return _translations.ugettext(message)
43
    except AttributeError:
44
        return _translations.gettext(message)
5875.2.7 by INADA Naoki
Change order of functions.
45
5875.2.9 by Vincent Ladeuil
Cleanup some PEP8 issues and move test code in test module, test_multiline still failing.
46
5971.1.24 by Jonathan Riddell
fix translations for plural forms
47
def ngettext(singular, plural, number):
48
    """Translate message with plural forms based on `number`.
49
50
    :param singular: English language message in singular form
51
    :param plural: English language message in plural form
52
    :param number: the number this message should be translated for
5875.2.9 by Vincent Ladeuil
Cleanup some PEP8 issues and move test code in test module, test_multiline still failing.
53
54
    :returns: translated message as unicode.
55
    """
6131.2.1 by Jonathan Riddell
install translations whenever they are used
56
    install()
6621.2.26 by Martin
Misc set of changes to get started with selftest on Python 3
57
    try:
58
        return _translations.ungettext(singular, plural, number)
59
    except AttributeError:
60
        return _translations.ngettext(singular, plural, number)
5875.2.7 by INADA Naoki
Change order of functions.
61
5875.2.9 by Vincent Ladeuil
Cleanup some PEP8 issues and move test code in test module, test_multiline still failing.
62
5875.2.7 by INADA Naoki
Change order of functions.
63
def N_(msg):
64
    """Mark message for translation but don't translate it right away."""
65
    return msg
66
5875.2.9 by Vincent Ladeuil
Cleanup some PEP8 issues and move test code in test module, test_multiline still failing.
67
5875.2.7 by INADA Naoki
Change order of functions.
68
def gettext_per_paragraph(message):
69
    """Translate message per paragraph.
70
5875.2.9 by Vincent Ladeuil
Cleanup some PEP8 issues and move test code in test module, test_multiline still failing.
71
    :returns: concatenated translated message as unicode.
72
    """
6133.3.14 by Jonathan Riddell
install() translations for per_paragraph too
73
    install()
5875.2.7 by INADA Naoki
Change order of functions.
74
    paragraphs = message.split(u'\n\n')
75
    # Be careful not to translate the empty string -- it holds the
76
    # meta data of the .po file.
6621.2.26 by Martin
Misc set of changes to get started with selftest on Python 3
77
    return u'\n\n'.join(gettext(p) if p else u'' for p in paragraphs)
5875.2.7 by INADA Naoki
Change order of functions.
78
79
6131.2.3 by Jonathan Riddell
rename to disable_i18n() to follow convention
80
def disable_i18n():
6131.2.2 by Jonathan Riddell
add disableI18n() function so bzrlib users can chose not to use i18n
81
    """Do not allow i18n to be enabled.  Useful for third party users
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
82
    of breezy."""
6133.3.13 by Jonathan Riddell
vila sorts it out, fix disable_i18n() and use it in tests.__init__
83
    global _translations
6133.3.10 by Jonathan Riddell
default _translations back to None so we can tell if it gets installed
84
    _translations = _gettext.NullTranslations()
6131.2.2 by Jonathan Riddell
add disableI18n() function so bzrlib users can chose not to use i18n
85
6133.3.13 by Jonathan Riddell
vila sorts it out, fix disable_i18n() and use it in tests.__init__
86
5875.3.25 by Vincent Ladeuil
Fix test failures and make sure we don't rely on a default translation.
87
def installed():
6133.3.10 by Jonathan Riddell
default _translations back to None so we can tell if it gets installed
88
    """Returns whether translations are in use or not."""
89
    return _translations is not None
5875.3.25 by Vincent Ladeuil
Fix test failures and make sure we don't rely on a default translation.
90
91
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
92
def install(lang=None):
6162.4.1 by Jonathan Riddell
alter code to make it more usable by plugins, add install_translations()
93
    """Enables gettext translations in bzr."""
5875.3.25 by Vincent Ladeuil
Fix test failures and make sure we don't rely on a default translation.
94
    global _translations
6112.1.1 by Jonathan Riddell
check for installed i18n before doing install
95
    if installed():
96
        return
6162.4.1 by Jonathan Riddell
alter code to make it more usable by plugins, add install_translations()
97
    _translations = install_translations(lang)
98
6162.4.7 by Jonathan Riddell
two empty lines between top level items
99
6162.4.1 by Jonathan Riddell
alter code to make it more usable by plugins, add install_translations()
100
def install_translations(lang=None, domain='bzr', locale_base=None):
101
    """Create a gettext translation object.
102
    
103
    :param lang: language to install.
104
    :param domain: translation domain to install.
105
    :param locale_base: plugins can specify their own directory.
106
107
    :returns: a gettext translations object to use
108
    """
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
109
    if lang is None:
110
        lang = _get_current_locale()
6025.1.1 by Jelmer Vernooij
Fix i18n use when no environment variables are set.
111
    if lang is not None:
112
        languages = lang.split(':')
113
    else:
114
        languages = None
6162.4.1 by Jonathan Riddell
alter code to make it more usable by plugins, add install_translations()
115
    translation = _gettext.translation(
116
            domain,
117
            localedir=_get_locale_dir(locale_base),
6025.1.1 by Jelmer Vernooij
Fix i18n use when no environment variables are set.
118
            languages=languages,
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
119
            fallback=True)
6162.4.1 by Jonathan Riddell
alter code to make it more usable by plugins, add install_translations()
120
    return translation
5875.2.7 by INADA Naoki
Change order of functions.
121
6162.4.7 by Jonathan Riddell
two empty lines between top level items
122
6162.4.2 by Jonathan Riddell
add add_fallback() method to i18n
123
def add_fallback(fallback):
124
    """
125
    Add a fallback translations object.  Typically used by plugins.
126
127
    :param fallback: gettext.GNUTranslations object
128
    """
129
    install()
130
    _translations.add_fallback(fallback)
131
6162.4.7 by Jonathan Riddell
two empty lines between top level items
132
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
133
def uninstall():
6133.3.10 by Jonathan Riddell
default _translations back to None so we can tell if it gets installed
134
    """Disables gettext translations."""
5875.3.25 by Vincent Ladeuil
Fix test failures and make sure we don't rely on a default translation.
135
    global _translations
6133.3.10 by Jonathan Riddell
default _translations back to None so we can tell if it gets installed
136
    _translations = None
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
137
138
6162.4.1 by Jonathan Riddell
alter code to make it more usable by plugins, add install_translations()
139
def _get_locale_dir(base):
140
    """Returns directory to find .mo translations file in, either local or system
141
142
    :param base: plugins can specify their own local directory
143
    """
6621.2.26 by Martin
Misc set of changes to get started with selftest on Python 3
144
    if sys.version_info > (3,):
145
        decode_path = str
146
    else:
147
        fs_enc = sys.getfilesystemencoding()
148
        def decode_path(path):
149
            return path.decode(fs_enc)
6437.56.1 by Martin Packman
Fall back to sys.prefix not /usr when looking for .mo files
150
    if getattr(sys, 'frozen', False):
6162.4.1 by Jonathan Riddell
alter code to make it more usable by plugins, add install_translations()
151
        if base is None:
6621.2.26 by Martin
Misc set of changes to get started with selftest on Python 3
152
            base = os.path.dirname(decode_path(sys.executable))
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
153
        return os.path.join(base, u'locale')
154
    else:
6162.4.1 by Jonathan Riddell
alter code to make it more usable by plugins, add install_translations()
155
        if base is None:
6621.2.26 by Martin
Misc set of changes to get started with selftest on Python 3
156
            base = os.path.dirname(decode_path(__file__))
5875.2.4 by INADA Naoki
Search '/usr/share/locale' when bzrlib/locale does not exist.
157
        dirpath = os.path.realpath(os.path.join(base, u'locale'))
158
        if os.path.exists(dirpath):
159
            return dirpath
6621.2.26 by Martin
Misc set of changes to get started with selftest on Python 3
160
    return os.path.join(decode_path(sys.prefix), u"share", u"locale")
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
161
162
163
def _check_win32_locale():
164
    for i in ('LANGUAGE','LC_ALL','LC_MESSAGES','LANG'):
165
        if os.environ.get(i):
166
            break
167
    else:
168
        lang = None
169
        import locale
170
        try:
171
            import ctypes
172
        except ImportError:
173
            # use only user's default locale
174
            lang = locale.getdefaultlocale()[0]
175
        else:
176
            # using ctypes to determine all locales
177
            lcid_user = ctypes.windll.kernel32.GetUserDefaultLCID()
178
            lcid_system = ctypes.windll.kernel32.GetSystemDefaultLCID()
179
            if lcid_user != lcid_system:
180
                lcid = [lcid_user, lcid_system]
181
            else:
182
                lcid = [lcid_user]
183
            lang = [locale.windows_locale.get(i) for i in lcid]
184
            lang = ':'.join([i for i in lang if i])
185
        # set lang code for gettext
186
        if lang:
187
            os.environ['LANGUAGE'] = lang
188
189
190
def _get_current_locale():
191
    if not os.environ.get('LANGUAGE'):
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
192
        from . import config
6056.2.3 by Vincent Ladeuil
Migrate language.
193
        lang = config.GlobalStack().get('language')
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
194
        if lang:
195
            os.environ['LANGUAGE'] = lang
196
            return lang
197
    if sys.platform == 'win32':
198
        _check_win32_locale()
199
    for i in ('LANGUAGE','LC_ALL','LC_MESSAGES','LANG'):
200
        lang = os.environ.get(i)
201
        if lang:
202
            return lang
203
    return None
6189.1.1 by Jelmer Vernooij
Add a load_plugin_translations method.
204
205
206
def load_plugin_translations(domain):
207
    """Load the translations for a specific plugin.
208
209
    :param domain: Gettext domain name (usually 'bzr-PLUGINNAME')
210
    """
211
    locale_base = os.path.dirname(
212
        unicode(__file__, sys.getfilesystemencoding()))
213
    translation = install_translations(domain=domain,
214
        locale_base=locale_base)
215
    add_fallback(translation)
216
    return translation