Exemplo n.º 1
0
    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)
Exemplo n.º 2
0
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
Exemplo n.º 3
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:
            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()
Exemplo n.º 4
0
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
Exemplo n.º 5
0
 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
Exemplo n.º 6
0
    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]
Exemplo n.º 7
0
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,
    }
Exemplo n.º 8
0
    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
Exemplo n.º 9
0
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
Exemplo n.º 10
0
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
Exemplo n.º 11
0
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
Exemplo n.º 12
0
    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
Exemplo n.º 13
0
    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
Exemplo n.º 14
0
Arquivo: views.py Projeto: arky/pootle
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
Exemplo n.º 15
0
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
Exemplo n.º 16
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'])
         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()
Exemplo n.º 17
0
 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]
Exemplo n.º 18
0
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
Exemplo n.º 19
0
    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
Exemplo n.º 20
0
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
Exemplo n.º 21
0
    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)
Exemplo n.º 22
0
    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
Exemplo n.º 23
0
    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)
Exemplo n.º 24
0
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
Exemplo n.º 25
0
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
Exemplo n.º 26
0
    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()
Exemplo n.º 27
0
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
Exemplo n.º 28
0
 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
Exemplo n.º 29
0
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
Exemplo n.º 30
0
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
Exemplo n.º 31
0
    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
Exemplo n.º 32
0
    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'])))
Exemplo n.º 33
0
 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
Exemplo n.º 34
0
    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()
Exemplo n.º 35
0
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
Exemplo n.º 36
0
    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]
Exemplo n.º 38
0
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
Exemplo n.º 39
0
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
Exemplo n.º 40
0
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
Exemplo n.º 41
0
    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
Exemplo n.º 42
0
    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
Exemplo n.º 43
0
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 ''
Exemplo n.º 44
0
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
Exemplo n.º 45
0
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
Exemplo n.º 46
0
 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]
Exemplo n.º 47
0
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
Exemplo n.º 48
0
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
Exemplo n.º 49
0
    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
Exemplo n.º 50
0
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
Exemplo n.º 51
0
 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()
Exemplo n.º 53
0
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
Exemplo n.º 54
0
    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
Exemplo n.º 55
0
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
Exemplo n.º 56
0
    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
Exemplo n.º 57
0
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
Exemplo n.º 58
0
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]
Exemplo n.º 59
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()
Exemplo n.º 60
0
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