mirror of https://github.com/searxng/searxng.git
[mod] add a Preferences.client property to store client prefs
Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
This commit is contained in:
parent
5a3f99ee1a
commit
c03b0ea650
|
@ -8,9 +8,10 @@
|
||||||
from base64 import urlsafe_b64encode, urlsafe_b64decode
|
from base64 import urlsafe_b64encode, urlsafe_b64decode
|
||||||
from zlib import compress, decompress
|
from zlib import compress, decompress
|
||||||
from urllib.parse import parse_qs, urlencode
|
from urllib.parse import parse_qs, urlencode
|
||||||
from typing import Iterable, Dict, List
|
from typing import Iterable, Dict, List, Optional
|
||||||
|
|
||||||
import flask
|
import flask
|
||||||
|
import babel
|
||||||
|
|
||||||
from searx import settings, autocomplete
|
from searx import settings, autocomplete
|
||||||
from searx.enginelib import Engine
|
from searx.enginelib import Engine
|
||||||
|
@ -287,10 +288,65 @@ class PluginsSetting(BooleanChoices):
|
||||||
return [item[len('plugin_') :] for item in items]
|
return [item[len('plugin_') :] for item in items]
|
||||||
|
|
||||||
|
|
||||||
|
class ClientPref:
|
||||||
|
"""Container to assemble client prefferences and settings."""
|
||||||
|
|
||||||
|
# hint: searx.webapp.get_client_settings should be moved into this class
|
||||||
|
|
||||||
|
locale: babel.Locale
|
||||||
|
"""Locale prefered by the client."""
|
||||||
|
|
||||||
|
def __init__(self, locale: Optional[babel.Locale] = None):
|
||||||
|
self.locale = locale
|
||||||
|
|
||||||
|
@property
|
||||||
|
def locale_tag(self):
|
||||||
|
if self.locale is None:
|
||||||
|
return None
|
||||||
|
tag = self.locale.language
|
||||||
|
if self.locale.territory:
|
||||||
|
tag += '-' + self.locale.territory
|
||||||
|
return tag
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_http_request(cls, http_request: flask.Request):
|
||||||
|
"""Build ClientPref object from HTTP request.
|
||||||
|
|
||||||
|
- `Accept-Language used for locale setting
|
||||||
|
<https://www.w3.org/International/questions/qa-accept-lang-locales.en>`__
|
||||||
|
|
||||||
|
"""
|
||||||
|
al_header = http_request.headers.get("Accept-Language")
|
||||||
|
if not al_header:
|
||||||
|
return cls(locale=None)
|
||||||
|
|
||||||
|
pairs = []
|
||||||
|
for l in al_header.split(','):
|
||||||
|
# fmt: off
|
||||||
|
lang, qvalue = [_.strip() for _ in (l.split(';') + ['q=1',])[:2]]
|
||||||
|
# fmt: on
|
||||||
|
try:
|
||||||
|
qvalue = float(qvalue.split('=')[-1])
|
||||||
|
locale = babel.Locale.parse(lang, sep='-')
|
||||||
|
except (ValueError, babel.core.UnknownLocaleError):
|
||||||
|
continue
|
||||||
|
pairs.append((locale, qvalue))
|
||||||
|
pairs.sort(reverse=True, key=lambda x: x[1])
|
||||||
|
return cls(locale=pairs[0][0])
|
||||||
|
|
||||||
|
|
||||||
class Preferences:
|
class Preferences:
|
||||||
"""Validates and saves preferences to cookies"""
|
"""Validates and saves preferences to cookies"""
|
||||||
|
|
||||||
def __init__(self, themes: List[str], categories: List[str], engines: Dict[str, Engine], plugins: Iterable[Plugin]):
|
def __init__(
|
||||||
|
self,
|
||||||
|
themes: List[str],
|
||||||
|
categories: List[str],
|
||||||
|
engines: Dict[str, Engine],
|
||||||
|
plugins: Iterable[Plugin],
|
||||||
|
client: Optional[ClientPref] = None,
|
||||||
|
):
|
||||||
|
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
self.key_value_settings: Dict[str, Setting] = {
|
self.key_value_settings: Dict[str, Setting] = {
|
||||||
|
@ -414,6 +470,7 @@ class Preferences:
|
||||||
self.engines = EnginesSetting('engines', engines=engines.values())
|
self.engines = EnginesSetting('engines', engines=engines.values())
|
||||||
self.plugins = PluginsSetting('plugins', plugins=plugins)
|
self.plugins = PluginsSetting('plugins', plugins=plugins)
|
||||||
self.tokens = SetSetting('tokens')
|
self.tokens = SetSetting('tokens')
|
||||||
|
self.client = client or ClientPref()
|
||||||
self.unknown_params: Dict[str, str] = {}
|
self.unknown_params: Dict[str, str] = {}
|
||||||
|
|
||||||
def get_as_url_params(self):
|
def get_as_url_params(self):
|
||||||
|
|
|
@ -96,6 +96,7 @@ from searx.plugins import Plugin, plugins, initialize as plugin_initialize
|
||||||
from searx.plugins.oa_doi_rewrite import get_doi_resolver
|
from searx.plugins.oa_doi_rewrite import get_doi_resolver
|
||||||
from searx.preferences import (
|
from searx.preferences import (
|
||||||
Preferences,
|
Preferences,
|
||||||
|
ClientPref,
|
||||||
ValidationException,
|
ValidationException,
|
||||||
)
|
)
|
||||||
from searx.answerers import (
|
from searx.answerers import (
|
||||||
|
@ -221,16 +222,9 @@ babel = Babel(app, locale_selector=get_locale)
|
||||||
|
|
||||||
|
|
||||||
def _get_browser_language(req, lang_list):
|
def _get_browser_language(req, lang_list):
|
||||||
for lang in req.headers.get("Accept-Language", "en").split(","):
|
client = ClientPref.from_http_request(req)
|
||||||
if ';' in lang:
|
locale = match_locale(client.locale_tag, lang_list, fallback='en')
|
||||||
lang = lang.split(';')[0]
|
|
||||||
if '-' in lang:
|
|
||||||
lang_parts = lang.split('-')
|
|
||||||
lang = "{}-{}".format(lang_parts[0], lang_parts[-1].upper())
|
|
||||||
locale = match_locale(lang, lang_list, fallback=None)
|
|
||||||
if locale is not None:
|
|
||||||
return locale
|
return locale
|
||||||
return 'en'
|
|
||||||
|
|
||||||
|
|
||||||
def _get_locale_rfc5646(locale):
|
def _get_locale_rfc5646(locale):
|
||||||
|
@ -512,7 +506,10 @@ def pre_request():
|
||||||
request.timings = [] # pylint: disable=assigning-non-slot
|
request.timings = [] # pylint: disable=assigning-non-slot
|
||||||
request.errors = [] # pylint: disable=assigning-non-slot
|
request.errors = [] # pylint: disable=assigning-non-slot
|
||||||
|
|
||||||
preferences = Preferences(themes, list(categories.keys()), engines, plugins) # pylint: disable=redefined-outer-name
|
client_pref = ClientPref.from_http_request(request)
|
||||||
|
# pylint: disable=redefined-outer-name
|
||||||
|
preferences = Preferences(themes, list(categories.keys()), engines, plugins, client_pref)
|
||||||
|
|
||||||
user_agent = request.headers.get('User-Agent', '').lower()
|
user_agent = request.headers.get('User-Agent', '').lower()
|
||||||
if 'webkit' in user_agent and 'android' in user_agent:
|
if 'webkit' in user_agent and 'android' in user_agent:
|
||||||
preferences.key_value_settings['method'].value = 'GET'
|
preferences.key_value_settings['method'].value = 'GET'
|
||||||
|
|
Loading…
Reference in New Issue