diff options
author | Bnyro <bnyro@tutanota.com> | 2024-04-07 16:17:11 +0200 |
---|---|---|
committer | Markus Heiser <markus.heiser@darmarIT.de> | 2024-04-27 18:11:33 +0200 |
commit | 46efb2f36d327e618c5cd6af702b96fa9143fc27 (patch) | |
tree | ca6cd38a297c87b2c09df3d4dcbb3e287dd29b6d /searx/plugins | |
parent | b3b1258e4e976ae27e8254fbc17339764276689b (diff) | |
download | searxng-46efb2f36d327e618c5cd6af702b96fa9143fc27.tar.gz searxng-46efb2f36d327e618c5cd6af702b96fa9143fc27.zip |
[feat] plugins: new unit converter plugin
Diffstat (limited to 'searx/plugins')
-rw-r--r-- | searx/plugins/unit_converter.py | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/searx/plugins/unit_converter.py b/searx/plugins/unit_converter.py new file mode 100644 index 000000000..dd515aa72 --- /dev/null +++ b/searx/plugins/unit_converter.py @@ -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 |