[cc-commits] [SCM] cc.engine: License chooser, public domain chooser, deeds (branch next) updated. 9ab9f6342697522b1dca6736ba7ea9057062a975

Gitosis User git at gandi0.creativecommons.org
Wed Jan 25 12:52:16 EST 2012


The branch, next has been updated
       via  9ab9f6342697522b1dca6736ba7ea9057062a975 (commit)
       via  4246cca0cdfd09c775ebacd53d4f08e8a2a82aee (commit)
      from  7dabb3aaecdaa78acb6bede3b77fd970d73fce86 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 9ab9f6342697522b1dca6736ba7ea9057062a975
Author: Jonathan Palecek <jonathan at creativecommons.org>
Date:   Wed Jan 25 11:51:48 2012 -0600

    More comprehensive test for util.get_target_lang_from_request.

commit 4246cca0cdfd09c775ebacd53d4f08e8a2a82aee
Author: Jonathan Palecek <jonathan at creativecommons.org>
Date:   Wed Jan 25 11:50:57 2012 -0600

    Not using webob's continually broken accept_language.best_match function anymore.

-----------------------------------------------------------------------

Summary of changes (followed by patch):
 cc/engine/tests/test_util.py |   24 ++++++++++++++----
 cc/engine/util.py            |   54 +++++++++++++++++++++++++++++++++++------
 2 files changed, 64 insertions(+), 14 deletions(-)

diff --git a/cc/engine/tests/test_util.py b/cc/engine/tests/test_util.py
index e498fe1..4ca8186 100644
--- a/cc/engine/tests/test_util.py
+++ b/cc/engine/tests/test_util.py
@@ -33,25 +33,37 @@ def test_get_target_lang_from_request():
         environ = {
             "REQUEST_METHOD" : "GET",
             "PATH_INFO" : "/",
+            "HTTP_ACCEPT_LANGUAGE" : ", ".join(langs),
             }
         if form_lang:
             environ["QUERY_STRING"] = "lang="+form_lang
         req = Request(environ)
         req.matchdict = {}
-        req.accept_language = ", ".join(langs)
-        return util.get_target_lang_from_request(req)
+        return util.get_target_lang_from_request(req, default_locale='default')
 
-    # neutral language case
-    assert pick_lang() == 'en'
+    # default language case
+    assert pick_lang() == 'default'
 
     # amurican english
-    assert pick_lang(['en-us', 'en']) == 'en'
+    assert pick_lang(['en-us', 'en']) == 'en_US'
 
     # spanish
     assert pick_lang(['es']) == 'es'
 
+    # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4
+    assert pick_lang(['da, en-gb;q=0.8, en;q=0.7']) == 'da'
+
+    # moar english
+    assert pick_lang(['en-bs']) == 'en'
+
     # bs
-    assert pick_lang(['total_bs_locale']) == 'en'
+    assert pick_lang(['total_bs_locale']) == 'default'
+
+    # lower upper
+    assert pick_lang(['es_ES']) == 'es_ES'
+
+    # lower lower
+    assert pick_lang(['es-es']) == 'es_ES'
 
     # specific language request
     assert pick_lang(['es', 'el'], form_lang='jp') == 'jp'
diff --git a/cc/engine/util.py b/cc/engine/util.py
index 6fc18dd..ddd41d8 100644
--- a/cc/engine/util.py
+++ b/cc/engine/util.py
@@ -563,7 +563,8 @@ def send_license_info_email(license_title, license_html,
         return False
 
 
-def get_target_lang_from_request(request):
+ACCEPT_LANG_CACHE = {}
+def get_target_lang_from_request(request, default_locale='en'):
     request_form = request.GET or request.POST
 
     if request_form.has_key('lang'):
@@ -572,13 +573,50 @@ def get_target_lang_from_request(request):
     if request.matchdict.has_key('target_lang'):
         target_lang = request.matchdict['target_lang']
     else:
-        # 'en' is prepended to the list of all supported languages to make it
-        # the first match in a tie breaker.  In the event in which the 
-        # accept_languages field is blank, webob doesn't just return the
-        # default value for some reason.
-        target_lang = request.accept_language.best_match(
-            ['en'] + list(get_all_supported_languages()),
-            default_match="en")
+        try:
+            header_value = request.accept_language.header_value
+        except AttributeError:
+            # header was not defined
+            header_value = default_locale
+        if ACCEPT_LANG_CACHE.has_key(header_value):
+            return ACCEPT_LANG_CACHE[header_value]
+
+        # clean the header into something we can use
+        accept_lang = []
+        for part in header_value.split(","):
+            try:
+                locale, quality = map(str.strip, part.split(";"))
+                quality = float(quality)
+            except ValueError:
+                locale = part.strip()
+                quality = 1
+            accept_lang.append((locale_to_lower_upper(locale), quality))
+            
+        available = list(get_all_supported_languages())
+
+        def run_matches(accept_lang, available):
+            best = -1
+            target_lang = None
+            for locale, quality in accept_lang:
+                if quality > best and available.count(locale):
+                    best = quality
+                    target_lang = locale
+            return target_lang
+
+        # search for exact matches
+        target_lang = run_matches(accept_lang, available)
+        
+        if not target_lang:
+            # search for near matches
+            reduced_accept = [(v.split("_")[0], q) for v,q in accept_lang]
+            reduced_available = [i.split("_")[0] for i in available]
+            target_lang = run_matches(reduced_accept, reduced_available)
+                              
+        if not target_lang:
+            # screw it
+            target_lang = default_locale
+
+        ACCEPT_LANG_CACHE[header_value] = target_lang
     return locale_to_lower_upper(target_lang)
 
 


hooks/post-receive
-- 
cc.engine: License chooser, public domain chooser, deeds


More information about the cc-commits mailing list