def test_preference_cookie_overrides_browser( self, logged_in, lang_cookie, lang_session_in, accept_lang_in, accept_lang_out, lang_session_out, ): if not logged_in: self.request.user = self.anonymous_user if lang_cookie: self.request.COOKIES[settings.LANGUAGE_COOKIE] = lang_cookie if lang_session_in: self.request.session[LANGUAGE_SESSION_KEY] = lang_session_in if accept_lang_in: self.request.META['HTTP_ACCEPT_LANGUAGE'] = accept_lang_in else: del self.request.META['HTTP_ACCEPT_LANGUAGE'] self.middleware.process_request(self.request) accept_lang_result = self.request.META.get('HTTP_ACCEPT_LANGUAGE') if accept_lang_result: accept_lang_result = parse_accept_lang_header(accept_lang_result) if accept_lang_out: accept_lang_out = parse_accept_lang_header(accept_lang_out) if accept_lang_out and accept_lang_result: self.assertItemsEqual(accept_lang_result, accept_lang_out) else: self.assertEqual(accept_lang_result, accept_lang_out) self.assertEquals(self.request.session.get(LANGUAGE_SESSION_KEY), lang_session_out)
def get_alt_src_langs(request, user, translation_project): language = translation_project.language project = translation_project.project source_language = project.source_language langs = user.alt_src_langs.exclude( id__in=(language.id, source_language.id) ).filter(translationproject__project=project) if not user.alt_src_langs.count(): from pootle_language.models import Language accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '') for accept_lang, unused in parse_accept_lang_header(accept): if accept_lang == '*': continue simplified = data.simplify_to_common(accept_lang) normalized = to_locale(data.normalize_code(simplified)) code = to_locale(accept_lang) if (normalized in ('en', 'en_US', source_language.code, language.code) or code in ('en', 'en_US', source_language.code, language.code)): continue langs = Language.objects.filter( code__in=(normalized, code), translationproject__project=project, ) if langs.count(): break return langs
def process_request(self, request): locale, path = utils.strip_path(request.path_info) if localeurl_settings.USE_ACCEPT_LANGUAGE and not locale: accept_langs = filter(lambda x: x, [utils.supported_language(lang[0]) for lang in parse_accept_lang_header( request.META.get('HTTP_ACCEPT_LANGUAGE', ''))]) if accept_langs: locale = accept_langs[0] locale_path = utils.locale_path(path, locale) if locale_path != request.path_info: locale_url = utils.add_script_prefix(locale_path) qs = request.META.get("QUERY_STRING", "") if qs: # Force this to remain a byte-string by encoding locale_path # first to avoid Unicode tainting - downstream will need to # handle the job of handling in-the-wild character encodings: locale_url = "%s?%s" % (locale_path.encode("utf-8"), qs) redirect_class = HttpResponsePermanentRedirect if not localeurl_settings.LOCALE_REDIRECT_PERMANENT: redirect_class = HttpResponseRedirect # @@@ iri_to_uri for Django 1.0; 1.1+ do it in HttpResp...Redirect return redirect_class(iri_to_uri(locale_url)) request.path_info = path if not locale: try: locale = request.LANGUAGE_CODE except AttributeError: locale = settings.LANGUAGE_CODE translation.activate(locale) request.LANGUAGE_CODE = translation.get_language()
def languages_from_request(request, only_supported=False, with_names=False): languages = [] for l in get_user_languages_from_cookie(request): if not l in languages: languages.append(l) if not languages: trans_lang = translation.get_language() if not trans_lang in languages: languages.append(trans_lang) if hasattr(request, 'session'): lang_code = request.session.get('django_language', None) if lang_code is not None and not lang_code in languages: languages.append(lang_code) cookie_lang_code = request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME) if cookie_lang_code and not cookie_lang_code in languages: languages.append(cookie_lang_code) accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '') for lang, val in parse_accept_lang_header(accept): if lang and lang != '*' and not lang in languages: languages.append(lang) if only_supported: for item in languages: if not item in SUPPORTED_LANGUAGES_DICT: languages.remove(item) return with_names and languages_with_names(languages) or languages
def get_best_language(self, accept_lang): """Given an Accept-Language header, return the best-matching language.""" ranked = parse_accept_lang_header(accept_lang) for lang, _ in ranked: supported = find_supported(lang) if supported: return supported
def process_request(self, request): """ If a user's UserPreference contains a language preference, use the user's preference. Save the current language preference cookie as the user's preferred language. """ cookie_lang = request.COOKIES.get(settings.LANGUAGE_COOKIE, None) if cookie_lang: if request.user.is_authenticated(): set_user_preference(request.user, LANGUAGE_KEY, cookie_lang) else: request._anonymous_user_cookie_lang = cookie_lang accept_header = request.META.get(LANGUAGE_HEADER, None) if accept_header: current_langs = parse_accept_lang_header(accept_header) # Promote the cookie_lang over any language currently in the accept header current_langs = [(lang, qvalue) for (lang, qvalue) in current_langs if lang != cookie_lang] current_langs.insert(0, (cookie_lang, 1)) accept_header = ",".join("{};q={}".format(lang, qvalue) for (lang, qvalue) in current_langs) else: accept_header = cookie_lang request.META[LANGUAGE_HEADER] = accept_header # Allow the new cookie setting to update the language in the user's session if LANGUAGE_SESSION_KEY in request.session and request.session[LANGUAGE_SESSION_KEY] != cookie_lang: del request.session[LANGUAGE_SESSION_KEY]
def detect_language(request): language_code = settings.DEFAULT_LANGUAGE language = None try: locales = parse_accept_lang_header(request.META['HTTP_ACCEPT_LANGUAGE']) # try to find a match. Check first item primarily for locale in locales: if not language: # check for presense of - (do we have full locale or just language) if locale[0].rfind('-') == -1: try: language = Language.objects.get(active=True, code__istartswith=locale[0]) language_code = language.code except Language.DoesNotExist: pass else: try: language = Language.objects.get(active=True, code__iexact=locale[0]) language_code = language.code except Language.DoesNotExist: pass except KeyError: pass return { 'code': language_code, 'language': language, }
def get_language_from_request(self, request): supported = dict(settings.LANGUAGES) accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '') for accept_lang, unused in parse_accept_lang_header(accept): if accept_lang == '*': break # We have a very restricted form for our language files # (no encoding specifier, since they all must be UTF-8 and # only one possible language each time. So we avoid the # overhead of gettext.find() and work out the MO file # manually. # 'normalized' is the root name of the locale in POSIX # format (which is the format used for the directories # holding the MO files). normalized = locale.locale_alias.get(to_locale(accept_lang, True)) if not normalized: continue # Remove the default encoding from locale_alias. normalized = normalized.split('.')[0] for lang_code in (accept_lang, accept_lang.split('-')[0]): lang_code = lang_code.lower() if lang_code in supported and check_for_language(lang_code): return lang_code return None
def get_accept_languages(header_value): """ Parse the user's Accept-Language HTTP header and return a list of languages """ # adapted from bedrock: http://j.mp/1o3pWo5 languages = [] pattern = re.compile(r'^([A-Za-z]{2,3})(?:-([A-Za-z]{2})(?:-[A-Za-z0-9]+)?)?$') # bug 1102652 header_value = header_value.replace('_', '-') try: parsed = parse_accept_lang_header(header_value) except ValueError: # see https://code.djangoproject.com/ticket/21078 return languages 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 newsletter_languages(): lang += '-' + m.group(2).upper() if lang not in languages: languages.append(lang) return languages
def get_alt_src_langs(request, profile, translation_project): language = translation_project.language project = translation_project.project source_language = project.source_language langs = profile.alt_src_langs.exclude(id__in=(language.id, source_language.id)).filter( translationproject__project=project ) if not profile.alt_src_langs.count(): from pootle_language.models import Language accept = request.META.get("HTTP_ACCEPT_LANGUAGE", "") for accept_lang, unused in parse_accept_lang_header(accept): if accept_lang == "*": continue normalized = to_locale(data.normalize_code(data.simplify_to_common(accept_lang))) code = to_locale(accept_lang) if normalized in ("en", "en_US", source_language.code, language.code) or code in ( "en", "en_US", source_language.code, language.code, ): continue langs = Language.objects.filter(code__in=(normalized, code), translationproject__project=project) if langs.count(): break return langs
def get_accept_languages(request): """ Parse the user's Accept-Language HTTP header and return a list of languages """ languages = [] pattern = re.compile(r'^([A-Za-z]{2,3})(?:-([A-Za-z]{2})(?:-[A-Za-z0-9]+)?)?$') try: parsed = parse_accept_lang_header(request.META.get('HTTP_ACCEPT_LANGUAGE', '')) except ValueError: # see https://code.djangoproject.com/ticket/21078 return languages 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) return languages
def get_language(self): """ Return a locale code we support on the site using the user's Accept-Language header to determine which is best. This mostly follows the RFCs but read bug 439568 for details. """ if 'lang' in self.request.GET: lang = self.request.GET['lang'].lower() if lang in settings.LANGUAGE_URL_MAP: return settings.LANGUAGE_URL_MAP[lang] if 'lang' in self.request.COOKIES: lang = self.request.COOKIES['lang'].lower() if lang in settings.LANGUAGE_URL_MAP: return settings.LANGUAGE_URL_MAP[lang] if self.request.META.get('HTTP_ACCEPT_LANGUAGE'): ranked_languages = parse_accept_lang_header( self.request.META['HTTP_ACCEPT_LANGUAGE']) # Do we support or remap their locale? supported = [lang[0] for lang in ranked_languages if lang[0] 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()] return settings.LANGUAGE_CODE
def process_request(self, request): """ If a user's UserPreference contains a language preference, use the user's preference. """ languages = released_languages() system_released_languages = [seq[0] for seq in languages] # If the user is logged in, check for their language preference if request.user.is_authenticated(): # Get the user's language preference user_pref = get_user_preference(request.user, LANGUAGE_KEY) # Set it to the LANGUAGE_SESSION_KEY (Django-specific session setting governing language pref) if user_pref: if user_pref in system_released_languages: request.session[LANGUAGE_SESSION_KEY] = user_pref else: delete_user_preference(request.user, LANGUAGE_KEY) else: preferred_language = request.META.get("HTTP_ACCEPT_LANGUAGE", "") lang_headers = [seq[0] for seq in parse_accept_lang_header(preferred_language)] # Setting the session language to the browser language, if it is supported. for browser_lang in lang_headers: if browser_lang in system_released_languages: if request.session.get(LANGUAGE_SESSION_KEY, None) is None: request.session[LANGUAGE_SESSION_KEY] = unicode(browser_lang) break
def get_alt_src_langs(request, user, translation_project): if request.user.is_anonymous: return language = translation_project.language project = translation_project.project source_language = project.source_language langs = list( user.alt_src_langs.exclude( id__in=(language.id, source_language.id) ).filter( translationproject__project=project)) if langs: return langs accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '') for accept_lang, __ in parse_accept_lang_header(accept): if accept_lang == '*': continue normalized = to_locale( data.normalize_code( data.simplify_to_common(accept_lang))) code = to_locale(accept_lang) is_source_lang = any( langcode in ('en', 'en_US', source_language.code, language.code) for langcode in [code, normalized]) if is_source_lang: continue langs = list( Language.objects.filter( code__in=(normalized, code), translationproject__project=project)) if langs: return langs
def guess_lang_from_request(request): if request.GET.get('nocr'): return if request.META.get('HTTP_HOST', settings.DEFAULT_HOST) != settings.DEFAULT_HOST: return # Do not guess if we are on a lang subdomain no_guess_please = request.COOKIES.get("no_country_redirect") if no_guess_please is not None: return # Do not guess if a cookie is present accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '') for accept_lang, unused in parse_accept_lang_header(accept): normalized_accept_lang = accept_lang.lower() if normalized_accept_lang in TO_FULL_INVERTED: return TO_FULL_INVERTED[normalized_accept_lang] if '-' in normalized_accept_lang: normalized_accept_lang = normalized_accept_lang.split('-')[0] if normalized_accept_lang == settings.LANGUAGE_CODE.split('-')[0]: break if normalized_accept_lang in dict(settings.LANGUAGES): return normalized_accept_lang
def process_request(self, request): locale, path = utils.strip_path(request.path_info) if localeurl_settings.USE_ACCEPT_LANGUAGE and not locale: accept_langs = filter(lambda x: x, [utils.supported_language(lang[0]) for lang in parse_accept_lang_header( request.META.get('HTTP_ACCEPT_LANGUAGE', ''))]) if accept_langs: locale = accept_langs[0] locale_path = utils.locale_path(path, locale) if locale_path != request.path_info: if request.META.get("QUERY_STRING", ""): locale_path = "%s?%s" % (locale_path, request.META['QUERY_STRING']) locale_url = utils.add_script_prefix(locale_path) # @@@ iri_to_uri for Django 1.0; 1.1+ do it in HttpResp...Redirect return HttpResponsePermanentRedirect(iri_to_uri(locale_url)) request.path_info = path if not locale: try: locale = request.LANGUAGE_CODE except AttributeError: locale = settings.LANGUAGE_CODE translation.activate(locale) request.LANGUAGE_CODE = translation.get_language()
def get_best_language(self, accept_lang): """Given an Accept-Language header, return the best-matching language.""" ranked = parse_accept_lang_header(accept_lang) for lang, _ in ranked: lang = lang.lower() if lang in FULL_LANGUAGE_MAP: return FULL_LANGUAGE_MAP[lang] pre = lang.split("-")[0] if pre in FULL_LANGUAGE_MAP: return FULL_LANGUAGE_MAP[pre]
def get_language_from_request(request): """ Analyzes the request to find what language the user wants the system to show. Only languages listed in settings.LANGUAGES are taken into account. If the user requests a sublanguage where we have a main language, we send out the main language. """ global _supported if _supported is None: _supported = OrderedDict(settings.LANGUAGES) # Priority 1: User settings if request.user.is_authenticated(): lang_code = request.user.locale if lang_code in _supported and lang_code is not None and check_for_language(lang_code): return lang_code # Priority 2: Anonymous user settings (session, cookie) if hasattr(request, 'session'): lang_code = request.session.get(LANGUAGE_SESSION_KEY) if lang_code in _supported and lang_code is not None and check_for_language(lang_code): return lang_code lang_code = request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME) try: return get_supported_language_variant(lang_code) except LookupError: pass # Priority 3: Event default if hasattr(request, 'event'): lang_code = request.event.locale try: return get_supported_language_variant(lang_code) except LookupError: pass # Priority 4: Browser default accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '') for accept_lang, unused in parse_accept_lang_header(accept): if accept_lang == '*': break if not language_code_re.search(accept_lang): continue try: return get_supported_language_variant(accept_lang) except LookupError: continue try: return get_supported_language_variant(settings.LANGUAGE_CODE) except LookupError: return settings.LANGUAGE_CODE
def guess_language_from_accept_header(self, request): supported = dict(settings.LANGUAGES) accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '') for lang, unused in trans_internals.parse_accept_lang_header(accept): if lang == '*': break lang = lang.split('-')[0].lower() if settings.LANGUAGE_FALLBACK.get(lang, lang) in supported: return lang return settings.LANGUAGE_CODE
def get_project_locale_from_request(request, locales): """Get Pontoon locale from Accept-language request header.""" header = request.META.get('HTTP_ACCEPT_LANGUAGE', '') accept = trans_real.parse_accept_lang_header(header) for a in accept: try: return locales.get(code__iexact=a[0]).code except: continue
def process_request(self, request): accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '') try: codes = [code for code, r in parse_accept_lang_header(accept)] if 'km' in codes and 'km-kh' not in codes: request.META['HTTP_ACCEPT_LANGUAGE'] = accept.replace('km', 'km-kh') except: # this might fail if i18n is disabled. pass super(LocaleMiddlewareWithTweaks, self).process_request(request)
def get_tz(self, request): tz = get_tz_from_request(request) if tz: return tz accept_lang = request.META.get('HTTP_ACCEPT_LANGUAGE', '') langs = trans_real.parse_accept_lang_header(accept_lang) for lang, unused in langs: tz = guess_tz_from_lang(lang) if tz: break return tz
def process_request(self, request): accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '') try: codes = [code for code, r in parse_accept_lang_header(accept)] if 'km' in codes and 'km-kh' not in codes: request.META['HTTP_ACCEPT_LANGUAGE'] = accept.replace('km', 'km-kh') except Exception as e: # this might fail if i18n is disabled. logging.exception(_(u'Settings request META HTTP accept language ' 'threw exceptions: %s' % str(e))) super(LocaleMiddlewareWithTweaks, self).process_request(request)
def get_language_from_browser(request) -> str: accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '') for accept_lang, unused in parse_accept_lang_header(accept): if accept_lang == '*': break if not language_code_re.search(accept_lang): continue try: return get_supported_language_variant(accept_lang) except LookupError: continue
def get_language_from_browser(request: HttpRequest) -> str: accept = request.headers.get('Accept-Language', '') for accept_lang, unused in parse_accept_lang_header(accept): if accept_lang == '*': break if not language_code_re.search(accept_lang): continue try: return get_supported_language_variant(accept_lang) except LookupError: continue
def process_request(self, request): locale, path = utils.strip_path(request.path_info) if localeurl_settings.USE_SESSION and not locale: slocale = request.session.get('django_language') if slocale and utils.supported_language(slocale): locale = slocale if localeurl_settings.USE_ACCEPT_LANGUAGE and not locale: accept_lang_header = request.META.get('HTTP_ACCEPT_LANGUAGE', '') header_langs = parse_accept_lang_header(accept_lang_header) accept_langs = [ l for l in (utils.supported_language(lang[0]) for lang in header_langs) if l ] if accept_langs: locale = accept_langs[0] if path == "/": # If accessing root URL redirect to the URL prefix return HttpResponseRedirect("/%s/" % settings.URL_PREFIXES) locale_path = utils.locale_path(path, locale) # locale case might be different in the two paths, that doesn't require # a redirect (besides locale they'll be identical anyway) if locale_path.lower() != request.path_info.lower(): locale_url = utils.add_script_prefix(locale_path) qs = request.META.get("QUERY_STRING", "") if qs: # Force this to remain a byte-string by encoding locale_path # first to avoid Unicode tainting - downstream will need to # handle the job of handling in-the-wild character encodings: locale_url = "%s?%s" % (locale_path.encode("utf-8"), qs) redirect_class = HttpResponsePermanentRedirect if not localeurl_settings.LOCALE_REDIRECT_PERMANENT: redirect_class = HttpResponseRedirect # @@@ iri_to_uri for Django 1.0; 1.1+ do it in HttpResp...Redirect return redirect_class(iri_to_uri(locale_url)) request.path_info = path if not locale: locale = settings.LANGUAGE_CODE """ try: locale = request.LANGUAGE_CODE except AttributeError: locale = settings.LANGUAGE_CODE """ translation.activate(locale) request.LANGUAGE_CODE = translation.get_language()
def lang_from_accept_header(header): # Map all our lang codes and any prefixes to the locale code. lang_url_map = settings.SHORTER_LANGUAGES.copy() lang_url_map.update((k.lower(), v) for k, v in settings.LANGUAGE_URL_MAP.items()) # If we have a lang or a prefix of the lang, return the locale code. for lang, _ in parse_accept_lang_header(header.lower()): if lang in lang_url_map: return lang_url_map[lang] prefix = lang.split('-')[0] if prefix in lang_url_map: return lang_url_map[prefix] return settings.LANGUAGE_CODE
def get_best_language(self, accept_lang): """Given an Accept-Language header, return the best-matching language.""" LUM = settings.LANGUAGE_URL_MAP PREFIXES = dict((x.split("-")[0], LUM[x]) for x in LUM) 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 lang_from_accept_header(header): # Map all our lang codes and any prefixes to the locale code. langs = [(k.lower(), v) for k, v in settings.LANGUAGE_URL_MAP.items()] # Start with prefixes so any real matches override them. lang_url_map = dict((k.split('-')[0], v) for k, v in langs) lang_url_map.update(langs) # If we have a lang or a prefix of the lang, return the locale code. for lang, _ in parse_accept_lang_header(header.lower()): if lang in lang_url_map: return lang_url_map[lang] prefix = lang.split('-')[0] if prefix in lang_url_map: return lang_url_map[prefix] return settings.LANGUAGE_CODE
def get_lang_from_http_header(request, supported): """If the user's browser sends a list of preferred languages in the HTTP_ACCEPT_LANGUAGE header, parse it into a list. Then walk through the list, and for each entry, we check whether we have a matching pootle translation project. If so, we return it. If nothing is found, return None. """ accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '') for accept_lang, __ in trans_real.parse_accept_lang_header(accept): if accept_lang == '*': return None supported_lang = get_language_supported(accept_lang, supported) if supported_lang: return supported_lang return None
def get_request_language(self, request): """ Guess user language from a HTTP request. Accept-Language HTTP header, for most browser it consists of browser language with higher rank and OS language with lower rank so it still might be usable guess. """ accept = request.META.get("HTTP_ACCEPT_LANGUAGE", "") for accept_lang, _unused in parse_accept_lang_header(accept): if accept_lang == "en": continue try: return self.get(code=accept_lang) except Language.DoesNotExist: continue return None
def connect(self, message, **kwargs): def extract_lang(headers): for header in headers: if header[0] == b'accept-language': return header[1].decode() return 'en' def get_best(langs): for lang, _ in langs: try: return get_supported_language_variant(lang) except LookupError: continue return 'en' super(LanguageConsumer, self).connect(message, **kwargs) self.message.channel_session['lang'] = get_best(parse_accept_lang_header(extract_lang(self.message.content['headers'])))
def get_best_language(self, accept_lang): """Given an Accept-Language header, return the best-matching language.""" LUM = settings.LANGUAGE_URL_MAP PREFIXES = dict((x.split('-')[0], LUM[x]) for x in LUM) 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 process_request(self, request): locale, path = utils.strip_path(request.path_info) if localeurl_settings.USE_SESSION and not locale: slocale = request.session.get('django_language') if slocale and utils.supported_language(slocale): locale = slocale if localeurl_settings.USE_ACCEPT_LANGUAGE and not locale: accept_lang_header = request.META.get('HTTP_ACCEPT_LANGUAGE', '') header_langs = parse_accept_lang_header(accept_lang_header) accept_langs = [ l for l in (utils.supported_language(lang[0]) for lang in header_langs) if l ] if accept_langs: locale = accept_langs[0] locale_path = utils.locale_path(path, locale) # locale case might be different in the two paths, that doesn't require # a redirect (besides locale they'll be identical anyway) if locale_path.lower() != request.path_info.lower(): locale_url = utils.add_script_prefix(locale_path) qs = request.META.get("QUERY_STRING", "") if qs: # Force this to remain a byte-string by encoding locale_path # first to avoid Unicode tainting - downstream will need to # handle the job of handling in-the-wild character encodings: locale_url = "%s?%s" % (locale_path.encode("utf-8"), qs) redirect_class = HttpResponsePermanentRedirect if not localeurl_settings.LOCALE_REDIRECT_PERMANENT: redirect_class = HttpResponseRedirect # @@@ iri_to_uri for Django 1.0; 1.1+ do it in HttpResp...Redirect return redirect_class(iri_to_uri(locale_url)) request.path_info = path if not locale: locale = settings.LANGUAGE_CODE """ try: locale = request.LANGUAGE_CODE except AttributeError: locale = settings.LANGUAGE_CODE """ translation.activate(locale) request.LANGUAGE_CODE = translation.get_language()
def dark_parse_accept_lang_header(accept): ''' The use of 'zh-cn' for 'Simplified Chinese' and 'zh-tw' for 'Traditional Chinese' are now deprecated, as discussed here: https://code.djangoproject.com/ticket/18419. The new language codes 'zh-hans' and 'zh-hant' are now used since django 1.7. Although majority of browsers still use the old language codes, some new browsers such as IE11 in Windows 8.1 start to use the new ones, which makes the current chinese translations of edX don't work properly under these browsers. This function can keep compatibility between the old and new language codes. If one day edX uses django 1.7 or higher, this function can be modified to support the old language codes until there are no browsers use them. ''' browser_langs = parse_accept_lang_header(accept) django_langs = [] for lang, priority in browser_langs: lang = CHINESE_LANGUAGE_CODE_MAP.get(lang.lower(), lang) django_langs.append((lang, priority)) return django_langs
async def connect(self): def extract_lang(headers): for header in headers: if header[0] == b'accept-language': return header[1].decode() return 'en' def get_best(langs): for lang, _ in langs: try: return get_supported_language_variant(lang) except LookupError: continue return 'en' await super(LanguageConsumer, self).connect() self.scope['lang'] = self.scope['user'].language if self.scope['user'].is_authenticated else \ get_best(parse_accept_lang_header(extract_lang(self.scope['headers'])))
def get_best_language(self, 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) try: ranked = parse_accept_lang_header(accept_lang) except ValueError: # see https://code.djangoproject.com/ticket/21078 return else: 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]
def get_language_from_request(request, check_path=False): """ Analyze the request to find what language the user wants the system to show. Only languages listed in settings.LANGUAGES are taken into account. If the user requests a sublanguage where we have a main language, we send out the main language. If check_path is True, the URL path prefix will be checked for a language code, otherwise this is skipped for backwards compatibility. """ if check_path: lang_code = translation.get_language_from_path(request.path_info) if lang_code is not None: return lang_code lang_code = request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME) try: return get_supported_language_variant(lang_code) except LookupError: pass accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '') for accept_lang, unused in parse_accept_lang_header(accept): if accept_lang == '*': break # Если браузер настроен на русский язык, то считать украинский основным if accept_lang == 'ru': return settings.LANGUAGE_CODE if not language_code_re.search(accept_lang): continue try: return get_supported_language_variant(accept_lang) except LookupError: continue try: return get_supported_language_variant(settings.LANGUAGE_CODE) except LookupError: return settings.LANGUAGE_CODE
def parse_accept_language_header(lang_str: str) -> str: """Obtain two char language string from header value. If value is already a two char string that will be returned. example usage: >>> parse_accept_language_header('en-US,en;q=0.9') 'en' >>> parse_accept_language_header('es') 'es' :param lang_str: str :return: str """ try: return parse_accept_lang_header(lang_str)[-1][0] except (AttributeError, IndexError): return DEFAULT_LANGUAGE
def lang_from_accept_header(header): # Map all our lang codes and any prefixes to the locale code. langs = settings.LANGUAGE_URL_MAP # If we have a lang or a prefix of the lang, return the locale code. for lang, _ in parse_accept_lang_header(header.lower()): if lang in langs: return langs[lang] prefix = lang.split('-')[0] # Downgrade a longer prefix to a shorter one if needed (es-PE > es) if prefix in langs: return langs[prefix] # Upgrade to a longer one, if present (zh > zh-CN) lookup = settings.SHORTER_LANGUAGES.get(prefix, '').lower() if lookup and lookup in langs: return langs[lookup] return settings.LANGUAGE_CODE
def get_best_match_score(self, obj): # best_match(accept_lang, enabledlangs, min_score=50) accept_header = self.context['request'].META.get('HTTP_ACCEPT_LANGUAGE', '') accept_lang = [] # Read https://docs.djangoproject.com/en/2.1/topics/i18n/translation/#internationalization-in-python-code for accepted, _q in parse_accept_lang_header(accept_header): accept_lang.append(accepted) # get best accepted match for this tag best = best_match(obj.langtag, accept_lang, min_score=50) # get the index of matched lang try: idx = accept_lang.index(best[0]) except ValueError: return 0 # return the score extracting the index, so the matched position at index # zero and score 100 will return 100. matched position at index 1 and # score 100 will return 99 return best[1] - idx
def _get_locale_from_language_header(self) -> Optional[str]: # Logic adapted from django.utils.translation.real_trans.get_language_from_request for accept_lang, unused in parse_accept_lang_header( self.accept_language_header): if accept_lang == "*": break if not language_code_re.search(accept_lang): continue try: locale_id = get_supported_language_variant(accept_lang) except LookupError: continue if is_supported(locale_id): return locale_id else: continue return None
def detect_language(request): """ Pick a user's preferred language from their Accept-Language headers. """ accept = request.META.get('HTTP_ACCEPT_LANGUAGE') if not accept: return '' ranked_languages = parse_accept_lang_header(accept) for lang, q in ranked_languages: locale = to_locale(lang).replace('_', '-') if locale in product_details.languages: return locale shortened_locale = locale.split('-')[0] if (shortened_locale != locale and shortened_locale in product_details.languages): return shortened_locale # No dice. return ''
def get_language_from_request(request, check_path=False): """ Replacement for django.utils.translation.get_language_from_request. The portion of code that is modified is identified below with a comment. """ if check_path: lang_code = get_language_from_path(request.path_info) if lang_code is not None: return lang_code lang_code = request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME) if lang_code is not None and lang_code in get_languages( ) and check_for_language(lang_code): return lang_code try: return get_supported_language_variant(lang_code) except LookupError: pass accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '') for accept_lang, unused in parse_accept_lang_header(accept): if accept_lang == '*': break # Convert lowercase region to uppercase before attempting to find a variant. # This is the only portion of code that is modified from the core function. accept_lang = language_code_to_iso_3166(accept_lang) if not language_code_re.search(accept_lang): continue try: return get_supported_language_variant(accept_lang) except LookupError: continue try: return get_supported_language_variant(settings.LANGUAGE_CODE) except LookupError: return settings.LANGUAGE_CODE
def get_best_language(accept_lang): """Given an Accept-Language header, return the best-matching language.""" LUM = settings.LANGUAGE_URL_MAP NSL = settings.NON_SUPPORTED_LOCALES LC = settings.LANGUAGE_CODE langs = dict(LUM) # Add in non-supported first to allow overriding prefix behavior. langs.update((k.lower(), v if v else LC) for k, v in list(NSL.items()) if k.lower() not in langs) langs.update((k.split('-')[0], v) for k, v in list(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] # Couldn't find any acceptable locale. return False
def get_best_language(self, accept_lang): """Given an Accept-Language header, return the best-matching language.""" lum = settings.LANGUAGE_URL_MAP langs = dict(lum.items() + settings.CANONICAL_LOCALES.items()) # Add missing short locales to the list. This will automatically map # en to en-GB (not en-US), es to es-AR (not es-ES), etc. in alphabetical # order. To override this behavior, explicitly define a preferred locale # map with the CANONICAL_LOCALES setting. langs.update((k.split('-')[0], v) for k, v in lum.items() if k.split('-')[0] not in langs) try: ranked = parse_accept_lang_header(accept_lang) except ValueError: # see https://code.djangoproject.com/ticket/21078 return else: 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]
def get_lang_from_http_header(request, supported): """If the user's browser sends a list of preferred languages in the HTTP_ACCEPT_LANGUAGE header, parse it into a list. Then walk through the list, and for each entry, we check whether we have a matching pootle translation project. If so, we return it. If nothing is found, return None.""" accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '') for accept_lang, unused in trans_real.parse_accept_lang_header(accept): if accept_lang == '*': return None normalized = data.normalize_code(data.simplify_to_common(accept_lang, supported)) if normalized in ['en-us', 'en']: return None if normalized in supported: return normalized #FIXME: horribly slow way of dealing with languages with @ in them for lang in supported.keys(): if normalized == data.normalize_code(lang): return lang return None
def get_alt_src_langs(request, user, translation_project): from pootle_language.models import Language language = translation_project.language project = translation_project.project source_language = project.source_language langs = user.alt_src_langs.exclude( id__in=(language.id, source_language.id)).filter( translationproject__project=project) project_alt_source = Language.objects.filter(id=source_language.id) langs |= project_alt_source if (not user.alt_src_langs.count()) and False: accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '') for accept_lang, unused in parse_accept_lang_header(accept): if accept_lang == '*': continue simplified = data.simplify_to_common(accept_lang) normalized = to_locale(data.normalize_code(simplified)) code = to_locale(accept_lang) if (normalized in ('en', 'en_US', source_language.code, language.code) or code in ('en', 'en_US', source_language.code, language.code)): continue langs = Language.objects.filter( code__in=(normalized, code), translationproject__project=project, ) if langs.count(): break return langs
def process_request(self, request): """ If a user's UserPreference contains a language preference, use the user's preference. Save the current language preference cookie as the user's preferred language. """ cookie_lang = request.COOKIES.get(settings.LANGUAGE_COOKIE, None) if cookie_lang: if request.user.is_authenticated(): set_user_preference(request.user, LANGUAGE_KEY, cookie_lang) accept_header = request.META.get(LANGUAGE_HEADER, None) if accept_header: current_langs = parse_accept_lang_header(accept_header) # Promote the cookie_lang over any language currently in the accept header current_langs = [(lang, qvalue) for (lang, qvalue) in current_langs if lang != cookie_lang] current_langs.insert(0, (cookie_lang, 1)) accept_header = ",".join("{};q={}".format(lang, qvalue) for (lang, qvalue) in current_langs) else: accept_header = cookie_lang request.META[LANGUAGE_HEADER] = accept_header
def get_language_from_scope(scope): """Get language from ASGI scope. Based on django.utils.translation.get_language_from_request """ accept = "" for k, v in scope["headers"]: if k == b"accept-language": accept = v.decode("latin1") for accept_lang, unused in parse_accept_lang_header(accept): if accept_lang == "*": break if not language_code_re.search(accept_lang): # pragma: no cover continue try: return get_supported_language_variant(accept_lang) except LookupError: # pragma: no cover continue try: return get_supported_language_variant(settings.LANGUAGE_CODE) except LookupError: # pragma: no cover return settings.LANGUAGE_CODE
def __init__(self, *args, **kwargs): http_accept_language = kwargs.pop('http_accept_language', '') super(LanguageDescModelForm, self).__init__(*args, **kwargs) self.fields['description'].widget.attrs.update({'rows': 1, 'cols': 20}) choices = [] # add HTTP_ACCEPTED_LANG first if http_accept_language: for code, q in parse_accept_lang_header(http_accept_language): try: li = get_language_info(code) except: continue choices.append((code, li['name'] + ' - ' + li['name_local'])) # Redefine our choices, so we can add the translated language names and # sort the list by language name choices.append(self.fields['language'].choices[0]) langs = self.fields['language'].choices[1:] langs.sort(key=lambda l: l[1].lower()) for code, lang in langs: li = get_language_info(code) choices.append((code, lang + ' - ' + li['name_local'])) self.fields['language'].choices = choices self.fields['language'].initial = choices[0]
def process_request(self, request): locale, path = utils.strip_path(request.path_info) if localeurl_settings.USE_ACCEPT_LANGUAGE and not locale: accept_langs = filter(lambda x: x, [utils.supported_language(lang[0]) for lang in parse_accept_lang_header( request.META.get('HTTP_ACCEPT_LANGUAGE', ''))]) if accept_langs: locale = accept_langs[0] locale_path = utils.locale_path(path, locale) if locale_path != request.path_info: if request.META.get("QUERY_STRING", ""): locale_path = "%s?%s" % (locale_path, request.META['QUERY_STRING']) return HttpResponsePermanentRedirect(locale_path) request.path_info = path if not locale: try: locale = request.LANGUAGE_CODE except AttributeError: locale = settings.LANGUAGE_CODE translation.activate(locale) request.LANGUAGE_CODE = translation.get_language()
def get_alt_src_langs(request, user, translation_project): language = translation_project.language project = translation_project.project source_language = project.source_language langs = user.alt_src_langs.exclude( id__in=(language.id, source_language.id)).filter( translationproject__project=project) if not user.alt_src_langs.count(): from pootle_language.models import Language accept = request.META.get("HTTP_ACCEPT_LANGUAGE", "") for accept_lang, __ in parse_accept_lang_header(accept): if accept_lang == "*": continue simplified = data.simplify_to_common(accept_lang) normalized = to_locale(data.normalize_code(simplified)) code = to_locale(accept_lang) if normalized in ( "en", "en_US", source_language.code, language.code, ) or code in ("en", "en_US", source_language.code, language.code): continue langs = Language.objects.filter( code__in=(normalized, code), translationproject__project=project, ) if langs.count(): break return langs
def get_language(self): """ Return a locale code we support on the site using the user's Accept-Language header to determine which is best. This mostly follows the RFCs but read bug 439568 for details. """ if 'lang' in self.request.GET: lang = self.request.GET['lang'].lower() if lang in settings.LANGUAGE_URL_MAP: return settings.LANGUAGE_URL_MAP[lang] if 'lang' in self.request.COOKIES: lang = self.request.COOKIES['lang'].lower() if lang in settings.LANGUAGE_URL_MAP: return settings.LANGUAGE_URL_MAP[lang] if self.request.META.get('HTTP_ACCEPT_LANGUAGE'): ranked_languages = parse_accept_lang_header( self.request.META['HTTP_ACCEPT_LANGUAGE']) # Do we support or remap their locale? supported = [ lang[0] for lang in ranked_languages if lang[0] 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()] return settings.LANGUAGE_CODE
def get_country_from_request(request): """ Analyzes the request to find which country the user wants the system to recognize. It checks the following sources in the given order: * session, * cookie, * HTTP_ACCEPT_LANGUAGE HTTP header, and * IP address if USE_GEOIP is True. It returns country code in ISO 3166-1 alpha-2 format. """ if hasattr(request, 'session'): country_code = request.session.get(COUNTRY_SESSION_KEY) if country_code: return get_supported_country(country_code) country_code = request.COOKIES.get(COUNTRY_COOKIE_NAME) if country_code: return get_supported_country(country_code) if USE_GEOIP: ip = _extract_ip_address(request.META) country_code = _geo.country_code_by_addr(ip) if country_code: return get_supported_country(country_code) if USE_LOCALE: accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '') for accept_lang, _ in trans_real.parse_accept_lang_header(accept): if LANG_COUNTRY_DELIM in accept_lang: country_code = accept_lang.split(LANG_COUNTRY_DELIM)[-1] if country_code: return get_supported_country(country_code) return DEFAULT_COUNTRY_CODE
def get_browser_language(request): """ Returns *ONLY* the language that is sent by the browser via the Accept-Language headers. Defaults to ``settings.LANGUAGE_CODE`` if that doesn't work! This is the language we switch back to when translation mode is turned off. Copied from the bottom half of ``django.utils.translation.trans_real.get_language_from_request()`` .. note:: Using ``get_language_from_request()`` doesn't work for us because it first inspects session and cookies and we've already set Esperanto in both the session and the cookie! """ accept = request.META.get("HTTP_ACCEPT_LANGUAGE", "") for accept_lang, _unused in trans_real.parse_accept_lang_header( accept): if accept_lang == "*": break if not trans_real.language_code_re.search(accept_lang): continue try: return translation.get_supported_language_variant(accept_lang) except LookupError: continue try: return translation.get_supported_language_variant( settings.LANGUAGE_CODE) except LookupError: return settings.LANGUAGE_CODE
def get_accept_languages(header_value): """ Parse the user's Accept-Language HTTP header and return a list of languages """ # adapted from bedrock: http://j.mp/1o3pWo5 if not header_value: return [] languages = [] pattern = re.compile( r"^([A-Za-z]{2,3})(?:-([A-Za-z]{2})(?:-[A-Za-z0-9]+)?)?$") # bug 1102652 header_value = header_value.replace("_", "-") try: parsed = parse_accept_lang_header(header_value) except ValueError: # see https://code.djangoproject.com/ticket/21078 return languages 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 newsletter_languages(): lang += "-" + m.group(2).upper() if lang not in languages: languages.append(lang) return languages
def guess_user_language(request, translations): """Guess user language for translations. It tries following: - Use session language. - Parse Accept-Language header. - Fallback to random language. """ # Session language session_lang = translation.get_language() if session_lang and session_lang != 'en': try: return Language.objects.get(code=session_lang) except Language.DoesNotExist: pass # Accept-Language HTTP header, for most browser it consists of browser # language with higher rank and OS language with lower rank so it still # might be usable guess accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '') for accept_lang, _unused in parse_accept_lang_header(accept): if accept_lang == 'en': continue try: return Language.objects.get(code=accept_lang) except Language.DoesNotExist: continue # Random language from existing translations, we do not want to list all # languages by default try: return translations.order_by('?')[0].language except IndexError: # There are not existing translations, so return any Language objects return Language.objects.all()[0]
def invokeResolverMatch(request, match): global current_requests from dtx.web import server with log.enter() as tm: base_handler = BaseHandler() try: base_handler.load_middleware() # META request.META = {} request.META['REQUEST_METHOD'] = request.method # Cookies request.COOKIES = {} session_id = getattr(settings, 'SESSION_COOKIE_NAME', 'sessionid') request.COOKIES[session_id] = request.getCookie(session_id) # Arguments request.GET = request.args # Accept accept = request.getHeader('accept') if (accept): log.debug(u'Accept: {}'.format(accept)) request.accept = parse_accept_header(accept) request.META['HTTP_ACCEPT'] = accept # Args content_type = request.getHeader('content-type') if (content_type): log.debug(u'Content-Type: {}'.format(content_type)) request.META['CONTENT_TYPE'] = content_type request.content_type = content_type.split(';') else: request.content_type = [] request.content_type_name = request.content_type[0] if ( len(request.content_type) >= 1) else None request.content_type_args = request.content_type[1] if ( len(request.content_type) >= 2) else None form = {} # TODO: Make decoders registry if (request.content_type_name == 'application/python-pickle'): content = request.content.read() form = pickle.loads(content) elif (request.content_type_name == 'application/json'): content = request.content.read() form = json.loads(content) elif (request.content_type_name == 'application/x-yaml'): content = request.content.read() form = yaml.load(content) request.POST = form request.REQUEST = dict( chain(request.GET.iteritems(), request.POST.iteritems())) # Parameters kwargs = match.kwargs params = dict(chain(kwargs.iteritems(), form.iteritems())) # Language accept_language = request.getHeader('accept-language') accept_language = accept_language if ( accept_language) else 'en-US,en;q=0.8' request.META['HTTP_ACCEPT_LANGUAGE'] = accept_language from django.utils.translation.trans_real import parse_accept_lang_header langs = parse_accept_lang_header(accept_language) log.debug(u'Accept-Language: {}'.format(unicode(langs))) request.language = langs[0][0] if ( langs) else settings.LANGUAGE_CODE log.debug(u'Activating language: {}'.format(request.language)) translation.activate(request.language) # Middleware for middleware_method in base_handler._request_middleware: try: response = middleware_method(request) except: pass # Invoke server.currentRequest = request with RequestInvocationContext.create(match.func, request, match.args, params) as ctx: #RequestInvocationContext.dump_all(ctx, u'>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>') try: response = yield maybeDeferred(match.func, request, *match.args, **params) except Exception: Failure().printTraceback() raise #RequestInvocationContext.dump_all(ctx, u'<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<') if (issubclass(response.__class__, HttpResponse)): log.debug('Response: HttpResponse') cls = response.__class__ try: content_type = response['content-type'] log.debug(u'Content-Type: {}'.format(content_type)) request.setHeader("Content-Type", content_type) except: log.debug(u'Using default content type') for key, value in response.items(): request.setHeader(key, value) status_code = response.__dict__.get( 'status_code', response.__class__.status_code) log.debug(u'Status-Code: {}'.format(status_code)) request.setResponseCode(status_code) content = response.content if (content): request.write(content) elif (isinstance(response, (unicode))): log.debug('Response: UTF-8') request.write(response.encode('utf-8')) elif (isinstance(response, (str))): log.debug('Response: Binary') request.write(response) else: log.debug(u'Response: Unknown ({})'.format(type(response))) request.setHeader("Content-Type", 'application/python-pickle') request.write(pickle.dumps(response)) request.finish() except Exception, ex: log.err(traceback.format_exc()) log.debug(u'Response-Code: {}'.format(500)) request.setResponseCode(500) request.write('500') request.finish()
def get_language_from_request(request): """ Analyzes the request to find what language the user wants the system to show. Only languages listed in settings.LANGUAGES are taken into account. If the user requests a sublanguage where we have a main language, we send out the main language. If there is a language code in the URL path prefix, then it is selected as the request language and other methods (language cookie, Accept-Language header) are skipped. In Django, the URL path prefix can be skipped with the check_path=False parameter, removed in this code. Based on Django 1.11.16's get_language_from_request from django/utils/translation/trans_real.py, with changes: * Always check the path. * Don't check session language. * Use LANGUAGE_CODE as the fallback language code, instead of passing it through get_supported_language_variant first. """ # Kuma: Always use the URL's language (force check_path=True) lang_code = get_language_from_path(request.path_info) if lang_code is not None: return lang_code # Kuma: Skip checking the session-stored language via LANGUAGE_SESSION_KEY # Use the (valid) language cookie override lang_code = request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME) try: return get_supported_language_variant(lang_code) except LookupError: pass # Pick the closest langauge based on the Accept Language header accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '') for accept_lang, unused in parse_accept_lang_header(accept): if accept_lang == '*': break # Kuma: Assert accept_lang fits the language code pattern # The regex check was added with a security fix: # https://www.djangoproject.com/weblog/2007/oct/26/security-fix/ # In the Django version, non-matching accept_lang codes are skipped. # However, it doesn't seem possible for parse_accept_lang_header to # return codes that would fail this check. # The assertion keeps the security aspect, and gives us an opportunity # to add a test case to Kuma and Django. assert language_code_re.search(accept_lang) try: return get_supported_language_variant(accept_lang) except LookupError: continue # Kuma: Fallback to default settings.LANGUAGE_CODE. # Django supports a case when LANGUAGE_CODE is not in LANGUAGES # (see https://github.com/django/django/pull/824). but our LANGUAGE_CODE is # always the first entry in LANGUAGES. return settings.LANGUAGE_CODE