mirror of https://github.com/searxng/searxng.git
Compare commits
6 Commits
1e1fb59bea
...
ecee56533c
Author | SHA1 | Date |
---|---|---|
Jinyuan Huang | ecee56533c | |
Markus Heiser | 11fdc2f56a | |
Markus Heiser | 648f43be1d | |
Bnyro | 3ea278aff4 | |
Bnyro | 46efb2f36d | |
Bnyro | b3b1258e4e |
File diff suppressed because it is too large
Load Diff
|
@ -238,7 +238,10 @@ def unit_to_str(unit):
|
|||
for prefix in WIKIDATA_PREFIX:
|
||||
if unit.startswith(prefix):
|
||||
wikidata_entity = unit[len(prefix) :]
|
||||
return WIKIDATA_UNITS.get(wikidata_entity, unit)
|
||||
real_unit = WIKIDATA_UNITS.get(wikidata_entity)
|
||||
if real_unit is None:
|
||||
return unit
|
||||
return real_unit['symbol']
|
||||
return unit
|
||||
|
||||
|
||||
|
|
|
@ -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
|
|
@ -1082,25 +1082,6 @@ engines:
|
|||
require_api_key: false
|
||||
results: HTML
|
||||
|
||||
- name: azlyrics
|
||||
shortcut: lyrics
|
||||
engine: xpath
|
||||
timeout: 4.0
|
||||
disabled: true
|
||||
categories: [music, lyrics]
|
||||
paging: true
|
||||
search_url: https://search.azlyrics.com/search.php?q={query}&w=lyrics&p={pageno}
|
||||
url_xpath: //td[@class="text-left visitedlyr"]/a/@href
|
||||
title_xpath: //span/b/text()
|
||||
content_xpath: //td[@class="text-left visitedlyr"]/a/small
|
||||
about:
|
||||
website: https://azlyrics.com
|
||||
wikidata_id: Q66372542
|
||||
official_api_documentation:
|
||||
use_official_api: false
|
||||
require_api_key: false
|
||||
results: HTML
|
||||
|
||||
- name: mastodon users
|
||||
engine: mastodon
|
||||
mastodon_type: accounts
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -27,6 +27,22 @@
|
|||
searxng.on(el, 'mouseenter', load_engine_descriptions);
|
||||
}
|
||||
|
||||
const enableAllEngines = d.querySelectorAll(".enable-all-engines");
|
||||
const disableAllEngines = d.querySelectorAll(".disable-all-engines");
|
||||
const engineToggles = d.querySelectorAll('tbody input[type=checkbox][class~=checkbox-onoff]');
|
||||
const toggleEngines = (enable) => {
|
||||
for (const el of engineToggles) {
|
||||
// check if element visible, so that only engines of the current category are modified
|
||||
if (el.offsetParent !== null) el.checked = !enable;
|
||||
}
|
||||
};
|
||||
for (const el of enableAllEngines) {
|
||||
searxng.on(el, 'click', () => toggleEngines(true));
|
||||
}
|
||||
for (const el of disableAllEngines) {
|
||||
searxng.on(el, 'click', () => toggleEngines(false));
|
||||
}
|
||||
|
||||
const copyHashButton = d.querySelector("#copy-hash");
|
||||
searxng.on(copyHashButton, 'click', (e) => {
|
||||
e.preventDefault();
|
||||
|
|
|
@ -185,6 +185,11 @@ table {
|
|||
}
|
||||
}
|
||||
|
||||
#toggle-all-engines-container {
|
||||
width: max-content;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
div.selectable_url {
|
||||
pre {
|
||||
width: 100%;
|
||||
|
|
|
@ -63,7 +63,7 @@ or manually by executing the searx/webapp.py file? -->
|
|||
<input type="checkbox" id="step1">
|
||||
<label for="step1">{{ _('Start submiting a new issue on GitHub') }}</label>
|
||||
<div class="step1 step_content">
|
||||
<p><a href="{{ get_setting('brand.issue_url') }}?q=is%3Aissue+Bug:%20{{ engine_name }}" target="_blank" rel="noreferrer noreferrer">{{ _('Please check for existing bugs about this engine on GitHub') }}</a></p>
|
||||
<p><a href="{{ get_setting('brand.issue_url') }}?q=is%3Aissue+Bug:%20{{ engine_name }} {{ technical_report }}" target="_blank" rel="noreferrer noreferrer">{{ _('Please check for existing bugs about this engine on GitHub') }}</a></p>
|
||||
</div>
|
||||
<input class="step1 step1_delay" type="checkbox" id="step2">
|
||||
<label class="step1 step1_delay" for="step2" >{{ _('I confirm there is no existing bug about the issue I encounter') }}</label>
|
||||
|
|
|
@ -10,6 +10,12 @@
|
|||
{{- ' ' -}}<a href="{{ url_for('info', pagename='search-syntax') }}">ⓘ</a>
|
||||
</p>
|
||||
{%- endif -%}
|
||||
|
||||
<div class="hide_if_nojs" id="toggle-all-engines-container">
|
||||
<button type="button" class="button enable-all-engines">{{ _("Enable all") }}</button>
|
||||
<button type="button" class="button disable-all-engines">{{ _("Disable all") }}</button>
|
||||
</div>
|
||||
|
||||
<div class="scrollx">{{- '' -}}
|
||||
<table class="striped table_engines">{{- '' -}}
|
||||
|
||||
|
|
|
@ -1161,6 +1161,21 @@ def stats():
|
|||
reliability_order = 1 - reliability_order
|
||||
return (reliability_order, key, engine_stat['name'])
|
||||
|
||||
technical_report = []
|
||||
for error in engine_reliabilities.get(selected_engine_name, {}).get('errors', []):
|
||||
technical_report.append(
|
||||
f"\
|
||||
Error: {error['exception_classname'] or error['log_message']} \
|
||||
Parameters: {error['log_parameters']} \
|
||||
File name: {error['filename'] }:{ error['line_no'] } \
|
||||
Error Function: {error['function']} \
|
||||
Code: {error['code']} \
|
||||
".replace(
|
||||
' ' * 12, ''
|
||||
).strip()
|
||||
)
|
||||
technical_report = ' '.join(technical_report)
|
||||
|
||||
engine_stats['time'] = sorted(engine_stats['time'], reverse=reverse, key=get_key)
|
||||
return render(
|
||||
# fmt: off
|
||||
|
@ -1170,6 +1185,7 @@ def stats():
|
|||
engine_reliabilities = engine_reliabilities,
|
||||
selected_engine_name = selected_engine_name,
|
||||
searx_git_branch = GIT_BRANCH,
|
||||
technical_report = technical_report,
|
||||
# fmt: on
|
||||
)
|
||||
|
||||
|
|
|
@ -29,31 +29,46 @@ set_loggers(wikidata, 'wikidata')
|
|||
# * https://www.wikidata.org/wiki/Help:Ranking
|
||||
# * https://www.mediawiki.org/wiki/Wikibase/Indexing/RDF_Dump_Format ("Statement representation" section)
|
||||
# * https://w.wiki/32BT
|
||||
# * https://en.wikibooks.org/wiki/SPARQL/WIKIDATA_Precision,_Units_and_Coordinates#Quantities
|
||||
# see the result for https://www.wikidata.org/wiki/Q11582
|
||||
# there are multiple symbols the same rank
|
||||
SARQL_REQUEST = """
|
||||
SELECT DISTINCT ?item ?symbol
|
||||
SELECT DISTINCT ?item ?symbol ?tosi ?tosiUnit
|
||||
WHERE
|
||||
{
|
||||
?item wdt:P31/wdt:P279 wd:Q47574 .
|
||||
?item p:P5061 ?symbolP .
|
||||
?symbolP ps:P5061 ?symbol ;
|
||||
wikibase:rank ?rank .
|
||||
OPTIONAL {
|
||||
?item p:P2370 ?tosistmt .
|
||||
?tosistmt psv:P2370 ?tosinode .
|
||||
?tosinode wikibase:quantityAmount ?tosi .
|
||||
?tosinode wikibase:quantityUnit ?tosiUnit .
|
||||
}
|
||||
FILTER(LANG(?symbol) = "en").
|
||||
}
|
||||
ORDER BY ?item DESC(?rank) ?symbol
|
||||
"""
|
||||
|
||||
_wikidata_url = "https://www.wikidata.org/entity/"
|
||||
|
||||
|
||||
def get_data():
|
||||
results = collections.OrderedDict()
|
||||
response = wikidata.send_wikidata_query(SARQL_REQUEST)
|
||||
for unit in response['results']['bindings']:
|
||||
name = unit['item']['value'].replace('http://www.wikidata.org/entity/', '')
|
||||
unit = unit['symbol']['value']
|
||||
name = unit['item']['value'].replace(_wikidata_url, '')
|
||||
symbol = unit['symbol']['value']
|
||||
si_name = unit.get('tosiUnit', {}).get('value', '').replace(_wikidata_url, '')
|
||||
to_si_factor = unit.get('tosi', {}).get('value', '')
|
||||
if name not in results:
|
||||
# ignore duplicate: always use the first one
|
||||
results[name] = unit
|
||||
results[name] = {
|
||||
'symbol': symbol,
|
||||
'si_name': si_name if si_name else None,
|
||||
'to_si_factor': float(to_si_factor) if to_si_factor else None,
|
||||
}
|
||||
return results
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue