예제 #1
0
def get_redirect_for_unsupported_locale(
        request) -> Optional[HttpResponseRedirect]:
    """
    Given an HttpRequest, determines if it has a locale preference for an explicitly
    unsupported EvictionFreeNY.org locale, and if so, redirects the client to
    a page that offers alternative resources for users of that locale.
    """

    if request.path_info == "/":
        site = get_site_from_request_or_default(request)
        if get_site_type(site) == SITE_CHOICES.EVICTIONFREE:
            accept = request.META.get("HTTP_ACCEPT_LANGUAGE", "")
            # Most of this is taken from:
            # https://github.com/django/django/blob/master/django/utils/translation/trans_real.py
            for accept_lang, _ in parse_accept_lang_header(accept):
                if accept_lang == "*":
                    break

                if not language_code_re.search(accept_lang):
                    continue

                if _is_language_supported(accept_lang):
                    break

                twochar_lang = accept_lang.lower()[:2]
                if twochar_lang in UNSUPPORTED_LOCALE_CHOICE_SET:
                    return HttpResponseRedirect(
                        f"/unsupported-locale/{twochar_lang}")
    return None
예제 #2
0
def _get_language_from_request(request, user):
    """从请求中获取需要同步到用户个人信息的语言
    """
    supported_lang_codes = get_languages()
    # session 有language,说明在登录页面有进行修改或设置,则需要同步到用户个人信息中
    lang_code = request.session.get(translation.LANGUAGE_SESSION_KEY)
    if lang_code in supported_lang_codes and lang_code is not None and check_for_language(
            lang_code):
        return lang_code

    # 个人信息中已有language
    if user.language:
        return None

    # session 情况不满足同步到用户个人信息,且目前个人信息中无language设置
    # 查询header头
    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

    # 使用settings默认设置
    try:
        return get_supported_language_variant(settings.LANGUAGE_CODE)
    except LookupError:
        return settings.LANGUAGE_CODE
예제 #3
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
예제 #4
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.8.19'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
    """
    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)

    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

        # 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

    # 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
예제 #5
0
    def _language_from_browser(request, supported):
        accept_value = request.headers.get("Accept-Language", "")
        for accept_lang, _ in parse_accept_lang_header(accept_value):
            if accept_lang == "*":
                break

            if not language_code_re.search(accept_lang):
                continue

            with suppress(LookupError):
                val = get_supported_language_variant(accept_lang)
                if val and val in supported:
                    return val
예제 #6
0
def get_language_from_browser(request: HttpRequest) -> 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
예제 #7
0
def get_accept_headers_language(request):
    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
예제 #8
0
파일: middleware.py 프로젝트: awg24/pretix
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
예제 #9
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
예제 #10
0
def get_language_from_request(request):  # noqa complexity-16
    """
    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 check_path is True, the URL path prefix will be checked for a language
    code, otherwise this is skipped for backwards compatibility.
    """
    global DEVICE_LANGUAGE

    supported_lang_codes = get_languages()

    if hasattr(request, 'session'):
        lang_code = request.session.get(LANGUAGE_SESSION_KEY)
        if lang_code in supported_lang_codes 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

    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:
        if DEVICE_LANGUAGE is None:
            DEVICE_LANGUAGE = DeviceSettings.objects.get().language_id
        return get_supported_language_variant(DEVICE_LANGUAGE)
    except (DeviceSettings.DoesNotExist, LookupError):
        pass

    try:
        return get_supported_language_variant(settings.LANGUAGE_CODE)
    except LookupError:
        return settings.LANGUAGE_CODE
예제 #11
0
    def _language_from_browser(self, request, supported):
        accept_value = request.META.get('HTTP_ACCEPT_LANGUAGE', '')
        for accept_lang, unused in parse_accept_lang_header(accept_value):
            if accept_lang == '*':
                break

            if not language_code_re.search(accept_lang):
                continue

            try:
                val = get_supported_language_variant(accept_lang)
                if val and val in supported:
                    return val
            except LookupError:
                continue
예제 #12
0
파일: i18n.py 프로젝트: afcarl/cjworkbench
    def _get_locale_from_language_header(self, request):
        # Copied from django.utils.translation.real_trans.get_language_from_request
        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
        return None
예제 #13
0
    def _language_from_browser(request, supported):
        accept_value = request.headers.get('Accept-Language', '')
        for accept_lang, _ in parse_accept_lang_header(accept_value):
            if accept_lang == '*':
                break

            if not language_code_re.search(accept_lang):
                continue

            try:
                val = get_supported_language_variant(accept_lang)
                if val and val in supported:
                    return val
            except LookupError:
                continue
        return None
예제 #14
0
    def get_language_from_header(self, header):
        for accept_lang, unused in parse_accept_lang_header(header):
            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
예제 #15
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
예제 #16
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
예제 #17
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
예제 #18
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
예제 #19
0
파일: i18n.py 프로젝트: Elchi3/kuma
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 langauge (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