Browse Source

[mod] migrate all key-value.html templates to KeyValue type

The engines now all use KeyValue results and return the results in a
EngineResults object.

The sqlite engine can return MainResult results in addition to KeyValue
results (based on engine's config in settings.yml),

Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
Markus Heiser 1 month ago
parent
commit
f49b2c94a9

+ 9 - 10
searx/engines/command.py

@@ -81,6 +81,7 @@ from subprocess import Popen, PIPE
 from threading import Thread
 from threading import Thread
 
 
 from searx import logger
 from searx import logger
+from searx.result_types import EngineResults
 
 
 
 
 engine_type = 'offline'
 engine_type = 'offline'
@@ -93,7 +94,6 @@ query_enum = []
 environment_variables = {}
 environment_variables = {}
 working_dir = realpath('.')
 working_dir = realpath('.')
 result_separator = '\n'
 result_separator = '\n'
-result_template = 'key-value.html'
 timeout = 4.0
 timeout = 4.0
 
 
 _command_logger = logger.getChild('command')
 _command_logger = logger.getChild('command')
@@ -126,17 +126,17 @@ def init(engine_settings):
         environment_variables = engine_settings['environment_variables']
         environment_variables = engine_settings['environment_variables']
 
 
 
 
-def search(query, params):
+def search(query, params) -> EngineResults:
+    res = EngineResults()
     cmd = _get_command_to_run(query)
     cmd = _get_command_to_run(query)
     if not cmd:
     if not cmd:
-        return []
+        return res
 
 
-    results = []
-    reader_thread = Thread(target=_get_results_from_process, args=(results, cmd, params['pageno']))
+    reader_thread = Thread(target=_get_results_from_process, args=(res, cmd, params['pageno']))
     reader_thread.start()
     reader_thread.start()
     reader_thread.join(timeout=timeout)
     reader_thread.join(timeout=timeout)
 
 
-    return results
+    return res
 
 
 
 
 def _get_command_to_run(query):
 def _get_command_to_run(query):
@@ -153,7 +153,7 @@ def _get_command_to_run(query):
     return cmd
     return cmd
 
 
 
 
-def _get_results_from_process(results, cmd, pageno):
+def _get_results_from_process(res: EngineResults, cmd, pageno):
     leftover = ''
     leftover = ''
     count = 0
     count = 0
     start, end = __get_results_limits(pageno)
     start, end = __get_results_limits(pageno)
@@ -173,12 +173,11 @@ def _get_results_from_process(results, cmd, pageno):
                     continue
                     continue
 
 
                 if start <= count and count <= end:  # pylint: disable=chained-comparison
                 if start <= count and count <= end:  # pylint: disable=chained-comparison
-                    result['template'] = result_template
-                    results.append(result)
+                    res.add(res.types.KeyValue(kvmap=result))
 
 
                 count += 1
                 count += 1
                 if end < count:
                 if end < count:
-                    return results
+                    return res
 
 
             line = process.stdout.readline()
             line = process.stdout.readline()
 
 

+ 18 - 13
searx/engines/demo_offline.py

@@ -13,6 +13,7 @@ close to the implementation, its just a simple example.  To get in use of this
 """
 """
 
 
 import json
 import json
+
 from searx.result_types import EngineResults
 from searx.result_types import EngineResults
 
 
 engine_type = 'offline'
 engine_type = 'offline'
@@ -29,7 +30,7 @@ about = {
 }
 }
 
 
 # if there is a need for globals, use a leading underline
 # if there is a need for globals, use a leading underline
-_my_offline_engine = None
+_my_offline_engine: str = ""
 
 
 
 
 def init(engine_settings=None):
 def init(engine_settings=None):
@@ -50,24 +51,28 @@ def init(engine_settings=None):
 
 
 
 
 def search(query, request_params) -> EngineResults:
 def search(query, request_params) -> EngineResults:
-    """Query (offline) engine and return results.  Assemble the list of results from
-    your local engine.  In this demo engine we ignore the 'query' term, usual
-    you would pass the 'query' term to your local engine to filter out the
+    """Query (offline) engine and return results.  Assemble the list of results
+    from your local engine.  In this demo engine we ignore the 'query' term,
+    usual you would pass the 'query' term to your local engine to filter out the
     results.
     results.
-
     """
     """
     res = EngineResults()
     res = EngineResults()
 
 
-    result_list = json.loads(_my_offline_engine)
-
-    for row in result_list:
-        entry = {
+    count = 0
+    for row in json.loads(_my_offline_engine):
+        count += 1
+        kvmap = {
             'query': query,
             'query': query,
             'language': request_params['searxng_locale'],
             'language': request_params['searxng_locale'],
             'value': row.get("value"),
             'value': row.get("value"),
-            # choose a result template or comment out to use the *default*
-            'template': 'key-value.html',
         }
         }
-        res.append(entry)
-
+        res.add(
+            res.types.KeyValue(
+                caption=f"Demo Offline Engine Result #{count}",
+                key_title="Name",
+                value_title="Value",
+                kvmap=kvmap,
+            )
+        )
+    res.add(res.types.LegacyResult(number_of_results=count))
     return res
     return res

+ 10 - 11
searx/engines/elasticsearch.py

@@ -43,6 +43,8 @@ authentication configured to read from ``my-index`` index.
 
 
 from json import loads, dumps
 from json import loads, dumps
 from searx.exceptions import SearxEngineAPIException
 from searx.exceptions import SearxEngineAPIException
+from searx.result_types import EngineResults
+from searx.extended_types import SXNG_Response
 
 
 
 
 base_url = 'http://localhost:9200'
 base_url = 'http://localhost:9200'
@@ -145,23 +147,20 @@ def _custom_query(query):
     return custom_query
     return custom_query
 
 
 
 
-def response(resp):
-    results = []
+def response(resp: SXNG_Response) -> EngineResults:
+    res = EngineResults()
 
 
     resp_json = loads(resp.text)
     resp_json = loads(resp.text)
     if 'error' in resp_json:
     if 'error' in resp_json:
-        raise SearxEngineAPIException(resp_json['error'])
-
-    for result in resp_json['hits']['hits']:
-        r = {key: str(value) if not key.startswith('_') else value for key, value in result['_source'].items()}
-        r['template'] = 'key-value.html'
+        raise SearxEngineAPIException(resp_json["error"])
 
 
+    for result in resp_json["hits"]["hits"]:
+        kvmap = {key: str(value) if not key.startswith("_") else value for key, value in result["_source"].items()}
         if show_metadata:
         if show_metadata:
-            r['metadata'] = {'index': result['_index'], 'id': result['_id'], 'score': result['_score']}
-
-        results.append(r)
+            kvmap["metadata"] = {"index": result["_index"], "id": result["_id"], "score": result["_score"]}
+        res.add(res.types.KeyValue(kvmap=kvmap))
 
 
-    return results
+    return res
 
 
 
 
 _available_query_types = {
 _available_query_types = {

+ 8 - 8
searx/engines/mariadb_server.py

@@ -35,6 +35,8 @@ except ImportError:
     # the engine
     # the engine
     pass
     pass
 
 
+from searx.result_types import EngineResults
+
 if TYPE_CHECKING:
 if TYPE_CHECKING:
     import logging
     import logging
 
 
@@ -63,7 +65,6 @@ query_str = ""
 
 
 limit = 10
 limit = 10
 paging = True
 paging = True
-result_template = 'key-value.html'
 _connection = None
 _connection = None
 
 
 
 
@@ -79,17 +80,16 @@ def init(engine_settings):
     _connection = mariadb.connect(database=database, user=username, password=password, host=host, port=port)
     _connection = mariadb.connect(database=database, user=username, password=password, host=host, port=port)
 
 
 
 
-def search(query, params):
+def search(query, params) -> EngineResults:
     query_params = {'query': query}
     query_params = {'query': query}
     query_to_run = query_str + ' LIMIT {0} OFFSET {1}'.format(limit, (params['pageno'] - 1) * limit)
     query_to_run = query_str + ' LIMIT {0} OFFSET {1}'.format(limit, (params['pageno'] - 1) * limit)
     logger.debug("SQL Query: %s", query_to_run)
     logger.debug("SQL Query: %s", query_to_run)
+    res = EngineResults()
 
 
     with _connection.cursor() as cur:
     with _connection.cursor() as cur:
         cur.execute(query_to_run, query_params)
         cur.execute(query_to_run, query_params)
-        results = []
         col_names = [i[0] for i in cur.description]
         col_names = [i[0] for i in cur.description]
-        for res in cur:
-            result = dict(zip(col_names, map(str, res)))
-            result['template'] = result_template
-            results.append(result)
-        return results
+        for row in cur:
+            kvmap = dict(zip(col_names, map(str, row)))
+            res.add(res.types.KeyValue(kvmap=kvmap))
+    return res

+ 10 - 11
searx/engines/meilisearch.py

@@ -33,15 +33,15 @@ Here is a simple example to query a Meilisearch instance:
 
 
 # pylint: disable=global-statement
 # pylint: disable=global-statement
 
 
-from json import loads, dumps
-
+from json import dumps
+from searx.result_types import EngineResults
+from searx.extended_types import SXNG_Response
 
 
 base_url = 'http://localhost:7700'
 base_url = 'http://localhost:7700'
 index = ''
 index = ''
 auth_key = ''
 auth_key = ''
 facet_filters = []
 facet_filters = []
 _search_url = ''
 _search_url = ''
-result_template = 'key-value.html'
 categories = ['general']
 categories = ['general']
 paging = True
 paging = True
 
 
@@ -75,13 +75,12 @@ def request(query, params):
     return params
     return params
 
 
 
 
-def response(resp):
-    results = []
+def response(resp: SXNG_Response) -> EngineResults:
+    res = EngineResults()
 
 
-    resp_json = loads(resp.text)
-    for result in resp_json['hits']:
-        r = {key: str(value) for key, value in result.items()}
-        r['template'] = result_template
-        results.append(r)
+    resp_json = resp.json()
+    for row in resp_json['hits']:
+        kvmap = {key: str(value) for key, value in row.items()}
+        res.add(res.types.KeyValue(kvmap=kvmap))
 
 
-    return results
+    return res

+ 12 - 11
searx/engines/mongodb.py

@@ -37,6 +37,7 @@ Implementations
 ===============
 ===============
 
 
 """
 """
+from __future__ import annotations
 
 
 import re
 import re
 
 
@@ -47,6 +48,8 @@ except ImportError:
     # to use the engine
     # to use the engine
     pass
     pass
 
 
+from searx.result_types import EngineResults
+
 
 
 engine_type = 'offline'
 engine_type = 'offline'
 
 
@@ -63,7 +66,6 @@ key = None
 paging = True
 paging = True
 results_per_page = 20
 results_per_page = 20
 exact_match_only = False
 exact_match_only = False
-result_template = 'key-value.html'
 
 
 _client = None
 _client = None
 
 
@@ -74,7 +76,7 @@ def init(_):
 
 
 def connect():
 def connect():
     global _client  # pylint: disable=global-statement
     global _client  # pylint: disable=global-statement
-    kwargs = {'port': port}
+    kwargs: dict[str, str | int] = {'port': port}
     if username:
     if username:
         kwargs['username'] = username
         kwargs['username'] = username
     if password:
     if password:
@@ -82,8 +84,8 @@ def connect():
     _client = MongoClient(host, **kwargs)[database][collection]
     _client = MongoClient(host, **kwargs)[database][collection]
 
 
 
 
-def search(query, params):
-    results = []
+def search(query, params) -> EngineResults:
+    res = EngineResults()
     if exact_match_only:
     if exact_match_only:
         q = {'$eq': query}
         q = {'$eq': query}
     else:
     else:
@@ -92,11 +94,10 @@ def search(query, params):
 
 
     query = _client.find({key: q}).skip((params['pageno'] - 1) * results_per_page).limit(results_per_page)
     query = _client.find({key: q}).skip((params['pageno'] - 1) * results_per_page).limit(results_per_page)
 
 
-    results.append({'number_of_results': query.count()})
-    for r in query:
-        del r['_id']
-        r = {str(k): str(v) for k, v in r.items()}
-        r['template'] = result_template
-        results.append(r)
+    res.add(res.types.LegacyResult(number_of_results=query.count()))
+    for row in query:
+        del row['_id']
+        kvmap = {str(k): str(v) for k, v in row.items()}
+        res.add(res.types.KeyValue(kvmap=kvmap))
 
 
-    return results
+    return res

+ 8 - 13
searx/engines/mysql_server.py

@@ -25,6 +25,8 @@ Implementations
 
 
 """
 """
 
 
+from searx.result_types import EngineResults
+
 try:
 try:
     import mysql.connector  # type: ignore
     import mysql.connector  # type: ignore
 except ImportError:
 except ImportError:
@@ -55,7 +57,6 @@ query_str = ""
 
 
 limit = 10
 limit = 10
 paging = True
 paging = True
-result_template = 'key-value.html'
 _connection = None
 _connection = None
 
 
 
 
@@ -78,21 +79,15 @@ def init(engine_settings):
     )
     )
 
 
 
 
-def search(query, params):
+def search(query, params) -> EngineResults:
+    res = EngineResults()
     query_params = {'query': query}
     query_params = {'query': query}
     query_to_run = query_str + ' LIMIT {0} OFFSET {1}'.format(limit, (params['pageno'] - 1) * limit)
     query_to_run = query_str + ' LIMIT {0} OFFSET {1}'.format(limit, (params['pageno'] - 1) * limit)
 
 
     with _connection.cursor() as cur:
     with _connection.cursor() as cur:
         cur.execute(query_to_run, query_params)
         cur.execute(query_to_run, query_params)
+        for row in cur:
+            kvmap = dict(zip(cur.column_names, map(str, row)))
+            res.add(res.types.KeyValue(kvmap=kvmap))
 
 
-        return _fetch_results(cur)
-
-
-def _fetch_results(cur):
-    results = []
-    for res in cur:
-        result = dict(zip(cur.column_names, map(str, res)))
-        result['template'] = result_template
-        results.append(result)
-
-    return results
+    return res

+ 9 - 12
searx/engines/postgresql.py

@@ -28,6 +28,8 @@ except ImportError:
     # manually to use the engine.
     # manually to use the engine.
     pass
     pass
 
 
+from searx.result_types import EngineResults
+
 engine_type = 'offline'
 engine_type = 'offline'
 
 
 host = "127.0.0.1"
 host = "127.0.0.1"
@@ -50,7 +52,6 @@ query_str = ""
 
 
 limit = 10
 limit = 10
 paging = True
 paging = True
-result_template = 'key-value.html'
 _connection = None
 _connection = None
 
 
 
 
@@ -72,7 +73,7 @@ def init(engine_settings):
     )
     )
 
 
 
 
-def search(query, params):
+def search(query, params) -> EngineResults:
     query_params = {'query': query}
     query_params = {'query': query}
     query_to_run = query_str + ' LIMIT {0} OFFSET {1}'.format(limit, (params['pageno'] - 1) * limit)
     query_to_run = query_str + ' LIMIT {0} OFFSET {1}'.format(limit, (params['pageno'] - 1) * limit)
 
 
@@ -82,20 +83,16 @@ def search(query, params):
             return _fetch_results(cur)
             return _fetch_results(cur)
 
 
 
 
-def _fetch_results(cur):
-    results = []
-    titles = []
-
+def _fetch_results(cur) -> EngineResults:
+    res = EngineResults()
     try:
     try:
         titles = [column_desc.name for column_desc in cur.description]
         titles = [column_desc.name for column_desc in cur.description]
-
-        for res in cur:
-            result = dict(zip(titles, map(str, res)))
-            result['template'] = result_template
-            results.append(result)
+        for row in cur:
+            kvmap = dict(zip(titles, map(str, row)))
+            res.add(res.types.KeyValue(kvmap=kvmap))
 
 
     # no results to fetch
     # no results to fetch
     except psycopg2.ProgrammingError:
     except psycopg2.ProgrammingError:
         pass
         pass
 
 
-    return results
+    return res

+ 20 - 25
searx/engines/redis_server.py

@@ -36,6 +36,8 @@ Implementations
 
 
 import redis  # pylint: disable=import-error
 import redis  # pylint: disable=import-error
 
 
+from searx.result_types import EngineResults
+
 engine_type = 'offline'
 engine_type = 'offline'
 
 
 # redis connection variables
 # redis connection variables
@@ -46,7 +48,6 @@ db = 0
 
 
 # engine specific variables
 # engine specific variables
 paging = False
 paging = False
-result_template = 'key-value.html'
 exact_match_only = True
 exact_match_only = True
 
 
 _redis_client = None
 _redis_client = None
@@ -63,30 +64,25 @@ def init(_engine_settings):
     )
     )
 
 
 
 
-def search(query, _params):
+def search(query, _params) -> EngineResults:
+    res = EngineResults()
+
     if not exact_match_only:
     if not exact_match_only:
-        return search_keys(query)
-
-    ret = _redis_client.hgetall(query)
-    if ret:
-        ret['template'] = result_template
-        return [ret]
-
-    if ' ' in query:
-        qset, rest = query.split(' ', 1)
-        ret = []
-        for res in _redis_client.hscan_iter(qset, match='*{}*'.format(rest)):
-            ret.append(
-                {
-                    res[0]: res[1],
-                    'template': result_template,
-                }
-            )
-        return ret
-    return []
-
-
-def search_keys(query):
+        for kvmap in search_keys(query):
+            res.add(res.types.KeyValue(kvmap=kvmap))
+        return res
+
+    kvmap: dict[str, str] = _redis_client.hgetall(query)
+    if kvmap:
+        res.add(res.types.KeyValue(kvmap=kvmap))
+    elif " " in query:
+        qset, rest = query.split(" ", 1)
+        for row in _redis_client.hscan_iter(qset, match='*{}*'.format(rest)):
+            res.add(res.types.KeyValue(kvmap={row[0]: row[1]}))
+    return res
+
+
+def search_keys(query) -> list[dict]:
     ret = []
     ret = []
     for key in _redis_client.scan_iter(match='*{}*'.format(query)):
     for key in _redis_client.scan_iter(match='*{}*'.format(query)):
         key_type = _redis_client.type(key)
         key_type = _redis_client.type(key)
@@ -98,7 +94,6 @@ def search_keys(query):
             res = dict(enumerate(_redis_client.lrange(key, 0, -1)))
             res = dict(enumerate(_redis_client.lrange(key, 0, -1)))
 
 
         if res:
         if res:
-            res['template'] = result_template
             res['redis_key'] = key
             res['redis_key'] = key
             ret.append(res)
             ret.append(res)
     return ret
     return ret

+ 15 - 20
searx/engines/solr.py

@@ -29,9 +29,10 @@ This is an example configuration for searching in the collection
 
 
 # pylint: disable=global-statement
 # pylint: disable=global-statement
 
 
-from json import loads
 from urllib.parse import urlencode
 from urllib.parse import urlencode
 from searx.exceptions import SearxEngineAPIException
 from searx.exceptions import SearxEngineAPIException
+from searx.result_types import EngineResults
+from searx.extended_types import SXNG_Response
 
 
 
 
 base_url = 'http://localhost:8983'
 base_url = 'http://localhost:8983'
@@ -72,27 +73,21 @@ def request(query, params):
     return params
     return params
 
 
 
 
-def response(resp):
-    resp_json = __get_response(resp)
-
-    results = []
-    for result in resp_json['response']['docs']:
-        r = {key: str(value) for key, value in result.items()}
-        if len(r) == 0:
-            continue
-        r['template'] = 'key-value.html'
-        results.append(r)
-
-    return results
-
-
-def __get_response(resp):
+def response(resp: SXNG_Response) -> EngineResults:
     try:
     try:
-        resp_json = loads(resp.text)
+        resp_json = resp.json()
     except Exception as e:
     except Exception as e:
         raise SearxEngineAPIException("failed to parse response") from e
         raise SearxEngineAPIException("failed to parse response") from e
 
 
-    if 'error' in resp_json:
-        raise SearxEngineAPIException(resp_json['error']['msg'])
+    if "error" in resp_json:
+        raise SearxEngineAPIException(resp_json["error"]["msg"])
+
+    res = EngineResults()
+
+    for result in resp_json["response"]["docs"]:
+        kvmap = {key: str(value) for key, value in result.items()}
+        if not kvmap:
+            continue
+        res.add(res.types.KeyValue(kvmap=kvmap))
 
 
-    return resp_json
+    return res

+ 39 - 25
searx/engines/sqlite.py

@@ -2,6 +2,14 @@
 """SQLite is a small, fast and reliable SQL database engine.  It does not require
 """SQLite is a small, fast and reliable SQL database engine.  It does not require
 any extra dependency.
 any extra dependency.
 
 
+Configuration
+=============
+
+The engine has the following (additional) settings:
+
+- :py:obj:`result_type`
+
+
 Example
 Example
 =======
 =======
 
 
@@ -18,29 +26,32 @@ Query to test: ``!mediathekview concert``
 
 
 .. code:: yaml
 .. code:: yaml
 
 
-   - name: mediathekview
-     engine: sqlite
-     disabled: False
-     categories: general
-     result_template: default.html
-     database: searx/data/filmliste-v2.db
-     query_str:  >-
-       SELECT title || ' (' || time(duration, 'unixepoch') || ')' AS title,
-              COALESCE( NULLIF(url_video_hd,''), NULLIF(url_video_sd,''), url_video) AS url,
-              description AS content
-         FROM film
-        WHERE title LIKE :wildcard OR description LIKE :wildcard
-        ORDER BY duration DESC
+  - name: mediathekview
+    engine: sqlite
+    shortcut: mediathekview
+    categories: [general, videos]
+    result_type: MainResult
+    database: searx/data/filmliste-v2.db
+    query_str: >-
+      SELECT title || ' (' || time(duration, 'unixepoch') || ')' AS title,
+             COALESCE( NULLIF(url_video_hd,''), NULLIF(url_video_sd,''), url_video) AS url,
+             description AS content
+        FROM film
+       WHERE title LIKE :wildcard OR description LIKE :wildcard
+       ORDER BY duration DESC
 
 
 Implementations
 Implementations
 ===============
 ===============
 
 
 """
 """
-
+import typing
 import sqlite3
 import sqlite3
 import contextlib
 import contextlib
 
 
-engine_type = 'offline'
+from searx.result_types import EngineResults
+from searx.result_types import MainResult, KeyValue
+
+engine_type = "offline"
 
 
 database = ""
 database = ""
 """Filename of the SQLite DB."""
 """Filename of the SQLite DB."""
@@ -48,9 +59,11 @@ database = ""
 query_str = ""
 query_str = ""
 """SQL query that returns the result items."""
 """SQL query that returns the result items."""
 
 
+result_type: typing.Literal["MainResult", "KeyValue"] = "KeyValue"
+"""The result type can be :py:obj:`MainResult` or :py:obj:`KeyValue`."""
+
 limit = 10
 limit = 10
 paging = True
 paging = True
-result_template = 'key-value.html'
 
 
 
 
 def init(engine_settings):
 def init(engine_settings):
@@ -80,9 +93,8 @@ def sqlite_cursor():
             yield cursor
             yield cursor
 
 
 
 
-def search(query, params):
-    results = []
-
+def search(query, params) -> EngineResults:
+    res = EngineResults()
     query_params = {
     query_params = {
         'query': query,
         'query': query,
         'wildcard': r'%' + query.replace(' ', r'%') + r'%',
         'wildcard': r'%' + query.replace(' ', r'%') + r'%',
@@ -97,9 +109,11 @@ def search(query, params):
         col_names = [cn[0] for cn in cur.description]
         col_names = [cn[0] for cn in cur.description]
 
 
         for row in cur.fetchall():
         for row in cur.fetchall():
-            item = dict(zip(col_names, map(str, row)))
-            item['template'] = result_template
-            logger.debug("append result --> %s", item)
-            results.append(item)
-
-    return results
+            kvmap = dict(zip(col_names, map(str, row)))
+            if result_type == "MainResult":
+                item = MainResult(**kvmap)  # type: ignore
+            else:
+                item = KeyValue(kvmap=kvmap)
+            res.add(item)
+
+    return res

+ 6 - 6
searx/settings.yml

@@ -1888,15 +1888,15 @@ engines:
   # For this demo of the sqlite engine download:
   # For this demo of the sqlite engine download:
   #   https://liste.mediathekview.de/filmliste-v2.db.bz2
   #   https://liste.mediathekview.de/filmliste-v2.db.bz2
   # and unpack into searx/data/filmliste-v2.db
   # and unpack into searx/data/filmliste-v2.db
-  # Query to test: "!demo concert"
+  # Query to test: "!mediathekview concert"
   #
   #
-  # - name: demo
+  # - name: mediathekview
   #   engine: sqlite
   #   engine: sqlite
-  #   shortcut: demo
-  #   categories: general
-  #   result_template: default.html
+  #   shortcut: mediathekview
+  #   categories: [general, videos]
+  #   result_type: MainResult
   #   database: searx/data/filmliste-v2.db
   #   database: searx/data/filmliste-v2.db
-  #   query_str:  >-
+  #   query_str: >-
   #     SELECT title || ' (' || time(duration, 'unixepoch') || ')' AS title,
   #     SELECT title || ' (' || time(duration, 'unixepoch') || ')' AS title,
   #            COALESCE( NULLIF(url_video_hd,''), NULLIF(url_video_sd,''), url_video) AS url,
   #            COALESCE( NULLIF(url_video_hd,''), NULLIF(url_video_sd,''), url_video) AS url,
   #            description AS content
   #            description AS content

+ 0 - 11
searx/templates/simple/result_templates/key-value.html

@@ -1,11 +0,0 @@
-<table>
-    {% for key, value in result.items() %}
-    {% if key in ['engine', 'engines', 'template', 'score', 'category', 'positions', 'parsed_url'] %}
-        {% continue %}
-    {% endif %}
-    <tr>
-        <td><b>{{ key|upper }}</b>: {{ value }}</td>
-    </tr>
-    {% endfor %}
-</table>
-<div class="engines">{% for engine in result.engines %}<span>{{ engine }}</span>{% endfor %}</div>{{- '' -}}