diff options
| -rw-r--r-- | fatcat_scholar/hacks.py | 26 | ||||
| -rw-r--r-- | fatcat_scholar/web.py | 13 | 
2 files changed, 38 insertions, 1 deletions
| diff --git a/fatcat_scholar/hacks.py b/fatcat_scholar/hacks.py index 710a25f..fc16564 100644 --- a/fatcat_scholar/hacks.py +++ b/fatcat_scholar/hacks.py @@ -51,3 +51,29 @@ class Jinja2Templates:              media_type=media_type,              background=background,          ) + + +def parse_accept_lang(header: str, options: typing.List[str]) -> typing.Optional[str]: +    """ +    Crude HTTP Accept-Language content negotiation. +    Assumes that languages are specified in order of priority, etc. +    """ +    if not header: +        return None +    chunks = [v.split(";")[0].split("-")[0] for v in header.split(",")] +    for c in chunks: +        if len(c) == 2 and c in options: +            return c +    return None + + +def test_parse_accept_lang() -> None: +    assert parse_accept_lang("", []) == None +    assert parse_accept_lang("en,de", []) == None +    assert parse_accept_lang("en,de", ["en"]) == "en" +    assert parse_accept_lang("en-GB,de", ["en"]) == "en" +    assert parse_accept_lang("en,de", ["de"]) == "de" +    assert ( +        parse_accept_lang("en-ca,en;q=0.8,en-us;q=0.6,de-de;q=0.4,de;q=0.2", ["de"]) +        == "de" +    ) diff --git a/fatcat_scholar/web.py b/fatcat_scholar/web.py index 73f79b5..f266e08 100644 --- a/fatcat_scholar/web.py +++ b/fatcat_scholar/web.py @@ -15,7 +15,7 @@ import sentry_sdk  from sentry_sdk.integrations.asgi import SentryAsgiMiddleware  from fatcat_scholar.config import settings, GIT_REVISION -from fatcat_scholar.hacks import Jinja2Templates +from fatcat_scholar.hacks import Jinja2Templates, parse_accept_lang  from fatcat_scholar.search import do_fulltext_search, FulltextQuery, FulltextHits @@ -49,6 +49,17 @@ class LangPrefix:      def __init__(self, request: Request):          self.prefix: str = ""          self.code: str = settings.I18N_LANG_DEFAULT +        # first try to parse a language code from header +        try: +            accept_code = parse_accept_lang( +                request.headers.get("accept-language", ""), I18N_LANG_TRANSLATIONS, +            ) +            if accept_code: +                self.code = accept_code +        except Exception: +            pass + +        # then override this with any language code in URL          for lang_option in I18N_LANG_OPTIONS:              if request.url.path.startswith(f"/{lang_option}/"):                  self.prefix = f"/{lang_option}" | 
