summaryrefslogtreecommitdiff
path: root/searx/preferences.py
diff options
context:
space:
mode:
authorBnyro <bnyro@tutanota.com>2023-08-22 15:35:46 +0200
committerMarkus Heiser <markus.heiser@darmarIT.de>2023-08-27 21:23:43 +0200
commit1428385d1cc67d16db1881bf7bbcaa6f60cd0142 (patch)
tree23d30deca09e716003d3844178f6067439c5d6b6 /searx/preferences.py
parente5535ec078776d07d8eeac0d51dc8f17f77cfb27 (diff)
downloadsearxng-1428385d1cc67d16db1881bf7bbcaa6f60cd0142.tar.gz
searxng-1428385d1cc67d16db1881bf7bbcaa6f60cd0142.zip
[mod] preferences.py: add and use BooleanSetting for checkbox preferences
Diffstat (limited to 'searx/preferences.py')
-rw-r--r--searx/preferences.py109
1 files changed, 52 insertions, 57 deletions
diff --git a/searx/preferences.py b/searx/preferences.py
index 6e7d4a5e1..0c59effc4 100644
--- a/searx/preferences.py
+++ b/searx/preferences.py
@@ -9,6 +9,7 @@ from base64 import urlsafe_b64encode, urlsafe_b64decode
from zlib import compress, decompress
from urllib.parse import parse_qs, urlencode
from typing import Iterable, Dict, List, Optional
+from collections import OrderedDict
import flask
import babel
@@ -24,6 +25,18 @@ from searx.engines import DEFAULT_CATEGORY
COOKIE_MAX_AGE = 60 * 60 * 24 * 365 * 5 # 5 years
DOI_RESOLVERS = list(settings['doi_resolvers'])
+MAP_STR2BOOL: Dict[str, bool] = OrderedDict(
+ [
+ ('0', False),
+ ('1', True),
+ ('on', True),
+ ('off', False),
+ ('True', True),
+ ('False', False),
+ ('none', False),
+ ]
+)
+
class ValidationException(Exception):
@@ -199,6 +212,26 @@ class MapSetting(Setting):
resp.set_cookie(name, self.key, max_age=COOKIE_MAX_AGE)
+class BooleanSetting(Setting):
+ """Setting of a boolean value that has to be translated in order to be storable"""
+
+ def normalized_str(self, val):
+ for v_str, v_obj in MAP_STR2BOOL.items():
+ if val == v_obj:
+ return v_str
+ raise ValueError("Invalid value: %s (%s) is not a boolean!" % (repr(val), type(val)))
+
+ def parse(self, data: str):
+ """Parse and validate ``data`` and store the result at ``self.value``"""
+ self.value = MAP_STR2BOOL[data]
+ self.key = self.normalized_str(self.value) # pylint: disable=attribute-defined-outside-init
+
+ def save(self, name: str, resp: flask.Response):
+ """Save cookie ``name`` in the HTTP response object"""
+ if hasattr(self, 'key'):
+ resp.set_cookie(name, self.key, max_age=COOKIE_MAX_AGE)
+
+
class BooleanChoices:
"""Maps strings to booleans that are either true or false."""
@@ -375,17 +408,9 @@ class Preferences:
locked=is_locked('autocomplete'),
choices=list(autocomplete.backends.keys()) + ['']
),
- 'image_proxy': MapSetting(
+ 'image_proxy': BooleanSetting(
settings['server']['image_proxy'],
- locked=is_locked('image_proxy'),
- map={
- '': settings['server']['image_proxy'],
- '0': False,
- '1': True,
- 'True': True,
- 'False': False,
- 'on': True
- }
+ locked=is_locked('image_proxy')
),
'method': EnumStringSetting(
settings['server']['method'],
@@ -406,16 +431,9 @@ class Preferences:
locked=is_locked('theme'),
choices=themes
),
- 'results_on_new_tab': MapSetting(
+ 'results_on_new_tab': BooleanSetting(
settings['ui']['results_on_new_tab'],
- locked=is_locked('results_on_new_tab'),
- map={
- '0': False,
- '1': True,
- 'False': False,
- 'True': True,
- 'on': True
- }
+ locked=is_locked('results_on_new_tab')
),
'doi_resolver': MultipleChoiceSetting(
[settings['default_doi_resolver'], ],
@@ -427,51 +445,21 @@ class Preferences:
locked=is_locked('simple_style'),
choices=['', 'auto', 'light', 'dark']
),
- 'center_alignment': MapSetting(
+ 'center_alignment': BooleanSetting(
settings['ui']['center_alignment'],
- locked=is_locked('center_alignment'),
- map={
- '0': False,
- '1': True,
- 'False': False,
- 'True': True,
- 'on': True
- }
+ locked=is_locked('center_alignment')
),
- 'advanced_search': MapSetting(
+ 'advanced_search': BooleanSetting(
settings['ui']['advanced_search'],
- locked=is_locked('advanced_search'),
- map={
- '0': False,
- '1': True,
- 'False': False,
- 'True': True,
- 'on': True,
- }
+ locked=is_locked('advanced_search')
),
- 'query_in_title': MapSetting(
+ 'query_in_title': BooleanSetting(
settings['ui']['query_in_title'],
- locked=is_locked('query_in_title'),
- map={
- '': settings['ui']['query_in_title'],
- '0': False,
- '1': True,
- 'True': True,
- 'False': False,
- 'on': True
- }
+ locked=is_locked('query_in_title')
),
- 'infinite_scroll': MapSetting(
+ 'infinite_scroll': BooleanSetting(
settings['ui']['infinite_scroll'],
- locked=is_locked('infinite_scroll'),
- map={
- '': settings['ui']['infinite_scroll'],
- '0': False,
- '1': True,
- 'True': True,
- 'False': False,
- 'on': True
- }
+ locked=is_locked('infinite_scroll')
),
# fmt: on
}
@@ -534,6 +522,13 @@ class Preferences:
disabled_engines = []
enabled_categories = []
disabled_plugins = []
+
+ # boolean preferences are not sent by the form if they're false,
+ # so we have to add them as false manually if they're not sent (then they would be true)
+ for key, setting in self.key_value_settings.items():
+ if key not in input_data.keys() and isinstance(setting, BooleanSetting):
+ input_data[key] = 'False'
+
for user_setting_name, user_setting in input_data.items():
if user_setting_name in self.key_value_settings:
self.key_value_settings[user_setting_name].parse(user_setting)