зеркало из https://github.com/mozilla/kitsune.git
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:
Родитель
6ff3e25730
Коммит
a1c8afeecf
|
@ -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
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче