diff options
author | Bryan Newbold <bnewbold@archive.org> | 2020-10-22 19:01:13 -0700 |
---|---|---|
committer | Bryan Newbold <bnewbold@archive.org> | 2020-10-22 19:01:13 -0700 |
commit | 08156558afdd37fdf2bb62a97e1814aab1f21945 (patch) | |
tree | 25d9a8f878f856f2732b5728eb654345b66ad752 /fatcat_scholar | |
parent | ea28911d14f3996ace13bf95ce1b8f6537d43fcc (diff) | |
download | fatcat-scholar-08156558afdd37fdf2bb62a97e1814aab1f21945.tar.gz fatcat-scholar-08156558afdd37fdf2bb62a97e1814aab1f21945.zip |
web: basic Accept-Language HTTP negotiation
Diffstat (limited to 'fatcat_scholar')
-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}" |