i18n: Add get_browser_language_code function.

This commit adds get_browser_language_code function
which returns None if there is no Accept-language
header in the request or Accept-languge header contains
only unsupported languages or all languages (meaning
header having value of '*'). Otherwise it returns the
language with highest weight/quality-value.
This commit is contained in:
Sahil Batra 2022-01-20 20:19:21 +05:30 committed by Tim Abbott
parent 3476f63dca
commit 476a217087
2 changed files with 39 additions and 0 deletions

View File

@ -9,6 +9,7 @@ import orjson
from django.conf import settings
from django.http import HttpRequest
from django.utils import translation
from django.utils.translation.trans_real import parse_accept_lang_header
from zerver.lib.request import RequestNotes
@ -67,3 +68,17 @@ def get_and_set_request_language(
RequestNotes.get_notes(request).set_language = translation.get_language()
return request_language
def get_browser_language_code(request: HttpRequest) -> Optional[str]:
accept_lang_header = request.META.get("HTTP_ACCEPT_LANGUAGE")
if accept_lang_header is None:
return None
available_language_codes = get_available_language_codes()
for accept_lang, priority in parse_accept_lang_header(request.META.get("HTTP_ACCEPT_LANGUAGE")):
if accept_lang == "*":
return None
if accept_lang in available_language_codes:
return accept_lang
return None

View File

@ -9,7 +9,9 @@ from django.http import HttpResponse
from django.utils import translation
from zerver.lib.email_notifications import enqueue_welcome_emails
from zerver.lib.i18n import get_browser_language_code
from zerver.lib.test_classes import ZulipTestCase
from zerver.lib.test_helpers import HostRequestMock
from zerver.management.commands import makemessages
from zerver.models import get_realm_stream
@ -128,6 +130,28 @@ class TranslationTestCase(ZulipTestCase):
response = self.fetch("get", f"/{lang}/integrations/", 200)
self.assert_in_response(word, response)
def test_get_browser_language_code(self) -> None:
req = HostRequestMock()
self.assertIsNone(get_browser_language_code(req))
req.META["HTTP_ACCEPT_LANGUAGE"] = "de"
self.assertEqual(get_browser_language_code(req), "de")
req.META["HTTP_ACCEPT_LANGUAGE"] = "en-GB,en;q=0.8"
self.assertEqual(get_browser_language_code(req), "en-gb")
# Case when unsupported language has higher weight.
req.META["HTTP_ACCEPT_LANGUAGE"] = "en-IND;q=0.9,de;q=0.8"
self.assertEqual(get_browser_language_code(req), "de")
# Browser locale is set to unsupported language.
req.META["HTTP_ACCEPT_LANGUAGE"] = "en-IND"
self.assertIsNone(get_browser_language_code(req))
req.META["HTTP_ACCEPT_LANGUAGE"] = "*"
self.assertIsNone(get_browser_language_code(req))
class JsonTranslationTestCase(ZulipTestCase):
def tearDown(self) -> None: