mirror of https://github.com/searxng/searxng
[feat] plugins: new unit converter plugin
parent
b3b1258e4e
commit
46efb2f36d
@ -0,0 +1,76 @@
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
"""Calculate mathematical expressions using ack#eval
|
||||
"""
|
||||
|
||||
from flask_babel import gettext
|
||||
|
||||
from searx.data import WIKIDATA_UNITS
|
||||
|
||||
name = "Unit converter plugin"
|
||||
description = gettext("Convert between units")
|
||||
default_on = True
|
||||
|
||||
CONVERT_KEYWORDS = ["in", "to", "as"]
|
||||
|
||||
|
||||
def _convert(from_value, source_si_factor, target_si_factor):
|
||||
return from_value * source_si_factor / target_si_factor
|
||||
|
||||
|
||||
def _parse_text_and_convert(search, splitted_query):
|
||||
if len(splitted_query) != 2 or splitted_query[0].strip() == "" or splitted_query[1].strip() == "":
|
||||
return
|
||||
|
||||
from_value = ""
|
||||
from_unit_key = ""
|
||||
|
||||
# only parse digits as value that belong together
|
||||
read_alpha = False
|
||||
for c in splitted_query[0]:
|
||||
if not read_alpha and (c in ("-", ".") or str.isdigit(c)):
|
||||
from_value += c
|
||||
read_alpha = True
|
||||
elif c != " ":
|
||||
from_unit_key += c
|
||||
|
||||
to_unit_key = splitted_query[1].strip()
|
||||
|
||||
from_unit = None
|
||||
to_unit = None
|
||||
|
||||
for unit in WIKIDATA_UNITS.values():
|
||||
if unit['symbol'] == from_unit_key:
|
||||
from_unit = unit
|
||||
|
||||
if unit['symbol'] == to_unit_key:
|
||||
to_unit = unit
|
||||
|
||||
if from_unit and to_unit:
|
||||
break
|
||||
|
||||
if from_unit is None or to_unit is None or to_unit.get('si_name') != from_unit.get('si_name'):
|
||||
return
|
||||
|
||||
result = _convert(float(from_value), from_unit['to_si_factor'], to_unit['to_si_factor'])
|
||||
search.result_container.answers['conversion'] = {'answer': f"{result:g} {to_unit['symbol']}"}
|
||||
|
||||
|
||||
def post_search(_request, search):
|
||||
# only convert between units on the first page
|
||||
if search.search_query.pageno > 1:
|
||||
return True
|
||||
|
||||
query = search.search_query.query
|
||||
query_parts = query.split(" ")
|
||||
|
||||
if len(query_parts) < 3:
|
||||
return True
|
||||
|
||||
for query_part in query_parts:
|
||||
for keyword in CONVERT_KEYWORDS:
|
||||
if query_part == keyword:
|
||||
keyword_split = query.split(keyword, 1)
|
||||
_parse_text_and_convert(search, keyword_split)
|
||||
return True
|
||||
|
||||
return True
|
Loading…
Reference in New Issue