From 65c29081cc3debad9b77194cb917f5b04ea4ac72 Mon Sep 17 00:00:00 2001 From: Alexandre Flament Date: Thu, 22 Apr 2021 12:14:11 +0200 Subject: [PATCH 1/4] [mod] update /stats --- searx/metrics/__init__.py | 54 ++++------- .../themes/oscar/css/logicodev-dark.css | 18 ++++ .../themes/oscar/css/logicodev-dark.min.css | Bin 18232 -> 18550 bytes .../oscar/css/logicodev-dark.min.css.map | Bin 8761 -> 8969 bytes searx/static/themes/oscar/css/logicodev.css | 18 ++++ .../static/themes/oscar/css/logicodev.min.css | Bin 14584 -> 14902 bytes .../themes/oscar/css/logicodev.min.css.map | Bin 7291 -> 7499 bytes searx/static/themes/oscar/js/searx.min.js | Bin 7829 -> 7829 bytes .../oscar/src/less/logicodev/preferences.less | 14 +++ searx/templates/oscar/stats.html | 86 ++++++++++++++---- searx/webapp.py | 7 +- 11 files changed, 134 insertions(+), 63 deletions(-) diff --git a/searx/metrics/__init__.py b/searx/metrics/__init__.py index bae62c915..063554f1a 100644 --- a/searx/metrics/__init__.py +++ b/searx/metrics/__init__.py @@ -135,27 +135,13 @@ def to_percentage(stats, maxvalue): def get_engines_stats(engine_list): - global counter_storage, histogram_storage - assert counter_storage is not None assert histogram_storage is not None list_time = [] - list_time_http = [] - list_time_total = [] - list_result_count = [] - list_error_count = [] - list_scores = [] - list_scores_per_result = [] - max_error_count = max_http_time = max_time_total = max_result_count = max_score = None # noqa + max_time_total = max_result_count = None # noqa for engine_name in engine_list: - error_count = counter('engine', engine_name, 'search', 'count', 'error') - - if counter('engine', engine_name, 'search', 'count', 'sent') > 0: - list_error_count.append({'avg': error_count, 'name': engine_name}) - max_error_count = max(error_count, max_error_count or 0) - successful_count = counter('engine', engine_name, 'search', 'count', 'successful') if successful_count == 0: continue @@ -163,6 +149,10 @@ def get_engines_stats(engine_list): result_count_sum = histogram('engine', engine_name, 'result', 'count').sum time_total = histogram('engine', engine_name, 'time', 'total').percentage(50) time_http = histogram('engine', engine_name, 'time', 'http').percentage(50) + time_total_p80 = histogram('engine', engine_name, 'time', 'total').percentage(80) + time_http_p80 = histogram('engine', engine_name, 'time', 'http').percentage(80) + time_total_p95 = histogram('engine', engine_name, 'time', 'total').percentage(95) + time_http_p95 = histogram('engine', engine_name, 'time', 'http').percentage(95) result_count = result_count_sum / float(successful_count) if result_count: @@ -172,35 +162,25 @@ def get_engines_stats(engine_list): score = score_per_result = 0.0 max_time_total = max(time_total, max_time_total or 0) - max_http_time = max(time_http, max_http_time or 0) max_result_count = max(result_count, max_result_count or 0) - max_score = max(score, max_score or 0) list_time.append({'total': round(time_total, 1), + 'total_p80': round(time_total_p80, 1), + 'total_p95': round(time_total_p95, 1), 'http': round(time_http, 1), + 'http_p80': round(time_http_p80, 1), + 'http_p95': round(time_http_p95, 1), 'name': engine_name, - 'processing': round(time_total - time_http, 1)}) - list_time_total.append({'avg': time_total, 'name': engine_name}) - list_time_http.append({'avg': time_http, 'name': engine_name}) - list_result_count.append({'avg': result_count, 'name': engine_name}) - list_scores.append({'avg': score, 'name': engine_name}) - list_scores_per_result.append({'avg': score_per_result, 'name': engine_name}) - - list_time = sorted(list_time, key=itemgetter('total')) - list_time_total = sorted(to_percentage(list_time_total, max_time_total), key=itemgetter('avg')) - list_time_http = sorted(to_percentage(list_time_http, max_http_time), key=itemgetter('avg')) - list_result_count = sorted(to_percentage(list_result_count, max_result_count), key=itemgetter('avg'), reverse=True) - list_scores = sorted(list_scores, key=itemgetter('avg'), reverse=True) - list_scores_per_result = sorted(list_scores_per_result, key=itemgetter('avg'), reverse=True) - list_error_count = sorted(to_percentage(list_error_count, max_error_count), key=itemgetter('avg'), reverse=True) + 'processing': round(time_total - time_http, 1), + 'processing_p80': round(time_total_p80 - time_http_p80, 1), + 'processing_p95': round(time_total_p95 - time_http_p95, 1), + 'score': score, + 'score_per_result': score_per_result, + 'result_count': result_count, + }) return { 'time': list_time, 'max_time': math.ceil(max_time_total or 0), - 'time_total': list_time_total, - 'time_http': list_time_http, - 'result_count': list_result_count, - 'scores': list_scores, - 'scores_per_result': list_scores_per_result, - 'error_count': list_error_count, + 'max_result_count': math.ceil(max_result_count or 0), } diff --git a/searx/static/themes/oscar/css/logicodev-dark.css b/searx/static/themes/oscar/css/logicodev-dark.css index 618de9327..f9cdc41f6 100644 --- a/searx/static/themes/oscar/css/logicodev-dark.css +++ b/searx/static/themes/oscar/css/logicodev-dark.css @@ -998,3 +998,21 @@ th:hover .engine-tooltip, padding: 0.4rem 0; width: 1px; } +.stacked-bar-chart-serie1 { + display: flex; + flex-shrink: 0; + flex-grow: 0; + flex-basis: unset; + background: #5bc0de; + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + padding: 0.4rem 0; +} +.stacked-bar-chart-serie2 { + display: flex; + flex-shrink: 0; + flex-grow: 0; + flex-basis: unset; + background: #deb15b; + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + padding: 0.4rem 0; +} diff --git a/searx/static/themes/oscar/css/logicodev-dark.min.css b/searx/static/themes/oscar/css/logicodev-dark.min.css index 09aed0298062b4224714fb176ab4098caab01ae5..e34b344801a0e453def73836f89396b4694f39c5 100644 GIT binary patch delta 177 zcmdnd$M|gm#U W%~dd{P0CNHoUGuiw0XYyOnv}SAUP%g delta 23 fcmex1fpJG4*U)qlA9k%hqD0ymEI^$ delta 26 icmeBl+v&35fHbFbm8+MIx1+P`WdXvjG5wbO}EI diff --git a/searx/static/themes/oscar/css/logicodev.css b/searx/static/themes/oscar/css/logicodev.css index 4f6b36b11..40256101a 100644 --- a/searx/static/themes/oscar/css/logicodev.css +++ b/searx/static/themes/oscar/css/logicodev.css @@ -971,6 +971,24 @@ th:hover .engine-tooltip, padding: 0.4rem 0; width: 1px; } +.stacked-bar-chart-serie1 { + display: flex; + flex-shrink: 0; + flex-grow: 0; + flex-basis: unset; + background: #5bc0de; + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + padding: 0.4rem 0; +} +.stacked-bar-chart-serie2 { + display: flex; + flex-shrink: 0; + flex-grow: 0; + flex-basis: unset; + background: #deb15b; + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + padding: 0.4rem 0; +} /*Global*/ body { background: #1d1f21 none !important; diff --git a/searx/static/themes/oscar/css/logicodev.min.css b/searx/static/themes/oscar/css/logicodev.min.css index db035aa75e2eb7a08b50011269c4721414f70f07..3daa9595d559da6b6598e20cad1384417c313eb5 100644 GIT binary patch delta 183 zcmexSxUFQvX$wic;*!MV?9>$9q{JfKQlf@|4hZTQnrd1XB&MWf=A~QdnM|H&F3AQq c%LrtaqjE}WlA&o5S!NZb<|-IWK4qZ?002ikz5oCK delta 11 Scmdm1@}qFWX^Y96R=NNtR|QG{ diff --git a/searx/static/themes/oscar/css/logicodev.min.css.map b/searx/static/themes/oscar/css/logicodev.min.css.map index 50598d2ef6346779d41cdcb8ef4ebf88b1736d75..bc97c8bc804bb6f0d5339f11141cf270a8951b35 100644 GIT binary patch delta 148 zcmexuaoTD_r3{yjr=z=yy2{LCy;a? Vh!2&97-9%A#G(?Wl_W!yY5`1pC|&>n delta 10 RcmX?Y_1j`Yr3{l&EdU!91RnqZ diff --git a/searx/static/themes/oscar/js/searx.min.js b/searx/static/themes/oscar/js/searx.min.js index b31aad6f036327e131d53d1a3f5face5d0f728de..ad36c8e062fa950e15710f7b46191eca7adab045 100644 GIT binary patch delta 12 TcmbPgJJoiA6r<5b=_)w@8~X$1 delta 12 TcmbPgJJoiA6r

{{ _('Engine stats') }}

- {% for stat_name,stat_category in stats %} -
-

{{ stat_name }}

-
- {% for engine in stat_category %} -
-
{{ engine.name }}
-
-
-
- {{ '%.02f'|format(engine.avg) }} -
-
+
+
+ {% if not engine_stats.get('time') %} +
+ {% include 'oscar/messages/no_data_available.html' %}
-
- {% endfor %} - {% if not stat_category %} -
- {% include 'oscar/messages/no_data_available.html' %} -
+ {% else %} + + + + + + + + {% for engine_stat in engine_stats.get('time', []) %} + + + + + + + {% endfor %} +
{{ _("Engine name") }}{{ _('Scores') }}{{ _('Number of results') }}{{ _('Response time') }}
{{ engine_stat.name }} + {{ engine_stat.score|round(1) }} + + + {{- engine_stat.result_count | int -}}{{- "" -}} + {{- "" -}} + + {{- engine_stat.total | round(1) -}}{{- "" -}} + {{- "" -}} + +
{% endif %}
- {% endfor %}
{% endblock %} diff --git a/searx/webapp.py b/searx/webapp.py index d02e142fc..d2a1ad5f5 100755 --- a/searx/webapp.py +++ b/searx/webapp.py @@ -1077,12 +1077,7 @@ def stats(): engine_stats = get_engines_stats(filtered_engines) return render( 'stats.html', - stats=[(gettext('Engine time (sec)'), engine_stats['time_total']), - (gettext('Page loads (sec)'), engine_stats['time_http']), - (gettext('Number of results'), engine_stats['result_count']), - (gettext('Scores'), engine_stats['scores']), - (gettext('Scores per result'), engine_stats['scores_per_result']), - (gettext('Errors'), engine_stats['error_count'])] + engine_stats=engine_stats ) From c54bf42cb9699501ccbd54a2df0d7fa73be8dcdb Mon Sep 17 00:00:00 2001 From: Markus Heiser Date: Thu, 22 Apr 2021 16:05:39 +0200 Subject: [PATCH 2/4] [mod] metrics: add to pylint and justify indentations Signed-off-by: Markus Heiser --- Makefile | 3 ++- searx/metrics/__init__.py | 32 +++++++++++++++++--------------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/Makefile b/Makefile index 166fb65e4..7149437be 100644 --- a/Makefile +++ b/Makefile @@ -199,7 +199,8 @@ PYLINT_FILES=\ searx/engines/yahoo_news.py \ searx/engines/apkmirror.py \ searx/engines/artic.py \ - searx_extra/update/update_external_bangs.py + searx_extra/update/update_external_bangs.py \ + searx/metrics/__init__.py test.pylint: pyenvinstall $(call cmd,pylint,$(PYLINT_FILES)) diff --git a/searx/metrics/__init__.py b/searx/metrics/__init__.py index 063554f1a..9648e6215 100644 --- a/searx/metrics/__init__.py +++ b/searx/metrics/__init__.py @@ -1,4 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-or-later +# pylint: disable=missing-module-docstring, missing-function-docstring import typing import math @@ -63,7 +64,7 @@ def initialize(engine_names=None): """ Initialize metrics """ - global counter_storage, histogram_storage + global counter_storage, histogram_storage # pylint: disable=global-statement counter_storage = CounterStorage() histogram_storage = HistogramStorage() @@ -164,20 +165,21 @@ def get_engines_stats(engine_list): max_time_total = max(time_total, max_time_total or 0) max_result_count = max(result_count, max_result_count or 0) - list_time.append({'total': round(time_total, 1), - 'total_p80': round(time_total_p80, 1), - 'total_p95': round(time_total_p95, 1), - 'http': round(time_http, 1), - 'http_p80': round(time_http_p80, 1), - 'http_p95': round(time_http_p95, 1), - 'name': engine_name, - 'processing': round(time_total - time_http, 1), - 'processing_p80': round(time_total_p80 - time_http_p80, 1), - 'processing_p95': round(time_total_p95 - time_http_p95, 1), - 'score': score, - 'score_per_result': score_per_result, - 'result_count': result_count, - }) + list_time.append({ + 'total': round(time_total, 1), + 'total_p80': round(time_total_p80, 1), + 'total_p95': round(time_total_p95, 1), + 'http': round(time_http, 1), + 'http_p80': round(time_http_p80, 1), + 'http_p95': round(time_http_p95, 1), + 'name': engine_name, + 'processing': round(time_total - time_http, 1), + 'processing_p80': round(time_total_p80 - time_http_p80, 1), + 'processing_p95': round(time_total_p95 - time_http_p95, 1), + 'score': score, + 'score_per_result': score_per_result, + 'result_count': result_count, + }) return { 'time': list_time, From 09e7ecdce22733be82bb141355c646ddec538714 Mon Sep 17 00:00:00 2001 From: Alexandre Flament Date: Thu, 22 Apr 2021 17:47:53 +0200 Subject: [PATCH 3/4] [mod] /stats : add reliability column and sort by column links --- searx/metrics/__init__.py | 79 ++++++++++++------ searx/static/themes/oscar/css/pointhi.css | 19 +++++ searx/static/themes/oscar/css/pointhi.min.css | Bin 10308 -> 10666 bytes .../themes/oscar/css/pointhi.min.css.map | Bin 5380 -> 5618 bytes .../oscar/src/less/pointhi/preferences.less | 15 ++++ searx/templates/oscar/stats.html | 28 +++++-- searx/webapp.py | 40 ++++++++- 7 files changed, 146 insertions(+), 35 deletions(-) diff --git a/searx/metrics/__init__.py b/searx/metrics/__init__.py index 9648e6215..5665ca63c 100644 --- a/searx/metrics/__init__.py +++ b/searx/metrics/__init__.py @@ -97,12 +97,12 @@ def initialize(engine_names=None): histogram_storage.configure(histogram_width, histogram_size, 'engine', engine_name, 'time', 'total') -def get_engine_errors(engline_list): +def get_engine_errors(engline_name_list): result = {} engine_names = list(errors_per_engines.keys()) engine_names.sort() for engine_name in engine_names: - if engine_name not in engline_list: + if engine_name not in engline_name_list: continue error_stats = errors_per_engines[engine_name] @@ -126,61 +126,86 @@ def get_engine_errors(engline_list): return result -def to_percentage(stats, maxvalue): - for engine_stat in stats: - if maxvalue: - engine_stat['percentage'] = int(engine_stat['avg'] / maxvalue * 100) +def get_reliabilities(engline_name_list, checker_results): + reliabilities = {} + + engine_errors = get_engine_errors(engline_name_list) + + for engine_name in engline_name_list: + checker_result = checker_results.get(engine_name, {}) + checker_success = checker_result.get('success', True) + errors = engine_errors.get(engine_name) or [] + if counter('engine', engine_name, 'search', 'count', 'sent') == 0: + # no request + reliablity = None + elif checker_success and not errors: + reliablity = 100 + elif 'simple' in checker_result.get('errors', {}): + # the basic (simple) test doesn't work: the engine is broken accoding to the checker + # even if there is no exception + reliablity = 0 else: - engine_stat['percentage'] = 0 - return stats + reliablity = 100 - sum([error['percentage'] for error in errors if not error.get('secondary')]) + + reliabilities[engine_name] = { + 'reliablity': reliablity, + 'errors': errors, + 'checker': checker_results.get(engine_name, {}).get('errors', {}).keys(), + } + return reliabilities -def get_engines_stats(engine_list): +def round_or_none(number, digits): + return round(number, digits) if number else number + + +def get_engines_stats(engine_name_list): assert counter_storage is not None assert histogram_storage is not None list_time = [] max_time_total = max_result_count = None # noqa - for engine_name in engine_list: - successful_count = counter('engine', engine_name, 'search', 'count', 'successful') - if successful_count == 0: + for engine_name in engine_name_list: + sent_count = counter('engine', engine_name, 'search', 'count', 'sent') + if sent_count == 0: continue - result_count_sum = histogram('engine', engine_name, 'result', 'count').sum + successful_count = counter('engine', engine_name, 'search', 'count', 'successful') + time_total = histogram('engine', engine_name, 'time', 'total').percentage(50) time_http = histogram('engine', engine_name, 'time', 'http').percentage(50) time_total_p80 = histogram('engine', engine_name, 'time', 'total').percentage(80) time_http_p80 = histogram('engine', engine_name, 'time', 'http').percentage(80) time_total_p95 = histogram('engine', engine_name, 'time', 'total').percentage(95) time_http_p95 = histogram('engine', engine_name, 'time', 'http').percentage(95) - result_count = result_count_sum / float(successful_count) - if result_count: + result_count = histogram('engine', engine_name, 'result', 'count').percentage(50) + result_count_sum = histogram('engine', engine_name, 'result', 'count').sum + if successful_count and result_count_sum: score = counter('engine', engine_name, 'score') # noqa score_per_result = score / float(result_count_sum) else: score = score_per_result = 0.0 - max_time_total = max(time_total, max_time_total or 0) - max_result_count = max(result_count, max_result_count or 0) + max_time_total = max(time_total or 0, max_time_total or 0) + max_result_count = max(result_count or 0, max_result_count or 0) list_time.append({ - 'total': round(time_total, 1), - 'total_p80': round(time_total_p80, 1), - 'total_p95': round(time_total_p95, 1), - 'http': round(time_http, 1), - 'http_p80': round(time_http_p80, 1), - 'http_p95': round(time_http_p95, 1), 'name': engine_name, - 'processing': round(time_total - time_http, 1), - 'processing_p80': round(time_total_p80 - time_http_p80, 1), - 'processing_p95': round(time_total_p95 - time_http_p95, 1), + 'total': round_or_none(time_total, 1), + 'total_p80': round_or_none(time_total_p80, 1), + 'total_p95': round_or_none(time_total_p95, 1), + 'http': round_or_none(time_http, 1), + 'http_p80': round_or_none(time_http_p80, 1), + 'http_p95': round_or_none(time_http_p95, 1), + 'processing': round(time_total - time_http, 1) if time_total else None, + 'processing_p80': round(time_total_p80 - time_http_p80, 1) if time_total else None, + 'processing_p95': round(time_total_p95 - time_http_p95, 1) if time_total else None, 'score': score, 'score_per_result': score_per_result, 'result_count': result_count, }) - return { 'time': list_time, 'max_time': math.ceil(max_time_total or 0), diff --git a/searx/static/themes/oscar/css/pointhi.css b/searx/static/themes/oscar/css/pointhi.css index 64f612d79..99ed7b576 100644 --- a/searx/static/themes/oscar/css/pointhi.css +++ b/searx/static/themes/oscar/css/pointhi.css @@ -682,6 +682,7 @@ input[type=checkbox]:not(:checked) + .label_hide_if_checked + .label_hide_if_not padding: 0.5rem 1rem; margin: 0rem 0 0 2rem; border: 1px solid #ddd; + box-shadow: 2px 2px 2px 0px rgba(0, 0, 0, 0.1); background: white; font-size: 14px; font-weight: normal; @@ -756,3 +757,21 @@ td:hover .engine-tooltip, padding: 0.4rem 0; width: 1px; } +.stacked-bar-chart-serie1 { + display: flex; + flex-shrink: 0; + flex-grow: 0; + flex-basis: unset; + background: #5bc0de; + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + padding: 0.4rem 0; +} +.stacked-bar-chart-serie2 { + display: flex; + flex-shrink: 0; + flex-grow: 0; + flex-basis: unset; + background: #deb15b; + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + padding: 0.4rem 0; +} diff --git a/searx/static/themes/oscar/css/pointhi.min.css b/searx/static/themes/oscar/css/pointhi.min.css index 4332e4767e124fc129392541da678aab9e505dc5..80027ff8ee4a93e8596c635086be171af84ddbd0 100644 GIT binary patch delta 212 zcmX>Suqt@NbY->t3f5*K2A607DK2{Qv*} diff --git a/searx/static/themes/oscar/css/pointhi.min.css.map b/searx/static/themes/oscar/css/pointhi.min.css.map index abb30817f90796bb7f1ca29ce819551aff376df9..708e2f63a1ef87f924e997018ccd7804fc485d0b 100644 GIT binary patch delta 177 zcmZqC`lP)fNl4Vw(a}){LAZjrshcB(Rx)t|h26b$44fSEoG1H {% endblock %} {% block title %}{{ _('stats') }} - {% endblock %} + +{%- macro th_sort(column_order, column_name) -%} + {% if column_order==sort_order %} + {{ column_name }} {{ icon('chevron-down') }} + {% else %} + {{ column_name }} + {% endif %} +{%- endmacro -%} + {% block content %}

{{ _('Engine stats') }}

@@ -25,27 +33,33 @@ {% else %} - - - - + + + + + {% for engine_stat in engine_stats.get('time', []) %}
{{ _("Engine name") }}{{ _('Scores') }}{{ _('Number of results') }}{{ _('Response time') }}{{ th_sort('name', _("Engine name")) }}{{ th_sort('score', _('Scores')) }}{{ th_sort('result_count', _('Result count')) }}{{ th_sort('time', _('Response time')) }}{{ th_sort('reliability', _('Reliability')) }}
{{ engine_stat.name }} + {% if engine_stat.score %} {{ engine_stat.score|round(1) }} + {% endif %} + {%- if engine_stat.result_count -%} {{- engine_stat.result_count | int -}}{{- "" -}} {{- "" -}} + + {%- endif -%} + {%- if engine_stat.total -%} {{- engine_stat.total | round(1) -}}{{- "" -}}
+ {%- endif -%} + {{ engine_reliabilities.get(engine_stat.name, {}).get('reliablity') }} {% endfor %} diff --git a/searx/webapp.py b/searx/webapp.py index d2a1ad5f5..d917c16d4 100755 --- a/searx/webapp.py +++ b/searx/webapp.py @@ -93,7 +93,7 @@ from searx.preferences import Preferences, ValidationException, LANGUAGE_CODES from searx.answerers import answerers from searx.network import stream as http_stream from searx.answerers import ask -from searx.metrics import get_engines_stats, get_engine_errors, histogram, counter +from searx.metrics import get_engines_stats, get_engine_errors, get_reliabilities, histogram, counter # serve pages with HTTP/1.1 from werkzeug.serving import WSGIRequestHandler @@ -1073,11 +1073,47 @@ def image_proxy(): @app.route('/stats', methods=['GET']) def stats(): """Render engine statistics page.""" + checker_results = checker_get_result() + checker_results = checker_results['engines'] \ + if checker_results['status'] == 'ok' and 'engines' in checker_results else {} + filtered_engines = dict(filter(lambda kv: (kv[0], request.preferences.validate_token(kv[1])), engines.items())) engine_stats = get_engines_stats(filtered_engines) + engine_reliabilities = get_reliabilities(filtered_engines, checker_results) + + sort_order = request.args.get('sort', default='name', type=str) + + SORT_PARAMETERS = { + 'name': (False, 'name', ''), + 'score': (True, 'score', 0), + 'result_count': (True, 'result_count', 0), + 'time': (False, 'total', 0), + 'reliability': (False, 'reliability', 100), + } + + if sort_order not in SORT_PARAMETERS: + sort_order = 'name' + + reverse, key_name, default_value = SORT_PARAMETERS[sort_order] + + def get_key(engine_stat): + reliability = engine_reliabilities.get(engine_stat['name']).get('reliablity', 0) + reliability_order = 0 if reliability else 1 + if key_name == 'reliability': + key = reliability + reliability_order = 0 + else: + key = engine_stat.get(key_name) or default_value + if reverse: + reliability_order = 1 - reliability_order + return (reliability_order, key, engine_stat['name']) + + engine_stats['time'] = sorted(engine_stats['time'], reverse=reverse, key=get_key) return render( 'stats.html', - engine_stats=engine_stats + sort_order=sort_order, + engine_stats=engine_stats, + engine_reliabilities=engine_reliabilities, ) From 7032f7521c344592dc68f89027c98cdec46d7055 Mon Sep 17 00:00:00 2001 From: Alexandre Flament Date: Fri, 23 Apr 2021 11:01:54 +0200 Subject: [PATCH 4/4] [mod] /stats: simple theme implementation --- searx/static/themes/simple/css/searx-rtl.css | 56 ++++++---- .../themes/simple/css/searx-rtl.min.css | Bin 28927 -> 29201 bytes searx/static/themes/simple/css/searx.css | 56 ++++++---- searx/static/themes/simple/css/searx.min.css | Bin 28892 -> 29166 bytes .../static/themes/simple/js/searx.head.min.js | Bin 752 -> 752 bytes searx/static/themes/simple/js/searx.min.js | Bin 24399 -> 24399 bytes .../themes/simple/less/preferences.less | 18 ---- searx/static/themes/simple/less/toolkit.less | 33 ++++++ searx/templates/oscar/stats.html | 18 +--- searx/templates/simple/stats.html | 100 +++++++++++++++--- 10 files changed, 197 insertions(+), 84 deletions(-) diff --git a/searx/static/themes/simple/css/searx-rtl.css b/searx/static/themes/simple/css/searx-rtl.css index 0da2850c5..8823fa8b6 100644 --- a/searx/static/themes/simple/css/searx-rtl.css +++ b/searx/static/themes/simple/css/searx-rtl.css @@ -1,4 +1,4 @@ -/*! searx | 21-04-2021 | */ +/*! searx | 23-04-2021 | */ /* * searx, A privacy-respecting, hackable metasearch engine * @@ -1153,6 +1153,25 @@ select:focus { transform: rotate(360deg); } } +/* -- engine-tooltip -- */ +.engine-tooltip { + display: none; + position: absolute; + padding: 0.5rem 1rem; + margin: 0rem 0 0 2rem; + border: 1px solid #ddd; + box-shadow: 2px 2px 2px 0px rgba(0, 0, 0, 0.1); + background: white; + font-size: 14px; + font-weight: normal; + z-index: 1000000; + text-align: left; +} +th:hover .engine-tooltip, +td:hover .engine-tooltip, +.engine-tooltip:hover { + display: inline-block; +} /* -- stacked bar chart -- */ .stacked-bar-chart { margin: 0; @@ -1216,6 +1235,24 @@ select:focus { padding: 0.4rem 0; width: 1px; } +.stacked-bar-chart-serie1 { + display: flex; + flex-shrink: 0; + flex-grow: 0; + flex-basis: unset; + background: #5bc0de; + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + padding: 0.4rem 0; +} +.stacked-bar-chart-serie2 { + display: flex; + flex-shrink: 0; + flex-grow: 0; + flex-basis: unset; + background: #deb15b; + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + padding: 0.4rem 0; +} /*! Autocomplete.js v2.6.3 | license MIT | (c) 2017, Baptiste Donaux | http://autocomplete-js.com */ .autocomplete { position: absolute; @@ -1494,23 +1531,6 @@ select:focus { #main_preferences div.selectable_url pre { width: 100%; } -#main_preferences .engine-tooltip { - display: none; - position: absolute; - padding: 0.5rem 1rem; - margin: 0rem 0 0 2rem; - border: 1px solid #ddd; - background: white; - font-size: 14px; - font-weight: normal; - z-index: 1000000; - text-align: left; -} -#main_preferences th:hover .engine-tooltip, -#main_preferences td:hover .engine-tooltip, -#main_preferences .engine-tooltip:hover { - display: inline-block; -} @media screen and (max-width: 75em) { .preferences_back { clear: both; diff --git a/searx/static/themes/simple/css/searx-rtl.min.css b/searx/static/themes/simple/css/searx-rtl.min.css index 615b88ec58e2068fa42993b00faf8205f129a98e..68b25fa600ea302e704e29e98aef3f90e6803814 100644 GIT binary patch delta 353 zcmezWka6M@Mm~KlMTO$j#G(p?8U-WciF^kpGcy`YJZHMunDLJOhMJSv-2)~&841@Hrxs5v8B^K!> zXCxMt=z?X8s*?}~X66;AmM9n~=o$h|Ml;b=)4CurB_%U2-Ad1-C^c8XpjIz6FFi9a zRktKRKc^(Kz$zoZEVW3dBn84y083B)A)p$!-yXlY4ErCp%b9-2BjT4bNs-k80-48@>Hh0r%#5*#H0l delta 227 zcmbREgz^7FMm~KlMTO$j#G(p?8U-W6iF^kp{xh9;&S0}K;~o9U&BlV8&lsI#o*Zw! zd9sT|@MK}jnUl9#icIFWVxN59!g2F_%K)ay|E=fpr{(9B=$5Bure~B`nHU&Mmh&~) zeBP##XYwI;p~?J)S(6tU`b`$HFq(YOU05?UFFi9aRktKRKc^(Kz$zoZEVW2SIX5vg zFTS8CH7&I$H7_}}SfM0ka-WfyFcz7~Jw|$)-92lVC6W@8v(t<6OY>56lk;=(i>#E5 PO)M>3oHifw@mB=^49r!2 diff --git a/searx/static/themes/simple/css/searx.css b/searx/static/themes/simple/css/searx.css index 15b9f0853..b8c95e19e 100644 --- a/searx/static/themes/simple/css/searx.css +++ b/searx/static/themes/simple/css/searx.css @@ -1,4 +1,4 @@ -/*! searx | 21-04-2021 | */ +/*! searx | 23-04-2021 | */ /* * searx, A privacy-respecting, hackable metasearch engine * @@ -1153,6 +1153,25 @@ select:focus { transform: rotate(360deg); } } +/* -- engine-tooltip -- */ +.engine-tooltip { + display: none; + position: absolute; + padding: 0.5rem 1rem; + margin: 0rem 0 0 2rem; + border: 1px solid #ddd; + box-shadow: 2px 2px 2px 0px rgba(0, 0, 0, 0.1); + background: white; + font-size: 14px; + font-weight: normal; + z-index: 1000000; + text-align: left; +} +th:hover .engine-tooltip, +td:hover .engine-tooltip, +.engine-tooltip:hover { + display: inline-block; +} /* -- stacked bar chart -- */ .stacked-bar-chart { margin: 0; @@ -1216,6 +1235,24 @@ select:focus { padding: 0.4rem 0; width: 1px; } +.stacked-bar-chart-serie1 { + display: flex; + flex-shrink: 0; + flex-grow: 0; + flex-basis: unset; + background: #5bc0de; + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + padding: 0.4rem 0; +} +.stacked-bar-chart-serie2 { + display: flex; + flex-shrink: 0; + flex-grow: 0; + flex-basis: unset; + background: #deb15b; + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + padding: 0.4rem 0; +} /*! Autocomplete.js v2.6.3 | license MIT | (c) 2017, Baptiste Donaux | http://autocomplete-js.com */ .autocomplete { position: absolute; @@ -1494,23 +1531,6 @@ select:focus { #main_preferences div.selectable_url pre { width: 100%; } -#main_preferences .engine-tooltip { - display: none; - position: absolute; - padding: 0.5rem 1rem; - margin: 0rem 0 0 2rem; - border: 1px solid #ddd; - background: white; - font-size: 14px; - font-weight: normal; - z-index: 1000000; - text-align: left; -} -#main_preferences th:hover .engine-tooltip, -#main_preferences td:hover .engine-tooltip, -#main_preferences .engine-tooltip:hover { - display: inline-block; -} @media screen and (max-width: 75em) { .preferences_back { clear: both; diff --git a/searx/static/themes/simple/css/searx.min.css b/searx/static/themes/simple/css/searx.min.css index 52ad98ecd613176bc1afa0af214c491acfa24589..54e4e73ef7f2649be3ab58d2338a9deb6c2c153f 100644 GIT binary patch delta 353 zcmccfkn!DPMm~KlMTO$j#G(p?8U-WciF^kpGcy`YJZHMunDLJOhMJSv-2)~&841@Hrxs5v8B^K!> zXCxMt=z?X8s*?}~X66;AmM9n~=o$h|Ml;b=)4CurB_%U2-Ad1-C^c8XpjIz6FFi9a zRktKRKc^(Kz$zoZEVW3dBn84y083B)A)p$!-yXlY4ErCp%b9-2BjT4bNs-k80-48@;tv0Yx=>?*IS* delta 227 zcmaF&nDNd-Mm~KlMTO$j#G(p?8U-W6iF^kp{xh9;&S0}K;~o9U&BlV8&lsI#o*Zw! zd9sT|@MK}jnUl9#icIFWVxN59!g2F_%K)ay|E=fpr{(9B=$5Bure~B`nHU&Mmh&~) zeBP##XYwI;p~?J)S(6tU`b`$HFq(YOU05?UFFi9aRktKRKc^(Kz$zoZEVW2SIX5vg zFTS8CH7&I$H7_}}SfM0ka-WfyFcz7~Jw|$)-92lVC6W@8v(t<6OY>56lk;=(i>#E5 PO)M>3oHifw(NP5eKYLY_ diff --git a/searx/static/themes/simple/js/searx.head.min.js b/searx/static/themes/simple/js/searx.head.min.js index 043f255158bd0b065d6dcea8366103ffd02589b5..cc57bdea904d9ecad56e90532fe231c0a618fa75 100644 GIT binary patch delta 12 Tcmeys`hj(VG^6oGnJY{HAQS{` delta 12 Tcmeys`hj(VG^620nJY{HAPNL) diff --git a/searx/static/themes/simple/js/searx.min.js b/searx/static/themes/simple/js/searx.min.js index 8ae15bedee0cf5f6eedcb511b63c04b6c7d81d70..36b8c38702c3b722efa6e77a4b504112c9aebb28 100644 GIT binary patch delta 14 VcmX@VkMaCI#tG7l#v5gf;{h*=1zP|B delta 14 VcmX@VkMaCI#tG7lh8ty!;{h*$1z7+9 diff --git a/searx/static/themes/simple/less/preferences.less b/searx/static/themes/simple/less/preferences.less index 93bdaad27..e1e88b51f 100644 --- a/searx/static/themes/simple/less/preferences.less +++ b/searx/static/themes/simple/less/preferences.less @@ -93,24 +93,6 @@ width: 100%; } } - - - .engine-tooltip { - display: none; - position: absolute; - padding: 0.5rem 1rem; - margin: 0rem 0 0 2rem; - border: 1px solid #ddd; - background: white; - font-size: 14px; - font-weight: normal; - z-index: 1000000; - text-align: left; - } - - th:hover .engine-tooltip, td:hover .engine-tooltip, .engine-tooltip:hover { - display: inline-block; - } } diff --git a/searx/static/themes/simple/less/toolkit.less b/searx/static/themes/simple/less/toolkit.less index b3dba9ea9..3e9274fc8 100644 --- a/searx/static/themes/simple/less/toolkit.less +++ b/searx/static/themes/simple/less/toolkit.less @@ -475,6 +475,25 @@ select { } } +/* -- engine-tooltip -- */ +.engine-tooltip { + display: none; + position: absolute; + padding: 0.5rem 1rem; + margin: 0rem 0 0 2rem; + border: 1px solid #ddd; + box-shadow: 2px 2px 2px 0px rgba(0,0,0,0.1); + background: white; + font-size: 14px; + font-weight: normal; + z-index: 1000000; + text-align: left; +} + +th:hover .engine-tooltip, td:hover .engine-tooltip, .engine-tooltip:hover { + display: inline-block; +} + /* -- stacked bar chart -- */ .stacked-bar-chart { margin: 0; @@ -532,3 +551,17 @@ select { padding: 0.4rem 0; width: 1px; } + +.stacked-bar-chart-serie1 { + .stacked-bar-chart-base(); + background: #5bc0de; + box-shadow: inset 0 -1px 0 rgba(0,0,0,.15); + padding: 0.4rem 0; +} + +.stacked-bar-chart-serie2 { + .stacked-bar-chart-base(); + background: #deb15b; + box-shadow: inset 0 -1px 0 rgba(0,0,0,.15); + padding: 0.4rem 0; +} diff --git a/searx/templates/oscar/stats.html b/searx/templates/oscar/stats.html index 149522226..b83714020 100644 --- a/searx/templates/oscar/stats.html +++ b/searx/templates/oscar/stats.html @@ -1,15 +1,5 @@ {% extends "oscar/base.html" %} -{% block styles %} - -{% endblock %} {% block title %}{{ _('stats') }} - {% endblock %} {%- macro th_sort(column_order, column_name) -%} @@ -45,7 +35,7 @@ {% if engine_stat.score %} {{ engine_stat.score|round(1) }} -