src/pyams_utils/i18n.py
changeset 1 3f89629b9e54
child 237 f7c3038259e7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_utils/i18n.py	Thu Feb 19 00:46:48 2015 +0100
@@ -0,0 +1,76 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+
+# import packages
+
+
+def normalize_lang(lang):
+    lang = lang.strip().lower()
+    lang = lang.replace('_', '-')
+    lang = lang.replace(' ', '')
+    return lang
+
+
+def get_browser_language(request):
+    """Custom locale negotiator
+
+    Copied from zope.publisher code
+    """
+    accept_langs = request.headers.get('Accept-Language', '').split(',')
+
+    # Normalize lang strings
+    accept_langs = [normalize_lang(l) for l in accept_langs]
+    # Then filter out empty ones
+    accept_langs = [l for l in accept_langs if l]
+
+    accepts = []
+    for index, lang in enumerate(accept_langs):
+        l = lang.split(';', 2)
+
+        # If not supplied, quality defaults to 1...
+        quality = 1.0
+
+        if len(l) == 2:
+            q = l[1]
+            if q.startswith('q='):
+                q = q.split('=', 2)[1]
+                try:
+                    quality = float(q)
+                except ValueError:
+                    # malformed quality value, skip it.
+                    continue
+
+        if quality == 1.0:
+            # ... but we use 1.9 - 0.001 * position to
+            # keep the ordering between all items with
+            # 1.0 quality, which may include items with no quality
+            # defined, and items with quality defined as 1.
+            quality = 1.9 - (0.001 * index)
+
+        accepts.append((quality, l[0]))
+
+    # Filter langs with q=0, which means
+    # unwanted lang according to the spec
+    # See: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4
+    accepts = [acc for acc in accepts if acc[0]]
+
+    accepts.sort()
+    accepts.reverse()
+
+    return [lang for qual, lang in accepts][0] if accepts else None