Skip to content

Commit

Permalink
Refactor get_accept_languages to remove extra work
Browse files Browse the repository at this point in the history
  • Loading branch information
robhudson authored and pmac committed Jan 12, 2022
1 parent e8eb7f3 commit 0b19d51
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 27 deletions.
33 changes: 11 additions & 22 deletions lib/l10n_utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

import re
from os.path import relpath, splitext
from typing import List

Expand Down Expand Up @@ -153,33 +152,23 @@ def get_locale(request):

def get_accept_languages(request):
"""
Parse the user's Accept-Language HTTP header and return a list of languages
Parse the user's Accept-Language HTTP header and return a list of languages in ranked order.
"""
languages = []
pattern = re.compile(r"^([A-Za-z]{2,3})(?:-([A-Za-z]{2})(?:-[A-Za-z0-9]+)?)?$")
ranked = parse_accept_lang_header(request.headers.get("Accept-Language", ""))
return [lang for lang, rank in ranked]

parsed = parse_accept_lang_header(request.headers.get("Accept-Language", ""))

for lang, priority in parsed:
m = pattern.match(lang)

if not m:
continue

lang = m.group(1).lower()

# Check if the shorter code is supported. This covers obsolete long
# codes like fr-FR (should match fr) or ja-JP (should match ja)
if m.group(2) and lang not in settings.PROD_LANGUAGES:
lang += "-" + m.group(2).upper()

if lang not in languages:
languages.append(lang)
def get_best_translation(translations, accept_languages):
"""
Return the best translation available comparing the accept languages against available translations.
return languages
This attempts to find a matching translation for each accept language. It
compares each accept language in full, and also the root. For example,
"en-CA" looks for "en-CA" as well as "en", which maps to "en-US".
If none found, it returns the first language code for the first available translation.
def get_best_translation(translations, accept_languages):
"""
lang_map = _get_language_map()
valid_lang_map = {k: v for k, v in lang_map.items() if v in translations}
for lang in accept_languages:
Expand Down
12 changes: 7 additions & 5 deletions lib/l10n_utils/tests/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,19 +126,21 @@ def test_valid_lang_codes(self):
"""
Should return a list of valid lang codes
"""
self._test("fr-FR", ["fr"])
self._test("en-us,en;q=0.5", ["en-US", "en"])
self._test("pt-pt,fr;q=0.8,it-it;q=0.5,de;q=0.3", ["pt-PT", "fr", "it", "de"])
self._test("ja-JP-mac,ja-JP;q=0.7,ja;q=0.3", ["ja"])
self._test("fr-FR", ["fr-fr"])
self._test("en-us,en;q=0.5", ["en-us", "en"])
self._test("pt-pt,fr;q=0.8,it-it;q=0.5,de;q=0.3", ["pt-pt", "fr", "it-it", "de"])
self._test("ja-JP-mac,ja-JP;q=0.7,ja;q=0.3", ["ja-jp-mac", "ja-jp", "ja"])
self._test("foo,bar;q=0.5", ["foo", "bar"])
# Verify the return lang codes are ordered by rank.
self._test("de;q=0.5,en-us", ["en-us", "de"])

def test_invalid_lang_codes(self):
"""
Should return a list of valid lang codes or an empty list
"""
self._test("", [])
self._test("en_us,en*;q=0.5", [])
self._test("Chinese,zh-cn;q=0.5", ["zh-CN"])
self._test("Chinese,zh-cn;q=0.5", ["chinese", "zh-cn"])


@patch.object(l10n_utils, "render")
Expand Down

0 comments on commit 0b19d51

Please sign in to comment.