Merge pull request #333 from dalf/enh-engine-descriptions

RFC: /preferences: display engine descriptions
This commit is contained in:
Alexandre Flament 2021-09-25 11:29:25 +02:00 committed by GitHub
commit b046322c7b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 4111 additions and 57 deletions

View file

@ -14,6 +14,7 @@ __all__ = [
'WIKIDATA_UNITS',
'EXTERNAL_BANGS',
'OSM_KEYS_TAGS',
'ENGINE_DESCRIPTIONS',
'ahmia_blacklist_loader',
]
@ -45,3 +46,4 @@ EXTERNAL_URLS = _load('external_urls.json')
WIKIDATA_UNITS = _load('wikidata_units.json')
EXTERNAL_BANGS = _load('external_bangs.json')
OSM_KEYS_TAGS = _load('osm_keys_tags.json')
ENGINE_DESCRIPTIONS = _load('engine_descriptions.json')

File diff suppressed because it is too large Load diff

View file

@ -12,6 +12,16 @@ from dateutil.parser import parse as dateparse
from lxml import html
from searx.utils import extract_text
# about
about = {
"website": 'https://bandcamp.com/',
"wikidata_id": 'Q545966',
"official_api_documentation": 'https://bandcamp.com/developer',
"use_official_api": False,
"require_api_key": False,
"results": 'HTML',
}
categories = ['music']
paging = True

View file

@ -9,9 +9,9 @@ from searx.utils import searx_useragent
# about
about = {
"website": 'https://photon.komoot.de',
"website": 'https://photon.komoot.io',
"wikidata_id": None,
"official_api_documentation": 'https://photon.komoot.de/',
"official_api_documentation": 'https://photon.komoot.io/',
"use_official_api": True,
"require_api_key": False,
"results": 'JSON',

View file

@ -1618,7 +1618,7 @@ engines:
categories: general
about:
website: https://brave.com/search/
wikidata_id: Q22906900
wikidata_id: Q107355971
use_official_api: false
require_api_key: false
results: HTML

View file

@ -1309,6 +1309,7 @@ input.cursor-text {
font-size: 14px;
font-weight: normal;
z-index: 1000000;
max-width: 40rem;
}
td:hover .engine-tooltip,
th:hover .engine-tooltip,

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1336,6 +1336,7 @@ input.cursor-text {
font-size: 14px;
font-weight: normal;
z-index: 1000000;
max-width: 40rem;
}
td:hover .engine-tooltip,
th:hover .engine-tooltip,

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -299,6 +299,29 @@ $(document).ready(function(){
$( this ).off( event );
});
});
;$(document).ready(function(){
let engine_descriptions = null;
function load_engine_descriptions() {
if (engine_descriptions == null) {
$.ajax("engine_descriptions.json", dataType="json").done(function(data) {
engine_descriptions = data;
for (const [engine_name, description] of Object.entries(data)) {
let elements = $('[data-engine-name="' + engine_name + '"] .description');
for(const element of elements) {
let source = ' (<i>' + searx.translations['Source'] + ':&nbsp;' + description[1] + '</i>)';
element.innerHTML = description[0] + source;
}
}
});
}
}
if (document.querySelector('body[class="preferences_endpoint"]')) {
$('[data-engine-name]').hover(function() {
load_engine_descriptions();
});
}
});
;$(document).ready(function(){
$("#allow-all-engines").click(function() {
$(".onoffswitch-checkbox").each(function() { this.checked = false;});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,23 @@
$(document).ready(function(){
let engine_descriptions = null;
function load_engine_descriptions() {
if (engine_descriptions == null) {
$.ajax("engine_descriptions.json", dataType="json").done(function(data) {
engine_descriptions = data;
for (const [engine_name, description] of Object.entries(data)) {
let elements = $('[data-engine-name="' + engine_name + '"] .description');
for(const element of elements) {
let source = ' (<i>' + searx.translations['Source'] + ':&nbsp;' + description[1] + '</i>)';
element.innerHTML = description[0] + source;
}
}
});
}
}
if (document.querySelector('body[class="preferences_endpoint"]')) {
$('[data-engine-name]').hover(function() {
load_engine_descriptions();
});
}
});

View file

@ -25,6 +25,7 @@ input.cursor-text {
font-size: 14px;
font-weight: normal;
z-index: 1000000;
max-width: 40rem;
}
td:hover .engine-tooltip, th:hover .engine-tooltip, .engine-tooltip:hover {

View file

@ -1929,6 +1929,14 @@ td:hover .engine-tooltip,
#main_preferences div.selectable_url pre {
width: 100%;
}
#main_preferences th.name .engine-tooltip {
margin-top: 1.8rem;
left: 20rem;
max-width: 40rem;
}
#main_preferences th.name .engine-tooltip .engine-description {
margin-top: 0.5rem;
}
@media screen and (max-width: 75em) {
.preferences_back {
clear: both;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1929,6 +1929,14 @@ td:hover .engine-tooltip,
#main_preferences div.selectable_url pre {
width: 100%;
}
#main_preferences th.name .engine-tooltip {
margin-top: 1.8rem;
left: 20rem;
max-width: 40rem;
}
#main_preferences th.name .engine-tooltip .engine-description {
margin-top: 0.5rem;
}
@media screen and (max-width: 75em) {
.preferences_back {
clear: both;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -621,6 +621,33 @@ searx.ready(function() {
});
});
})(window, document, window.searx);
;(function (w, d, searx) {
'use strict';
searx.ready(function() {
let engine_descriptions = null;
function load_engine_descriptions() {
if (engine_descriptions == null) {
searx.http("GET", "engine_descriptions.json").then(function(content) {
engine_descriptions = JSON.parse(content);
for (const [engine_name, description] of Object.entries(engine_descriptions)) {
let elements = d.querySelectorAll('[data-engine-name="' + engine_name + '"] .engine-description');
for(const element of elements) {
let source = ' (<i>' + searx.translations['Source'] + ':&nbsp;' + description[1] + '</i>)';
element.innerHTML = description[0] + source;
}
}
});
}
}
if (d.querySelector('body[class="preferences_endpoint"]')) {
for(const el of d.querySelectorAll('[data-engine-name]')) {
searx.on(el, 'mouseenter', load_engine_descriptions);
}
}
});
})(window, document, window.searx);
;/**
* searx is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,27 @@
(function (w, d, searx) {
'use strict';
searx.ready(function() {
let engine_descriptions = null;
function load_engine_descriptions() {
if (engine_descriptions == null) {
searx.http("GET", "engine_descriptions.json").then(function(content) {
engine_descriptions = JSON.parse(content);
for (const [engine_name, description] of Object.entries(engine_descriptions)) {
let elements = d.querySelectorAll('[data-engine-name="' + engine_name + '"] .engine-description');
for(const element of elements) {
let source = ' (<i>' + searx.translations['Source'] + ':&nbsp;' + description[1] + '</i>)';
element.innerHTML = description[0] + source;
}
}
});
}
}
if (d.querySelector('body[class="preferences_endpoint"]')) {
for(const el of d.querySelectorAll('[data-engine-name]')) {
searx.on(el, 'mouseenter', load_engine_descriptions);
}
}
});
})(window, document, window.searx);

View file

@ -108,6 +108,18 @@
width: 100%;
}
}
th.name {
.engine-tooltip {
margin-top: 1.8rem;
left: 20rem;
max-width: 40rem;
.engine-description {
margin-top: 0.5rem;
}
}
}
}
@media screen and (max-width: 75em) {

View file

@ -4,6 +4,7 @@
{% if search_engine.about is defined or stats[search_engine.name]['result_count'] > 0 %}
{% set about = search_engine.about %}
<div class="engine-tooltip" role="tooltip" id="{{ id }}">{{- "" -}}
<p class="description"></p>
{% if search_engine.about is defined %}
<h5><a href="{{about.website}}" rel="noreferrer">{{about.website}}</a></h5>
{%- if about.wikidata_id -%}<p><a href="https://www.wikidata.org/wiki/{{about.wikidata_id}}" rel="noreferrer">wikidata.org/wiki/{{about.wikidata_id}}</a></p>{%- endif -%}
@ -343,7 +344,7 @@
<td class="onoff-checkbox">
{{- checkbox_toggle('engine_' + search_engine.name|replace(' ', '_') + '__' + categ|replace(' ', '_'), (search_engine.name, categ) in disabled_engines) -}}
</td>
<th scope="row"><span aria-labelledby="{{ 'tooltip_' + categ + '_' + search_engine.name }}">
<th scope="row" data-engine-name="{{ search_engine.name }}"><span aria-labelledby="{{ 'tooltip_' + categ + '_' + search_engine.name }}">
{%- if search_engine.enable_http %}{{ icon('exclamation-sign', 'No HTTPS') }}{% endif -%}
{{- search_engine.name -}}</span>
{{- engine_about(search_engine, 'tooltip_' + categ + '_' + search_engine.name) -}}
@ -363,7 +364,7 @@
<td>{{ support_toggle(supports[search_engine.name]['safesearch']) }}</td>
<td>{{ support_toggle(supports[search_engine.name]['supports_selected_language']) }}</td>
<td>{{ shortcuts[search_engine.name] }}</td>
<th scope="row"><span>{% if search_engine.enable_http %}{{ icon('exclamation-sign', 'No HTTPS') }}{% endif %}{{ search_engine.name }}</span>{{ engine_about(search_engine) }}</th>
<th scope="row" data-engine-name="{{ search_engine.name }}"><span>{% if search_engine.enable_http %}{{ icon('exclamation-sign', 'No HTTPS') }}{% endif %}{{ search_engine.name }}</span>{{ engine_about(search_engine) }}</th>
<td class="onoff-checkbox">
{{ checkbox_toggle('engine_' + search_engine.name|replace(' ', '_') + '__' + categ|replace(' ', '_'), (search_engine.name, categ) in disabled_engines) }}
</td>

View file

@ -22,6 +22,7 @@
{% if search_engine.about is defined %}
{% set about = search_engine.about %}
<div class="engine-tooltip" role="tooltip">{{- "" -}}
<p class="engine-description"></p>
<p><a href="{{about.website}}" rel="noreferrer">{{about.website}}</a></p>
{%- if about.wikidata_id -%}<p><a href="https://www.wikidata.org/wiki/{{about.wikidata_id}}" rel="noreferrer">wikidata.org/wiki/{{about.wikidata_id}}</a></p>{%- endif -%}
{%- if search_engine.enable_http %}<p>{{ icon('exclamation-sign', 'No HTTPS') }}{{ _('No HTTPS')}}</p>{% endif -%}
@ -262,7 +263,7 @@
{% set engine_id = 'engine_' + search_engine.name|replace(' ', '_') + '__' + categ|replace(' ', '_') %}
<tr>
<td class="engine_checkbox">{{ checkbox_onoff(engine_id, (search_engine.name, categ) in disabled_engines) }}</td>
<th class="name">{% if search_engine.enable_http %}{{ icon('warning', 'No HTTPS') }}{% endif %} {{ search_engine.name }} {{ engine_about(search_engine) }}</th>
<th class="name" data-engine-name="{{ search_engine.name }}">{% if search_engine.enable_http %}{{ icon('warning', 'No HTTPS') }}{% endif %} {{ search_engine.name }} {{ engine_about(search_engine) }}</th>
<td class="shortcut">{{ shortcuts[search_engine.name] }}</td>
<td>{{ checkbox(engine_id + '_supported_languages', supports[search_engine.name]['supports_selected_language'], true, true) }}</td>
<td>{{ checkbox(engine_id + '_safesearch', supports[search_engine.name]['safesearch'], true, true) }}</td>

View file

@ -54,6 +54,7 @@ from searx import (
settings,
searx_debug,
)
from searx.data import ENGINE_DESCRIPTIONS
from searx.settings_defaults import OUTPUT_FORMATS
from searx.settings_loader import get_default_settings_path
from searx.exceptions import SearxParameterException
@ -393,7 +394,9 @@ def image_proxify(url):
def get_translations():
return {
# when there is autocompletion
'no_item_found': gettext('No item found')
'no_item_found': gettext('No item found'),
# /preferences: the source of the engine description (wikipedata, wikidata, website)
'Source': gettext('Source'),
}
@ -1140,6 +1143,23 @@ def image_proxy():
return '', 400
@app.route('/engine_descriptions.json', methods=['GET'])
def engine_descriptions():
locale = get_locale().split('_')[0]
result = ENGINE_DESCRIPTIONS['en'].copy()
if locale != 'en':
for engine, description in ENGINE_DESCRIPTIONS.get(locale, {}).items():
result[engine] = description
for engine, description in result.items():
if len(description) ==2 and description[1] == 'ref':
ref_engine, ref_lang = description[0].split(':')
description = ENGINE_DESCRIPTIONS[ref_lang][ref_engine]
if isinstance(description, str):
description = [ description, 'wikipedia' ]
result[engine] = description
return jsonify(result)
@app.route('/stats', methods=['GET'])
def stats():
"""Render engine statistics page."""