Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle if lang code in settings is None #66

Merged
merged 9 commits into from
Feb 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 32 additions & 1 deletion garnett/middleware.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
from django.conf import settings
from django.http import Http404
from django.utils.module_loading import import_string
from django.utils.translation import gettext as _

import logging
import langcodes
from langcodes import Language

from .utils import get_language_from_request, is_valid_language
from .utils import is_valid_language, get_default_language
from .context import set_field_language

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -86,3 +89,31 @@ def __call__(self, request):
)

return self.get_response(request)


def get_language_from_request(request) -> Language:
opt_order = getattr(
settings,
"GARNETT_REQUEST_LANGUAGE_SELECTORS",
[
"garnett.selectors.header",
"garnett.selectors.query",
"garnett.selectors.cookie",
],
)
for opt in opt_order:
func = import_string(opt)
if lang := func(request):
try:
return Language.get(lang)
except langcodes.tag_parser.LanguageTagError:
raise Http404(
_(
"The provided language %(lang_code)s is not a valid language code"
)
% {
"lang_code": lang,
}
)

return get_default_language()
55 changes: 33 additions & 22 deletions garnett/utils.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from typing import List, Union
from typing import List, Union, Optional

import langcodes.tag_parser
from django.conf import settings
from django.utils.module_loading import import_string
from django.core.exceptions import ImproperlyConfigured
from langcodes import Language

Expand Down Expand Up @@ -68,31 +68,42 @@ def get_current_blank_override() -> bool:
return _ctx_force_blank.get(False)


def get_safe_language(lang_code: str) -> Optional[Language]:
"""Return language if language for lang code exists, otherwise none"""
try:
return Language.get(lang_code)
except langcodes.tag_parser.LanguageTagError:
return None


def validate_language_list(langs) -> List[Language]:
"""
Validate and clean a potential list of languages.
This may return an empty list if the provided languages are invalid
"""
if type(langs) is not list:
return []

languages = []
for lang_code in langs:
if language := get_safe_language(lang_code):
languages.append(language)

if languages:
return languages


def get_languages() -> List[Language]:
langs = getattr(
settings, "GARNETT_TRANSLATABLE_LANGUAGES", [get_default_language()]
)
if callable(langs):
langs = langs()
if type(langs) == list:
return [Language.get(lang) for lang in langs]
raise ImproperlyConfigured(
"GARNETT_TRANSLATABLE_LANGUAGES must be a list or a callable that returns a list"
)

languages = validate_language_list(langs)

def get_language_from_request(request) -> Language:
opt_order = getattr(
settings,
"GARNETT_REQUEST_LANGUAGE_SELECTORS",
[
"garnett.selectors.header",
"garnett.selectors.query",
"garnett.selectors.cookie",
],
)
for opt in opt_order:
func = import_string(opt)
if lang := func(request):
return Language.get(lang)
return get_default_language()
if not languages:
raise ImproperlyConfigured(
"GARNETT_TRANSLATABLE_LANGUAGES must be a list of languages or a callable that returns a list of languages"
)
return languages
Loading