~ubuntu-branches/ubuntu/hardy/gnue-common/hardy

« back to all changes in this revision

Viewing changes to src/apps/i18n.py

  • Committer: Bazaar Package Importer
  • Author(s): Andrew Mitchell
  • Date: 2005-03-09 11:06:31 UTC
  • Revision ID: james.westby@ubuntu.com-20050309110631-8gvvn39q7tjz1kj6
Tags: upstream-0.5.14
ImportĀ upstreamĀ versionĀ 0.5.14

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# GNU Enterprise Common Library - i18n support
 
2
#
 
3
# This file is part of GNU Enterprise.
 
4
#
 
5
# GNU Enterprise is free software; you can redistribute it
 
6
# and/or modify it under the terms of the GNU General Public
 
7
# License as published by the Free Software Foundation; either
 
8
# version 2, or (at your option) any later version.
 
9
#
 
10
# GNU Enterprise is distributed in the hope that it will be
 
11
# useful, but WITHOUT ANY WARRANTY; without even the implied
 
12
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 
13
# PURPOSE. See the GNU General Public License for more details.
 
14
#
 
15
# You should have received a copy of the GNU General Public
 
16
# License along with program; see the file COPYING. If not,
 
17
# write to the Free Software Foundation, Inc., 59 Temple Place
 
18
# - Suite 330, Boston, MA 02111-1307, USA.
 
19
#
 
20
# Copyright 2001-2005 Free Software Foundation
 
21
#
 
22
# $Id: i18n.py 6976 2005-02-08 12:54:14Z reinhard $
 
23
"""
 
24
Internationalization support
 
25
"""
 
26
from types import *
 
27
 
 
28
import exceptions
 
29
import gettext
 
30
import locale
 
31
import os.path
 
32
import string
 
33
import sys
 
34
 
 
35
from gnue import paths
 
36
 
 
37
# -----------------------------------------------------------------------------
 
38
# Global variables
 
39
# -----------------------------------------------------------------------------
 
40
 
 
41
__modules = {}                          # Modules by filename
 
42
__catalogs = {}                         # Message catalogs by domain
 
43
__userlanguage = None
 
44
 
 
45
language = None
 
46
encoding = None
 
47
enc_policy = "replace"                  # policy to use if an unicode character
 
48
 
 
49
 
 
50
# -----------------------------------------------------------------------------
 
51
# Find a module from filename
 
52
# -----------------------------------------------------------------------------
 
53
 
 
54
def __find_module (filename):
 
55
  if __modules.has_key (filename):
 
56
    return __modules [filename]
 
57
  for mod in sys.modules.values ():
 
58
    if hasattr (mod, '__file__'):
 
59
      # mod.__file__ can be .pyc if the module is already compiled
 
60
      f = mod.__file__
 
61
      if f [-1:] == 'c':
 
62
        f = f [:-1]
 
63
      if os.path.normcase (f) == os.path.normcase (filename):
 
64
        __modules [filename] = mod
 
65
        return mod
 
66
 
 
67
# -----------------------------------------------------------------------------
 
68
# Find the correct translation catalog
 
69
# -----------------------------------------------------------------------------
 
70
 
 
71
def __find_catalog ():
 
72
 
 
73
  # find out the filename of the calling function
 
74
  caller_file = (sys._getframe (2)).f_code.co_filename
 
75
 
 
76
  # find out the module name
 
77
  caller_module = __find_module (caller_file)
 
78
 
 
79
  if caller_module is None:
 
80
    return None
 
81
 
 
82
  # make 'gnue-common' from 'gnue.common.foo.bar'
 
83
  x = string.replace (caller_module.__name__, '.', '-', 1)
 
84
  i = string.find (x, '.')
 
85
  domain = x [:i]
 
86
 
 
87
  if __catalogs.has_key (domain):
 
88
    return __catalogs [domain]
 
89
  else:
 
90
    try:
 
91
      if os.name == 'posix':
 
92
        catalog = gettext.translation (domain, paths.data + '/share/locale')
 
93
      else:
 
94
        catalog = gettext.translation (domain, paths.data + '/share/locale',
 
95
                                       [language])
 
96
    except:
 
97
      catalog = None
 
98
 
 
99
    __catalogs [domain] = catalog
 
100
 
 
101
    return catalog
 
102
 
 
103
# -----------------------------------------------------------------------------
 
104
# Translate a message and return unicode
 
105
# -----------------------------------------------------------------------------
 
106
 
 
107
def utranslate (message):
 
108
  """
 
109
  Translates a message and returns a unicode string.  This function is
 
110
  available as the builtin function "u_()".
 
111
  """
 
112
  catalog = __find_catalog ()
 
113
 
 
114
  if catalog is None:
 
115
    return message
 
116
 
 
117
  return catalog.ugettext (message)
 
118
 
 
119
# -----------------------------------------------------------------------------
 
120
# Translate a message and return local encoding
 
121
# -----------------------------------------------------------------------------
 
122
 
 
123
def translate (message):
 
124
  """
 
125
  Translates a message and returns an 8 bit string, encoded with @encoding (the
 
126
  current locale's encoding).  This function is available as the builtin
 
127
  function "_()".
 
128
  """
 
129
  catalog = __find_catalog ()
 
130
 
 
131
  if catalog is None:
 
132
    return message
 
133
 
 
134
  return (catalog.ugettext (message)).encode (encoding, enc_policy)
 
135
 
 
136
# -----------------------------------------------------------------------------
 
137
# Convert Unicode to String, let everything else untouched. This is o().
 
138
# -----------------------------------------------------------------------------
 
139
 
 
140
def outconv (message):
 
141
  """
 
142
  Encodes a message to @encoding (the current locale's encoding).  This
 
143
  function is available as the builtin function "o()".
 
144
  """
 
145
  if isinstance (message, UnicodeType):
 
146
    return message.encode (encoding, enc_policy)
 
147
  else:
 
148
    return message
 
149
 
 
150
 
 
151
# -----------------------------------------------------------------------------
 
152
# Get the current encoding
 
153
# -----------------------------------------------------------------------------
 
154
 
 
155
def getencoding ():
 
156
  """
 
157
  This function returns the encoding of the currently active locale
 
158
  @returns: encoding of the current locale
 
159
  """
 
160
  # For Windows, getlocale () is broken - it returns e.g. ('Hungarian_Hungary',
 
161
  # '1250') instead of ('hu_HU', 'cp1250'). So we have to use getdefaultlocale.
 
162
  # However, this means that under Windows, no locales but the default locale
 
163
  # can be used.
 
164
  if sys.platform == 'win32':
 
165
    return locale.getdefaultlocale () [1] or 'ascii'
 
166
  else:
 
167
    return locale.getlocale () [1] or 'ascii'
 
168
 
 
169
 
 
170
# -----------------------------------------------------------------------------
 
171
# Get the current language
 
172
# -----------------------------------------------------------------------------
 
173
 
 
174
def getlanguage ():
 
175
  """
 
176
  This function return the language of the currently acitve locale
 
177
  @returns: language of the current locale
 
178
  """
 
179
  return __userlanguage or 'C'
 
180
 
 
181
 
 
182
# ---------------------------------------------------------------------------
 
183
# Get the locale string of the current user
 
184
# ---------------------------------------------------------------------------
 
185
 
 
186
def getuserlocale ():
 
187
  """
 
188
  This function tries to find out which locale the user is using.
 
189
  @returns: localestring of the user's locale, i.e. de_AT@euro
 
190
  """
 
191
 
 
192
  # *Actually* the following is very much what locale.getdefaultlocale should
 
193
  # do anyway.  However, that function is broken for $LANGUAGE containing a
 
194
  # list of locales, separated with ":". So we have to manually rebuild it...
 
195
  items = ['LANGUAGE', 'LC_ALL', 'LC_MESSAGES', 'LANG']
 
196
  for key in items:
 
197
    if os.environ.has_key (key):
 
198
      # Some systems (most notably Debian...) set $LANGUAGE to a *list* of
 
199
      # locales, separated by a ":".
 
200
      envLang = (os.environ [key]).split (':') [0]
 
201
      return locale.locale_alias.get (envLang, envLang)
 
202
 
 
203
  # Now this should only happen on Windows, where getdefaultlocale seems to
 
204
  # work ok.
 
205
  try:
 
206
    result = locale.getdefaultlocale () [0]
 
207
  except locale.Error:
 
208
    result = ''
 
209
 
 
210
  return result
 
211
 
 
212
 
 
213
# ---------------------------------------------------------------------------
 
214
# Change the current locale
 
215
# ---------------------------------------------------------------------------
 
216
 
 
217
def setcurrentlocale (newLocale):
 
218
  """
 
219
  This function changes the current locale. If it fails it tries to succeed
 
220
  using a more general form of the requested locale, i.e. if 'de_AT@euro'
 
221
  fails, 'de_AT' will be tried next. If that fails too 'de' will be tried.
 
222
  @param newLocale: string of the locale to be set, e.g. de_AT.ISO88591@euro
 
223
      (full blown) or 'de_AT' or 'en_AU'
 
224
  """
 
225
  if newLocale is None:
 
226
    newLocale = ''
 
227
 
 
228
  parts  = []
 
229
  add    = []
 
230
  normal = locale.normalize (newLocale)
 
231
  next   = normal.split ('@') [0]
 
232
  __userlanguage = next.split ('.') [0]
 
233
 
 
234
  # Setting a locale different than the current locale doesn't work on Windows.
 
235
  if sys.platform == 'win32':
 
236
    return
 
237
 
 
238
  alias  = locale.locale_alias.get (__userlanguage.split ('_') [0].lower ())
 
239
  if alias:
 
240
    add = [alias.split ('@') [0]]
 
241
    add.append (add [-1].split ('.') [0])
 
242
    add.append (locale.locale_alias.get (add [-1].split ('_') [0].lower ()))
 
243
 
 
244
  for item in [normal, next, __userlanguage] + add:
 
245
    if item is not None and item not in parts:
 
246
      parts.append (item)
 
247
 
 
248
  for item in parts:
 
249
    try:
 
250
      locale.setlocale (locale.LC_ALL, item)
 
251
 
 
252
    except locale.Error:
 
253
      pass
 
254
 
 
255
    else:
 
256
      break
 
257
 
 
258
 
 
259
# -----------------------------------------------------------------------------
 
260
# Module initialization
 
261
# -----------------------------------------------------------------------------
 
262
 
 
263
# Initialize locale. This has been reported to fail on Mac.
 
264
try:
 
265
  locale.setlocale (locale.LC_ALL, '')
 
266
except:
 
267
  pass
 
268
 
 
269
# On win32, getlocale is broken - it returns Hungarian_Hungary instead of
 
270
# hu_HU. On the other hand, getdefaultlocale is broken when $LANGUAGE contains
 
271
# a ":" separated list of locales, like it does for Debian...
 
272
if sys.platform == 'win32':
 
273
  (language, encoding) = locale.getdefaultlocale ()
 
274
else:
 
275
  (language, encoding) = locale.getlocale ()
 
276
 
 
277
# Make sure encoding is not None
 
278
if not encoding:
 
279
  encoding = 'ascii'
 
280
 
 
281
# Now define the new builtin stuff
 
282
import __builtin__
 
283
__builtin__.__dict__['u_'] = utranslate
 
284
__builtin__.__dict__['_'] = translate
 
285
__builtin__.__dict__['o'] = outconv