Try to pick the best language [bug 639818]

Given Accept-Language: en-gb, en;q=0.8, fr-fr;q=0.6, es;q=0.2, don't pick 'es'.
This commit is contained in:
James Socol 2011-03-08 11:06:39 -05:00
Родитель 6ff3e25730
Коммит a1c8afeecf
2 изменённых файлов: 54 добавлений и 15 удалений

Просмотреть файл

@ -1,4 +1,7 @@
from nose.tools import eq_
from sumo.tests import TestCase
from sumo.urlresolvers import get_best_language
class TestLocaleMiddleware(TestCase):
@ -49,3 +52,32 @@ class TestLocaleMiddleware(TestCase):
response = self.client.get('/search', follow=True,
HTTP_ACCEPT_LANGUAGE='en-US,fr;q=0.3')
self.assertRedirects(response, '/en-US/search', status_code=302)
class BestLanguageTests(TestCase):
def test_english_only(self):
best = get_best_language('en-us, en;q=0.8')
eq_('en-US', best)
def test_en_GB(self):
"""Stick with English if you can."""
best = get_best_language('en-gb, fr;q=0.8')
eq_('en-US', best)
def test_not_worst_choice(self):
"""Try not to fall back to 'es' here."""
best = get_best_language('en-gb, en;q=0.8, fr-fr;q=0.6, es;q=0.2')
eq_('en-US', best)
def test_fr_FR(self):
best = get_best_language('fr-FR, es;q=0.8')
eq_('fr', best)
def test_non_existent(self):
best = get_best_language('xx-YY, xx;q=0.8')
eq_(False, best)
def test_prefix_matching(self):
"""en-US is a better match for en-gb, es;q=0.2 than es."""
best = get_best_language('en-gb, es;q=0.2')
eq_('en-US', best)

Просмотреть файл

@ -61,6 +61,25 @@ def find_supported(test):
x.split('-', 1)[0] == test.lower().split('-', 1)[0]]
def get_best_language(accept_lang):
"""Given an Accept-Language header, return the best-matching language."""
LUM = settings.LANGUAGE_URL_MAP
langs = dict(LUM)
langs.update((k.split('-')[0], v) for k, v in LUM.items() if
k.split('-')[0] not in langs)
ranked = parse_accept_lang_header(accept_lang)
for lang, _ in ranked:
lang = lang.lower()
if lang in langs:
return langs[lang]
pre = lang.split('-')[0]
if pre in langs:
return langs[pre]
# Could not find an acceptable language.
return False
def split_path(path):
"""
Split the requested path into (locale, path).
@ -103,22 +122,10 @@ class Prefixer(object):
return settings.LANGUAGE_URL_MAP[lang]
if self.request.META.get('HTTP_ACCEPT_LANGUAGE'):
ranked_languages = parse_accept_lang_header(
best = get_best_language(
self.request.META['HTTP_ACCEPT_LANGUAGE'])
# Do we support or remap their locale?
supported = [lang[0] for lang in ranked_languages if
lang[0].lower() in settings.LANGUAGE_URL_MAP]
# Do we support a less specific locale? (xx-YY -> xx)
if not len(supported):
for lang in ranked_languages:
supported = find_supported(lang[0])
if supported:
break
if len(supported):
return settings.LANGUAGE_URL_MAP[supported[0].lower()]
if best:
return best
return settings.LANGUAGE_CODE