Ticket #1086: dLocalize.4.py

File dLocalize.4.py, 5.1 kB (added by shawkat@samdu.uz, 1 year ago)
Line 
1 # -*- coding: utf-8 -*-
2 import gettext
3 import locale
4 import os
5 import dabo
6
7 __app_initialized = False
8 __app_has_locale = False
9 __dabo_trans = None
10 __app_trans = None
11 _localedir = "locale"
12 _frozenlocaledir = "dabo.locale"
13
14 """
15     Beware: if you are using 8-bit (non-Unicode) locales, you could encounter errors like
16     "UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-7: ordinal not in range(128)"
17     Such error could appear, for example, when comparing non-Unicode string with Unicode string,
18     or when printing Unicode string on non-Unicode console. 
19     
20     Unfortunately, this is a Python specifics, not a Dabo framework error.
21     This is because Python by default use only 7-bit ascii <-> Unicode conversion.
22     e.g. look at http://mail.python.org/pipermail/python-list/2007-March/433232.html
23     
24     Suggested solutions are:
25     1) Use unicode locale
26     2) Modify the site.py, so that locale-aware encoding will be set up (site-wide effect)
27     3) Insert following code at the top of app, does the same thing as above (inspired by site.py)
28
29         import sys
30         import locale
31         reload(sys)
32         sys.setdefaultencoding(locale.getdefaultlocale()[1])
33         
34 """
35 #TODO:  Maybe, this code should go to the beginning of this file ??? then everything will be ok
36
37 def _(s):
38     """ Use it to get translated strings.   
39     Localization files of app should be in under its locale directory.
40     Localization files of dabo framework should be under dabo's locale directory.
41     """
42    
43     global defLang, __app_initialized, __app_has_locale
44    
45     if not __app_initialized:
46         try:
47             app = dabo.dAppRef
48         except AttributeError:
49             app = None
50            
51         if app:
52             __app_initialized = True
53            
54             appShortName = app.getAppInfo("appShortName").lower()
55             # if not changed in user app, defaults to "daboapplication"
56             localedir = os.path.join(app.HomeDirectory, _localedir)
57
58             if gettext.find(appShortName, localedir, [defLang,"en"], all = True):
59                 # application really has some localization file, "en" at least 
60
61                 __app_has_locale = True
62                 setLanguage(domain = appShortName, localedir = localedir)
63                 __app_trans.add_fallback(__dabo_trans)
64                 # application's localization is inplace now, dabo's localization is a fallback
65             else:
66                 # app doesn't appear to have a locale directory set up.
67                 pass
68
69     # as it looks like the default is to use Unicode, then we return Unicode strings
70     if __app_initialized and __app_has_locale:
71         return __app_trans.ugettext(s)
72     else:
73         # application's localization is not ready for now, use only dabo's localization
74         return __dabo_trans.ugettext(s)
75
76 def n_(s):
77     """ Use it if you want to tell translation service about string
78     but don't want to translate it inplace.
79     """
80     return s
81     #TODO: wouldn't it be better, if we will use something like _("string",False) in _ function ???
82     # i.e. one more argument for _function, telling by default to translate strings ?
83     # def _(s, translate=True):
84     #  pkm: Agree. Actually, can someone give an example of when you'd even want this?
85     #      Do we use it even?
86
87 def setLanguage(lang=None, charset=None, domain="dabo", localedir=None):
88     """Use it if you want to switch to another localizations than your default.
89     You should call it twice - once for dabo framework, and once for app.
90     """
91     global defLang, defCharset, __dabo_trans, __app_trans
92    
93     #TODO: we should search system localizations directory as well
94
95     if localedir is None:
96         localedir = os.path.join(os.path.split(dabo.__file__)[0], _localedir)
97         if not os.path.exists(localedir):
98             localedir = os.path.join(os.getcwd(), _frozenlocaledir)
99
100     if charset is None:
101         charset = defCharset
102
103     if lang is None:
104         lang = defLang
105     else:
106         lang = lang.lower()
107         # It might be the full name instead of the two-letter abbreviation
108         if lang not in getLanguages():
109             try:
110                 lang = {"english": "en",
111                         "spanish": "es", "espanol": "es", "español": "es",
112                         "french": "fr", "francais": "fr", "français": "fr",
113                         "german": "de", "deutsch": "de",
114                         "italian": "it", "italiano": "it",
115                         "portuguese": "pt", "portuguése": "pt",
116                         "russian": "ru"}[lang]
117             except KeyError:
118                 pass
119        
120     dabolocalefile = gettext.find(domain, localedir, languages=[lang], all=True)
121     print dabolocalefile
122
123     if not dabolocalefile:
124         print "Gettext file for language %s was not found , falling back to english" % lang
125
126         dabolocalefile = gettext.find(domain, localedir, languages = ['en'], all=True)
127    
128         if not dabolocalefile:
129             raise IOError, "Neither english nor '%s' language was found " % lang
130    
131         defLang = "en"
132         defCharset = "UTF-8"
133
134     if domain == "dabo":
135         __dabo_trans = gettext.translation(domain, localedir, languages=[lang], codeset=charset)
136         defLang = lang
137     else:
138         __app_trans = gettext.translation(domain, localedir, languages=[lang], codeset=charset)
139        
140 defLang, defCharset = locale.getdefaultlocale()
141
142 if defLang is None:
143     defLang = "en"
144 else:
145     defLang = defLang[:2]
146 if defCharset is None:
147     defCharset = "UTF-8"
148    
149 setLanguage()
150
151 if __name__ == "__main__":
152     # this code is important for every non-unicode locale 
153     import sys
154     import locale
155     reload(sys)
156     sys.setdefaultencoding(locale.getdefaultlocale()[1])
157    
158     print 'user locale is ', locale.getdefaultlocale()
159     print 'framework locale is ', defLang, defCharset
160     print _("Framework localization test")