/[opental]/opental/PlacelessTranslationService/Negotiator.py
ViewVC logotype

Diff of /opental/PlacelessTranslationService/Negotiator.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.8 by lalo, Thu Aug 28 19:12:10 2003 UTC revision 1.9 by lalo, Mon Oct 6 21:29:31 2003 UTC
# Line 20  Line 20 
20  $Id$  $Id$
21  """  """
22    
23  _langPrefsRegistry = []  try:
24        True
25    except NameError:
26        True=1
27        False=0
28    
29    def lang_normalize(lang):
30        return lang.replace('_', '-')
31    
32    def type_accepted(available, preferred):
33        # ex: preferred is text/* and available is text/html
34        av = available.split('/')
35        pr = preferred.split('/')
36        if len(av) < 2 or len(pr) < 2:
37            return False
38        return pr[1] == '*' and pr[0] == av[0]
39    
40    def lang_accepted(available, preferred):
41        # ex: available is pt, preferred is pt-br
42        return available.startswith(preferred)
43    
44  def registerLangPrefsMethod(prefs):  def _false(*a, **kw):
45      if type(prefs) is not type({}):      pass
         prefs = {'klass':prefs,'priority':0}  
     _langPrefsRegistry.append(prefs)  
     _langPrefsRegistry.sort(lambda x, y: cmp(x['priority'], y['priority']))  
46    
47  def getLangPrefsMethod(env):  class Negotiator:
48      return _langPrefsRegistry[-1]['klass'](env)      filters = {
49            'content-type': (str.lower,),
50  class DummyUserPreferredLanguages:          'language': (str.lower, lang_normalize),
51        }
52      def __init__(self, env):  
53          self._env = env      tests = {
54            'content-type': type_accepted,
55      def getPreferredLanguages(self):          'language': lang_accepted,
56          return self._env.getPreferredLanguages()      }
57    
58  registerLangPrefsMethod(DummyUserPreferredLanguages)      def getAccepted(self, request, kind='content-type'):
59            get = request.get
60            custom_name = ('user_%s' % kind).lower()
61            if kind == 'content-type':
62                header_name = ('HTTP_ACCEPT').upper()
63            else:
64                header_name = ('HTTP_ACCEPT_%s' % kind).upper()
65    
 class BrowserLanguages:  
       
     def __init__(self, context):  
         get = context.get  
               
66          try:          try:
67              user_langs = get('user_language', '')              user_accepts = get(custom_name, '')
68              http_langs = get('HTTP_ACCEPT_LANGUAGE', '')              http_accepts = get(header_name, '')
69          except:          except:
70              from traceback import print_exc              from traceback import print_exc
71              print_exc()              print_exc()
             self.langs = ()  
72              return              return
73          if user_langs and http_langs and user_langs == context.cookies.get('user_language'):          if user_accepts and http_accepts and user_accepts == request.cookies.get('custom_name'):
74              user_langs = user_langs.split(',')              user_accepts = user_accepts.split(',')
75              http_langs = http_langs.split(',')              http_accepts = http_accepts.split(',')
76              for l in user_langs:              for l in user_accepts:
77                  if l not in http_langs:                  if l not in http_accepts:
78                      req_langs = user_langs + http_langs                      req_accepts = user_accepts + http_accepts
79                      break                      break
80                  else:                  else:
81                      # user_langs is a subset of http_langs                      # user_accepts is a subset of http_accepts
82                      context.RESPONSE.expireCookie('user_language', path='/')                      request.RESPONSE.expireCookie('custom_name', path='/')
83                      req_langs = http_langs                      req_accepts = http_accepts
84          else:          else:
85              req_langs = (user_langs +','+ http_langs).split(',')              req_accepts = (user_accepts +','+ http_accepts).split(',')
86    
87          langs = []          accepts = []
88          i=0          i=0
89          length=len(req_langs)          length=len(req_accepts)
90            filters = self.filters.get(kind, ())
91                    
92          # parse quality strings and build a tuple          # parse quality strings and build a tuple
93          # like ((float(quality), lang), (float(quality), lang))          # like ((float(quality), lang), (float(quality), lang))
94          # which is sorted afterwards          # which is sorted afterwards
95          # if no quality string is given then the list order          # if no quality string is given then the list order
96          # is used as quality indicator          # is used as quality indicator
97          for lang in req_langs:          for accept in req_accepts:
98              lang = lang.strip().lower().replace('_', '-')              for normalizer in filters:
99              if lang:                  accept = normalizer(accept)
100                  l = lang.split(';', 2)              if accept:
101                    l = accept.split(';', 2)
102                  quality = []                  quality = []
103    
104                  if len(l) == 2:                  if len(l) == 2:
# Line 95  class BrowserLanguages: Line 113  class BrowserLanguages:
113                  if quality == []:                  if quality == []:
114                      quality = float(length-i)                      quality = float(length-i)
115                                                                                                                                                                    
116                  language = l[0]                  accepts.append((quality, l[0]))
                 langs.append((quality, language))  
117                  i += 1                  i += 1
118                                    
119          # sort and reverse it          # sort and reverse it
120          langs.sort()          accepts.sort()
121          langs.reverse()          accepts.reverse()
122                    
123          # filter quality string                  return [accept[1] for accept in accepts]
         langs = map(lambda x: x[1], langs)      
               
         self.langs = langs  
           
     def getPreferredLanguages(self):  
         """  
         """  
         return self.langs  
                   
 registerLangPrefsMethod({'klass':BrowserLanguages,'priority':10 })  
   
 class Negotiator:  
124    
125        def negotiate(self, choices, request, kind='content-type'):
126      def getLanguage(self, langs, env):          choices = tuple(choices)
127          langs = tuple(langs)          cache_name = '_pts_negotiator_cache_%s' % kind
128          try:          try:
129              cache = env.other['_pts_negotiator_cache']              cache = request.other[cache_name]
130          except KeyError:          except KeyError:
131              # Store cache in request object              # Store cache in request object
132              cache = {}              cache = {}
133              env.set('_pts_negotiator_cache', cache)              request.set(cache_name, cache)
134          try:          try:
135              return cache[langs]              return cache[choices]
136          except KeyError:          except KeyError:
137              cache[langs] = self._getLanguage(langs, env)              cache[choices] = self._negotiate(choices, request, kind)
138              return cache[langs]              return cache[choices]
139    
140      def _getLanguage(self, langs, env):      def _negotiate(self, choices, request, kind):
141          envprefs = getLangPrefsMethod(env)          userchoices = self.getAccepted(request, kind)
142          userlangs = envprefs.getPreferredLanguages()          # Prioritize on the user preferred choices.  Return the first user
143          # Prioritize on the user preferred languages.  Return the first user          # preferred choice that the object has available.
144          # preferred language that the object has available.          test = self.tests.get(kind, _false)
145          for lang in userlangs:          for choice in userchoices:
146              if lang in langs:              if choice in choices:
147                  return lang                  return choice
148              for l_avail in langs:              for l_avail in choices:
149                  if l_avail.startswith(lang):                  if test(l_avail, choice):
150                      return l_avail                      return l_avail
151          return None          return None
152    
153      def getLanguages(self, env):      # backwards compatibility... should be deprecated
154          envprefs = getLangPrefsMethod(env)      def getLanguage(self, langs, request):
155          return envprefs.getPreferredLanguages()          return self.negotiate(langs, request, 'language')
156    
157        def getLanguages(self, request):
158            return self.getAccepted(request, 'language')
159    
160    
161  negotiator = Negotiator()  negotiator = Negotiator()

Legend:
Removed from v.1.8  
changed lines
  Added in v.1.9

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26