basic support for http Accept header (untested) tls-sprint
authorsylvain.thenault@logilab.fr
Thu, 07 May 2009 17:33:15 +0200
branchtls-sprint
changeset 1716 b12d9e22bac3
parent 1715 cba9f175da2d
child 1717 d2c4d3bd0602
basic support for http Accept header (untested)
web/request.py
web/views/__init__.py
--- a/web/request.py	Thu May 07 16:42:34 2009 +0200
+++ b/web/request.py	Thu May 07 17:33:15 2009 +0200
@@ -598,21 +598,33 @@
                            auth, ex.__class__.__name__, ex)
         return None, None
 
+    @obsolete("use parse_accept_header('Accept-Language')")
     def header_accept_language(self):
         """returns an ordered list of preferred languages"""
-        acceptedlangs = self.get_header('Accept-Language', '')
-        langs = []
-        for langinfo in acceptedlangs.split(','):
+        return [value.split('-')[0] for value in
+                self.parse_accept_header('Accept-Language')]
+
+    def parse_accept_header(self, header):
+        """returns an ordered list of preferred languages"""
+        accepteds = self.get_header(header, '')
+        values = []
+        for info in accepteds.split(','):
             try:
-                lang, score = langinfo.split(';')
-                score = float(score[2:]) # remove 'q='
+                value, scores = info.split(';', 1)
             except ValueError:
-                lang = langinfo
+                value = info
                 score = 1.0
-            lang = lang.split('-')[0]
-            langs.append( (score, lang) )
-        langs.sort(reverse=True)
-        return (lang for (score, lang) in langs)
+            else:
+                for score in scores.split(';'):
+                    try:
+                        scorekey, scoreval = score.split('=')
+                        if scorekey = 'q': # XXX 'level'
+                            score = float(score[2:]) # remove 'q='
+                    except ValueError:
+                        continue
+            values.append(value, score)
+        values.sort(reverse=True)
+        return (value for (score, value) in values)
 
     def header_if_modified_since(self):
         """If the HTTP header If-modified-since is set, return the equivalent
--- a/web/views/__init__.py	Thu May 07 16:42:34 2009 +0200
+++ b/web/views/__init__.py	Thu May 07 17:33:15 2009 +0200
@@ -52,11 +52,16 @@
             return True
     return False
 
-
+VID_BY_MIMETYPE = {'text/xml': 'xml',
+                   # XXX rss, owl...
+                  }
 def vid_from_rset(req, rset, schema):
     """given a result set, return a view id"""
     if rset is None:
         return 'index'
+    for mimetype in req.parse_accept_header('Accept'):
+        if mimetype in VID_FROM_RSET:
+            return VID_FROM_RSET[mimetype]
     nb_rows = len(rset)
     # empty resultset
     if nb_rows == 0 :
@@ -72,7 +77,7 @@
         return 'list'
     return 'table'
 
-    
+
 def linksearch_select_url(req, rset):
     """when searching an entity to create a relation, return an url to select
     entities in the given rset
@@ -85,16 +90,16 @@
         id_fmt = '%%s:%s:%s' % (r_type, eid)
     triplets = '-'.join(id_fmt % row[0] for row in rset.rows)
     return "javascript: selectForAssociation('%s', '%s');" % (triplets, eid)
-                
-        
+
+
 class TmpFileViewMixin(object):
     binary = True
     content_type = 'application/octet-stream'
-    cache_max_age = 60*60*2 # stay in http cache for 2 hours by default 
-    
+    cache_max_age = 60*60*2 # stay in http cache for 2 hours by default
+
     def call(self):
         self.cell_call()
-        
+
     def cell_call(self, row=0, col=0):
         self.row, self.col = row, col # in case one need it
         tmpfile = mktemp('.png')