Changeset 3286

Show
Ignore:
Timestamp:
07/27/07 14:37:22 (1 year ago)
Author:
paul
Message:

I refactored, added docstrings, and tested a new dLocalize.py, which tries to combine work done by
Ed, Nizamov Shawcat, and myself. I still need to test with frozen apps, but it seems to be
working fine.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/dabo/dLocalize.py

    r3278 r3286  
    1 # -*- coding: utf-8 -*- 
     1# -*- coding: utf-8 -*- 
     2 
     3# First thing is to try to make sure the default charset is unicode, not ascii: 
     4import sys 
     5import locale 
     6 
     7reload(sys) 
     8sys.setdefaultencoding(locale.getdefaultlocale()[1]) 
     9 
     10import os 
    211import gettext 
    3 import locale 
    4 import os 
    5 import re 
    612import dabo 
    713 
     14__app_initialized = False 
     15__app_has_locale = False 
     16__dabo_trans = None 
     17__app_trans = None 
     18_localedir = "locale" 
     19_frozenlocaledir = "dabo.locale" 
    820 
    9 def getLanguages(): 
    10     # Probably need to add more 
    11     langs = gettext.find("dabo", daboLocaleDir, languages=_trans.keys(), all=True) 
    12     sep = os.path.sep 
     21language_aliases = {"english": "en", 
     22        "spanish": "es", "espanol": "es", "español": "es", 
     23        "french": "fr", "francais": "fr", "français": "fr",  
     24        "german": "de", "deutsch": "de", 
     25        "italian": "it", "italiano": "it",  
     26        "portuguese": "pt", "portuguése": "pt", 
     27        "russian": "ru"} 
     28 
     29def _(s): 
     30    """Translate the passed string into the current language, if possible.    
     31 
     32    Dabo provides translations of common strings into several languages. If a  
     33    translation is found for the passed string, it will be returned. Otherwise, 
     34    the identical string will be returned. 
     35 
     36    In addition, user applications can define their own translations, in which 
     37    case we'll first look for translations in the application's locale directory, 
     38    and then fall back on Dabo's translations. 
     39  
     40    Localization files of app should be in under its locale directory, with the .mo 
     41    file's named after the application's short name. The default application name 
     42    is "daboapplication", so by default the app's .mo files should be named 
     43    "daboapplication.mo".  
     44    """ 
     45    global defLang, __app_initialized, __app_has_locale 
    1346     
    14     ret = [] 
    15     for lang in langs: 
    16         pathparts = lang.split(sep) 
     47    if not __app_initialized: 
    1748        try: 
    18             pos = pathparts.index("locale") 
    19         except ValueError: 
    20             # frozen App? 
    21             pos = pathparts.index("dabo.locale") 
    22         ret.append(pathparts[pos+1]) 
    23     return ret 
     49            app = dabo.dAppRef 
     50        except AttributeError: 
     51            app = None 
     52             
     53        if app: 
     54            __app_initialized = True 
     55            # If appShortName not changed in user app, defaults to "daboapplication" 
     56            __app_has_locale = setLanguage(domain=app.getAppInfo("appShortName").lower(), 
     57                    localedir=os.path.join(app.HomeDirectory, _localedir)) 
    2458 
    2559 
    26 def setLanguage(lang=None, charset=None): 
    27     global defLang, defCharset, _trans 
    28     if charset is None: 
    29         charset = defCharset 
    30     if lang is None: 
    31         lang = defLang 
     60    # Always return Unicode strings 
     61    if __app_initialized and __app_has_locale: 
     62        # Use app's localization, with Dabo's as a fallback: 
     63        return __app_trans.ugettext(s) 
    3264    else: 
    33         lang = lang.lower() 
    34         # It might be the full name instead of the two-letter abbreviation 
    35         if lang not in getLanguages(): 
    36             try: 
    37                 lang = {"english": "en",  
    38                         "spanish": "es", "espanol": "es", "español": "es", 
    39                         "french": "fr", "francais": "fr", "français": "fr",  
    40                         "german": "de", "deutsch": "de",  
    41                         "italian": "it", "italiano": "it",  
    42                         "portuguese": "pt", "portuguése": "pt", 
    43                         "russian": "ru"}[lang] 
    44             except KeyError: 
    45                 pass 
    46     if not lang in getLanguages(): 
    47         raise IOError, "Invalid language '%s' (localeDir: %s)" % (lang, daboLocaleDir) 
    48      
    49     if _trans.get(lang) is None: 
    50         _trans[lang] = gettext.translation("dabo", daboLocaleDir,  
    51                 languages=[lang], codeset=charset) 
    52     defLang = lang 
    53      
    54      
    55 def _(s): 
    56     global defLang, _trans 
    57     return _trans[defLang].gettext(s) 
    58      
     65        # App's localization is not in place; use only Dabo's: 
     66        return __dabo_trans.ugettext(s) 
    5967 
    6068def n_(s): 
     
    6270    but don't want to translate it inplace. 
    6371    """ 
    64     global defLang 
    65     return _trans[defLang].gettext(s) 
     72    return s 
     73    #TODO: wouldn't it be better, if we will use something like _("string",False) in _ function ???  
     74    # i.e. one more argument for _function, telling by default to translate strings ? 
     75    # def _(s, translate=True): 
     76    #  pkm: Agree. Actually, can someone give an example of when you'd even want this? 
     77    #      Do we use it even? 
    6678 
     79def setLanguage(lang=None, charset=None, domain="dabo", localedir=None): 
     80    """Use it if you want to switch to another localizations than your default. 
     81    You should call it twice - once for dabo framework, and once for app. 
     82    """ 
     83    global defLang, defCharset, __dabo_trans, __app_trans 
     84     
     85    #TODO: we should search system localizations directory as well 
    6786 
    68 daboLocaleDir = os.path.join(os.path.split(dabo.__file__)[0], "locale") 
    69 if not os.path.exists(daboLocaleDir): 
    70     # Frozen app? 
    71     # First need to find the directory that contains the .exe: 
    72     startupDir = daboLocaleDir 
    73     while startupDir: 
    74         startupDir = os.path.split(startupDir)[0] 
    75         if os.path.isdir(startupDir): 
    76             break 
    77     daboLocaleDir = os.path.join(startupDir, "dabo.locale") 
    78 #   raise ValueError, daboLocaleDir 
     87    if localedir is None: 
     88        localedir = os.path.join(os.path.split(dabo.__file__)[0], _localedir) 
     89        if not os.path.exists(localedir): 
     90            # Frozen app? 
     91            # First need to find the directory that contains the .exe: 
     92            startupDir = localeDir 
     93            while startupDir: 
     94                startupDir = os.path.split(startupDir)[0] 
     95                if os.path.isdir(startupDir): 
     96                    break 
     97            if domain == "dabo": 
     98                frozenLocaleDir = _frozenlocaledir 
     99            else: 
     100                frozenLocaleDir = _localedir 
     101            localedir = os.path.join(startupDir, frozenLocaleDir) 
    79102 
    80 _trans = {"en": None, "fr": None, "es": None, "pt": None, "ru": None, "de": None, "it": None} 
    81 defLang, defCharset = locale.getlocale() 
     103    if charset is None: 
     104        charset = defCharset 
     105 
     106    if lang is None: 
     107        lang = defLang 
     108    else: 
     109        lang = lang.lower() 
     110        # It might be the full name instead of the two-letter abbreviation: 
     111        lang = language_aliases.get(lang, lang) 
     112         
     113    localefile = gettext.find(domain, localedir, languages=[lang], all=True) 
     114 
     115    if domain == "dabo": 
     116        if not localefile: 
     117            raise IOError, "No translation files found for Dabo. Looked in %s." % localedir 
     118        __dabo_trans = gettext.translation(domain, localedir, languages=[lang], codeset=charset) 
     119        defLang = lang 
     120    else: 
     121        if localefile: 
     122            __app_trans = gettext.translation(domain, localedir, languages=[lang], codeset=charset) 
     123            if __app_trans: 
     124                __app_trans.add_fallback(__dabo_trans) 
     125            return bool(__app_trans) 
     126        return False 
     127         
     128 
     129defLang, defCharset = locale.getdefaultlocale() 
     130 
    82131if defLang is None: 
    83132    defLang = "en" 
     
    85134    defLang = defLang[:2] 
    86135if defCharset is None: 
    87     defCharset = "ISO8859-1" 
    88 setLanguage() 
     136    defCharset = "UTF-8" 
     137 
     138setLanguage(domain="dabo") 
     139 
     140if __name__ == "__main__": 
     141    # this code is important for every non-unicode locale   
     142    import sys 
     143    import locale 
     144    reload(sys) 
     145    sys.setdefaultencoding(locale.getdefaultlocale()[1]) 
     146     
     147    print 'user locale is ', locale.getdefaultlocale() 
     148    print 'framework locale is ', defLang, defCharset 
     149    print _("Framework localization test")