Changeset 437
- Timestamp:
- Wed Jul 18 16:11:39 2007
- Files:
-
- subprojects/Wuming/trunk/wuming/web.py (modified) (diff)
- subprojects/Wuming/trunk/wuming/i18n.py (modified) (diff)
- subprojects/Wuming/trunk/wuming/auth.py (modified) (diff)
- subprojects/Wuming/trunk/wuming/interfaces.py (modified) (diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
subprojects/Wuming/trunk/wuming/web.py
r434 r437 4 4 from twisted.web2 import resource, log 5 5 from twisted.web2 import http, stream, http_headers 6 from twisted.web2.iweb import IRequest 6 7 from twisted.python import log 7 8 8 9 from wuming.admin import start_modrebuilder 9 10 from wuming.interfaces import ITemplateResource, ITemplate, ITemplateLoader, ITemplateGuessingStrategy 11 from wuming.interfaces import ITranslationStrategy, ITranslationPreferences 10 12 11 13 from zope.interface import Interface, Attribute, implements … … 35 37 36 38 37 class RequestContext(object):38 pass39 40 41 39 class DryTemplateGuessingStrategy(object): 42 40 """ … … 65 63 66 64 67 68 65 class TemplateResource(BaseResource): 69 66 """A template resource implements ITemplateResource … … 95 92 # create a new context for the request 96 93 log.msg('The id of self : %s' % id(self)) 97 request.context = RequestContext()98 request.context.view = self99 request.root = self100 94 tpl = self.template 101 95 if tpl is None: 102 96 tpl = templateGuessingStrategy.templateName(self, request) 103 ctx = { 'request' : request, 'view' : self , 'context' : request.context}97 ctx = { 'request' : request, 'view' : self } 103 97 ctx.update(self.render_context(request)) 104 98 return self.templateLoader.loadTemplate(tpl).addCallback( … … 130 124 131 125 126 127 import weakref 128 129 class LocalizedRequest(object): 130 131 implements(ITranslationStrategy) 132 133 _cache = weakref.WeakKeyDictionary() 134 135 preferences = lambda self, r: None 136 137 def __init__(self, translator, preferencesFunction=None): 138 self.translator = translator 139 self.preferences = preferencesFunction or self.preferences 140 141 def getTranslator(self, request): 142 """Get the translate function for a request 143 """ 144 if request in self._request_cache: 145 return self._cache[request] 146 prefs = self.preferences(request) 147 if prefs is None: 148 prefs = ITranslationPreferences(request) 149 # ??? 150 langs = [] 151 r = [ langs.extend(t) for t in prefs ] 152 return self.translator(langs) 153 154 155 def languagesDomainFactory(s, request): 156 header = request.headers.getHeader('accept-language') 157 if header is None: 158 return [], None 159 langs = {} 160 for lang in header.split(','): 161 quality = 1.0 162 if ';' in lang: 163 lang, quality = lang.split(';', 1) 164 if quality[:2] == 'q=': 165 try: 166 quality = float(quality[2:]) 167 except ValueError: 168 pass 169 #langs.append((quality, lang)) 170 t = langs.get(quality, ()) 171 t = langs[quality] = t + (lang,) 172 if '-' in lang: 173 #langs.append((quality, lang.split('-')[0])) 174 langs[quality] = t + (lang.split('-')[0],) 175 items = langs.items() 176 items.sort(lambda a,b: cmp(b[0], a[0])) 177 return [lang for quality, lang in langs], None 178 179 class RequestToTranslationPreferencesAdapter(object): 180 """I adapt an http request to an ITranslationPreferences 181 182 >>> from twisted.web2.http import Request 183 >>> from twisted.web2 import http_headers 184 >>> r = Request(None, 'GET', 'http://host/', 'HTTP/1.1', 0, http_headers.Headers()) 185 >>> prefs = ITranslationPreferences(r) 186 187 An incoming request may specify the accept-language header 188 189 >>> r2 = Request(None, 'GET', 'http://host/', 'HTTP/1.1', 0, http_headers.Headers()) 190 191 """ 192 implements(ITranslationPreferences) 193 194 languagesDomainFactory = languagesDomainFactory 195 196 def __init__(self, request): 197 self.languages, self.domain = self.languagesDomainFactory(request) 198 199 def __iter__(self): 200 return iter(self.languages) 201 202 from twisted.python import components 203 204 components.registerAdapter(RequestToTranslationPreferencesAdapter, 205 IRequest, ITranslationPreferences) 206 132 207 application = None 133 208 -
subprojects/Wuming/trunk/wuming/i18n.py
r436 r437 1 # internationalization stuff 1 # internationalization. 2 # some inspiration from Nevow's i18n - the goal here is to have i18n 3 # as a generic service to the application, decoupled from the templating 4 # system. 2 5 3 from wuming.interfaces import ITranslator, ITranslationStrategy 6 from wuming.interfaces import ITranslator, ITranslationStrategy, ITranslationPreferences 3 6 4 7 from zope.interface import implements 5 8 9 import gettext 6 10 import weakref 7 11 … … 12 16 >>> verifyClass(ITranslator, GettextTranslator) 13 17 True 14 >>> verifyObject(ITranslator, GettextTranslator()) 18 >>> verifyObject(ITranslator, GettextTranslator(None)) 14 18 True 15 19 """ … … 18 22 implements(ITranslator) 19 23 20 domain = None 21 localedir = None 22 fallback = True 24 domain = 'messages' 23 25 _tsl_cache = weakref.WeakValueDictionary() 24 26 gettextFunction = 'ugettext' 25 27 _last = [] 26 28 27 def __init__(self, domain=None, localedir=None, fallback=None): 28 pass 29 def __init__(self, localedir, domain=None, fallback=True): 30 self.domain = domain or self.domain 31 self.localedir = localedir 32 self.fallback = fallback 33 #if install: 34 #gettext.install(self.domain, self.localedir, unicode=1) 29 35 30 36 def _initTranslation(self, languages, domain): 31 import gettext32 37 translation = gettext.translation( 33 38 domain=domain, … … 40 45 return f 41 46 42 def translate(self, s, languages, domain=None):47 def __call__(self, languages=None, domain=None): 42 47 """Example usage 43 48 44 >>> tsl = GettextTranslator() 45 >>> tsl.translate('Hello', None) 49 >>> tsl = GettextTranslator(None) 50 >>> tsl.translator(None)('Hello') 46 51 u'Hello' 47 52 """ 53 langs = languages 54 if langs is not None and type(langs) is not tuple: 55 langs = tuple(langs) 48 56 domain = domain or self.domain 49 tsl = self._tsl_cache.get((domain, lang uages), None)57 tsl = self._tsl_cache.get((domain, langs), None) 49 57 if tsl is None: 50 tsl = self._initTranslation(lang uages, domain)58 tsl = self._initTranslation(langs, domain) 50 58 # keep some references for stronger caching 51 59 if tsl not in self._last: … … 56 64 self._last.pop(0) 57 65 self._last.append(tsl) 58 return tsl(s) 66 return (lambda *p, **k : tsl(*p, **k)) 67 68 translator = __call__ 59 69 60 _ = GettextTranslator()70 _ = gettext.gettext 60 70 61 71 class AcceptLangStrategy(object): … … 64 74 request header to find the best translator. 65 75 76 You must instantiatiate with a provider of ITranslator. The following will fail: 77 78 >>> try: 79 ... strag = AcceptLangStrategy('hello') 80 ... except TypeError: 81 ... print 'type error' 82 ... 83 type error 84 85 This is correct implementation of the ITranslationStrategy interface: 86 66 87 >>> from zope.interface.verify import verifyClass, verifyObject 67 88 >>> verifyClass(ITranslationStrategy, AcceptLangStrategy) 68 89 True 69 >>> verifyObject(ITranslationStrategy, AcceptLangStrategy()) 90 >>> verifyObject(ITranslationStrategy, AcceptLangStrategy(GettextTranslator(None))) 69 90 True 70 91 """ … … 73 94 implements(ITranslationStrategy) 74 95 75 def getTranslator(self, resource, request): 76 pass 96 def __init__(self, translator): 97 self.translator = ITranslator(translator) 98 99 def getTranslator(self, preferences): 100 prefs = ITranslationPreferences(preferences) 101 102 103 from twisted.python import components 104 from UserList import UserList 105 106 class ListAdapter(UserList): 107 """I adapt a list to an ITranslationPreferences provider 108 109 >>> prefs = ITranslationPreferences([('en','ja'), ('zh',)]) 110 >>> prefs.preferences 111 [('en', 'ja'), ('zh',)] 112 >>> for p in prefs: 113 ... print p 114 ... 115 ('en', 'ja') 116 ('zh',) 117 118 """ 119 implements(ITranslationPreferences) 120 121 domain = None 122 123 def __init__(self, orig): 124 UserList.__init__(self, orig) 125 self.preferences = orig 126 127 components.registerAdapter(ListAdapter, list, ITranslationPreferences) 77 128 78 79 129 -
subprojects/Wuming/trunk/wuming/auth.py
r436 r437 19 19 class AuthResource(wrapper.HTTPAuthResource): 20 20 """AuthResource works like is parent class C{HTTPAuthResource} except 21 ifAuthenticate is not found in the request header it can try authentication21 Authenticate is not found in the request header it can try authentication 21 21 otherwise based on the incoming request object. This allows you to add simple 22 22 cookie checkers etc. to the portal. -
subprojects/Wuming/trunk/wuming/interfaces.py
r436 r437 43 43 """ 44 44 45 def translate(s, languages, domain=None): 46 """translate a string s to target language 47 @param s: a string to translate 45 domain = Attribute("""Default domain for this translator""") 46 47 def translator(languages=None, domain=None): 48 """Get a translator function for languages and optionally domain 48 49 @param languages: a list of languages, e.g. ['en', 'ja'] 49 50 @param domain: optional domain arguments (e.g. 'foodomain') … … 51 52 """ 52 53 54 def __call__(languages=None, domain=None): 55 """An alias for translate 56 """ 57 58 59 class ITranslationPreferences(Interface): 60 61 domain = Attribute("""The preferred domain""") 62 63 languages = Attribute("""A list of language tuples in order of precendence. 64 For example: 65 66 [('en','es'), ('fr',)] 67 68 indicates we'd like English or Spanish equally or French if not available""") 69 70 def __iter__(): 71 """An generator for the preferred tuple types 72 """ 73 53 74 class ITranslationStrategy(Interface): 54 75 55 def getTranslator(resource, request): 56 """get a ITranslator provider for the given resource/request 76 translator = Attribute("An ITranslator provider used to get translate function") 77 78 def getTranslator(prefences): 79 """Return transalator function for the given resource/request. 57 80 58 @return a ITranslator provider 81 @param param: ITranslationPreferences 82 @return a translation function (like ugettext) 59 83 """ 60 84
