[enh] add surrogates

to lower fork maintenance, some objects in SearXNG can be replaced.
The configuration is done in settings.yml
This commit is contained in:
Alexandre Flament 2021-09-15 16:34:52 +02:00
parent 602cbc2c99
commit 752c224608
11 changed files with 102 additions and 52 deletions

View file

@ -8,6 +8,7 @@ from searx.engines import categories, engines, engine_shortcuts
from searx.external_bang import get_bang_definition_and_autocomplete
from searx.search import EngineRef
from searx.webutils import VALID_LANGUAGE_CODE
from searx.surrogates import get_actual_object
class QueryPartParser(ABC):
@ -232,7 +233,7 @@ class BangParser(QueryPartParser):
self._add_autocomplete(first_char + engine_shortcut)
class RawTextQuery:
class DefaultRawTextQuery:
"""parse raw text query (the value from the html input)"""
PARSER_CLASSES = [
@ -328,3 +329,6 @@ class RawTextQuery:
+ f"autocomplete_list={self.autocomplete_list!r}\n " \
+ f"query_parts={self.query_parts!r}\n " \
+ f"user_query_parts={self.user_query_parts!r} >"
RawTextQuery = get_actual_object('searx.query.RawTextQuery', DefaultRawTextQuery)

View file

@ -19,6 +19,7 @@ from searx.network import initialize as initialize_network
from searx.metrics import initialize as initialize_metrics, counter_inc, histogram_observe_time
from searx.search.processors import PROCESSORS, initialize as initialize_processors
from searx.search.checker import initialize as initialize_checker
from searx.surrogates import get_actual_object
logger = logger.getChild('search')
@ -34,7 +35,7 @@ def initialize(settings_engines=None, enable_checker=False):
initialize_checker()
class Search:
class BasicSearch:
"""Search information container"""
__slots__ = "search_query", "result_container", "start_time", "actual_timeout"
@ -171,7 +172,7 @@ class Search:
return self.result_container
class SearchWithPlugins(Search):
class SearchWithPlugins(BasicSearch):
"""Inherit from the Search class, add calls to the plugins."""
__slots__ = 'ordered_plugin_list', 'request'
@ -201,3 +202,6 @@ class SearchWithPlugins(Search):
self.result_container.close()
return self.result_container
Search = get_actual_object('searx.search.Search', SearchWithPlugins)

View file

@ -29,6 +29,10 @@ search:
formats:
- html
# surrogates:
# searx.search.Search: bidule.search.SearchWithPlugins
# searx.query.RawTextQuery: searx.query.DefaultRawTextQuery
server:
# If you change port, bind_address or base_url don't forget to rebuild
# instance's enviroment (make buildenv)

View file

@ -135,6 +135,10 @@ SCHEMA = {
'public_instances': SettingsValue(str, None),
'wiki_url': SettingsValue(str, None),
},
'surrogates': SettingsValue(dict, {
'searx.search.Search': 'searx.search.SearchWithPlugins',
'searx.query.RawTextQuery': 'searx.query.DefaultRawTextQuery',
}),
'search': {
'safe_search': SettingsValue((0,1,2), 0),
'autocomplete': SettingsValue(str, ''),

35
searx/surrogates.py Normal file
View file

@ -0,0 +1,35 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
# lint: pylint
"""
Allow to replace some objects using settings.yml to lower fork maintenance.
"""
import sys
from importlib import import_module
from functools import wraps
from searx import settings, logger
logger = logger.getChild('surrogates')
def _get_obj_by_name(name):
module_name, obj_name = name.rsplit('.', 1)
if module_name not in sys.modules:
module = import_module(module_name)
else:
module = sys.modules[module_name]
return getattr(module, obj_name, None)
def get_actual_object(name, obj):
surrogate_name = settings['surrogates'].get(name)
actual_obj = _get_obj_by_name(surrogate_name) if surrogate_name else obj
logger.info('Replace "%s" with "%s"', name, surrogate_name)
if not callable(actual_obj):
raise ValueError(f"{surrogate_name} is not callable")
@wraps(obj)
def wrapped(*args, **kwargs):
return actual_obj(*args, **kwargs)
return wrapped

View file

@ -109,7 +109,7 @@ from searx.flaskfix import patch_application
from searx.autocomplete import search_autocomplete, backends as autocomplete_backends
from searx.languages import language_codes as languages
from searx.locales import LOCALE_NAMES, UI_LOCALE_CODES, RTL_LOCALES
from searx.search import SearchWithPlugins, initialize as search_initialize
from searx.search import Search, initialize as search_initialize
from searx.network import stream as http_stream, set_context_network_name
from searx.search.checker import get_result as checker_get_result
@ -652,8 +652,7 @@ def search():
search_query, raw_text_query, _, _ = get_search_query_from_webapp(
request.preferences, request.form
)
# search = Search(search_query) # without plugins
search = SearchWithPlugins(search_query, request.user_plugins, request) # pylint: disable=redefined-outer-name
search = Search(search_query, request.user_plugins, request) # pylint: disable=redefined-outer-name
result_container = search.search()