[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>
This commit is contained in:
parent
af5dbdf768
commit
f49b2c94a9
@ -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=(res, cmd, params['pageno']))
|
||||||
reader_thread = Thread(target=_get_results_from_process, args=(results, 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
|
res.add(res.types.KeyValue(kvmap=result))
|
||||||
results.append(result)
|
|
||||||
|
|
||||||
count += 1
|
count += 1
|
||||||
if end < count:
|
if end < count:
|
||||||
return results
|
return res
|
||||||
|
|
||||||
line = process.stdout.readline()
|
line = process.stdout.readline()
|
||||||
|
|
||||||
|
@ -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
|
"""Query (offline) engine and return results. Assemble the list of results
|
||||||
your local engine. In this demo engine we ignore the 'query' term, usual
|
from your local engine. In this demo engine we ignore the 'query' term,
|
||||||
you would pass the 'query' term to your local engine to filter out the
|
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)
|
count = 0
|
||||||
|
for row in json.loads(_my_offline_engine):
|
||||||
for row in result_list:
|
count += 1
|
||||||
entry = {
|
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
|
||||||
|
@ -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):
|
def response(resp: SXNG_Response) -> EngineResults:
|
||||||
results = []
|
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'])
|
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'
|
|
||||||
|
|
||||||
|
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']}
|
kvmap["metadata"] = {"index": result["_index"], "id": result["_id"], "score": result["_score"]}
|
||||||
|
res.add(res.types.KeyValue(kvmap=kvmap))
|
||||||
|
|
||||||
results.append(r)
|
return res
|
||||||
|
|
||||||
return results
|
|
||||||
|
|
||||||
|
|
||||||
_available_query_types = {
|
_available_query_types = {
|
||||||
|
@ -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:
|
for row in cur:
|
||||||
result = dict(zip(col_names, map(str, res)))
|
kvmap = dict(zip(col_names, map(str, row)))
|
||||||
result['template'] = result_template
|
res.add(res.types.KeyValue(kvmap=kvmap))
|
||||||
results.append(result)
|
return res
|
||||||
return results
|
|
||||||
|
@ -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):
|
def response(resp: SXNG_Response) -> EngineResults:
|
||||||
results = []
|
res = EngineResults()
|
||||||
|
|
||||||
resp_json = loads(resp.text)
|
resp_json = resp.json()
|
||||||
for result in resp_json['hits']:
|
for row in resp_json['hits']:
|
||||||
r = {key: str(value) for key, value in result.items()}
|
kvmap = {key: str(value) for key, value in row.items()}
|
||||||
r['template'] = result_template
|
res.add(res.types.KeyValue(kvmap=kvmap))
|
||||||
results.append(r)
|
|
||||||
|
|
||||||
return results
|
return res
|
||||||
|
@ -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):
|
def search(query, params) -> EngineResults:
|
||||||
results = []
|
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()})
|
res.add(res.types.LegacyResult(number_of_results=query.count()))
|
||||||
for r in query:
|
for row in query:
|
||||||
del r['_id']
|
del row['_id']
|
||||||
r = {str(k): str(v) for k, v in r.items()}
|
kvmap = {str(k): str(v) for k, v in row.items()}
|
||||||
r['template'] = result_template
|
res.add(res.types.KeyValue(kvmap=kvmap))
|
||||||
results.append(r)
|
|
||||||
|
|
||||||
return results
|
return res
|
||||||
|
@ -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)
|
return res
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
|
@ -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):
|
def _fetch_results(cur) -> EngineResults:
|
||||||
results = []
|
res = EngineResults()
|
||||||
titles = []
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
titles = [column_desc.name for column_desc in cur.description]
|
titles = [column_desc.name for column_desc in cur.description]
|
||||||
|
for row in cur:
|
||||||
for res in cur:
|
kvmap = dict(zip(titles, map(str, row)))
|
||||||
result = dict(zip(titles, map(str, res)))
|
res.add(res.types.KeyValue(kvmap=kvmap))
|
||||||
result['template'] = result_template
|
|
||||||
results.append(result)
|
|
||||||
|
|
||||||
# no results to fetch
|
# no results to fetch
|
||||||
except psycopg2.ProgrammingError:
|
except psycopg2.ProgrammingError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return results
|
return res
|
||||||
|
@ -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)
|
for kvmap in search_keys(query):
|
||||||
|
res.add(res.types.KeyValue(kvmap=kvmap))
|
||||||
|
return res
|
||||||
|
|
||||||
ret = _redis_client.hgetall(query)
|
kvmap: dict[str, str] = _redis_client.hgetall(query)
|
||||||
if ret:
|
if kvmap:
|
||||||
ret['template'] = result_template
|
res.add(res.types.KeyValue(kvmap=kvmap))
|
||||||
return [ret]
|
elif " " in query:
|
||||||
|
qset, rest = query.split(" ", 1)
|
||||||
if ' ' in query:
|
for row in _redis_client.hscan_iter(qset, match='*{}*'.format(rest)):
|
||||||
qset, rest = query.split(' ', 1)
|
res.add(res.types.KeyValue(kvmap={row[0]: row[1]}))
|
||||||
ret = []
|
return res
|
||||||
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):
|
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
|
||||||
|
@ -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):
|
def response(resp: SXNG_Response) -> EngineResults:
|
||||||
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):
|
|
||||||
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:
|
if "error" in resp_json:
|
||||||
raise SearxEngineAPIException(resp_json['error']['msg'])
|
raise SearxEngineAPIException(resp_json["error"]["msg"])
|
||||||
|
|
||||||
return resp_json
|
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 res
|
||||||
|
@ -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
|
||||||
=======
|
=======
|
||||||
|
|
||||||
@ -20,9 +28,9 @@ Query to test: ``!mediathekview concert``
|
|||||||
|
|
||||||
- name: mediathekview
|
- name: mediathekview
|
||||||
engine: sqlite
|
engine: sqlite
|
||||||
disabled: False
|
shortcut: mediathekview
|
||||||
categories: general
|
categories: [general, videos]
|
||||||
result_template: default.html
|
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,
|
||||||
@ -36,11 +44,14 @@ 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):
|
def search(query, params) -> EngineResults:
|
||||||
results = []
|
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)))
|
kvmap = dict(zip(col_names, map(str, row)))
|
||||||
item['template'] = result_template
|
if result_type == "MainResult":
|
||||||
logger.debug("append result --> %s", item)
|
item = MainResult(**kvmap) # type: ignore
|
||||||
results.append(item)
|
else:
|
||||||
|
item = KeyValue(kvmap=kvmap)
|
||||||
|
res.add(item)
|
||||||
|
|
||||||
return results
|
return res
|
||||||
|
@ -1888,13 +1888,13 @@ 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
|
# shortcut: mediathekview
|
||||||
# categories: general
|
# categories: [general, videos]
|
||||||
# result_template: default.html
|
# 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,
|
||||||
|
@ -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>{{- '' -}}
|
|
Loading…
x
Reference in New Issue
Block a user