Removed some leftovers from media.xsl.
[enkel.git] / enkel / i18n.py
blobd7b5a5fd386b56296e3193e56845dc4c36ca4645
1 # This file is part of the Enkel web programming library.
3 # Copyright (C) 2007 Espen Angell Kristiansen (espeak@users.sourceforge.net)
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 """ Internationalization.
21 @var BUILTIN_LOCALEDIR: The folder containing the translations
22 of the library.
23 @var BUILTIN_DOMAIN: The domain used for the library translations.
24 """
25 from gettext import translation, NullTranslations
26 from os.path import split, join, dirname
28 from enkel.settings import encoding
31 BUILTIN_LOCALEDIR = join(dirname(__file__), "translations")
32 BUILTIN_DOMAIN = "default"
33 I18N_LANG_ENV = "enkel.i18n.lang"
34 I18N_ENV = "enkel.i18n"
37 class DomainBoxInterface(object):
38 """ A DomainBox is a threadsafe interface to a gettext domain. """
39 def __init__(self, domain, localedir,
40 codeset = encoding,
41 fallback = False):
42 """
43 All parameters are forwarded to gettext.translations() when
44 the gettext dictionary is loaded.
45 """
46 self.domain = domain
47 self.localedir = localedir
48 self.codeset = codeset
49 self.fallback = fallback
50 self.trans = {}
52 def add(self, langcode, *fallback_langcodes):
53 """ Add a language to the box.
54 @param langcode: The primary language.
55 @param fallback_langcodes: Other languages that can be
56 used when translations for "langcode" is not
57 available.
58 """
59 raise NotImplementedError()
61 def get(self, langcode, fallback=NullTranslations()):
62 """ Get the gettext dictionary for a language.
63 @param langcode: A langcode added with L{add}.
64 @param fallback: A gettext.NullTranslations compatible
65 object to use as fallback if no dictionary for
66 "langcode" is found.
67 """
68 raise NotImplementedError()
72 class CacheDomainBox(DomainBoxInterface):
73 """ A DomainBoxInterface implementation that loads all
74 dictionaries into memory once. This gives very fast lookup,
75 but uses alot of memory if you wish to support many
76 languages.
78 >>> d = CacheDomainBox(BUILTIN_DOMAIN, BUILTIN_LOCALEDIR)
79 >>> d.add("nb")
80 >>> d.get("nb").ugettext("Delete")
81 u'Slett'
82 >>> d.get("null").ugettext("Delete")
83 u'Delete'
84 """
85 def add(self, langcode, *fallback_langcodes):
86 self.trans[langcode] = translation(
87 self.domain, self.localedir,
88 [langcode] + list(fallback_langcodes),
89 fallback=self.fallback, codeset=self.codeset)
91 def get(self, langcode, fallback=NullTranslations()):
92 try:
93 return self.trans[langcode]
94 except KeyError:
95 return fallback
98 class OnDemandDomainBox(DomainBoxInterface):
99 """ A DomainBoxInterface implementation that loads
100 dictionaries on demand, everytime L{get} is invoked.
101 This only uses memory when the dictionary is loaded,
102 and might be more effective than L{CacheDomainBox} when
103 using lots of languages.
105 >>> d = CacheDomainBox(BUILTIN_DOMAIN, BUILTIN_LOCALEDIR)
106 >>> d.add("nb")
107 >>> d.get("nb").ugettext("Delete")
108 u'Slett'
109 >>> d.get("null").ugettext("Delete")
110 u'Delete'
112 def add(self, langcode, *fallback_langcodes):
113 self.trans[langcode] = fallback_langcodes
115 def get(self, langcode, fallback=NullTranslations()):
116 try:
117 fallback_langcodes = self.trans[langcode]
118 except KeyError:
119 return fallback
120 else:
121 return translation(
122 self.domain, self.localedir,
123 [langcode] + list(fallback_langcodes),
124 fallback=self.fallback, codeset=self.codeset)
128 def suite():
129 import doctest
130 return doctest.DocTestSuite()
132 if __name__ == "__main__":
133 from enkel.wansgli.testhelpers import run_suite
134 run_suite(suite())