/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
6681.2.4 by Jelmer Vernooij
More renames.
21
# This module is copied from Bazaar Explorer and modified for brz.
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
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
7058.4.10 by Jelmer Vernooij
Fix i18n stuff.
31
from .sixish import text_type
32
6162.4.7 by Jonathan Riddell
two empty lines between top level items
33
6133.3.10 by Jonathan Riddell
default _translations back to None so we can tell if it gets installed
34
_translations = None
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
35
36
5875.2.7 by INADA Naoki
Change order of functions.
37
def gettext(message):
38
    """Translate message. 
5875.2.9 by Vincent Ladeuil
Cleanup some PEP8 issues and move test code in test module, test_multiline still failing.
39
    
40
    :returns: translated message as unicode.
41
    """
6131.2.1 by Jonathan Riddell
install translations whenever they are used
42
    install()
6621.2.26 by Martin
Misc set of changes to get started with selftest on Python 3
43
    try:
44
        return _translations.ugettext(message)
45
    except AttributeError:
46
        return _translations.gettext(message)
5875.2.7 by INADA Naoki
Change order of functions.
47
5875.2.9 by Vincent Ladeuil
Cleanup some PEP8 issues and move test code in test module, test_multiline still failing.
48
5971.1.24 by Jonathan Riddell
fix translations for plural forms
49
def ngettext(singular, plural, number):
50
    """Translate message with plural forms based on `number`.
51
52
    :param singular: English language message in singular form
53
    :param plural: English language message in plural form
54
    :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.
55
56
    :returns: translated message as unicode.
57
    """
6131.2.1 by Jonathan Riddell
install translations whenever they are used
58
    install()
6621.2.26 by Martin
Misc set of changes to get started with selftest on Python 3
59
    try:
60
        return _translations.ungettext(singular, plural, number)
61
    except AttributeError:
62
        return _translations.ngettext(singular, plural, number)
5875.2.7 by INADA Naoki
Change order of functions.
63
5875.2.9 by Vincent Ladeuil
Cleanup some PEP8 issues and move test code in test module, test_multiline still failing.
64
5875.2.7 by INADA Naoki
Change order of functions.
65
def N_(msg):
66
    """Mark message for translation but don't translate it right away."""
67
    return msg
68
5875.2.9 by Vincent Ladeuil
Cleanup some PEP8 issues and move test code in test module, test_multiline still failing.
69
5875.2.7 by INADA Naoki
Change order of functions.
70
def gettext_per_paragraph(message):
71
    """Translate message per paragraph.
72
5875.2.9 by Vincent Ladeuil
Cleanup some PEP8 issues and move test code in test module, test_multiline still failing.
73
    :returns: concatenated translated message as unicode.
74
    """
6133.3.14 by Jonathan Riddell
install() translations for per_paragraph too
75
    install()
5875.2.7 by INADA Naoki
Change order of functions.
76
    paragraphs = message.split(u'\n\n')
77
    # Be careful not to translate the empty string -- it holds the
78
    # meta data of the .po file.
6621.2.26 by Martin
Misc set of changes to get started with selftest on Python 3
79
    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.
80
81
6131.2.3 by Jonathan Riddell
rename to disable_i18n() to follow convention
82
def disable_i18n():
6131.2.2 by Jonathan Riddell
add disableI18n() function so bzrlib users can chose not to use i18n
83
    """Do not allow i18n to be enabled.  Useful for third party users
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
84
    of breezy."""
6133.3.13 by Jonathan Riddell
vila sorts it out, fix disable_i18n() and use it in tests.__init__
85
    global _translations
6133.3.10 by Jonathan Riddell
default _translations back to None so we can tell if it gets installed
86
    _translations = _gettext.NullTranslations()
6131.2.2 by Jonathan Riddell
add disableI18n() function so bzrlib users can chose not to use i18n
87
6133.3.13 by Jonathan Riddell
vila sorts it out, fix disable_i18n() and use it in tests.__init__
88
5875.3.25 by Vincent Ladeuil
Fix test failures and make sure we don't rely on a default translation.
89
def installed():
6133.3.10 by Jonathan Riddell
default _translations back to None so we can tell if it gets installed
90
    """Returns whether translations are in use or not."""
91
    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.
92
93
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
94
def install(lang=None):
6681.2.4 by Jelmer Vernooij
More renames.
95
    """Enables gettext translations in brz."""
5875.3.25 by Vincent Ladeuil
Fix test failures and make sure we don't rely on a default translation.
96
    global _translations
6112.1.1 by Jonathan Riddell
check for installed i18n before doing install
97
    if installed():
98
        return
6162.4.1 by Jonathan Riddell
alter code to make it more usable by plugins, add install_translations()
99
    _translations = install_translations(lang)
100
6162.4.7 by Jonathan Riddell
two empty lines between top level items
101
6681.2.4 by Jelmer Vernooij
More renames.
102
def install_translations(lang=None, domain='brz', locale_base=None):
6162.4.1 by Jonathan Riddell
alter code to make it more usable by plugins, add install_translations()
103
    """Create a gettext translation object.
104
    
105
    :param lang: language to install.
106
    :param domain: translation domain to install.
107
    :param locale_base: plugins can specify their own directory.
108
109
    :returns: a gettext translations object to use
110
    """
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
111
    if lang is None:
112
        lang = _get_current_locale()
6025.1.1 by Jelmer Vernooij
Fix i18n use when no environment variables are set.
113
    if lang is not None:
114
        languages = lang.split(':')
115
    else:
116
        languages = None
6162.4.1 by Jonathan Riddell
alter code to make it more usable by plugins, add install_translations()
117
    translation = _gettext.translation(
118
            domain,
119
            localedir=_get_locale_dir(locale_base),
6025.1.1 by Jelmer Vernooij
Fix i18n use when no environment variables are set.
120
            languages=languages,
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
121
            fallback=True)
6162.4.1 by Jonathan Riddell
alter code to make it more usable by plugins, add install_translations()
122
    return translation
5875.2.7 by INADA Naoki
Change order of functions.
123
6162.4.7 by Jonathan Riddell
two empty lines between top level items
124
6162.4.2 by Jonathan Riddell
add add_fallback() method to i18n
125
def add_fallback(fallback):
126
    """
127
    Add a fallback translations object.  Typically used by plugins.
128
129
    :param fallback: gettext.GNUTranslations object
130
    """
131
    install()
132
    _translations.add_fallback(fallback)
133
6162.4.7 by Jonathan Riddell
two empty lines between top level items
134
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
135
def uninstall():
6133.3.10 by Jonathan Riddell
default _translations back to None so we can tell if it gets installed
136
    """Disables gettext translations."""
5875.3.25 by Vincent Ladeuil
Fix test failures and make sure we don't rely on a default translation.
137
    global _translations
6133.3.10 by Jonathan Riddell
default _translations back to None so we can tell if it gets installed
138
    _translations = None
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
139
140
6162.4.1 by Jonathan Riddell
alter code to make it more usable by plugins, add install_translations()
141
def _get_locale_dir(base):
142
    """Returns directory to find .mo translations file in, either local or system
143
144
    :param base: plugins can specify their own local directory
145
    """
6621.2.26 by Martin
Misc set of changes to get started with selftest on Python 3
146
    if sys.version_info > (3,):
147
        decode_path = str
148
    else:
149
        fs_enc = sys.getfilesystemencoding()
150
        def decode_path(path):
151
            return path.decode(fs_enc)
6437.56.1 by Martin Packman
Fall back to sys.prefix not /usr when looking for .mo files
152
    if getattr(sys, 'frozen', False):
6162.4.1 by Jonathan Riddell
alter code to make it more usable by plugins, add install_translations()
153
        if base is None:
6621.2.26 by Martin
Misc set of changes to get started with selftest on Python 3
154
            base = os.path.dirname(decode_path(sys.executable))
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
155
        return os.path.join(base, u'locale')
156
    else:
6162.4.1 by Jonathan Riddell
alter code to make it more usable by plugins, add install_translations()
157
        if base is None:
6621.2.26 by Martin
Misc set of changes to get started with selftest on Python 3
158
            base = os.path.dirname(decode_path(__file__))
5875.2.4 by INADA Naoki
Search '/usr/share/locale' when bzrlib/locale does not exist.
159
        dirpath = os.path.realpath(os.path.join(base, u'locale'))
160
        if os.path.exists(dirpath):
161
            return dirpath
6621.2.26 by Martin
Misc set of changes to get started with selftest on Python 3
162
    return os.path.join(decode_path(sys.prefix), u"share", u"locale")
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
163
164
165
def _check_win32_locale():
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
166
    for i in ('LANGUAGE', 'LC_ALL', 'LC_MESSAGES', 'LANG'):
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
167
        if os.environ.get(i):
168
            break
169
    else:
170
        lang = None
171
        import locale
172
        try:
173
            import ctypes
174
        except ImportError:
175
            # use only user's default locale
176
            lang = locale.getdefaultlocale()[0]
177
        else:
178
            # using ctypes to determine all locales
179
            lcid_user = ctypes.windll.kernel32.GetUserDefaultLCID()
180
            lcid_system = ctypes.windll.kernel32.GetSystemDefaultLCID()
181
            if lcid_user != lcid_system:
182
                lcid = [lcid_user, lcid_system]
183
            else:
184
                lcid = [lcid_user]
185
            lang = [locale.windows_locale.get(i) for i in lcid]
186
            lang = ':'.join([i for i in lang if i])
187
        # set lang code for gettext
188
        if lang:
189
            os.environ['LANGUAGE'] = lang
190
191
192
def _get_current_locale():
193
    if not os.environ.get('LANGUAGE'):
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
194
        from . import config
6056.2.3 by Vincent Ladeuil
Migrate language.
195
        lang = config.GlobalStack().get('language')
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
196
        if lang:
197
            os.environ['LANGUAGE'] = lang
198
            return lang
199
    if sys.platform == 'win32':
200
        _check_win32_locale()
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
201
    for i in ('LANGUAGE', 'LC_ALL', 'LC_MESSAGES', 'LANG'):
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
202
        lang = os.environ.get(i)
203
        if lang:
204
            return lang
205
    return None
6189.1.1 by Jelmer Vernooij
Add a load_plugin_translations method.
206
207
208
def load_plugin_translations(domain):
209
    """Load the translations for a specific plugin.
210
6681.2.4 by Jelmer Vernooij
More renames.
211
    :param domain: Gettext domain name (usually 'brz-PLUGINNAME')
6189.1.1 by Jelmer Vernooij
Add a load_plugin_translations method.
212
    """
7058.4.10 by Jelmer Vernooij
Fix i18n stuff.
213
    locale_base = os.path.dirname(__file__)
6189.1.1 by Jelmer Vernooij
Add a load_plugin_translations method.
214
    translation = install_translations(domain=domain,
215
        locale_base=locale_base)
216
    add_fallback(translation)
217
    return translation