Package turbogears :: Package i18n :: Module tg_gettext

Source Code for Module turbogears.i18n.tg_gettext

  1  import os 
  2  import sys 
  3  from gettext import translation 
  4   
  5  from turbogears import config 
  6  from turbogears.util import get_package_name, request_available 
  7  from turbogears.i18n.utils import get_locale 
  8  from turbojson.jsonify import jsonify 
  9   
 10  import logging 
 11  log = logging.getLogger("turbogears.i18n") 
 12   
 13  _catalogs = {} 
14 15 -def get_locale_dir():
16 localedir = config.get("i18n.locale_dir") 17 if not localedir: 18 package = get_package_name() 19 if package: 20 localedir = os.path.join(os.path.dirname( 21 sys.modules[package].__path__[0]), "locales") 22 return localedir
23
24 -def is_locale_supported(locale, domain=None):
25 """Check if [domain].mo file exists for this language.""" 26 if not domain: 27 domain = config.get("i18n.domain", "messages") 28 29 localedir = get_locale_dir() 30 return localedir and os.path.exists(os.path.join( 31 localedir, locale, "LC_MESSAGES", "%s.mo" % domain))
32
33 -def get_catalog(locale, domain = None):
34 """Return translations for given locale.""" 35 if not domain: 36 domain = config.get("i18n.domain", "messages") 37 38 catalog = _catalogs.get(domain) 39 40 if not catalog: 41 catalog = _catalogs[domain] = {} 42 43 messages = catalog.get(locale) 44 if not messages: 45 localedir = get_locale_dir() 46 messages = catalog[locale] = translation(domain=domain, 47 localedir=localedir, languages=[locale]) 48 49 return messages
50
51 -def plain_gettext(key, locale=None, domain=None):
52 """Get the gettext value for key. 53 54 Added to builtins as '_'. Returns Unicode string. 55 56 @param key: text to be translated 57 @param locale: locale code to be used. 58 If locale is None, gets the value provided by get_locale. 59 60 """ 61 gettext_func_name = config.get("i18n.gettext", "tg_gettext") 62 gettext_func = None 63 64 if gettext_func_name == "tg_gettext": 65 gettext_func = tg_gettext 66 67 elif gettext_func_name == "so_gettext": 68 try: 69 from turbogears.i18n.sogettext import so_gettext 70 gettext_func = so_gettext 71 72 except ImportError, e: 73 log.error("Could not load sogettext: %s" % e) 74 log.error("Translation disabled") 75 76 77 elif gettext_func_name == "sa_gettext": 78 try: 79 from turbogears.i18n.sagettext import sa_gettext 80 gettext_func = sa_gettext 81 82 except ImportError, e: 83 log.error("Could not load sagettext: %s" % e) 84 log.error("Translation disabled") 85 86 else: 87 log.error("Invalid i18n.gettext option: %s" % gettext_func_name) 88 log.error("Translation disabled") 89 90 if gettext_func is None: 91 # gettext function could not be loaded? Just avoid 92 # to translate and return original data 93 return key 94 95 else: 96 # gettext function loaded properly, use it :) 97 return gettext_func(key, locale, domain)
98
99 -def tg_gettext(key, locale=None, domain=None):
100 """Get the gettext value for key. 101 102 Added to builtins as '_'. Returns Unicode string. 103 104 @param key: text to be translated 105 @param locale: locale code to be used. 106 If locale is None, gets the value provided by get_locale. 107 108 """ 109 if locale is None: 110 locale = get_locale() 111 112 if not is_locale_supported(locale): 113 locale = locale[:2] 114 115 if key == '': 116 return '' # special case 117 118 try: 119 return get_catalog(locale, domain).ugettext(key) 120 121 except KeyError: 122 return key 123 124 except IOError: 125 return key
126
127 -def plain_ngettext(key1, key2, num, locale=None):
128 """Translate two possible texts based on whether num is greater than 1. 129 130 @param key1: text if num==1 131 @param key2: text if num!=1 132 @param num: a number 133 @type num: integer 134 @locale: locale code to be used. 135 If locale is None, gets the value provided by get_locale. 136 137 """ 138 if num==1: 139 return plain_gettext(key1, locale) 140 141 else: 142 return plain_gettext(key2, locale)
143
144 -class lazystring(object):
145 """Has a number of lazily evaluated functions replicating a string. 146 147 Just override the eval() method to produce the actual value. 148 149 """ 150
151 - def __init__(self, func, *args, **kw):
152 self.func = func 153 self.args = args 154 self.kw = kw
155
156 - def eval(self):
157 return self.func(*self.args, **self.kw)
158
159 - def __unicode__(self):
160 return unicode(self.eval())
161
162 - def __str__(self):
163 return str(self.eval())
164
165 - def __mod__(self, other):
166 return self.eval() % other
167
168 - def __cmp__(self, other):
169 return cmp(self.eval(), other)
170
171 - def __eq__(self, other):
172 return self.eval() == other
173
174 - def __deepcopy__(self, memo):
175 return self
176
177 -def lazify(func):
178 def newfunc(*args, **kw): 179 lazystr = lazystring(func, *args, **kw) 180 return lazystr
181 182 return newfunc 183
184 @jsonify.when("isinstance(obj, lazystring)") 185 -def jsonify_lazystring(obj):
186 return unicode(obj)
187 188 lazy_gettext = lazify(plain_gettext) 189 lazy_ngettext = lazify(plain_ngettext)
190 191 -def gettext(key, locale=None, domain=None):
192 """Get the gettext value for key. 193 194 Added to builtins as '_'. Returns Unicode string. 195 196 @param key: text to be translated 197 @param locale: locale code to be used. 198 If locale is None, gets the value provided by get_locale. 199 200 """ 201 if request_available(): 202 return plain_gettext(key, locale, domain) 203 204 else: 205 return lazy_gettext(key, locale, domain)
206
207 -def ngettext(key1, key2, num, locale=None):
208 """Translate two possible texts based on whether num is greater than 1. 209 210 @param key1: text if num==1 211 @param key2: text if num!=1 212 @param num: a number 213 @type num: integer 214 @param locale: locale code to be used. 215 If locale is None, gets the value provided by get_locale. 216 217 """ 218 if request_available(): 219 return plain_ngettext(key1, key2, num, locale) 220 else: 221 return lazy_ngettext(key1, key2, num, locale)
222
223 -def install():
224 """Add the gettext function to __builtins__ as '_'.""" 225 __builtins__["_"] = gettext
226