Author: johannes Date: 2007-11-14 02:46:21 -0600 (Wed, 14 Nov 2007) New Revision: 9800
Added: trunk/gnue-common/src/base/i18n.py Modified: trunk/gnue-common/src/apps/errors.py trunk/gnue-common/src/apps/i18n.py Log: Moved i18n from apps into base Modified: trunk/gnue-common/src/apps/errors.py =================================================================== --- trunk/gnue-common/src/apps/errors.py 2007-11-13 14:15:52 UTC (rev 9799) +++ trunk/gnue-common/src/apps/errors.py 2007-11-14 08:46:21 UTC (rev 9800) @@ -31,7 +31,7 @@ import string import exceptions -from gnue.common.apps import i18n +from gnue.common.base import i18n # ============================================================================= # New basic exception class. Python's standard exception class cannot handle @@ -108,7 +108,7 @@ @rtype: Unicode """ if self.detail is not None: - return self._fmtUnicode (self.detail, i18n.getencoding ()) + return self._fmtUnicode (self.detail, i18n.get_encoding ()) if sys.exc_info () == (None, None, None): tStack = traceback.format_exception (type, value, trace) @@ -116,7 +116,7 @@ tStack = traceback.format_exception (*sys.exc_info ()) if count is not None: del tStack [1:count + 1] - return self._fmtUnicode ("%s" % string.join (tStack), i18n.getencoding ()) + return self._fmtUnicode ("%s" % string.join (tStack), i18n.get_encoding ()) # --------------------------------------------------------------------------- @@ -261,10 +261,10 @@ if count is not None: del lines [1:count + 1] - name = unicode ("%s" % aType, i18n.getencoding (), 'replace') + name = unicode ("%s" % aType, i18n.get_encoding (), 'replace') name = name.split ('.') [-1] - message = unicode ("%s" % aValue, i18n.getencoding (), 'replace') + message = unicode ("%s" % aValue, i18n.get_encoding (), 'replace') detail = string.join (lines) if isinstance (detail, types.StringType): - detail = unicode (detail, i18n.getencoding (), 'replace') + detail = unicode (detail, i18n.get_encoding (), 'replace') return ('system', name, message, detail) Modified: trunk/gnue-common/src/apps/i18n.py =================================================================== --- trunk/gnue-common/src/apps/i18n.py 2007-11-13 14:15:52 UTC (rev 9799) +++ trunk/gnue-common/src/apps/i18n.py 2007-11-14 08:46:21 UTC (rev 9800) @@ -24,128 +24,70 @@ """ Internationalization support. +This module is *DEPRECATED*. Please use gnue.common.base.i18n instead + @var language: Language of the current locale @var encoding: Encoding of the current locale """ -import gettext -import locale -import os -import os.path -import sys +from gnue.common.base import i18n +from gnue.common.base import log -from gnue import paths - __all__ = ['language', 'encoding', 'outconv', 'utranslate', 'translate', 'getlanguage', 'getencoding', 'getuserlocale', 'setcurrentlocale'] - # ----------------------------------------------------------------------------- # Global variables # ----------------------------------------------------------------------------- -__modules = {} # Modules by filename -__catalogs = {} # Message catalogs by domain:language +language = i18n.language +encoding = i18n.encoding -language = None -encoding = None - # ----------------------------------------------------------------------------- # Convert Unicode to String, let everything else untouched. This is o(). # ----------------------------------------------------------------------------- def outconv(message): """ + This module is *DEPRECATED*. Please use gnue.common.base.i18n instead. + Encodes a message to L{encoding} (the current locale's encoding). This function is available as the builtin function "o()". """ - if isinstance(message, unicode): - return message.encode(encoding, 'replace') - else: - return message + log.deprecated('Please use gnue.common.base.i18n instead') + return i18n.outconv(message) # ----------------------------------------------------------------------------- -# Find a module from filename -# ----------------------------------------------------------------------------- - -def __find_module(filename): - if __modules.has_key(filename): - return __modules[filename] - for mod in sys.modules.values(): - if hasattr(mod, '__file__'): - # mod.__file__ can be .pyc if the module is already compiled - mod_filename = mod.__file__ - if mod_filename.endswith('c'): - mod_filename = mod_filename[:-1] - if os.path.normcase(mod_filename) == os.path.normcase(filename): - __modules[filename] = mod - return mod - - -# ----------------------------------------------------------------------------- -# Find the correct translation catalog -# ----------------------------------------------------------------------------- - -def __find_catalog(): - - # find out the filename of the calling function - caller_file = (sys._getframe(2)).f_code.co_filename - - # find out the module name - caller_module = __find_module(caller_file) - - if caller_module is None: - return None - - # make 'gnue-common' from 'gnue.common.foo.bar' - module_name = caller_module.__name__.replace('.', '-', 1) - i = module_name.find('.') - domain = module_name[:i] - - if __catalogs.has_key(domain + ':' + language): - return __catalogs[domain + ':' + language] - else: - try: - catalog = gettext.translation(domain, paths.data + '/share/locale', - [language]) - except: - catalog = None - - __catalogs[domain + ':' + language] = catalog - - return catalog - - -# ----------------------------------------------------------------------------- # Translate a message and return unicode # ----------------------------------------------------------------------------- def utranslate(message): """ + This module is *DEPRECATED*. Please use gnue.common.base.i18n instead. + Translates a message and returns a unicode string. This function is available as the builtin function "u_()". """ - catalog = __find_catalog() + log.deprecated('Please use gnue.common.base.i18n instead') + return i18n.utranslate(message) - if catalog is None: - return message - return catalog.ugettext(message) - - # ----------------------------------------------------------------------------- # Translate a message and return local encoding # ----------------------------------------------------------------------------- def translate(message): """ + This module is *DEPRECATED*. Please use gnue.common.base.i18n instead. + Translates a message and returns an 8 bit string, encoded with L{encoding} (the current locale's encoding). This function is available as the builtin function "_()". """ - return outconv(utranslate(message)) + log.deprecated('Please use gnue.common.base.i18n instead') + return i18n.translate(message) # ----------------------------------------------------------------------------- @@ -154,12 +96,15 @@ def getlanguage(): """ + This module is *DEPRECATED*. Please use gnue.common.base.i18n instead. + Returns the language of the currently acitve locale. This can be changed with L{setcurrentlocale}. @return: language of the current locale. """ - return language + log.deprecated('Please use gnue.common.base.i18n instead') + return i18n.get_language() # ----------------------------------------------------------------------------- @@ -168,12 +113,15 @@ def getencoding(): """ + This module is *DEPRECATED*. Please use gnue.common.base.i18n instead. + Returns the encoding of the currently active locale. This can be changed with L{setcurrentlocale}. @return: encoding of the current locale. """ - return encoding + log.deprecated('Please use gnue.common.base.i18n instead') + return i18n.get_encoding() # ----------------------------------------------------------------------------- @@ -182,61 +130,25 @@ def getuserlocale(): """ + This module is *DEPRECATED*. Please use gnue.common.base.i18n instead. + Try to find out which locale the user is using. This is always the locale of the user running the program and is not touched by setcurrentlocale. @return: localestring of the user's locale, i.e. [EMAIL PROTECTED] """ + log.deprecated('Please use gnue.common.base.i18n instead') + return i18n.get_user_locale() - # *Actually* the following is very much what locale.getdefaultlocale should - # do anyway. However, that function is broken for $LANGUAGE containing a - # list of locales, separated with ":". So we have to manually rebuild it... - items = ['LANGUAGE', 'LC_ALL', 'LC_MESSAGES', 'LANG'] - for key in items: - if os.environ.has_key(key): - # Some systems (most notably Debian...) set $LANGUAGE to a *list* - # of locales, separated by a ":". - env_lang = (os.environ[key]).split(':')[0] - return locale.locale_alias.get(env_lang, env_lang) - # Now this should only happen on Windows, where getdefaultlocale seems to - # work ok. - try: - result = locale.getdefaultlocale()[0] - except locale.Error: - result = '' - - return result or 'C' - - # ----------------------------------------------------------------------------- -# Update global variables -# ----------------------------------------------------------------------------- - -def __updateglobals(): - - global language, encoding - - # On win32, getlocale is broken - it returns strings like Hungarian_Hungary - # instead of hu_HU. - if sys.platform in ['win32', 'Pocket PC']: - (language, encoding) = locale.getdefaultlocale() - else: - (language, encoding) = locale.getlocale() - - # Make sure language and encoding are not None - if not language: - language = 'C' - if not encoding: - encoding = 'ascii' - - -# ----------------------------------------------------------------------------- # Change the current locale # ----------------------------------------------------------------------------- def setcurrentlocale(new_locale): """ + This module is *DEPRECATED*. Please use gnue.common.base.i18n instead. + Set the current locale. If it fails it tries to succeed using a more general form of the requested @@ -246,67 +158,5 @@ @param new_locale: string of the locale to be set, e.g. [EMAIL PROTECTED] (full blown) or 'de_AT' or 'en_AU' """ - # Setting a locale different than the current locale doesn't work on - # Windows. - if sys.platform == 'win32': - return - - if new_locale is None: - new_locale = '' - - new_locale = new_locale.encode() - - parts = [] - add = [] - normal = locale.normalize(new_locale) # [EMAIL PROTECTED] - next = normal.split('@')[0] # lc_CC.ENCODING - lang = next.split('.')[0] # lc_CC - - alias = locale.locale_alias.get(lang.split('_')[0].lower()) - if alias: - add = [alias.split('@')[0]] - add.append(add[-1].split('.')[0]) - add.append(locale.locale_alias.get(add[-1].split('_')[0].lower())) - - for item in [normal, next, lang] + add: - if item is not None and item not in parts: - parts.append(item) - - for item in parts: - try: - locale.setlocale(locale.LC_ALL, item) - - except locale.Error: - pass - - else: - break - - __updateglobals() - - -# ----------------------------------------------------------------------------- -# Module initialization -# ----------------------------------------------------------------------------- - -# Initialize locale. On Mac locale.setlocale() does not return the default -# locale. Instead we have to query the system preferences for the AppleLocale -if sys.platform == 'darwin': - pipe = os.popen('defaults read -g AppleLocale') - deflc = pipe.read().strip() + '.UTF-8' - pipe.close() -else: - deflc = '' - -try: - locale.setlocale(locale.LC_ALL, deflc) -except: - pass - -__updateglobals() - -# Now define the new builtin stuff -import __builtin__ -__builtin__.__dict__['o'] = outconv -__builtin__.__dict__['u_'] = utranslate -__builtin__.__dict__['_'] = translate + log.deprecated('Please use gnue.common.base.i18n instead') + return i18n.set_current_locale(new_locale) Added: trunk/gnue-common/src/base/i18n.py =================================================================== --- trunk/gnue-common/src/base/i18n.py 2007-11-13 14:15:52 UTC (rev 9799) +++ trunk/gnue-common/src/base/i18n.py 2007-11-14 08:46:21 UTC (rev 9800) @@ -0,0 +1,322 @@ +# GNU Enterprise Common Library - i18n support +# +# This file is part of GNU Enterprise. +# +# GNU Enterprise is free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public +# License as published by the Free Software Foundation; either +# version 2, or (at your option) any later version. +# +# GNU Enterprise is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +# PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with program; see the file COPYING. If not, +# write to the Free Software Foundation, Inc., 59 Temple Place +# - Suite 330, Boston, MA 02111-1307, USA. +# +# Copyright 2001-2007 Free Software Foundation +# +# $Id: i18n.py 9799 2007-11-13 14:15:52Z johannes $ + +""" +Internationalization support. + [EMAIL PROTECTED] language: Language of the current locale [EMAIL PROTECTED] encoding: Encoding of the current locale +""" + +import gettext +import locale +import os +import os.path +import sys + +from gnue import paths + +__all__ = ['language', 'encoding', 'outconv', 'utranslate', 'translate', + 'get_language', 'get_encoding', 'get_user_locale', + 'set_current_locale'] + + +# ----------------------------------------------------------------------------- +# Global variables +# ----------------------------------------------------------------------------- + +__modules = {} # Modules by filename +__catalogs = {} # Message catalogs by domain:language + +language = None +encoding = None + + +# ----------------------------------------------------------------------------- +# Convert Unicode to String, let everything else untouched. This is o(). +# ----------------------------------------------------------------------------- + +def outconv(message): + """ + Encodes a message to L{encoding} (the current locale's encoding). This + function is available as the builtin function "o()". + """ + if isinstance(message, unicode): + return message.encode(encoding, 'replace') + else: + return message + + +# ----------------------------------------------------------------------------- +# Find a module from filename +# ----------------------------------------------------------------------------- + +def __find_module(filename): + if __modules.has_key(filename): + return __modules[filename] + for mod in sys.modules.values(): + if hasattr(mod, '__file__'): + # mod.__file__ can be .pyc if the module is already compiled + mod_filename = mod.__file__ + if mod_filename.endswith('c'): + mod_filename = mod_filename[:-1] + if os.path.normcase(mod_filename) == os.path.normcase(filename): + __modules[filename] = mod + return mod + + +# ----------------------------------------------------------------------------- +# Find the correct translation catalog +# ----------------------------------------------------------------------------- + +def __find_catalog(): + + # find out the filename of the calling function + caller_file = (sys._getframe(2)).f_code.co_filename + + # find out the module name + caller_module = __find_module(caller_file) + + if caller_module is None: + return None + + # make 'gnue-common' from 'gnue.common.foo.bar' + module_name = caller_module.__name__.replace('.', '-', 1) + i = module_name.find('.') + domain = module_name[:i] + + if __catalogs.has_key(domain + ':' + language): + return __catalogs[domain + ':' + language] + else: + try: + catalog = gettext.translation(domain, paths.data + '/share/locale', + [language]) + except: + catalog = None + + __catalogs[domain + ':' + language] = catalog + + return catalog + + +# ----------------------------------------------------------------------------- +# Translate a message and return unicode +# ----------------------------------------------------------------------------- + +def utranslate(message): + """ + Translates a message and returns a unicode string. This function is + available as the builtin function "u_()". + """ + catalog = __find_catalog() + + if catalog is None: + return message + + return catalog.ugettext(message) + + +# ----------------------------------------------------------------------------- +# Translate a message and return local encoding +# ----------------------------------------------------------------------------- + +def translate(message): + """ + Translates a message and returns an 8 bit string, encoded with L{encoding} + (the current locale's encoding). This function is available as the builtin + function "_()". + """ + return outconv(utranslate(message)) + + +# ----------------------------------------------------------------------------- +# Get the current language +# ----------------------------------------------------------------------------- + +def get_language(): + """ + Returns the language of the currently active locale. This can be changed + with L{set_current_locale}. + + @return: language of the current locale. + """ + return language + + +# ----------------------------------------------------------------------------- +# Get the current encoding +# ----------------------------------------------------------------------------- + +def get_encoding(): + """ + Returns the encoding of the currently active locale. This can be changed + with L{set_current_locale}. + + @return: encoding of the current locale. + """ + return encoding + + +# ----------------------------------------------------------------------------- +# Get the locale string of the current user +# ----------------------------------------------------------------------------- + +def get_user_locale(): + """ + Try to find out which locale the user is using. This is always the locale + of the user running the program and is not touched by + L{set_current_locale}. + + @return: localestring of the user's locale, i.e. [EMAIL PROTECTED] + """ + + # *Actually* the following is very much what locale.getdefaultlocale should + # do anyway. However, that function is broken for $LANGUAGE containing a + # list of locales, separated with ":". So we have to manually rebuild it... + items = ['LANGUAGE', 'LC_ALL', 'LC_MESSAGES', 'LANG'] + for key in items: + if os.environ.has_key(key): + # Some systems (most notably Debian...) set $LANGUAGE to a *list* + # of locales, separated by a ":". + env_lang = (os.environ[key]).split(':')[0] + return locale.locale_alias.get(env_lang, env_lang) + + # On Mac OS X getdefaultlocale always returns 'C', so we will query the + # system preferences here. + if sys.platform == 'darwin': + pipe = os.popen('defaults read -g AppleLocale') + result = pipe.read().strip() + '.UTF-8' + pipe.close() + + else: + # Now this should only happen on Windows, where getdefaultlocale seems + # to work ok. + try: + result = locale.getdefaultlocale()[0] + except locale.Error: + result = '' + + return result or 'C' + + +# ----------------------------------------------------------------------------- +# Update global variables +# ----------------------------------------------------------------------------- + +def __updateglobals(): + + global language, encoding + + # On win32, getlocale is broken - it returns strings like Hungarian_Hungary + # instead of hu_HU. + if sys.platform in ['win32', 'Pocket PC']: + (language, encoding) = locale.getdefaultlocale() + else: + (language, encoding) = locale.getlocale() + + # Make sure language and encoding are not None + if not language: + language = 'C' + if not encoding: + encoding = 'ascii' + + +# ----------------------------------------------------------------------------- +# Change the current locale +# ----------------------------------------------------------------------------- + +def set_current_locale(new_locale): + """ + Set the current locale. + + If it fails it tries to succeed using a more general form of the requested + locale, i.e. if '[EMAIL PROTECTED]' fails, 'de_AT' will be tried next. If that + fails too, 'de' will be tried. + + @param new_locale: string of the locale to be set, e.g. [EMAIL PROTECTED] + (full blown) or 'de_AT' or 'en_AU' + """ + # Setting a locale different than the current locale doesn't work on + # Windows. + if sys.platform == 'win32': + return + + if new_locale is None: + new_locale = '' + + new_locale = new_locale.encode() + + parts = [] + add = [] + normal = locale.normalize(new_locale) # [EMAIL PROTECTED] + next = normal.split('@')[0] # lc_CC.ENCODING + lang = next.split('.')[0] # lc_CC + + alias = locale.locale_alias.get(lang.split('_')[0].lower()) + if alias: + add = [alias.split('@')[0]] + add.append(add[-1].split('.')[0]) + add.append(locale.locale_alias.get(add[-1].split('_')[0].lower())) + + for item in [normal, next, lang] + add: + if item is not None and item not in parts: + parts.append(item) + + for item in parts: + try: + locale.setlocale(locale.LC_ALL, item) + + except locale.Error: + pass + + else: + break + + __updateglobals() + + +# ----------------------------------------------------------------------------- +# Module initialization +# ----------------------------------------------------------------------------- + +# Initialize locale. On Mac locale.setlocale() does not return the default +# locale. Instead we have to query the system preferences for the AppleLocale +if sys.platform == 'darwin': + pipe = os.popen('defaults read -g AppleLocale') + deflc = pipe.read().strip() + '.UTF-8' + pipe.close() +else: + deflc = '' + +try: + locale.setlocale(locale.LC_ALL, deflc) +except: + pass + +__updateglobals() + +# Now define the new builtin stuff +import __builtin__ +__builtin__.__dict__['o'] = outconv +__builtin__.__dict__['u_'] = utranslate +__builtin__.__dict__['_'] = translate _______________________________________________ commit-gnue mailing list commit-gnue@gnu.org http://lists.gnu.org/mailman/listinfo/commit-gnue