first commit

This commit is contained in:
Iyas Altawil
2025-06-26 15:38:10 +03:30
commit e928faf6d2
899 changed files with 403713 additions and 0 deletions

View File

@@ -0,0 +1,9 @@
{% extends "simple/base.html" %}
{% block content %}
<div class="center">
<h1>{{ _('Page not found') }}</h1>
{% autoescape false %}
<p>{{ _('Go to %(search_page)s.', search_page='<a href="{}">{}</a>'.format(url_for('index'), _('search page'))) }}</p>
{% endautoescape %}
</div>
{% endblock %}

View File

@@ -0,0 +1,8 @@
<span>{{ answer.answer }}</span>
{%- if answer.url -%}
<a href="{{ answer.url }}" class="answer-url"
{%- if results_on_new_tab %} target="_blank" rel="noopener noreferrer"
{%- else -%} rel="noreferrer"
{%- endif -%}
>{{ urlparse(answer.url).hostname }}</a>
{% endif -%}

View File

@@ -0,0 +1,52 @@
<details class="answer-translations">
<summary>{{ answer.translations[0].text }}</summary>
<dl>
{%- for item in answer.translations -%}
<dt>{{ item.text }}</dt>
<dd>
{%- if item.transliteration -%}
<div class="item-transliteration">{{ item.transliteration }}</div>
{%- endif -%}
{%- if item.examples -%}
<div>{{ _('Examples') }}</div>
<ul>
{%- for i in item.examples -%}
<li>{{ i }}</li>
{%- endfor -%}
</ul>
{%- endif -%}
{%- if item.definitions -%}
<div>{{ _('Definitions') }}</div>
<ul>
{%- for i in item.definitions -%}
<li>{{ i }}</li>
{%- endfor -%}
</ul>
{%- endif -%}
{%- if item.synonyms -%}
<div>{{ _('Synonyms') }}</div>
<ul>
{%- for i in item.synonyms -%}
<li>{{ i }}</li>
{%- endfor -%}
</ul>
{%- endif -%}
</dd>
{%- endfor -%}
</dl>
</details>
{%- if answer.url -%}
<a href="{{ answer.url }}" class="answer-url"
{%- if results_on_new_tab %}
target="_blank" rel="noopener noreferrer"
{%- else -%}
rel="noreferrer"
{%- endif -%}
>{{ answer.engine }}</a>
{%- else -%}
<span class="answer-url">{{ answer.engine }}</span>
{% endif -%}

View File

@@ -0,0 +1,62 @@
{% macro show_weather_data(answer, data) %}
<table>
<colgroup>
<col span="1" class="thumbnail">
<col span="1" class="title">
<col span="1" class="measured">
<col span="1" class="title">
<col span="1" class="measured">
</colgroup>
<tbody>
<tr>
<td rowspan="4">
{%- if data.url %}<img class="symbol" src="{{ data.url }}" title="{{ data.summary }}">{% endif -%}
</td>
</tr>
<tr>
<td>{{ _("Temperature") }}:</td>
<td>{{ data.temperature.l10n(locale=data.location) }}</td>
<td>{{ _("Feels Like") }}:</td>
<td>{{ data.feels_like.l10n(locale=data.location) }}</td>
</tr>
<tr>
<td>{{ _("Wind") }}:</td>
<td>{{ data.wind_from.l10n(locale=data.location) }}: {{ data.wind_speed.l10n(locale=data.location) }}</td>
<td>{{ _("Pressure") }}:</td>
<td>{{ data.pressure.l10n(locale=data.location) }}</td>
</tr>
<tr>
<td>{{_("Humidity")}}:</td>
<td>{{ data.humidity.l10n(locale=data.location) }}</td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
{% endmacro %}
<details class="weather">
<summary>
<div class="summary"> {{ answer.current.summary }}</div>
{{ show_weather_data(answer, answer.current) }}
</summary>
<div class="weather-forecast">
{%- if answer.forecasts -%}
<div class="answer-weather-forecasts">
{%- for forecast in answer.forecasts -%}
<div class="summary">{{ forecast.datetime.l10n(locale=answer.current.location,fmt="short") }} {{ forecast.summary }}</div>
{{ show_weather_data(answer, forecast) }}
{%- endfor -%}
</div>
{%- endif -%}
</div>
</details>
{%- if answer.url -%}
<a href="{{ answer.url }}" class="answer-url"
{%- if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{%- else -%}rel="noreferrer"{%- endif -%}>
{{ answer.service }}
</a>
{%- else -%}
<span class="answer-url">{{ answer.service }}</span>
{% endif -%}

View File

@@ -0,0 +1,89 @@
<!DOCTYPE html>
<html class="no-js theme-{{ preferences.get_value('simple_style') or 'auto' }} center-alignment-{{ preferences.get_value('center_alignment') and 'yes' or 'no' }}" lang="{{ locale_rfc5646 }}" {% if rtl %} dir="rtl"{% endif %}>
<head>
<meta charset="UTF-8">
<meta name="description" content="SearXNG — a privacy-respecting, open metasearch engine">
<meta name="keywords" content="SearXNG, search, search engine, metasearch, meta search">
<meta name="generator" content="searxng/{{ searx_version }}">
<meta name="referrer" content="no-referrer">
<meta name="robots" content="noarchive">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="HandheldFriendly" content="True">
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1">
<title>{% block title %}{% endblock %}{{ instance_name }}</title>
{% block meta %}{% endblock %}
{% if rtl %}
<link rel="stylesheet" href="{{ url_for('static', filename='css/searxng-rtl.min.css') }}" type="text/css" media="screen">
{% else %}
<link rel="stylesheet" href="{{ url_for('static', filename='css/searxng.min.css') }}" type="text/css" media="screen">
{% endif %}
{% if get_setting('server.limiter') or get_setting('server.public_instance') %}
<link rel="stylesheet" href="{{ url_for('client_token', token=link_token) }}" type="text/css">
{% endif %}
<!--[if gte IE 9]>-->
<script src="{{ url_for('static', filename='js/searxng.head.min.js') }}" client_settings="{{ client_settings }}"></script>
<!--<![endif]-->
{% block head %}
<link title="{{ instance_name }}" type="application/opensearchdescription+xml" rel="search" href="{{ opensearch_url }}">
{% endblock %}
<link rel="icon" href="{{ url_for('static', filename='img/favicon.png') }}" sizes="any">
<link rel="icon" href="{{ url_for('static', filename='img/favicon.svg') }}" type="image/svg+xml">
<link rel="apple-touch-icon" href="{{ url_for('static', filename='img/favicon.png') }}">
</head>
<body class="{{ endpoint }}_endpoint" >
<main id="main_{{ self._TemplateReference__context.name|replace("simple/", "")|replace(".html", "") }}" class="{{body_class}}">
{% if errors %}
<div class="dialog-error" role="alert">
<a href="#" class="close" aria-label="close" title="close">×</a>
<ul>
{% for message in errors %}
<li>{{ message }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
<nav id="links_on_top">
{%- from 'simple/icons.html' import icon_big -%}
{%- block linkto_about -%}
<a href="{{ url_for('info', pagename='about') }}" class="link_on_top_about">{{ icon_big('information-circle') }}<span>{{ _('About') }}</span></a>
{%- endblock -%}
{%- block linkto_donate -%}
{%- if donation_url -%}
<a href="{{ donation_url }}" class="link_on_top_donate">{{ icon_big('heart') }}<span>{{ _('Donate') }}</span></a>
{%- endif -%}
{%- endblock -%}
{%- block linkto_preferences -%}
<a href="{{ url_for('preferences') }}" class="link_on_top_preferences">{{ icon_big('settings') }}<span>{{ _('Preferences') }}</span></a>
{%- endblock -%}
</nav>
{% block header %}
{% endblock %}
{% block content %}
{% endblock %}
</main>
<footer>
<p>
{{ _('Powered by') }} <a href="{{ url_for('info', pagename='about') }}">SearXNG</a> - {{ searx_version }} — {{ _('a privacy-respecting, open metasearch engine') }}<br>
<a href="{{ searx_git_url }}">{{ _('Source code') }}</a>
| <a href="{{ get_setting('brand.issue_url') }}">{{ _('Issue tracker') }}</a>
{% if enable_metrics %}| <a href="{{ url_for('stats') }}">{{ _('Engine stats') }}</a>{% endif %}
{% if get_setting('brand.public_instances') %}
| <a href="{{ get_setting('brand.public_instances') }}">{{ _('Public instances') }}</a>
{% endif %}
{% if get_setting('general.privacypolicy_url') %}
| <a href="{{ get_setting('general.privacypolicy_url') }}">{{ _('Privacy policy') }}</a>
{% endif %}
{% if get_setting('general.contact_url') %}
| <a href="{{ get_setting('general.contact_url') }}">{{ _('Contact instance maintainer') }}</a>
{% endif %}
{% for title, link in get_setting('brand.custom.links').items() %}
| <a href="{{ link }}">{{ _(title) }}</a>
{% endfor %}
</p>
</footer>
<!--[if gte IE 9]>-->
<script src="{{ url_for('static', filename='js/searxng.min.js') }}"></script>
<!--<![endif]-->
</body>
</html>

View File

@@ -0,0 +1,42 @@
{% from 'simple/icons.html' import icon_big %}
{%- set category_icons = {
'apps': 'appstore',
'dictionaries': 'book',
'files': 'file-tray-full',
'general': 'search',
'images': 'image',
'it': 'layers',
'map': 'location',
'music': 'musical-notes',
'news': 'newspaper',
'radio': 'radio',
'science': 'school',
'social media': 'people',
'TV': 'tv',
'videos': 'play',
} -%}
<div id="categories" class="search_categories">{{- '' -}}
<div id="categories_container">
{%- if not search_on_category_select or not display_tooltip -%}
{%- for category in categories -%}
<div class="category category_checkbox">{{- '' -}}
<input type="checkbox" id="checkbox_{{ category|replace(' ', '_') }}" name="category_{{ category }}"{% if category in selected_categories %} checked="checked"{% endif %}>
<label for="checkbox_{{ category|replace(' ', '_') }}" class="tooltips">
{{- icon_big(category_icons[category]) if category in category_icons else icon_big('globe') -}}
<div class="category_name">{{- _(category) -}}</div>
</label>
</div>
{%- endfor -%}
{%- if display_tooltip %}<div class="help">{{ _('Click on the magnifier to perform search') }}</div>{% endif -%}
{%- else -%}
{%- for category in categories -%}{{- '\n' -}}
<button type="submit" name="category_{{ category }}" class="category category_button {% if category in selected_categories %}selected{% endif %}">
{{- icon_big(category_icons[category]) if category in category_icons else icon_big('globe') -}}
<div class="category_name">{{- _(category) -}}</div>{{- '' -}}
</button>{{- '' -}}
{%- endfor -%}
<input name="categories" id="selected-categories" type="hidden" />
{{- '\n' -}}
{%- endif -%}
</div>{{- '' -}}
</div>

View File

@@ -0,0 +1,8 @@
<div id="answers" role="complementary" aria-labelledby="answers-title">
<h4 class="title" id="answers-title">{{ _('Answers') }} : </h4>
{%- for answer in answers -%}
<div class="answer">
{%- include ("simple/" + (answer.template or "answer/legacy.html")) -%}
</div>
{%- endfor -%}
</div>

View File

@@ -0,0 +1,26 @@
<div id="apis" role="complementary" aria-labelledby="apis-title">
<details class="sidebar-collapsible">
<summary class="title" id="apis-title">{{ _('Download results') }}</summary>
<div class="wrapper">
{%- for output_type in search_formats -%}
<div class="left">
<form method="{{ method or 'POST' }}" action="{{ url_for('search') }}">
<input type="hidden" name="q" value="{{ q|e }}">
{%- for category in selected_categories -%}
<input type="hidden" name="category_{{ category }}" value="1">
{%- endfor -%}
<input type="hidden" name="pageno" value="{{ pageno }}">
<input type="hidden" name="language" value="{{ current_language }}">
<input type="hidden" name="time_range" value="{{ time_range }}">
<input type="hidden" name="safesearch" value="{{ safesearch }}">
<input type="hidden" name="format" value="{{ output_type }}">
{%- if timeout_limit -%}
<input type="hidden" name="timeout_limit" value="{{ timeout_limit|e }}" >
{%- endif -%}
<input type="submit" role="link" value="{{ output_type }}">
</form>
</div>
{%- endfor -%}
</div>
</details>
</div>

View File

@@ -0,0 +1,19 @@
<div id="corrections" role="complementary" aria-labelledby="corrections-title">
<h4 id="corrections-title">{{ _('Try searching for:') }}</h4>
{% for correction in corrections %}
<div class="left">
<form method="{{ method or 'POST' }}" action="{{ url_for('search') }}" role="navigation">
{% for category in selected_categories %}
<input type="hidden" name="category_{{ category }}" value="1">
{% endfor %}
<input type="hidden" name="q" value="{{ correction.url }}">
<input type="hidden" name="language" value="{{ current_language }}">
<input type="hidden" name="time_range" value="{{ time_range }}">
<input type="hidden" name="safesearch" value="{{ safesearch }}">
<input type="hidden" name="theme" value="{{ theme }}">
{% if timeout_limit %}<input type="hidden" name="timeout_limit" value="{{ timeout_limit }}" >{% endif %}
<input type="submit" role="link" value="{{ correction.title }}">
</form>
</div>
{% endfor %}
</div>

View File

@@ -0,0 +1,34 @@
<div id="engines_msg">
{% if (not results and not answers) or not max_response_time %}
<details class="sidebar-collapsible" open>
<summary class="title" id="engines_msg-title">{{ _('Messages from the search engines') }}</summary>
{% else %}
<details class="sidebar-collapsible">
<summary class="title" id="engines_msg-title">{{ _('Response time') }}: {{ max_response_time | round(1) }} {{ _('seconds') }}</summary>
{% endif %}
<table class="engine-stats" id="engines_msg-table">
{%- for engine_name, error_type in unresponsive_engines -%}
<tr>
<td class="engine-name">
<a href="{{ url_for('stats', engine=engine_name|e) }}"
title="{{ _('View error logs and submit a bug report') }}">
{{- engine_name -}}
</a>
</td>
<td class="response-error">{{- error_type -}}</td>
</tr>
{%- endfor -%}
{%- for engine_name, response_time in timings -%}
<tr>
<td class="engine-name"><a href="{{ url_for('stats', engine=engine_name|e) }}">{{ engine_name }}</a></td>
<td class="response-time">
<div class="bar-chart-value">{{- response_time | round(1) -}}</div>
<div class="bar-chart-graph" aria-labelledby="{{engine_name}}_time" aria-hidden="true">
<div class="bar-chart-bar bar{{ (100 * response_time / max_response_time) | round | int }}"></div>
</div>
</td>
</tr>
{%- endfor -%}
</table>
</details>
</div>

View File

@@ -0,0 +1,48 @@
<aside class="infobox" aria-label="{{ infobox.infobox }}">
<h2 class="title"><bdi>{{ infobox.infobox }}</bdi></h2>
{%- if infobox.img_src -%}<img src="{{ image_proxify(infobox.img_src) }}" title="{{ infobox.infobox|striptags }}" alt="{{ infobox.infobox|striptags }}">{%- endif -%}
<p><bdi>{{ infobox.content | safe }}</bdi></p>
{%- if infobox.attributes -%}
<div class="attributes">
{%- for attribute in infobox.attributes -%}
<dl>
<dt><bdi>{{ attribute.label }} :</bdi></dt>
{%- if attribute.image -%}
<dd><img src="{{ image_proxify(attribute.image.src) }}" alt="{{ attribute.image.alt }}"></dd>
{%- else -%}
<dd><bdi>{{ attribute.value }}</bdi></dd>
{%- endif -%}
</dl>
{%- endfor -%}
</div>
{%- endif -%}
{%- if infobox.urls -%}
<div class="urls">
<ul>
{%- for url in infobox.urls -%}
<li class="url"><bdi><a href="{{ url.url }}" {%- if results_on_new_tab -%}target="_blank" rel="noopener noreferrer"{%- else -%}rel="noreferrer"{%- endif -%}>{{ url.title }}</a></bdi></li>
{%- endfor -%}
</ul>
</div>
{%- endif -%}
{%- if infobox.relatedTopics -%}
<div class="relatedTopics">
{%- for topic in infobox.relatedTopics -%}
<div>
<h3><bdi>{{ topic.name }}</bdi></h3>
{%- for suggestion in topic.suggestions -%}
<form method="{{ method or 'POST' }}" action="{{ url_for('search') }}">
<input type="hidden" name="q" value="{{ suggestion }}">
<input type="hidden" name="time_range" value="{{ time_range }}">
<input type="hidden" name="language" value="{{ current_language }}">
<input type="hidden" name="safesearch" value="{{ safesearch }}">
<input type="hidden" name="theme" value="{{ theme }}">
{%- if timeout_limit -%}<input type="hidden" name="timeout_limit" value="{{ timeout_limit|e }}" >{%- endif -%}
<input type="submit" value="{{ suggestion }}">
</form>
{%- endfor -%}
</div>
{%- endfor -%}
</div>
{%- endif -%}
</aside>

View File

@@ -0,0 +1,19 @@
<div id="search_url" role="complementary" aria-labelledby="search_url-title">
<details class="sidebar-collapsible">
<summary class="title" id="search_url-title">{{ _('Search URL') }}</summary>
<button id="copy_url" type="submit" data-copied-text="{{ _('Copied') }}">{{ _('Copy') }}</button>
<div class="selectable_url">
<pre>{{ url_for('search', _external=True) }}?q={{ q|urlencode }}&amp;language={{ current_language }}&amp;time_range={{ time_range }}&amp;safesearch={{ safesearch }}
{%- if pageno > 1 -%}
&amp;pageno={{ pageno }}
{%- endif -%}
{%- if selected_categories -%}
&amp;categories={{ selected_categories|join(",") | replace(' ','+') }}
{%- endif -%}
{%- if timeout_limit -%}
&amp;timeout_limit={{ timeout_limit|urlencode }}
{%- endif -%}
</pre>
</div>
</details>
</div>

View File

@@ -0,0 +1,23 @@
<div id="suggestions" role="complementary" aria-labelledby="suggestions-title">
<details class="sidebar-collapsible">
<summary class="title" id="suggestions-title">{{ _('Suggestions') }}</summary>
<div class="wrapper">
{%- for suggestion in suggestions -%}
<form method="{{ method or 'POST' }}" action="{{ url_for('search') }}">
<input type="hidden" name="q" value="{{ suggestion.url }}">
{%- for category in selected_categories -%}
<input type="hidden" name="category_{{ category }}" value="1">
{%- endfor -%}
<input type="hidden" name="language" value="{{ current_language }}">
<input type="hidden" name="time_range" value="{{ time_range }}">
<input type="hidden" name="safesearch" value="{{ safesearch }}">
<input type="hidden" name="theme" value="{{ theme }}">
{%- if timeout_limit -%}
<input type="hidden" name="timeout_limit" value="{{ timeout_limit|e }}" >
{%- endif -%}
<input type="submit" class="suggestion" role="link" value="&bull; {{ suggestion.title }}">
</form>
{%- endfor -%}
</div>
</details>
</div>

View File

@@ -0,0 +1,18 @@
<select class="language" id="language" name="language" aria-label="{{ _('Search language') }}">{{- '' -}}
<option value="all"
{%- if current_language == 'all' %} selected="selected" {%- endif -%}>
{{- _('Default language') }} [all] {{- '' -}}
</option>{{- '' -}}
<option value="auto"
{%- if current_language == 'auto' %} selected="selected" {%- endif -%}>
{{- _('Auto-detect') }} ({{ search_language }}) {{- '' -}}
</option>{{- '' -}}
{% for sxng_tag,lang_name,country_name,english_name,flag in sxng_locales | sort(attribute=1) -%}
<option value="{{ sxng_tag }}"
{%- if sxng_tag == current_language %} selected="selected" {%- endif -%}>
{{ lang_name }}{%- if country_name -%}-{{ country_name }}{%- endif -%}
{{- ' ' -}}[{{sxng_tag}}]{{- ' ' -}}
{%- if flag -%}{{ flag }}{%- endif -%}
</option>
{%- endfor -%}
</select>

View File

@@ -0,0 +1,5 @@
<select name="safesearch" id="safesearch" class="safesearch" aria-label="{{ _('SafeSearch') }}">
<option value="2" {% if safesearch == '2' %}selected="selected"{% endif %} aria-label="{{ _('Strict') }}">{{ _("SafeSearch") + ": " + _('Strict') }}</option>
<option value="1" {% if safesearch == '1' %}selected="selected"{% endif %} aria-label="{{ _('Moderate') }}">{{ _("SafeSearch") + ": " + _('Moderate') }}</option>
<option value="0" {% if safesearch == '0' %}selected="selected"{% endif %} aria-label="{{ _('None') }}">{{ _("SafeSearch") + ": " + _('None') }}</option>
</select>

View File

@@ -0,0 +1,17 @@
<select name="time_range" id="time_range" class="time_range" aria-label="{{ _('Time range') }}">{{- '' -}}
<option id="time-range-anytime" value="" {{ "selected" if time_range=="" or not time_range else ""}}>
{{- _('Anytime') -}}
</option>{{- '' -}}
<option id="time-range-day" value="day" {{ "selected" if time_range=="day" else ""}}>
{{- _('Last day') -}}
</option>{{- '' -}}
<option id="time-range-week" value="week" {{ "selected" if time_range=="week" else ""}}>
{{- _('Last week') -}}
</option>{{- '' -}}
<option id="time-range-month" value="month" {{ "selected" if time_range=="month" else ""}}>
{{- _('Last month') -}}
</option>{{- '' -}}
<option id="time-range-year" value="year" {{ "selected" if time_range=="year" else ""}}>
{{- _('Last year') -}}
</option>{{- '' -}}
</select>

View File

@@ -0,0 +1,55 @@
{#
Catalog of SVG symbols that can be inserted into the HTML output of a Jinja
template. This file from:
client/simple/tools/icon_catalog.edge.html
#}
{%-
set catalog = {
'alert' : '<svg viewBox="0 0 512 512" class="ionicon __jinja_class_placeholder__" aria-hidden="true"><path d="M256 80c-8.66 0-16.58 7.36-16 16l8 216a8 8 0 0 0 8 8h0a8 8 0 0 0 8-8l8-216c.58-8.64-7.34-16-16-16" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32px"/><circle cx="256" cy="416" r="16" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32px"/></svg>',
'appstore' : '<svg viewBox="0 0 512 512" class="ionicon __jinja_class_placeholder__" aria-hidden="true"><rect width="80" height="80" x="64" y="64" rx="40" ry="40" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="32px"/><rect width="80" height="80" x="216" y="64" rx="40" ry="40" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="32px"/><rect width="80" height="80" x="368" y="64" rx="40" ry="40" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="32px"/><rect width="80" height="80" x="64" y="216" rx="40" ry="40" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="32px"/><rect width="80" height="80" x="216" y="216" rx="40" ry="40" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="32px"/><rect width="80" height="80" x="368" y="216" rx="40" ry="40" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="32px"/><rect width="80" height="80" x="64" y="368" rx="40" ry="40" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="32px"/><rect width="80" height="80" x="216" y="368" rx="40" ry="40" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="32px"/><rect width="80" height="80" x="368" y="368" rx="40" ry="40" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="32px"/></svg>',
'book' : '<svg viewBox="0 0 512 512" class="ionicon __jinja_class_placeholder__" aria-hidden="true"><path d="M256 160c16-63.16 76.43-95.41 208-96a15.94 15.94 0 0 1 16 16v288a16 16 0 0 1-16 16c-128 0-177.45 25.81-208 64-30.37-38-80-64-208-64-9.88 0-16-8.05-16-17.93V80a15.94 15.94 0 0 1 16-16c131.57.59 192 32.84 208 96M256 160v288" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32px"/></svg>',
'close' : '<svg viewBox="0 0 512 512" class="ionicon __jinja_class_placeholder__" aria-hidden="true"><path d="M368 368 144 144M368 144 144 368" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32px"/></svg>',
'download' : '<svg viewBox="0 0 512 512" class="ionicon __jinja_class_placeholder__" aria-hidden="true"><path d="M336 176h40a40 40 0 0 1 40 40v208a40 40 0 0 1-40 40H136a40 40 0 0 1-40-40V216a40 40 0 0 1 40-40h40" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32px"/><path d="m176 272 80 80 80-80M256 48v288" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32px"/></svg>',
'ellipsis-vertical' : '<svg viewBox="0 0 512 512" class="ionicon __jinja_class_placeholder__" aria-hidden="true"><circle cx="256" cy="256" r="32" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="32px"/><circle cx="256" cy="416" r="32" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="32px"/><circle cx="256" cy="96" r="32" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="32px"/></svg>',
'file-tray-full' : '<svg viewBox="0 0 512 512" class="ionicon __jinja_class_placeholder__" aria-hidden="true"><path d="M384 80H128c-26 0-43 14-48 40L48 272v112a48.14 48.14 0 0 0 48 48h320a48.14 48.14 0 0 0 48-48V272l-32-152c-5-27-23-40-48-40Z" fill="none" stroke="currentColor" stroke-linejoin="round" stroke-width="32px"/><path d="M48 272h144M320 272h144M192 272a64 64 0 0 0 128 0M144 144h224M128 208h256" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32px"/></svg>',
'film' : '<svg viewBox="0 0 512 512" class="ionicon __jinja_class_placeholder__" aria-hidden="true"><rect width="416" height="320" x="48" y="96" rx="28" ry="28" fill="none" stroke="currentColor" stroke-linejoin="round" stroke-width="32px"/><rect width="80" height="80" x="384" y="336" rx="28" ry="28" fill="none" stroke="currentColor" stroke-linejoin="round" stroke-width="32px"/><rect width="80" height="80" x="384" y="256" rx="28" ry="28" fill="none" stroke="currentColor" stroke-linejoin="round" stroke-width="32px"/><rect width="80" height="80" x="384" y="176" rx="28" ry="28" fill="none" stroke="currentColor" stroke-linejoin="round" stroke-width="32px"/><rect width="80" height="80" x="384" y="96" rx="28" ry="28" fill="none" stroke="currentColor" stroke-linejoin="round" stroke-width="32px"/><rect width="80" height="80" x="48" y="336" rx="28" ry="28" fill="none" stroke="currentColor" stroke-linejoin="round" stroke-width="32px"/><rect width="80" height="80" x="48" y="256" rx="28" ry="28" fill="none" stroke="currentColor" stroke-linejoin="round" stroke-width="32px"/><rect width="80" height="80" x="48" y="176" rx="28" ry="28" fill="none" stroke="currentColor" stroke-linejoin="round" stroke-width="32px"/><rect width="80" height="80" x="48" y="96" rx="28" ry="28" fill="none" stroke="currentColor" stroke-linejoin="round" stroke-width="32px"/><rect width="256" height="160" x="128" y="96" rx="28" ry="28" fill="none" stroke="currentColor" stroke-linejoin="round" stroke-width="32px"/><rect width="256" height="160" x="128" y="256" rx="28" ry="28" fill="none" stroke="currentColor" stroke-linejoin="round" stroke-width="32px"/></svg>',
'globe' : '<svg viewBox="0 0 512 512" class="ionicon __jinja_class_placeholder__" aria-hidden="true"><path d="M256 48C141.13 48 48 141.13 48 256s93.13 208 208 208 208-93.13 208-208S370.87 48 256 48Z" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="32px"/><path d="M256 48c-58.07 0-112.67 93.13-112.67 208S197.93 464 256 464s112.67-93.13 112.67-208S314.07 48 256 48Z" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="32px"/><path d="M117.33 117.33c38.24 27.15 86.38 43.34 138.67 43.34s100.43-16.19 138.67-43.34M394.67 394.67c-38.24-27.15-86.38-43.34-138.67-43.34s-100.43 16.19-138.67 43.34" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32px"/><path d="M256 48v416M464 256H48" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="32px"/></svg>',
'heart' : '<svg viewBox="0 0 512 512" class="ionicon __jinja_class_placeholder__" aria-hidden="true"><path d="M352.92 80C288 80 256 144 256 144s-32-64-96.92-64c-52.76 0-94.54 44.14-95.08 96.81-1.1 109.33 86.73 187.08 183 252.42a16 16 0 0 0 18 0c96.26-65.34 184.09-143.09 183-252.42-.54-52.67-42.32-96.81-95.08-96.81" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32px"/></svg>',
'image' : '<svg viewBox="0 0 512 512" class="ionicon __jinja_class_placeholder__" aria-hidden="true"><rect width="416" height="352" x="48" y="80" rx="48" ry="48" fill="none" stroke="currentColor" stroke-linejoin="round" stroke-width="32px"/><circle cx="336" cy="176" r="32" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="32px"/><path d="m304 335.79-90.66-90.49a32 32 0 0 0-43.87-1.3L48 352M224 432l123.34-123.34a32 32 0 0 1 43.11-2L464 368" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32px"/></svg>',
'layers' : '<svg viewBox="0 0 512 512" class="ionicon __jinja_class_placeholder__" aria-hidden="true"><path d="m434.8 137.65-149.36-68.1c-16.19-7.4-42.69-7.4-58.88 0L77.3 137.65c-17.6 8-17.6 21.09 0 29.09l148 67.5c16.89 7.7 44.69 7.7 61.58 0l148-67.5c17.52-8 17.52-21.1-.08-29.09M160 308.52l-82.7 37.11c-17.6 8-17.6 21.1 0 29.1l148 67.5c16.89 7.69 44.69 7.69 61.58 0l148-67.5c17.6-8 17.6-21.1 0-29.1l-79.94-38.47" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32px"/><path d="m160 204.48-82.8 37.16c-17.6 8-17.6 21.1 0 29.1l148 67.49c16.89 7.7 44.69 7.7 61.58 0l148-67.49c17.7-8 17.7-21.1.1-29.1L352 204.48" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32px"/></svg>',
'leecher' : '<svg viewBox="0 0 512 512" class="ionicon __jinja_class_placeholder__" aria-hidden="true"><path d="m112 268 144 144 144-144M256 392V100" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48px"/></svg>',
'location' : '<svg viewBox="0 0 512 512" class="ionicon __jinja_class_placeholder__" aria-hidden="true"><path d="M256 48c-79.5 0-144 61.39-144 137 0 87 96 224.87 131.25 272.49a15.77 15.77 0 0 0 25.5 0C304 409.89 400 272.07 400 185c0-75.61-64.5-137-144-137" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32px"/><circle cx="256" cy="192" r="48" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32px"/></svg>',
'magnet' : '<svg viewBox="0 0 512 512" class="ionicon __jinja_class_placeholder__" aria-hidden="true"><path d="M421.83 293.82A144 144 0 0 0 218.18 90.17" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="32px"/><path d="M353.94 225.94a48 48 0 0 0-67.88-67.88" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="32px"/><path d="M192 464v-48M90.18 421.82l33.94-33.94M48 320h48" stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="32px"/><path d="M286.06 158.06 172.92 271.19a32 32 0 0 1-45.25 0L105 248.57a32 32 0 0 1 0-45.26L218.18 90.17M421.83 293.82 308.69 407a32 32 0 0 1-45.26 0l-22.62-22.63a32 32 0 0 1 0-45.26l113.13-113.17M139.6 169.98l67.88 67.89M275.36 305.75l67.89 67.88" fill="none" stroke="currentColor" stroke-linejoin="round" stroke-width="32px"/></svg>',
'musical-notes' : '<svg viewBox="0 0 512 512" class="ionicon __jinja_class_placeholder__" aria-hidden="true"><path d="M192 218v-6c0-14.84 10-27 24.24-30.59l174.59-46.68A20 20 0 0 1 416 154v22" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32px"/><path d="M416 295.94v80c0 13.91-8.93 25.59-22 30l-22 8c-25.9 8.72-52-10.42-52-38h0a33.37 33.37 0 0 1 23-32l51-18.15c13.07-4.4 22-15.94 22-29.85V58a10 10 0 0 0-12.6-9.61L204 102a16.48 16.48 0 0 0-12 16v226c0 13.91-8.93 25.6-22 30l-52 18c-13.88 4.68-22 17.22-22 32h0c0 27.58 26.52 46.55 52 38l22-8c13.07-4.4 22-16.08 22-30v-80" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32px"/></svg>',
'navigate-down' : '<svg viewBox="0 0 512 512" class="ionicon __jinja_class_placeholder__" aria-hidden="true"><path d="m112 184 144 144 144-144" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48px"/></svg>',
'navigate-left' : '<svg viewBox="0 0 512 512" class="ionicon __jinja_class_placeholder__" aria-hidden="true"><path d="M328 112 184 256l144 144" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48px"/></svg>',
'navigate-right' : '<svg viewBox="0 0 512 512" class="ionicon __jinja_class_placeholder__" aria-hidden="true"><path d="m184 112 144 144-144 144" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48px"/></svg>',
'navigate-up' : '<svg viewBox="0 0 512 512" class="ionicon __jinja_class_placeholder__" aria-hidden="true"><path d="m112 328 144-144 144 144" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48px"/></svg>',
'people' : '<svg viewBox="0 0 512 512" class="ionicon __jinja_class_placeholder__" aria-hidden="true"><path d="M402 168c-2.93 40.67-33.1 72-66 72s-63.12-31.32-66-72c-3-42.31 26.37-72 66-72s69 30.46 66 72" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32px"/><path d="M336 304c-65.17 0-127.84 32.37-143.54 95.41-2.08 8.34 3.15 16.59 11.72 16.59h263.65c8.57 0 13.77-8.25 11.72-16.59C463.85 335.36 401.18 304 336 304Z" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="32px"/><path d="M200 185.94c-2.34 32.48-26.72 58.06-53 58.06s-50.7-25.57-53-58.06C91.61 152.15 115.34 128 147 128s55.39 24.77 53 57.94" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32px"/><path d="M206 306c-18.05-8.27-37.93-11.45-59-11.45-52 0-102.1 25.85-114.65 76.2-1.65 6.66 2.53 13.25 9.37 13.25H154" fill="none" stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="32px"/></svg>',
'play' : '<svg viewBox="0 0 512 512" class="ionicon __jinja_class_placeholder__" aria-hidden="true"><path d="M112 111v290c0 17.44 17 28.52 31 20.16l247.9-148.37c12.12-7.25 12.12-26.33 0-33.58L143 90.84c-14-8.36-31 2.72-31 20.16Z" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="32px"/></svg>',
'radio' : '<svg viewBox="0 0 512 512" class="ionicon __jinja_class_placeholder__" aria-hidden="true"><circle cx="256" cy="256.02" r="32"/><path d="M184.25 192.25a96 96 0 0 0 0 127.52M327.77 319.77a96 96 0 0 0 0-127.52M133.28 141.28a168 168 0 0 0 0 229.44M378.72 370.72a168 168 0 0 0 0-229.44" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32px"/><path d="M435 416a240.34 240.34 0 0 0 0-320M77 96a240.34 240.34 0 0 0 0 320" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32px"/></svg>',
'save' : '<svg viewBox="0 0 512 512" class="ionicon __jinja_class_placeholder__" aria-hidden="true"><path d="M380.93 57.37A32 32 0 0 0 358.3 48H94.22A46.21 46.21 0 0 0 48 94.22v323.56A46.21 46.21 0 0 0 94.22 464h323.56A46.36 46.36 0 0 0 464 417.78V153.7a32 32 0 0 0-9.37-22.63ZM256 416a64 64 0 1 1 64-64 63.92 63.92 0 0 1-64 64m48-224H112a16 16 0 0 1-16-16v-64a16 16 0 0 1 16-16h192a16 16 0 0 1 16 16v64a16 16 0 0 1-16 16" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32px"/></svg>',
'school' : '<svg viewBox="0 0 512 512" class="ionicon __jinja_class_placeholder__" aria-hidden="true"><path d="M32 192 256 64l224 128-224 128z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32px"/><path d="M112 240v128l144 80 144-80V240M480 368V192M256 320v128" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32px"/></svg>',
'search' : '<svg viewBox="0 0 512 512" class="ionicon __jinja_class_placeholder__" aria-hidden="true"><path d="M221.09 64a157.09 157.09 0 1 0 157.09 157.09A157.1 157.1 0 0 0 221.09 64Z" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="32px"/><path d="M338.29 338.29 448 448" fill="none" stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="32px"/></svg>',
'seeder' : '<svg viewBox="0 0 512 512" class="ionicon __jinja_class_placeholder__" aria-hidden="true"><path d="M464 208 352 96 240 208M352 113.13V416M48 304l112 112 112-112M160 398V96" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32px"/></svg>',
'settings' : '<svg viewBox="0 0 512 512" class="ionicon __jinja_class_placeholder__" aria-hidden="true"><path d="M262.29 192.31a64 64 0 1 0 57.4 57.4 64.13 64.13 0 0 0-57.4-57.4M416.39 256a154 154 0 0 1-1.53 20.79l45.21 35.46a10.81 10.81 0 0 1 2.45 13.75l-42.77 74a10.81 10.81 0 0 1-13.14 4.59l-44.9-18.08a16.11 16.11 0 0 0-15.17 1.75A164.5 164.5 0 0 1 325 400.8a15.94 15.94 0 0 0-8.82 12.14l-6.73 47.89a11.08 11.08 0 0 1-10.68 9.17h-85.54a11.11 11.11 0 0 1-10.69-8.87l-6.72-47.82a16.07 16.07 0 0 0-9-12.22 155 155 0 0 1-21.46-12.57 16 16 0 0 0-15.11-1.71l-44.89 18.07a10.81 10.81 0 0 1-13.14-4.58l-42.77-74a10.8 10.8 0 0 1 2.45-13.75l38.21-30a16.05 16.05 0 0 0 6-14.08c-.36-4.17-.58-8.33-.58-12.5s.21-8.27.58-12.35a16 16 0 0 0-6.07-13.94l-38.19-30A10.81 10.81 0 0 1 49.48 186l42.77-74a10.81 10.81 0 0 1 13.14-4.59l44.9 18.08a16.11 16.11 0 0 0 15.17-1.75A164.5 164.5 0 0 1 187 111.2a15.94 15.94 0 0 0 8.82-12.14l6.73-47.89A11.08 11.08 0 0 1 213.23 42h85.54a11.11 11.11 0 0 1 10.69 8.87l6.72 47.82a16.07 16.07 0 0 0 9 12.22 155 155 0 0 1 21.46 12.57 16 16 0 0 0 15.11 1.71l44.89-18.07a10.81 10.81 0 0 1 13.14 4.58l42.77 74a10.8 10.8 0 0 1-2.45 13.75l-38.21 30a16.05 16.05 0 0 0-6.05 14.08c.33 4.14.55 8.3.55 12.47" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32px"/></svg>',
'tv' : '<svg viewBox="0 0 512 512" class="ionicon __jinja_class_placeholder__" aria-hidden="true"><rect width="448" height="272" x="32" y="96" rx="32.14" ry="32.14" fill="none" stroke="currentColor" stroke-linejoin="round" stroke-width="32px"/><path d="M128 416h256" stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="32px"/></svg>',
'information-circle' : '<svg viewBox="0 0 512 512" aria-hidden="true" class="__jinja_class_placeholder__"><path d="M248 64C146.39 64 64 146.39 64 248s82.39 184 184 184 184-82.39 184-184S349.61 64 248 64z" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="32"/><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M220 220h32v116"/><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="32" d="M208 340h88"/><path d="M248 130a26 26 0 1026 26 26 26 0 00-26-26z" fill="currentColor" stroke="currentColor" stroke-miterlimit="10" stroke-width="1"/></svg>',
'newspaper' : '<svg viewBox="0 0 512 512" aria-hidden="true" class="__jinja_class_placeholder__"><path d="M368 415.86V72a24.07 24.07 0 00-24-24H72a24.07 24.07 0 00-24 24v352a40.12 40.12 0 0040 40h328" fill="none" stroke="currentColor" stroke-linejoin="round" stroke-width="32"/><path d="M416 464h0a48 48 0 01-48-48V128h72a24 24 0 0124 24v264a48 48 0 01-48 48z" fill="none" stroke="currentColor" stroke-linejoin="round" stroke-width="32"/><path d="M240 128h64M240 192h64M112 256h192M112 320h192M112 384h192" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32"/><path d="M176 208h-64a16 16 0 01-16-16v-64a16 16 0 0116-16h64a16 16 0 0116 16v64a16 16 0 01-16 16z" fill="currentColor" stroke="currentColor" stroke-linejoin="round" stroke-width="1"/></svg>',
}
-%}
{% macro icon(action, alt) -%}
{{ catalog[action] | replace("__jinja_class_placeholder__", "sxng-icon-set") | safe }}
{%- endmacro %}
{% macro icon_small(action, alt) -%}
{{ catalog[action] | replace("__jinja_class_placeholder__", "sxng-icon-set-small") | safe }}
{%- endmacro %}
{% macro icon_big(action, alt) -%}
{{ catalog[action] | replace("__jinja_class_placeholder__", "sxng-icon-set-big") | safe }}
{%- endmacro %}

View File

@@ -0,0 +1,8 @@
{% extends "simple/base.html" %}
{% from 'simple/icons.html' import icon_big %}
{% block content %}
<div class="index">
<div class="title"><h1>SearXNG</h1></div>
{% include 'simple/simple_search.html' %}
</div>
{% endblock %}

View File

@@ -0,0 +1,16 @@
{% extends 'simple/page_with_header.html' %}
{% block title %}{{ active_page.title }} - {% endblock %}
{% block linkto_about %}{% endblock %}
{% block linkto_donate %}{% endblock %}
{% block content %}
<ul class="tabs">
{% for pagename, locale, page in all_pages %}
<li>
<a href="{{ url_for('info', pagename=pagename, locale=locale) }}" {% if pagename == active_pagename %}class="active"{% endif %}>{{page.title}}</a>
</li>
{% endfor %}
</ul>
<div class="info-page {{pagename}}">
{{- active_page.html | safe -}}
</div>
{% endblock %}

View File

@@ -0,0 +1,68 @@
{% from 'simple/icons.html' import icon_small %}
<!-- Draw favicon -->
{% macro draw_favicon(favicon) -%}
<img width="14" height="14" class="favicon" src="{{ url_for('static', filename='themes/simple/img/icons/' + favicon + '.png') }}" alt="{{ favicon }}">
{%- endmacro %}
{% macro result_open_link(url, classes='') -%}
<a href="{{ url }}" {% if classes %}class="{{ classes }}" {% endif %}{% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}>
{%- endmacro %}
{%- macro result_close_link() -%}
</a>
{%- endmacro %}
{%- macro result_link(url, title, classes='') -%}
{{ result_open_link(url, classes) }}{{ title }}{{ result_close_link() }}
{%- endmacro -%}
<!-- Draw result header -->
{% macro result_header(result, favicons, image_proxify) -%}
<article class="result {% if result['template'] %}result-{{ result.template|replace('.html', '') }}{% else %}result-default{% endif %} {% if result['category'] %}category-{{ result['category'] }}{% endif %}">
{{- result_open_link(result.url, "url_header") -}}
{%- if favicon_resolver != "" %}
<div class="favicon"><img loading="lazy" src="{{ favicon_url(result.parsed_url.netloc) }}"></div>
{%- endif -%}
<div class="url_wrapper">
{%- for part in get_pretty_url(result.parsed_url) -%}
<span class="url_o{{loop.index}}"><span class="url_i{{loop.index}}">{{- part -}}</span></span>
{%- endfor %}
</div>
{{- result_close_link() -}}
{%- if result.thumbnail %}{{ result_open_link(result.url) }}<img class="thumbnail" src="{{ image_proxify(result.thumbnail) }}" title="{{ result.title|striptags }}" loading="lazy">{{ result_close_link() }}{% endif -%}
<h3>{{ result_link(result.url, result.title|safe) }}</h3>
{%- endmacro -%}
<!-- Draw result sub header -->
{%- macro result_sub_header(result) -%}
{%- if result.publishedDate %}<time class="published_date" datetime="{{ result.pubdate }}" >{{ result.publishedDate }}</time>{% endif -%}
{%- if result.length %}<div class="result_length">{{ _('Length') }}: {{ result.length }}</div>{% endif -%}
{%- if result.views %}<div class="result_views">{{ _('Views') }}: {{ result.views }}</div>{% endif -%}
{%- if result.author %}<div class="result_author">{{ _('Author') }}: {{ result.author }}</div>{% endif -%}
{%- if result.metadata %}<div class="highlight">{{ result.metadata|safe }}</div>{% endif -%}
{%- endmacro -%}
<!-- Draw result sub footer -->
{%- macro result_sub_footer(result) -%}
<div class="engines">
{% for engine in result.engines %}<span>{{ engine }}</span>{% endfor %}
{{ icon_small('ellipsis-vertical') + result_link(cache_url + result.url, _('cached'), "cache_link") }}
</div>{{- '' -}}
<div class="break"></div>{{- '' -}}
{%- endmacro -%}
<!-- Draw result footer -->
{%- macro result_footer(result) -%}
</article>
{%- endmacro -%}
<!-- input checkbox, on/off slider user can tap-->
{%- macro checkbox_onoff(name, checked) -%}
<input type="checkbox" {{- ' ' -}}
name="{{ name }}" {{- ' ' -}}
id="{{ name }}" {{- ' ' -}}
aria-labelledby="pref_{{ name }}"{{- ' ' -}}
class="checkbox-onoff"{{- ' ' -}}
{%- if checked -%} checked{%- endif -%}/>
{%- endmacro -%}

View File

@@ -0,0 +1,5 @@
{% from 'simple/icons.html' import icon %}
<div class="alert alert-info fade in" role="alert">
<strong class="lead">{{ icon('info-sign') }} {{ _('Information!') }}</strong>
{{ _('currently, there are no cookies defined.') }}
</div>

View File

@@ -0,0 +1,28 @@
{% from 'simple/icons.html' import icon_big %}
<div class="dialog-error-block" role="alert">{{- '' -}}
<p>{{- '' -}}
<strong>
{%- if pageno == 1 -%}
{{ _('Sorry!') }}
{%- endif -%}
</strong>{{- '' -}}
</p>{{- '' -}}
<p>
{%- if pageno == 1 -%}
{{ _("No results were found. You can try to:") }}
{%- else -%}
{{ _("There are no more results. You can try to:") }}
{%- endif -%}
</p>{{- '' -}}
<ul>
{%- if pageno == 1 -%}
<li>{{ _("Refresh the page.") }}</li>{{- '' -}}
<li>{{ _("Search for another query or select another category (above).") }}</li>{{- '' -}}
<li>{{ _("Change the search engine used in the preferences:") }} <a href="/preferences">/preferences</a></li>{{- '' -}}
<li>{{ _("Switch to another instance:") }} <a href="https://searx.space">https://searx.space</a></li>{{- '' -}}
{%- else -%}
<li>{{ _("Search for another query or select another category.") }}</li>{{- '' -}}
<li>{{ _("Go back to the previous page using the previous page button.") }}</li>{{- '' -}}
{%- endif -%}
</ul>
</div>

View File

@@ -0,0 +1,75 @@
{% macro new_issue(engine_name, engine_reliability) %}
<form action="{{ get_setting('brand.new_issue_url') }}" method="GET">
<input name="title" type="hidden" value="Bug: {{ engine_name }} engine">
<input name="labels" type="hidden" value="bug">
<input name="template" type="hidden" value="bug-report.md">
<textarea name="body" class="issue-hide">{{- '' -}}
**Version of SearXNG, commit number if you are using on master branch and stipulate if you forked SearXNG**
{% if searx_git_url and searx_git_url != 'unknow' %}
Repository: {{ searx_git_url }}
Branch: {{ searx_git_branch }}
Version: {{ searx_version }}
<!-- Check if these values are correct -->
{% else %}
<!-- If you are running on master branch using git execute this command
in order to fetch the latest commit ID:
```
git log -1
```
If you are using searxng-docker then look at the bottom of the SearXNG page
and check for the version after "Powered by SearXNG"
Please also stipulate if you are using a forked version of SearxNG and
include a link to the fork source code.
-->
{% endif %}
**How did you install SearXNG?**
<!-- Did you install SearXNG using the official wiki or using searxng-docker
or manually by executing the searx/webapp.py file? -->
**What happened?**
<!-- A clear and concise description of what the bug is. -->
**How To Reproduce**
<!-- How can we reproduce this issue? (as minimally and as precisely as possible) -->
**Expected behavior**
<!-- A clear and concise description of what you expected to happen. -->
**Screenshots & Logs**
<!-- If applicable, add screenshots, logs to help explain your problem. -->
**Additional context**
<!-- Add any other context about the problem here. -->
**Technical report**
{% for error in engine_reliability.errors %}
{% if secondary %}Warning{% else %}Error{% endif %}
{{'\n '}}* Error: {{ error.exception_classname or error.log_message }}
{{' '}}* Percentage: {{ error.percentage }}
{{' '}}* Parameters: `{{ error.log_parameters }}`
{{' '}}* File name: `{{ error.filename }}:{{ error.line_no }}`
{{' '}}* Function: `{{ error.function }}`
{{' '}}* Code: `{{ error.code }}`
{{'\n'-}}
{%- endfor -%}
{%- for test_name, results in engine_reliability.checker.items() -%}
{%- if loop.first %}Checker{% endif -%}
{{-'\n '}}* {{ test_name }}: {% for result in results%}`{{ result }}`,{% endfor -%}
{%- endfor -%}
</textarea>
<input type="checkbox" id="step1">
<label for="step1">{{ _('Start submitting 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 }} {{ 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>
<div class="step2 step_content">
<p>{{ _('If this is a public instance, please specify the URL in the bug report') }}</p>
<button type="submit" class="github-issue-button button" title="{{ get_setting('brand.new_issue_url') }}">{{ _('Submit a new issue on Github including the above information') }}</button>
</div>
</form>
{% endmacro %}

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/" xmlns:moz="http://www.mozilla.org/2006/browser/search/">
<ShortName>{{ instance_name }}</ShortName>
<LongName>SearXNG metasearch</LongName>
<Description>SearXNG is a metasearch engine that respects your privacy.</Description>
<InputEncoding>UTF-8</InputEncoding>
<Image type="image/png">{{ url_for('static', filename='img/favicon.png', _external=True) }}</Image>
{% if opensearch_method == 'GET' %}
<Url rel="results" type="text/html" method="{{ opensearch_method }}" template="{{ url_for('search', _external=True) }}?q={searchTerms}"/>
{% else %}
<Url rel="results" type="text/html" method="{{ opensearch_method }}" template="{{ url_for('search', _external=True) }}">
<Param name="q" value="{searchTerms}" />
</Url>
{% endif %}
{% if autocomplete %}
<Url rel="suggestions" type="application/x-suggestions+json" method="{{ opensearch_method }}" template="{{ url_for('autocompleter', _external=True) }}?q={searchTerms}"/>
{% endif %}
<Url rel="self" type="application/opensearchdescription+xml" method="{{ opensearch_method }}" template="{{ url_for('opensearch', _external=True) }}" />
<Query role="example" searchTerms="SearXNG" />
<moz:SearchForm>{{ url_for('search', _external=True) }}</moz:SearchForm>
</OpenSearchDescription>

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="{{ url_for('rss_xsl') }}" type="text/xsl"?>
<rss version="2.0"
xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>SearXNG search: {{ q|e }}</title>
<link>{{ url_for('search', _external=True) }}?q={{ q|e }}</link>
<description>Search results for "{{ q|e }}" - SearXNG</description>
<opensearch:totalResults>{{ number_of_results }}</opensearch:totalResults>
<opensearch:startIndex>1</opensearch:startIndex>
<opensearch:itemsPerPage>{{ number_of_results }}</opensearch:itemsPerPage>
<atom:link rel="search" type="application/opensearchdescription+xml" href="{{ opensearch_url }}"/>
<opensearch:Query role="request" searchTerms="{{ q|e }}" startPage="1" />
{% if error_message %}
<item>
<title>Error</title>
<description>{{ error_message|e }}</description>
</item>
{% endif %}
{% for r in results %}
<item>
<title>{{ r.title }}</title>
<type>result</type>
<link>{{ r.url }}</link>
<description>{{ r.content }}</description>
{% if r.pubdate %}<pubDate>{{ r.pubdate }}</pubDate>{% endif %}
</item>
{% endfor %}
</channel>
</rss>

View File

@@ -0,0 +1,7 @@
{%- set body_class = "page_with_header" -%}
{%- extends "simple/base.html" -%}
{%- block header -%}
<a href="{{ url_for('index') }}">{{- '' -}}
<img class="logo" src="{{ url_for('static', filename='img/searxng.png') }}" alt="SearXNG">{{- '' -}}
</a>{{- '' -}}
{%- endblock -%}

View File

@@ -0,0 +1,261 @@
{%- from 'simple/icons.html' import icon_small, icon_big -%}
{%- extends "simple/page_with_header.html" -%}
{%- macro tabs_open() -%}
<div class="tabs" role="tablist">
{%- endmacro -%}
{%- macro tab_header(name, id, label, checked) -%}
<input type="radio" name="{{ name }}" id="tab-{{ id }}" {% if checked is sameas true %}checked="checked"{% endif %}>
<label id="tab-label-{{ id }}" for="tab-{{ id }}" role="tab" aria-controls="tab-content-{{ id }}">{{ label }}</label>
<section id="tab-content-{{ id }}" role="tabpanel" aria-hidden="false">
{%- endmacro -%}
{%- macro tab_footer() -%}
</section>
{%- endmacro -%}
{%- macro tabs_close() -%}
</div>
{%- endmacro -%}
{%- macro checkbox(name, checked, disabled) -%}
{%- if checked == '?' -%}
{{- icon_small('alert') -}}
{%- else -%}
<input type="checkbox" {%- if name %} name="{{ name }}" {%- endif %} value="None" {%- if checked %} checked {%- endif -%}{%- if disabled %} disabled {%- endif -%}>
{%- endif -%}
{%- endmacro -%}
{%- macro checkbox_onoff_reversed(name, checked, labelledby) -%}
<input type="checkbox" {{- ' ' -}}
name="{{ name }}" {{- ' ' -}}
id="{{ name }}" {{- ' ' -}}
{%- if labelledby -%} aria-labelledby="{{ labelledby }}"{{- ' ' -}}{%- endif -%}
class="checkbox-onoff reversed-checkbox"{{- ' ' -}}
{%- if checked -%} checked{%- endif -%}>
{%- endmacro -%}
{%- macro plugin_preferences(section) -%}
{%- for plugin in plugins_storage -%}
{%- if plugin.preference_section == section -%}
<fieldset>{{- '' -}}
<legend>{{ _(plugin.name) }}</legend>{{- '' -}}
<div class="value">
{{- checkbox_onoff_reversed('plugin_' + plugin.id, plugin.id not in allowed_plugins, 'plugin_labelledby' + plugin.id) -}}
</div>{{- '' -}}
<div class="description" id="{{ 'plugin_labelledby' + plugin.id }}">
{{- _(plugin.description) -}}
</div>{{- '' -}}
</fieldset>
{%- endif -%}
{%- endfor -%}
{%- endmacro -%}
{%- macro engine_about(search_engine) -%}
{%- 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_big('exclamation-sign', 'No HTTPS') -}}{{- _('No HTTPS')-}}</p>
{% endif -%}
{%- if reliabilities.get(search_engine.name, {}).errors or reliabilities.get(search_engine.name, {}).checker -%}
<a href="{{ url_for('stats', engine=search_engine.name|e) }}" {{- ' ' -}}
title="{{ _('View error logs and submit a bug report') }}">
{{- _('View error logs and submit a bug report') -}}
</a>
{%- endif -%}
<p>{{- '' -}}
<span class="right">{{ _("!bang for this engine") }}</span>{{- '' -}}
{%- for bang in [search_engine.name] + [search_engine.shortcut] -%}
<span class="bang"> {{ '!' + bang.replace(' ', '_') }}</span>
{%- endfor -%}
</p>{{- '' -}}
<p>{{- '' -}}
<span class="right">{{ _("!bang for its categories") }}</span>
{%- for bang in search_engine.categories -%}
<span class="bang">{{ '!' + bang.replace(' ', '_') }}</span>
{%- endfor -%}
</p>{{- '' -}}
</div>
{%- endif -%}
{%- endmacro -%}
{%- macro engine_time(engine_name) -%}
<td class="{{ label }}">{{- '' -}}
{%- if stats[engine_name].time != None -%}
<span class="stacked-bar-chart-value">{{- stats[engine_name].time -}}</span>{{- '' -}}
<span class="stacked-bar-chart" aria-hidden="true">
{%- if max_rate95 is not none and max_rate95 > 0 -%}
<div class="stacked-bar-chart-median bar{{ (100 * (stats[engine_name].time / max_rate95))|round }}"></div>{{- '' -}}
<div class="stacked-bar-chart-rate80 bar{{ (100 * ((stats[engine_name].rate80 - stats[engine_name].time) / max_rate95))|round }}"></div>{{- '' -}}
<div class="stacked-bar-chart-rate95 bar{{ (100 * ((stats[engine_name].rate95 - stats[engine_name].rate80) / max_rate95))|round }}"></div>{{- '' -}}
<span class="stacked-bar-chart-rate100"></span>
{%- endif -%}
</span>{{- '' -}}
<div class="engine-tooltip text-left" role="tooltip" id="{{engine_name}}_graph">{{- '' -}}
<p>{{ _('Median') }}: {{ stats[engine_name].time }}</p>{{- '' -}}
<p>{{ _('P80') }}: {{ stats[engine_name].rate80 }}</p>{{- '' -}}
<p>{{ _('P95') }}: {{ stats[engine_name].rate95 }}</p>{{- '' -}}
</div>
{%- endif -%}
</td>
{%- endmacro -%}
{%- macro engine_reliability(engine_name) -%}
{%- set r = reliabilities.get(engine_name, {}).get('reliability', None) -%}
{%- set checker_result = reliabilities.get(engine_name, {}).get('checker', []) -%}
{%- set errors = reliabilities.get(engine_name, {}).get('errors', []) -%}
{%- if r != None -%}
{%- if r <= 50 -%}
{% set label = 'danger' -%}
{%- elif r < 80 -%}
{%- set label = 'warning' -%}
{%- elif r < 90 %}
{%- set label = '' -%}
{%- else -%}
{%- set label = 'success' -%}
{%- endif -%}
{% else %}
{%- set r = '' -%}
{%- endif -%}
{%- if checker_result or errors -%}
<td class="{{ label }} column-reliability">{{- '' -}}
<a href="{{ url_for('stats', engine=engine_name|e) }}">{{- '' -}}
<span>
{{- icon_big('alert', 'The engine is not reliabled') }} {{ r -}}
</span>{{- '' -}}
</a>{{- '' -}}
<div class="engine-tooltip" role="tooltip" id="{{engine_name}}_reliability">
{%- if checker_result -%}
<p>{{ _("Failed checker test(s): ") }} {{ ', '.join(checker_result) }}</p>
{%- endif -%}
{%- if errors -%}<p>{{ _('Errors:') }}</p>{%- endif -%}
{%- for error in errors -%}
<p>{{ error }}</p>{{- '' -}}
{%- endfor -%}
</div>{{- '' -}}
</td>
{%- else -%}
<td class="{{ label }}">{% if r %}<span>{{ r }}</span>
{%- endif -%}
</td>
{%- endif -%}
{%- endmacro -%}
{%- block head -%}{%- endblock -%}
{%- block linkto_preferences -%}{%- endblock -%}
{%- block content -%}
<h1>{{ _('Preferences') }}</h1>
<form id="search_form" method="post" action="{{ url_for('preferences') }}" autocomplete="off">
{{- tabs_open() -}}
{# tab: general #}
{{- tab_header('maintab', 'general', _('General'), True) -}}
{%- if 'categories' not in locked_preferences -%}
<fieldset>
<legend>{{- _('Default categories') -}}</legend>
{% set display_tooltip = false %}
{% include 'simple/categories.html' %}
</fieldset>
{%- endif -%}
{%- if 'language' not in locked_preferences -%}
{%- include 'simple/preferences/language.html' -%}
{% endif %}
{%- if 'autocomplete' not in locked_preferences -%}
{%- include 'simple/preferences/autocomplete.html' -%}
{%- endif -%}
{%- if 'favicon' not in locked_preferences -%}
{%- include 'simple/preferences/favicon.html' -%}
{%- endif -%}
{% if 'safesearch' not in locked_preferences %}
{%- include 'simple/preferences/safesearch.html' -%}
{%- endif -%}
{%- include 'simple/preferences/tokens.html' -%}
{{- plugin_preferences('general') -}}
{%- if 'doi_resolver' not in locked_preferences %}
{%- include 'simple/preferences/doi_resolver.html' -%}
{%- endif -%}
{{- tab_footer() -}}
{# tab: ui #}
{{- tab_header('maintab', 'ui', _('User interface')) -}}
{%- if 'locale' not in locked_preferences -%}
{%- include 'simple/preferences/ui_locale.html' -%}
{%- endif -%}
{%- if 'theme' not in locked_preferences -%}
{%- include 'simple/preferences/theme.html' -%}
{%- endif -%}
{%- if 'results_on_new_tab' not in locked_preferences -%}
{%- include 'simple/preferences/results_on_new_tab.html' -%}
{%- endif -%}
{%- if 'infinite_scroll' not in locked_preferences -%}
{%- include 'simple/preferences/infinite_scroll.html' -%}
{%- endif -%}
{%- if 'search_on_category_select' not in locked_preferences -%}
{%- include 'simple/preferences/search_on_category_select.html' -%}
{%- endif -%}
{%- include 'simple/preferences/hotkeys.html' -%}
{%- include 'simple/preferences/urlformatting.html' -%}
{{- plugin_preferences('ui') -}}
{{- tab_footer() -}}
{# tab: privacy #}
{{- tab_header('maintab', 'privacy', _('Privacy')) -}}
{%- if 'method' not in locked_preferences -%}
{%- include 'simple/preferences/method.html' -%}
{%- endif -%}
{%- if 'image_proxy' not in locked_preferences -%}
{%- include 'simple/preferences/image_proxy.html' -%}
{%- endif -%}
{%- if 'query_in_title' not in locked_preferences -%}
{%- include 'simple/preferences/query_in_title.html' -%}
{%- endif -%}
{{- plugin_preferences('privacy') -}}
{{- tab_footer() -}}
{# tab: enignes #}
{{- tab_header('maintab', 'engines', _('Engines')) -}}
<p>
{{- _('Currently used search engines') -}}
</p>
{{- tabs_open() -}}
{%- include 'simple/preferences/engines.html' -%}
{{- tabs_close() -}}
{{- tab_footer() -}}
{# tab: query #}
{{- tab_header('maintab', 'query', _('Special Queries')) -}}
{%- if answer_storage -%}
{%- include 'simple/preferences/answerers.html' -%}
{%- endif -%}
{{- tab_footer() -}}
{# tab: cookies #}
{{- tab_header('maintab', 'cookies', _('Cookies')) -}}
{%- include 'simple/preferences/cookies.html' -%}
{{- tab_footer() -}}
{{- tabs_close() -}}
{# footer with save & reset buttons #}
{%- include 'simple/preferences/footer.html' -%}
</form>{{- '' -}}
{%- endblock -%}

View File

@@ -0,0 +1,45 @@
<div class="scrollx">{{- '' -}}
<table class="striped">{{- '' -}}
<tr>{{- '' -}}
<th>{{ _('Allow') }}</th>{{- '' -}}
<th>{{ _('Keywords (first word in query)') }}</th>{{- '' -}}
<th>{{ _('Name') }}</th>{{- '' -}}
<th>{{ _('Description') }}</th>{{- '' -}}
<th>{{ _('Examples') }}</th>{{- '' -}}
</tr>{{- '' -}}
<tr class="pref-group" >{{- '' -}}
<th scope="colgroup" colspan="5">
{{- _("This is the list of SearXNG's instant answering modules.") -}}
</th>{{- '' -}}
</tr>
{%- for info in answer_storage -%}
<tr>{{- '' -}}
<td class="checkbox-col"></td>{{- '' -}}
<td>{{ info.keywords|join(', ') }}</td>{{- '' -}}
<td>{{ info.name }}</td>{{- '' -}}
<td>{{ info.description }}</td>{{- '' -}}
<td>{{ info.examples|join(', ') }}</td>{{- '' -}}
</tr>
{%- endfor -%}
<tr class="pref-group" >{{- '' -}}
<th scope="colgroup" colspan="5">
{{- _('This is the list of plugins.') -}}
</th>{{- '' -}}
</th>
{%- for plugin in plugins_storage -%}
{%- if plugin.preference_section == 'query' -%}
<tr>{{- '' -}}
<td class="checkbox-col">{{- checkbox_onoff_reversed('plugin_' + plugin.id, plugin.id not in allowed_plugins, 'plugin_labelledby' + plugin.id) -}}</td>{{- '' -}}
<td>{{ plugin.keywords|join(', ') }}</td>{{- '' -}}
<td>{{ _(plugin.name) }}</td>{{- '' -}}
<td id="{{ 'plugin_labelledby' + plugin.id }}">{{ _(plugin.description) }}</td>{{- '' -}}
<td>{{ plugin.examples|join(', ') }}</td>{{- '' -}}
</tr>
{%- endif -%}
{%- endfor -%}
</table>{{- '' -}}
</div>{{- '' -}}

View File

@@ -0,0 +1,17 @@
<fieldset>{{- '' -}}
<legend id="pref_autocomplete">{{- _('Autocomplete') -}}</legend>{{- '' -}}
<div class="value">{{- '' -}}
<select name="autocomplete" aria-labelledby="pref_autocomplete">{{- '' -}}
<option value=""> - </option>
{%- for backend in autocomplete_backends -%}
<option value="{{ backend }}"
{%- if backend == autocomplete %} selected="selected" {%- endif -%}>
{{- backend -}}
</option>
{%- endfor -%}
</select>{{- '' -}}
</div>{{- '' -}}
<div class="description">
{{- _('Show possible queries as you type') -}}
</div>{{- '' -}}
</fieldset>{{- '' -}}

View File

@@ -0,0 +1,16 @@
<fieldset>{{- '' -}}
<legend id="pref_center_alignment">{{ _('Center Alignment') }}</legend>{{- '' -}}
<p class="value">{{- '' -}}
<input type="checkbox" {{- ' ' -}}
name="center_alignment" {{- ' ' -}}
aria-labelledby="pref_center_alignment" {{- ' ' -}}
class="checkbox-onoff" {{- ' ' -}}
{%- if preferences.get_value('center_alignment') -%}
checked
{%- endif -%}{{- ' ' -}}
>{{- '' -}}
</p>{{- '' -}}
<div class="description">
{{- _('Display results in the center of the page (Oscar layout).') -}}
</div>{{- '' -}}
</fieldset>{{- '' -}}

View File

@@ -0,0 +1,59 @@
<p class="text-muted">
{{- _('This is the list of cookies and their values SearXNG is storing on your computer.') }}
<br>{{- _('With this list, you can assess the transparency of SearXNG.') -}}
<br>{{- '' -}}
</p>
{% if cookies %}
<table class="cookies">
<tr>{{- '' -}}
<th>{{ _('Cookie name') }}</th>{{- '' -}}
<th>{{ _('Value') }}</th>{{- '' -}}
</tr>
{%- for cookie in cookies -%}
<tr>{{- '' -}}
<td>{{ cookie }}</td>{{- '' -}}
<td>{{ cookies[cookie] }}</td>{{- '' -}}
</tr>
{%- endfor -%}
</table>
{%- else -%}
{% include 'simple/messages/no_cookies.html' %}
{% endif %}
<h4>
{{- _('Search URL of the currently saved preferences') -}}:{{- '' -}}
</h4>{{- '' -}}
<div class="selectable_url">{{- '' -}}
<pre>
{{- url_for('index', _external=True) -}}?preferences={{- preferences_url_params|e -}}
{%- raw -%}&amp;q=%s{%- endraw -%}
</pre>{{- '' -}}
</div>{{- '' -}}
<p class="small_font">
{{- _('Note: specifying custom settings in the search URL can reduce privacy by leaking data to the clicked result sites.') -}}
</p>
<h4>
{{- _('URL to restore your preferences in another browser') -}}:{{- '' -}}
</h4>{{- '' -}}
<div class="selectable_url">{{- '' -}}
<pre>
{{- url_for('preferences', _external=True) -}}?preferences={{- preferences_url_params|e -}}{{- '' -}}
</pre>{{- '' -}}
</div>{{- '' -}}
<p class="small_font">
{{- _('A URL containing your preferences. This URL can be used to restore your settings on a different device.') -}}
</p>
<h4>
{{- _('Copy preferences hash') -}}:{{- '' -}}
</h4>{{- '' -}}
<div id="copy-hash-container">{{- '' -}}
<div class="selectable_url">{{- '' -}}
<pre>
{{- preferences_url_params|e }}
</pre>{{- '' -}}
</div>
<button id="copy-hash" class="button" data-hash="{{- preferences_url_params|e -}}" data-copied-text="{{- _('Copied') -}}">{{- _('Copy') -}}</button>
</div>
<h4>
{{- _('Insert copied preferences hash (without URL) to restore') -}}:{{- '' -}}
</h4>{{- '' -}}
<input type="text" id="pref-hash-input" name="preferences" placeholder="{{- _('Preferences hash') -}}">{{- '' -}}

View File

@@ -0,0 +1,20 @@
<div class="pref-group">{{- _('Digital Object Identifier (DOI)') -}}</div>
{{- plugin_preferences('general/doi_resolver') -}}
<fieldset>{{- '' -}}
<legend id="pref_doi_resolver">{{- _('Open Access DOI resolver') -}}</legend>{{- '' -}}
<div class="value">{{- '' -}}
<select id='doi_resolver' name='doi_resolver' aria-labelledby="pref_doi_resolver">{{- '' -}}
{%- for doi_resolver_name,doi_resolver_url in doi_resolvers.items() -%}
<option value="{{ doi_resolver_name }}"
{%- if doi_resolver_url == current_doi_resolver %} selected="selected" {%- endif -%}>
{{- doi_resolver_name }} - {{ doi_resolver_url -}}
</option>
{%- endfor -%}
</select>{{- '' -}}
</div>{{- '' -}}
<div class="description">
{{- _('Select service used by DOI rewrite') -}}
</div>{{- '' -}}
</fieldset>{{- '' -}}

View File

@@ -0,0 +1,101 @@
{%- set ns = namespace(checked=true) -%}
{%- for categ in categories_as_tabs + [DEFAULT_CATEGORY] -%}
{{- tab_header('enginetab', 'category_' + categ, _(categ), ns.checked ) -}}
{%- set ns.checked = false -%}
{%- if categ == DEFAULT_CATEGORY -%}
<p>
{{- _('This tab does not exist in the user interface, but you can search with these engines via !bangs.') -}}
{{- ' ' -}}<a href="{{ url_for('info', pagename='search-syntax') }}">&#9432;</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">{{- '' -}}
<tr>{{- '' -}}
<th class="checkbox-col">{{- _("Allow") -}}</th>{{- '' -}}
<th class="name">{{- _("Engine name") -}}</th>{{- '' -}}
<th class="shortcut">{{ _("!bang") -}}</th>{{- '' -}}
<th>{{- _("Supports selected language") -}}</th>{{- '' -}}
<th>{{- _("SafeSearch") -}}</th>{{- '' -}}
<th>{{- _("Time range") -}}</th>{{- '' -}}
<th>{{- _("Weight") }}</th>
{%- if enable_metrics -%}
<th>{{- _("Response time") -}}</th>
{%- endif -%}
<th>{{- _("Max time") -}}</th>
{%- if enable_metrics -%}
<th>{{- _("Reliability") }}</th>
{%- endif -%}
</tr>{{- '' -}}
{%- for group, group_bang, engines in engines_by_category[categ] | group_engines_in_tab -%}
{%- if loop.length > 1 -%}
<tr class="pref-group" >{{- '' -}}
<th colspan="2">{{- _(group) -}}</th>{{- '' -}}
<th colspan="8">
{%- if group_bang -%}
<span class="bang">{{- group_bang -}}</span>
{%- endif -%}</th>{{- '' -}}
</tr>{{- '' -}}
{%- endif -%}
{%- for search_engine in engines -%}
{%- if not search_engine.private -%}
{%- set engine_id = 'engine_' + search_engine.name|replace(' ', '_') + '__' + categ|replace(' ', '_') -%}
<tr>{{- '' -}}
<td>
{{- checkbox_onoff_reversed(engine_id, (search_engine.name, categ) in disabled_engines) -}}
</td>{{- '' -}}
<th class="name" data-engine-name="{{ search_engine.name }}">
{%- if search_engine.enable_http -%}
{{- icon_big('alert', 'No HTTPS') -}}
{%- endif -%}
<label for="{{ engine_id }}">
{{- ' ' -}}{{- search_engine.name -}}
{%- if search_engine.about and search_engine.about.language -%}
{{- ' ' -}}({{search_engine.about.language | upper}})
{%- endif -%}
</label>
{{- engine_about(search_engine) -}}
</th>{{- '' -}}
<td class="shortcut">{{- '' -}}
<span class="bang">{{ '!' + shortcuts[search_engine.name] }}</span>{{- '' -}}
</td>{{- '' -}}
<td>
{{- checkbox(None, supports[search_engine.name]['supports_selected_language'], true) -}}
</td>{{- '' -}}
<td>
{{- checkbox(None, supports[search_engine.name]['safesearch'], true) -}}
</td>{{- '' -}}
<td>
{{- checkbox(None, supports[search_engine.name]['time_range_support'], true) -}}
</td>{{- '' -}}
<td>{{- search_engine.weight or '1.0' -}}</td>{{- '' -}}
{%- if enable_metrics -%}
{{- engine_time(search_engine.name) -}}
{%- endif -%}
<td class="{{ 'danger' if stats[search_engine.name]['warn_timeout'] else '' }}">
{{- search_engine.timeout -}}
</td>{{- '' -}}
{%- if enable_metrics -%}
{{- engine_reliability(search_engine.name) -}}
{%- endif -%}
</tr>
{%- endif -%}
{%- endfor -%}
{%- endfor -%}
</table>{{- '' -}}
</div>
{{- tab_footer() -}}
{%- endfor -%}

View File

@@ -0,0 +1,17 @@
<fieldset>{{- '' -}}
<legend id="pref_favicon_resolver">{{- _('Favicon Resolver') -}}</legend>{{- '' -}}
<div class="value">{{- '' -}}
<select name="favicon_resolver" aria-labelledby="pref_favicon_resolver">{{- '' -}}
<option value=""> - </option>
{%- for backend in favicon_resolver_names -%}
<option value="{{ backend }}"
{%- if backend == favicon_resolver %} selected="selected" {%- endif -%}>
{{- backend -}}
</option>
{%- endfor -%}
</select>{{- '' -}}
</div>{{- '' -}}
<div class="description">
{{- _('Display favicons near search results') -}}
</div>{{- '' -}}
</fieldset>{{- '' -}}

View File

@@ -0,0 +1,14 @@
<p class="small_font">
{{- _('These settings are stored in your cookies. This allows us not to store this data about you.') -}}
<br>{{- _("These cookies serve your sole convenience; we don't use them to track you.") -}}
</p>{{- '' -}}
<input type="submit" value="{{ _('Save') }}">{{- '' -}}
<div class="{% if rtl %}left{% else %}right{% endif %} preferences_back">{{- '' -}}
<a href="{{ url_for('clear_cookies') }}">{{ _('Reset defaults') }}</a>{{- '' -}}
</div>{{- '' -}}
<div class="{% if rtl %}left{% else %}right{% endif %} preferences_back">{{- '' -}}
<a href="{{ url_for('index') }}">{{ _('Back') }}</a>{{- '' -}}
</div>

View File

@@ -0,0 +1,23 @@
<fieldset>{{- '' -}}
<legend id="pref_hotkeys">{{- _('Hotkeys') -}}</legend>{{- '' -}}
<div class="value">{{- '' -}}
<select name="hotkeys" aria-labelledby="pref_hotkeys">{{- '' -}}
<option value="default"
{%- if hotkeys == 'default' %} selected="selected"
{%- endif -%}>
SearXNG{{- '' -}}
</option>{{- '' -}}
<option value="vim"
{%- if hotkeys == 'vim' %} selected="selected"
{%- endif -%}>
{{- _('Vim-like') -}}
</option>{{- '' -}}
</select>{{- '' -}}
</div>{{- '' -}}
<div class="description">
{{- _(
'Navigate search results with hotkeys (JavaScript required). '
'Press "h" key on main or result page to get help.'
) -}}
</div>{{- '' -}}
</fieldset>{{- '' -}}

View File

@@ -0,0 +1,16 @@
<fieldset>{{- '' -}}
<legend id="pref_image_proxy">{{ _('Image proxy') }}</legend>{{- '' -}}
<p class="value">{{- '' -}}
<input type="checkbox" {{- ' ' -}}
name="image_proxy" {{- ' ' -}}
aria-labelledby="pref_image_proxy" {{- ' ' -}}
class="checkbox-onoff" {{- ' ' -}}
{%- if preferences.get_value('image_proxy') -%}
checked
{%- endif -%}{{- ' ' -}}
>{{- '' -}}
</p>{{- '' -}}
<div class="description">
{{- _('Proxy image results through SearXNG') -}}
</div>{{- '' -}}
</fieldset>{{- '' -}}

View File

@@ -0,0 +1,16 @@
<fieldset>{{- '' -}}
<legend>{{ _('Infinite scroll') }}</legend>{{- '' -}}
<p class="value">{{- '' -}}
<input type="checkbox" {{- ' ' -}}
name="infinite_scroll" {{- ' ' -}}
aria-labelledby="pref_infinite_scroll" {{- ' ' -}}
class="checkbox-onoff" {{- ' ' -}}
{%- if preferences.get_value('infinite_scroll') -%}
checked
{%- endif -%}{{- ' ' -}}
>{{- '' -}}
</p>{{- '' -}}
<div class="description" id="pref_infinite_scroll">
{{- _('Automatically load the next page when scrolling to the bottom of the current page') -}}
</div>{{- '' -}}
</fieldset>{{- '' -}}

View File

@@ -0,0 +1,27 @@
<fieldset>{{- '' -}}
<legend id="pref_language">{{- _('Search language') -}}</legend>{{- '' -}}
<div class="value">{{- '' -}}
<select name='language' aria-labelledby="pref_language" aria-describedby="desc_language">{{- '' -}}
<option value="all"
{%- if current_language == 'all' %} selected="selected" {%- endif -%}>
{{- _('Default language') }} [all] {{- '' -}}
</option>{{- '' -}}
<option value="auto"
{%- if current_language == 'auto' %} selected="selected" {%- endif -%}>
{{- _('Auto-detect') }} [auto] {{- '' -}}
</option>{{- '' -}}
{% for sxng_tag,lang_name,country_name,english_name,flag in sxng_locales | sort(attribute=1) -%}
<option value="{{ sxng_tag }}"
{%- if sxng_tag == current_language %} selected="selected" {%- endif -%}>
{{ lang_name }}{%- if country_name -%}-{{ country_name }}{%- endif -%}
{{- ' ' -}}[{{sxng_tag}}]{{- ' ' -}}
{%- if flag -%}{{ flag }}{%- endif -%}
</option>
{%- endfor -%}
</select>{{- '' -}}
</div>{{- '' -}}
<div class="description" id="desc_language">
{{- _('What language do you prefer for search?') }} {{- ' ' -}}
{{- _('Choose Auto-detect to let SearXNG detect the language of your query.') -}}
</div>{{- '' -}}
</fieldset>{{- '' -}}

View File

@@ -0,0 +1,16 @@
<fieldset>{{- '' -}}
<legend id="pref_method">{{- _('HTTP Method') -}}</legend>{{- '' -}}
<div class="value">{{- '' -}}
<select name='method' aria-labelledby="pref_method">{{- '' -}}
<option value="POST"
{%- if method == 'POST' %} selected="selected"{%- endif -%}>POST{{- '' -}}
</option>{{- '' -}}
<option value="GET"
{%- if method == 'GET' %} selected="selected"{%- endif -%}>GET{{- '' -}}
</option>{{- '' -}}
</select>{{- '' -}}
</div>{{- '' -}}
<div class="description">
{{- _('Change how forms are submitted') }} <a href="https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods" rel="external">🔗</a>
</div>{{- '' -}}
</fieldset>{{- '' -}}

View File

@@ -0,0 +1,16 @@
<fieldset>{{- '' -}}
<legend id="pref_query_in_title">{{ _("Query in the page's title") }}</legend>{{- '' -}}
<p class="value">{{- '' -}}
<input type="checkbox" {{- ' ' -}}
name="query_in_title" {{- ' ' -}}
aria-labelledby="pref_query_in_title" {{- ' ' -}}
class="checkbox-onoff" {{- ' ' -}}
{%- if preferences.get_value('query_in_title') -%}
checked
{%- endif -%}{{- ' ' -}}
>{{- '' -}}
</p>{{- '' -}}
<div class="description">
{{- _("When enabled, the result page's title contains your query. Your browser can record this title") -}}
</div>{{- '' -}}
</fieldset>{{- '' -}}

View File

@@ -0,0 +1,16 @@
<fieldset>{{- '' -}}
<legend id="pref_results_on_new_tab">{{ _('Results in new tabs') }}</legend>{{- '' -}}
<p class="value">{{- '' -}}
<input type="checkbox" {{- ' ' -}}
name="results_on_new_tab" {{- ' ' -}}
aria-labelledby="pref_results_on_new_tab" {{- ' ' -}}
class="checkbox-onoff" {{- ' ' -}}
{%- if preferences.get_value('results_on_new_tab') -%}
checked
{%- endif -%}{{- ' ' -}}
>{{- ' ' -}}
</p>{{- '' -}}
<div class="description">
{{- _('Open result links in new browser tabs') -}}
</div>{{- '' -}}
</fieldset>{{- '' -}}

View File

@@ -0,0 +1,22 @@
<fieldset>{{- '' -}}
<legend id="pref_safesearch">{{- _('SafeSearch') -}}</legend>{{- '' -}}
<div class="value">{{- '' -}}
<select name='safesearch' aria-labelledby="pref_safesearch">{{- '' -}}
<option value="2"
{%- if safesearch == '2' %} selected="selected" {%- endif -%}>
{{- _('Strict') -}}
</option>{{- '' -}}
<option value="1"
{%- if safesearch == '1' %} selected="selected" {%- endif -%}>
{{- _('Moderate') -}}
</option>{{- '' -}}
<option value="0"
{%- if safesearch == '0' %} selected="selected" {%- endif -%}>
{{- _('None') -}}
</option>{{- '' -}}
</select>{{- '' -}}
</div>{{- '' -}}
<div class="description">
{{- _('Filter content') -}}
</div>{{- '' -}}
</fieldset>{{- '' -}}

View File

@@ -0,0 +1,16 @@
<fieldset>{{- '' -}}
<legend>{{ _('Search on category select') }}</legend>{{- '' -}}
<p class="value">{{- '' -}}
<input type="checkbox" {{- ' ' -}}
name="search_on_category_select" {{- ' ' -}}
aria-labelledby="pref_search_on_category_select" {{- ' ' -}}
class="checkbox-onoff" {{- ' ' -}}
{%- if preferences.get_value('search_on_category_select') -%}
checked
{%- endif -%}{{- ' ' -}}
>{{- '' -}}
</p>{{- '' -}}
<div class="description" id="pref_search_on_category_select">
{{- _('Perform a search immediately if a category is selected. Disable to select multiple categories') -}}
</div>{{- '' -}}
</fieldset>{{- '' -}}

View File

@@ -0,0 +1,35 @@
<fieldset>{{- '' -}}
<legend id="pref_theme">{{- _('Theme') -}}</legend>{{- '' -}}
<div class="value">{{- '' -}}
<select name="theme" aria-labelledby="pref_theme">{{- '' -}}
{%- for name in themes -%}
<option value="{{ name }}"
{%- if name == theme %} selected="selected"{%- endif -%}>
{{- name | capitalize -}}
</option>
{%- endfor -%}
</select>{{- '' -}}
</div>{{- '' -}}
<div class="description">
{{- _('Change the layout of SearXNG') -}}
</div>{{- '' -}}
</fieldset>{{- '' -}}
<fieldset>{{- '' -}}
<legend id="pref_simple_style">{{- _('Theme style') -}}</legend>{{- '' -}}
<div class="value">{{- '' -}}
<select name="simple_style" aria-labelledby="pref_simple_style">
{%- for name in ['auto', 'light', 'dark', 'black'] -%}
<option value="{{ name }}"
{%- if name == preferences.get_value('simple_style') %} selected="selected" {%- endif -%}>
{{- _(name) | capitalize -}}
</option>
{%- endfor -%}
</select>{{- '' -}}
</div>{{- '' -}}
<div class="description">
{{- _('Choose auto to follow your browser settings') -}}
</div>{{- '' -}}
</fieldset>{{- '' -}}
{%- include 'simple/preferences/center_alignment.html' -%}

View File

@@ -0,0 +1,11 @@
<fieldset>{{- '' -}}
<legend id="pref_tokens">{{- _('Engine tokens') -}}</legend>{{- '' -}}
<div class="value">{{- '' -}}
<input name="tokens" aria-labelledby="pref_tokens" type="text"
autocomplete="off" spellcheck="false" autocorrect="off"
value='{{ preferences.tokens.get_value() }}'>{{- '' -}}
</div>{{- '' -}}
<div class="description">
{{- _('Access tokens for private engines') -}}
</div>{{- '' -}}
</fieldset>{{- '' -}}

View File

@@ -0,0 +1,16 @@
<fieldset>{{- '' -}}
<legend id="pref_ui_locale">{{- _('Interface language') -}}</legend>{{- '' -}}
<div class="value">{{- '' -}}
<select name='locale' aria-labelledby="pref_ui_locale">{{- '' -}}
{%- for locale_id,locale_name in locales.items() | sort -%}
<option value="{{ locale_id }}"
{%- if locale_id == current_locale %} selected="selected" {%- endif %}>
{{- locale_name -}}
</option>{{- '' -}}
{%- endfor -%}
</select>{{- '' -}}
</div>{{- '' -}}
<div class="description">
{{- _('Change the language of the layout') -}}
</div>{{- '' -}}
</fieldset>{{- '' -}}

View File

@@ -0,0 +1,25 @@
<fieldset>{{- '' -}}
<legend id="pref_url_formatting">{{- _('URL formatting') -}}</legend>{{- '' -}}
<div class="value">{{- '' -}}
<select name="url_formatting" aria-labelledby="pref_url_formatting">{{- '' -}}
<option value="pretty"
{%- if preferences.get_value('url_formatting') == 'pretty' %} selected="selected"
{%- endif -%}>
{{- _('Pretty') -}}
</option>{{- '' -}}
<option value="full"
{%- if preferences.get_value('url_formatting') == 'full' %} selected="selected"
{%- endif -%}>
{{- _('Full') -}}
</option>{{- '' -}}
<option value="host"
{%- if preferences.get_value('url_formatting') == 'host' %} selected="selected"
{%- endif -%}>
{{- _('Host') -}}
</option>{{- '' -}}
</select>{{- '' -}}
</div>{{- '' -}}
<div class="description">
{{- _('Change result URL formatting') -}}
</div>{{- '' -}}
</fieldset>{{- '' -}}

View File

@@ -0,0 +1,32 @@
{% from 'simple/macros.html' import result_header, result_sub_header, result_sub_footer, result_footer with context %}
{{ result_header(result, favicons, image_proxify) -}}
{{- result_sub_header(result) -}}
{%- if result.content -%}
<p class="content">
{{- result.content|safe -}}
</p>
{%- endif -%}
{%- if result.repository -%}
<p class="content">{{- '' -}}
{{ _('repo') }}: {{- ' ' -}}
<a href="{{ result.repository|safe }}"{{- ' ' -}}
{% if results_on_new_tab %}
target="_blank" {{- ' ' -}}
rel="noopener noreferrer"
{%- else -%}
rel="noreferrer"
{%- endif -%}
>
{{- result.repository -}}
</a>{{- '' -}}
</p>
{%- endif -%}
<div dir="ltr" class="codelines">
{{- result.codelines|code_highlighter(result.code_language)|safe -}}
</div>
{{- result_sub_footer(result) -}}
{{- result_footer(result) -}}

View File

@@ -0,0 +1,28 @@
{% from 'simple/macros.html' import result_header, result_sub_header, result_sub_footer, result_footer with context %}
{{ result_header(result, favicons, image_proxify) -}}
{{- result_sub_header(result) -}}
{% if result.iframe_src -%}
<p class="altlink"><a class="btn-collapse collapsed media-loader disabled_if_nojs" data-target="#result-media-{{ index }}" data-btn-text-collapsed="{{ _('show media') }}" data-btn-text-not-collapsed="{{ _('hide media') }}">{{ icon('music-note') }} {{ _('show media') }}</a></p>
{%- endif %}
{%- if result.content %}
<p class="content">
{{ result.content|safe }}
</p>
{%- else %}
<p class="content empty_element">
{{ _('This site did not provide any description.')|safe }}
</p>
{% endif -%}
{{- result_sub_footer(result) -}}
{% if result.iframe_src -%}
<div id="result-media-{{ index }}" class="embedded-content invisible">
<iframe data-src="{{result.iframe_src}}" frameborder="0" allowfullscreen></iframe>
</div>
{%- endif %}
{% if result.audio_src -%}
<div id="result-media-{{ index }}" class="audio-control">
<audio controls><source src="{{result.audio_src}}"></audio>
</div>
{%- endif %}
{{- result_footer(result) }}

View File

@@ -0,0 +1,45 @@
{% from 'simple/macros.html' import result_header, result_sub_header, result_sub_footer, result_footer, result_link with context %}
{% from 'simple/icons.html' import icon_small %}
{{- result_header(result, favicons, image_proxify) -}}
{{- result_sub_header(result) -}}
{%- if result.embedded -%}
<small> &bull; <a class="text-info btn-collapse collapsed cursor-pointer media-loader disabled_if_nojs" data-toggle="collapse" data-target="#result-media-{{ index }}" data-btn-text-collapsed="{{ _('show media') }}" data-btn-text-not-collapsed="{{ _('hide media') }}">
{%- if result.mtype == 'audio' %}{{ icon_small('musical-notes') -}}
{%- elif result.mtype == 'video' %} {{ icon_small('play') -}}
{%- endif %} {{ _('show media') }}</a></small>
{%- endif -%}
{%- if result.embedded -%}
<div id="result-media-{{ index }}" class="collapse invisible">
{{- result.embedded|safe -}}
</div>
{%- endif -%}
{%- if result.abstract %}<p class="result-content result-abstract">{{ result.abstract|safe }}</p>{% endif -%}
{%- if result.img_src -%}
<div class="container-fluid">
<div class="row">
<img src="{{ image_proxify(result.img_src) }}" alt="{{ result.title|striptags }}" title="{{ result.title|striptags }}" style="width: auto; max-height: 60px; min-height: 60px;" class="col-xs-2 col-sm-4 col-md-4 result-content">
{%- if result.content %}<p class="result-content col-xs-8 col-sm-8 col-md-8">{{ result.content|safe }}</p>{% endif -%}
</div>
</div>
{%- else -%}
{%- if result.content %}<p class="result-content">{{ result.content|safe }}</p>{% endif -%}
{%- endif -%}
<table class="result-metadata result-content">
{%- if result.author %}<tr><td>{{ _('Author') }}</td><td>{{ result.author|safe }}</td></tr>{% endif -%}
{%- if result.filename %}<tr><td>{{ _('Filename') }}</td><td>{{ result.filename|safe }}</td></tr>{% endif -%}
{%- if result.size %}<tr><td>{{ _('Filesize') }}</td><td>{{ result.size|safe }}</td></tr>{%- endif -%}
{%- if result.time %}<tr><td>{{ _('Date') }}</td><td>{{ result.time|safe }}</td></tr>{% endif -%}
{%- if result.mtype %}<tr><td>{{ _('Type') }}</td><td>{{ result.mtype|safe }}/{{ result.subtype|safe }}</td></tr>{% endif -%}
</table>
{{ result_footer(result) }}

View File

@@ -0,0 +1,28 @@
<article class="result result-images {% if result['category'] %}category-{{ result['category'] }}{% endif %}">{{- "" -}}
<a {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %} href="{{ result.img_src }}">{{- "" -}}
<img class="image_thumbnail" {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %} src="{% if result.thumbnail_src %}{{ image_proxify(result.thumbnail_src) }}{% else %}{{ image_proxify(result.img_src) }}{% endif %}" alt="{{ result.title|striptags }}" loading="lazy" width="200" height="200">{{- "" -}}
{%- if result.resolution %} <span class="image_resolution">{{ result.resolution }}</span> {%- endif -%}
<span class="title">{{ result.title|striptags }}</span>{{- "" -}}
<span class="source">{{- result.parsed_url.netloc -}}</span>{{- "" -}}
</a>{{- "" -}}
<div class="detail swipe-horizontal">{{- "" -}}
<a class="result-detail-close" href="#">{{ icon('close') }}</a>{{- "" -}}
<a class="result-detail-previous" href="#">{{ icon('navigate-left') }}</a>{{- "" -}}
<a class="result-detail-next" href="#">{{ icon('navigate-right') }}</a>{{- "" -}}
<a class="result-images-source" {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %} href="{{ result.img_src }}">
<img src="" data-src="{{ image_proxify(result.img_src) }}" alt="{{ result.title|striptags }}">{{- "" -}}
</a>{{- "" -}}
<div class="result-images-labels">{{- "" -}}
<h4>{{ result.title|striptags }}</h4>{{- "" -}}
<p class="result-content">{%- if result.content %}{{ result.content|striptags }}{% else %}&nbsp;{% endif -%}</p>{{- "" -}}
<hr>{{- "" -}}
<p class="result-author">{%- if result.author %}<span>{{ _('Author') }}:</span>{{ result.author|striptags }}{% else %}&nbsp;{% endif -%}</p>{{- "" -}}
<p class="result-resolution">{%- if result.resolution %}<span>{{ _('Resolution') }}:</span>{{ result.resolution }}{% else %}&nbsp;{% endif -%}</p>{{- "" -}}
<p class="result-format">{%- if result.img_format %}<span>{{ _('Format') }}:</span>{{ result.img_format }}{% else %}&nbsp;{% endif -%}</p>{{- "" -}}
<p class="result-filesize">{%- if result.filesize %}<span>{{ _('Filesize') }}:</span>{{ result.filesize}}{% else %}&nbsp;{% endif -%}</p>{{- "" -}}
<p class="result-source">{%- if result.source %}<span>{{ _('Source') }}:</span>{{ result.source }}{% else %}&nbsp;{% endif -%}</p>{{- "" -}}
<p class="result-engine"><span>{{ _('Engine') }}:</span>{{ result.engine }}</p>{{- "" -}}{{- "" -}}
<p class="result-url"><span>{{ _('View source') }}:</span><a {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %} href="{{ result.url }}">{{ result.url }}</a></p>{{- "" -}}
</div>{{- "" -}}
</div>{{- "" -}}
</article>

View File

@@ -0,0 +1,21 @@
<article class="result result-keyvalue {% if result.category -%}category-{{ result.category }}{%- endif -%}">
<table>
{%- if result.caption %}<caption>{{ result.caption }}</caption>{%- endif -%}
{%- if result.key_title or result.value_title %}
<thead>
<tr>
<th class="col-key" scope="col" >{{result.key_title}}</th>
<th class="col-value" scope="col" >{{result.value_title}}</th>
</tr>
</thead>
{%- endif -%}
{%- for key, value in result.kvmap.items() -%}
<tr class="{{ loop.cycle('odd', 'even') }}">
<th class="col-key" scope="row">{{ key }}</th>{{- '' -}}
<td class="col-value">{{ value }}</td>{{- '' -}}
</tr>
{%- endfor -%}
</table>{{- '' -}}
<div class="engines">{% for engine in result.engines %}<span>{{ engine }}</span>{% endfor %}</div>{{- '' -}}
<div class="break"></div>{{- '' -}}
</article>

View File

@@ -0,0 +1,52 @@
{% from 'simple/macros.html' import result_header, result_sub_header, result_sub_footer, result_footer with context %}
{% from 'simple/icons.html' import icon_small %}
{{ result_header(result, favicons, image_proxify) -}}
{{- result_sub_header(result) -}}
{%- if result.content %}<p class="content">{{ result.content|safe }}</p>{% endif -%}
<table>
{%- if result.address -%}
<tr>
<th scope="row">{{ result.address_label or _('address') }}</th>
<td itemscope itemtype="http://schema.org/PostalAddress">
{%- if result.address.name -%}
<strong itemprop="name" class="hidden">{{ result.address.name }}</strong>
{%- endif -%}
{% if result.address.road -%}
<span itemprop="streetAddress">
{%- if result.address.house_number -%}{{- result.address.house_number -}}, {% endif %}
{{- result.address.road -}}
</span><br>
{%- endif %}
{%- if result.address.locality -%}
<span itemprop="addressLocality">{{- result.address.locality -}}</span>
{%- if result.address.postcode -%}, <span itemprop="postalCode">{{- result.address.postcode -}}</span>{% endif %}
<br>
{%- endif -%}
{%- if result.address.country -%}
<span itemprop="addressCountry">{{- result.address.country -}}</span>
{%- endif -%}
</td>
</tr>
{%- endif %}
{%- for info in result.data -%}
<tr><th scope="row">{{ info.label }}</th><td>{{ info.value|safe }}</td></tr>
{%- endfor -%}
{%- for link in result.links -%}
<tr><th scope="row">{{ link.label }}</th><td><a class="text-info cursor-pointer" href="{{ link.url }}">{{ link.url_label|safe }}</a></td></tr>
{%- endfor -%}
</table>
{%- if (result.latitude and result.longitude) or result.boundingbox -%}
<small> <a class="btn-collapse collapsed searxng_init_map hide_if_nojs" data-target="#result-map-{{ index }}" data-btn-text-collapsed="{{ _('show map') }}" data-btn-text-not-collapsed="{{ _('hide map') }}" data-leaflet-target="osm-map-{{ index }}" data-map-lon="{{ result.longitude }}" data-map-lat="{{ result.latitude }}" {% if result.boundingbox %}data-map-boundingbox='{{ result.boundingbox|tojson|safe }}'{% endif %} {% if result.geojson %}data-map-geojson='{{ result.geojson|tojson|safe }}'{% endif %}>{{ icon_small( 'globe') }} {{ _('show map') }}</a></small>
{%- endif -%}
{{- result_sub_footer(result) -}}
{% if (result.latitude and result.longitude) or result.boundingbox -%}
<div id="result-map-{{ index }}" class="invisible"><div id="osm-map-{{ index }}" class="osm-map-box"></div></div>
{%- endif %}
{{- result_footer(result) }}

View File

@@ -0,0 +1,75 @@
{%- from 'simple/macros.html' import result_header, result_sub_header, result_sub_footer, result_footer with context -%}
{{ result_header(result, favicons, image_proxify) -}}
{%- if result.content -%}<p class="content">{{- result.content|safe -}}</p>{%- endif -%}
<div class="attributes">{{- '' -}}
<div class="result_package_name">{{- '' -}}
<span>{{ _('Name') }}:</span>{{- '' -}}
<span><code>{{- result.package_name -}}</code></span>{{- '' -}}
</div>
{%- if result.version -%}
<div class="result_version">{{- '' -}}
<span>{{- _('Version') }}:</span>{{- '' -}}
<span><strong>{{ result.version }}</strong></span>{{- '' -}}
</div>
{%- endif -%}
{%- if result.maintainer -%}
<div class="result_maintainer">{{- '' -}}
<span>{{ _('Maintainer') }}:</span>{{- '' -}}
<span>{{ result.maintainer }}</span>{{- '' -}}
</div>
{%- endif -%}
{%- if result.publishedDate -%}
<div class="result_pubdate">{{- '' -}}
<span>{{ _('Updated at') }}:</span>{{- '' -}}
<span><time datetime="{{ result.pubdate }}">{{ result.publishedDate }}</time></span>{{- '' -}}
</div>
{%- endif -%}
{%- if result.tags -%}
<div class="result_tags">{{- '' -}}
<span>{{ _('Tags') }}:</span>{{- '' -}}
<span>{{ result.tags|join(', ') }}</span>{{- '' -}}
</div>
{%- endif -%}
{%- if result.popularity -%}
<div class="result_popularity">{{- '' -}}
<span>{{ _('Popularity') }}:</span>{{- '' -}}
<span>{{ result.popularity }}</span>{{- '' -}}
</div>
{%- endif -%}
{%- if result.license_name -%}
<div class="result_license">{{- '' -}}
<span>{{- _('License') -}}:</span>
{%- if result.license_url -%}
<span><a href="{{ result.license_url }}" target="_blank">{{ result.license_name }}</a></span>
{%- else -%}
<span>{{ result.license_name }}</span>
{%- endif -%}
</div>
{%- endif -%}
{%- if result.homepage or result.source_code_url or result.links -%}
<div class="result_project">{{- '' -}}
<span>{{ _('Project') }}</span>
<span>{{- '' -}}
{%- if result.homepage -%}
<a href="{{ result.homepage }}" target="_blank">{{ _('Project homepage') }}</a>
{%- endif -%}
{%- if result.homepage and result.source_code_url %} | {% endif -%}
{%- if result.source_code_url -%}
<a href="{{ result.source_code_url }}" target="_blank">{{ _('Source code') }}</a>
{%- endif -%}
{%- if result.links %}
{%- for name, link in result.links.items() -%}
{% if not loop.first or result.homepage or result.source_code_url %} | {% endif %}
<a href="{{ link }}" target="_blank">
{{- _(name) -}}
</a>
{%- endfor -%}
{%- endif -%}
</span>{{- '' -}}
</div>
{%- endif -%}
</div>{{- '' -}}
<div class="break"></div>
{{- result_footer(result) }}

View File

@@ -0,0 +1,38 @@
{% from 'simple/macros.html' import result_header, result_sub_header, result_sub_footer, result_footer, result_link with context %}
{{ result_header(result, favicons, image_proxify) -}}
<div class="attributes">
{%- if result.publishedDate %}<div class="result_publishedDate"><span>{{ _("Published date") }}:</span><span><time class="published_date" datetime="{{ result.pubdate }}" >{{ result.publishedDate }}</time></span></div>{% endif -%}
{%- if result.authors %}<div class="result_authors"><span>{{ _("Author") }}:</span><span>{{ result.authors | join(", ") }}</span></div>{% endif -%}
{%- if result.journal -%}
<div class="result_journal">
<span>{{- _("Journal") }}:</span><span>{{ result.journal -}}
{%- if result.volume -%}
&nbsp;{{- result.volume -}}
{%- if result.number -%}
.{{- result.number -}}
{%- endif -%}
{%- endif -%}
{%- if result.pages -%}
&nbsp;{{- result.pages -}}
{%- endif -%}
</span>
</div>
{%- endif %}
{%- if result.editor %}<div class="result_editor"><span>{{ _("Editor") }}:</span><span>{{ result.editor }}</span></div>{% endif -%}
{%- if result.publisher %}<div class="result_publisher"><span>{{ _("Publisher") }}:</span><span>{{ result.publisher }}</span></div>{% endif -%}
{%- if result.type %}<div class="result_type"><span>{{ _("Type") }}:</span><span>{{ result.type }}</span></div>{% endif -%}
{%- if result.tags %}<div class="result_tags"><span>{{ _("Tags") }}:</span><span>{{ result.tags | join(", ")}}</span></div>{%- endif -%}
{%- if result.doi %}<div class="result_doi"><span>{{ _("DOI") }}:</span><span>{{ result_link(doi_resolver + result.doi, result.doi) }}</span></div>{% endif -%}
{%- if result.issn %}<div class="result_issn"><span>{{ _("ISSN") }}:</span><span>{{ result.issn | join(", ") }}</span></div>{% endif -%}
{%- if result.isbn %}<div class="result_isbn"><span>{{ _("ISBN") }}:</span><span>{{ result.isbn | join(", ") }}</span></div>{% endif -%}
</div>
{%- if result.content -%}<p class="content">{{- result.content | safe -}}</p>{%- endif -%}
{%- if result.comments -%}<p class="comments">{{- result.comments -}}</p>{%- endif -%}
<p class="altlink">
{%- if result.pdf_url -%}{{ result_link(result.pdf_url, _('PDF')) }}{%- endif -%}
{%- if result.html_url -%}{{ result_link(result.html_url, _('HTML')) }}{%- endif -%}
{%- if result.doi %}{{ result_link('https://www.altmetric.com/details/doi/' + result.doi, 'Altmetric') }}{% endif -%}
</p>
{{- result_sub_footer(result) -}}
{{- result_footer(result) }}

View File

@@ -0,0 +1,14 @@
{% from 'simple/macros.html' import result_header, result_sub_header, result_sub_footer, result_footer with context %}
{{ result_header(result, favicons, image_proxify) -}}
{{- result_sub_header(result) -}}
{% if result.price %}<div class="result_price">{{ result.price }}</div></br>{% endif %}
{% if result.shipping %}<div class="result_shipping">{{ result.shipping }}</div></br>{% endif %}
{% if result.source_country %}<div class="result_source_country">{{ result.source_country }}</div></br>{% endif %}
{%- if result.content %}
<p class="content">
{{ result.content|safe }}
</p>
{% endif -%}
{{- result_sub_footer(result) -}}
{{- result_footer(result) }}

View File

@@ -0,0 +1,23 @@
{% from 'simple/macros.html' import result_header, result_sub_header, result_sub_footer, result_footer, result_link with context %}
{{ result_header(result, favicons, image_proxify) -}}
{{- result_sub_header(result) -}}
<p class="altlink">
{%- if result.magnetlink %}{{ result_link(result.magnetlink, icon_big('magnet') + _('magnet link'), "magnetlink") }}{%- endif -%}
{%- if result.torrentfile %}{{ result_link(result.torrentfile, icon_big('download-alt') + _('torrent file'), "torrentfile") }}{%- endif -%}
</p>
<p class="stat">
{%- if result.seed is defined %}
{{ icon_big('seeder') }} <span class="badge">{{ result.seed }} {{ _('Seeder') }} </span>
{{ icon_big('leecher') }} <span class="badge">{{ result.leech }} {{ _('Leecher') }}</span>
{% endif %}
</p>
<p class="stat">
{%- if result.filesize %}{{ icon_big('save') }} <span class="badge">{{ result.filesize }} {{ _('Filesize') }}</span>{%- endif -%}
{%- if result.files %}{{ icon_big('file') }} <span class="badge">{{ result.files }} {{ _('Number of Files') }}</span>{%- endif -%}
</p>
{%- if result.content %}<p class="content">{{ result.content|safe }}</p>{%- endif -%}
{{- result_sub_footer(result) -}}
{{- result_footer(result) -}}

View File

@@ -0,0 +1,24 @@
{% from 'simple/macros.html' import result_header, result_sub_header, result_sub_footer, result_footer with context %}
{{ result_header(result, favicons, image_proxify) }}
{{ result_sub_header(result) }}
{% if result.iframe_src -%}
<p class="altlink"> <a class="btn-collapse collapsed media-loader disabled_if_nojs" data-target="#result-video-{{ index }}" data-btn-text-collapsed="{{ _('show video') }}" data-btn-text-not-collapsed="{{ _('hide video') }}">{{ icon_small('film') }} {{ _('show video') }}</a></p>
{%- endif %}
{%- if result.content %}
<p class="content">
{{ result.content|safe }}
</p>
{%- else %}
<p class="content empty_element">
{{ _('This site did not provide any description.')|safe }}
</p>
{% endif -%}
</p>
{{- result_sub_footer(result) -}}
{% if result.iframe_src -%}
<div id="result-video-{{ index }}" class="embedded-video invisible">
<iframe data-src="{{result.iframe_src}}" frameborder="0" allowfullscreen></iframe>
</div>
{%- endif %}
{{ result_footer(result) }}

View File

@@ -0,0 +1,149 @@
{% extends "simple/base.html" %}
{% from 'simple/icons.html' import icon, icon_big, icon_small %}
{% macro engine_data_form(engine_data) -%}
{% for engine_name, kv_data in engine_data.items() %}
{% for k, v in kv_data.items() %}
<input type="hidden" name="engine_data-{{ engine_name }}-{{ k|e }}" value="{{ v|e }}">
{% endfor %}
{% endfor %}
{%- endmacro %}
{% block title %}{% if query_in_title %}{{- q|e }} - {% endif %}{% endblock %}
{% block meta %}<link rel="alternate" type="application/rss+xml" title="Searx search: {{ q|e }}" href="{{ url_for('search', _external=True) }}?q={{ q|urlencode }}&amp;categories={{ selected_categories|join(",") | replace(' ','+') }}&amp;pageno={{ pageno }}&amp;time_range={{ time_range }}&amp;language={{ current_language }}&amp;safesearch={{ safesearch }}&amp;format=rss">{% endblock %}
{% block content %}
{% include 'simple/search.html' %}
{% if results and results|map(attribute='template')|unique|list|count == 1 %}
{% set only_template = 'only_template_' + results[0]['template']|default('default')|replace('.html', '') %}
{% else %}
{% set only_template = '' %}
{% endif %}
<div id="results" class="{{ only_template }}">
{%- if answers -%}
{%- include 'simple/elements/answers.html' -%}
{%- endif %}
<div id="sidebar">
{%- if number_of_results != '0' -%}
<p id="result_count"><small>{{ _('Number of results') }}: {{ number_of_results }}</small></p>
{%- endif -%}
{%- if infoboxes -%}
<div id="infoboxes">
<details open class="sidebar-collapsible">
<summary class="title">{{ _('Info') }}</summary>
{%- for infobox in infoboxes -%}
{%- include 'simple/elements/infobox.html' -%}
{%- endfor -%}
</details>
</div>
{%- endif -%}
{%- if suggestions -%}
{%- include 'simple/elements/suggestions.html' -%}
{%- endif -%}
{%- include 'simple/elements/engines_msg.html' -%}
{%- if method == 'POST' -%}
{%- include 'simple/elements/search_url.html' -%}
{%- endif -%}
{%- if search_formats -%}
{%- include 'simple/elements/apis.html' -%}
{%- endif -%}
<div id="sidebar-end-collapsible"></div>
</div>
{%- if corrections -%}
{%- include 'simple/elements/corrections.html' -%}
{%- endif -%}
<div id="urls" role="main">
{% for result in results %}
{% if result.open_group and not only_template %}<div class="template_group_{{ result['template']|replace('.html', '') }}">{% endif %}
{% set index = loop.index %}
{% include get_result_template('simple', result['template']) %}
{% if result.close_group and not only_template %}</div>{% endif %}
{% endfor %}
{% if not results and not answers %}
{% include 'simple/messages/no_results.html' %}
{% endif %}
</div>
<div id="backToTop">
<a href="#" aria-label="{{ _('Back to top') }}">{{ icon_small('navigate-up') }}</a>
</div>
{% if paging %}
<nav id="pagination" role="navigation">
{% if pageno > 1 %}
<form method="{{ method or 'POST' }}" action="{{ url_for('search') }}" class="previous_page">
<div class="{% if rtl %}right{% else %}left{% endif %}">
<input type="hidden" name="q" value="{{ q|e }}" >
{% for category in selected_categories %}
<input type="hidden" name="category_{{ category }}" value="1" >
{% endfor %}
<input type="hidden" name="pageno" value="{{ pageno-1 }}" >
<input type="hidden" name="language" value="{{ current_language }}" >
<input type="hidden" name="time_range" value="{{ time_range }}" >
<input type="hidden" name="safesearch" value="{{ safesearch }}" >
<input type="hidden" name="theme" value="{{ theme }}" >
{% if timeout_limit %}<input type="hidden" name="timeout_limit" value="{{ timeout_limit|e }}" >{% endif %}
{{- engine_data_form(engine_data) -}}
<button role="link" type="submit">{{ icon_small('navigate-left') }} {{ _('Previous page') }}</button>
</div>
</form>
{% endif %}
{%- if results | count > 0 -%}
<form method="{{ method or 'POST' }}" action="{{ url_for('search') }}" class="next_page">
<div class="{% if rtl %}left{% else %}right{% endif %}">
<input type="hidden" name="q" value="{{ q|e }}" >
{% for category in selected_categories %}
<input type="hidden" name="category_{{ category }}" value="1" >
{% endfor %}
<input type="hidden" name="pageno" value="{{ pageno+1 }}" >
<input type="hidden" name="language" value="{{ current_language }}" >
<input type="hidden" name="time_range" value="{{ time_range }}" >
<input type="hidden" name="safesearch" value="{{ safesearch }}" >
<input type="hidden" name="theme" value="{{ theme }}" >
{% if timeout_limit %}<input type="hidden" name="timeout_limit" value="{{ timeout_limit|e }}" >{% endif %}
{{- engine_data_form(engine_data) -}}
<button role="link" type="submit">{{ _('Next page') }} {{ icon_small('navigate-right') }}</button>
</div>
</form>
{%- endif -%}
{% set pstart = 1 %}
{% set pend = 11 %}
{% if pageno > 5 %}
{% set pstart = pageno - 4 %}
{% set pend = pageno + 6 %}
{% endif %}
<div class="numbered_pagination">
{% for x in range(pstart, pend) %}
<form method="{{ method or 'POST' }}" action="{{ url_for('search') }}" class="page_number">
<input type="hidden" name="q" value="{{ q|e }}" >
{% for category in selected_categories %}
<input type="hidden" name="category_{{ category }}" value="1" >
{% endfor %}
<input type="hidden" name="pageno" value="{{ x }}" >
<input type="hidden" name="language" value="{{ current_language }}" >
<input type="hidden" name="time_range" value="{{ time_range }}" >
<input type="hidden" name="safesearch" value="{{ safesearch }}" >
<input type="hidden" name="theme" value="{{ theme }}" >
{% if timeout_limit %}<input type="hidden" name="timeout_limit" value="{{ timeout_limit|e }}" >{% endif %}
{{- engine_data_form(engine_data) -}}
{% if pageno == x %}
<input role="link" class="page_number_current" type="button" value="{{ x }}">
{% else %}
<input role="link" class="page_number" type="submit" value="{{ x }}">
{% endif %}
</form>
{% endfor %}
</div>
</nav>
{% endif %}
</div>
{% endblock %}

View File

@@ -0,0 +1,40 @@
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" version="5" encoding="UTF-8" indent="yes" />
<xsl:template match="rss">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title><xsl:value-of select="channel/title" />RSS Feed</title>
<meta charset="UTF-8" />
<meta http-equiv="x-ua-compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link rel="stylesheet" href="{{ url_for('static', filename='css/rss.min.css') }}" type="text/css" media="screen"/>
</head>
<body>
<header>
<h2>
<xsl:value-of select="channel/description" />
</h2>
</header>
<hr />
<main>
<xsl:for-each select="channel/item">
<article>
<h3>
<a hreflang="en" target="_blank">
<xsl:attribute name="href">
<xsl:value-of select="link" />
</xsl:attribute>
<xsl:value-of select="title" />
</a>
</h3>
<time><xsl:value-of select="pubDate" /></time>
<p><xsl:value-of select="description" /></p>
<hr />
</article>
</xsl:for-each>
</main>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

View File

@@ -0,0 +1,25 @@
<form id="search" method="{{ method or 'POST' }}" action="{{ url_for('search') }}" role="search">
<div id="search_header">
<a id="search_logo" href="{{ url_for('index') }}" tabindex="0" title="{{ _('Display the front page') }}">
<span hidden>SearXNG</span>
{% include 'simple/searxng-wordmark.min.svg' without context %}
</a>
<div id="search_view">
<div class="search_box">
<input id="q" name="q" type="text" placeholder="{{ _('Search for...') }}" tabindex="1" autocomplete="off" autocapitalize="none" spellcheck="false" autocorrect="off" dir="auto" value="{{ q or '' }}">
<button id="clear_search" type="reset" aria-label="{{ _('clear') }}" class="hide_if_nojs"><span>{{ icon_big('close') }}</span><span class="show_if_nojs">{{ _('clear') }}</span></button>
<button id="send_search" type="submit" {%- if search_on_category_select -%}name="category_{{ selected_categories[0]|replace(' ', '_') }}"{%- endif -%} aria-label="{{ _('search') }}"><span class="hide_if_nojs">{{ icon_big('search') }}</span><span class="show_if_nojs">{{ _('search') }}</span></button>
<div class="autocomplete hide_if_nojs"><ul></ul></div>
</div>
</div>
{% set display_tooltip = true %}
{% include 'simple/categories.html' %}
</div>
<div class="search_filters">
{% include 'simple/filters/languages.html' %}
{% include 'simple/filters/time_range.html' %}
{% include 'simple/filters/safesearch.html' %}
</div>
<input type="hidden" name="theme" value="{{ theme }}" >
{% if timeout_limit %}<input type="hidden" name="timeout_limit" value="{{ timeout_limit|e }}" >{% endif %}
</form>

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="137" height="148"><path fill="#FEFDFE" d="M0 0h137v148H0z"/><path fill="#892B8D" d="m55 30 .113 3.184c.387 8.855 1.072 16.553 5.325 24.504L61 60c-1.75 2.875-1.75 2.875-4 6-3.398 8.834-2.646 17.585.29 26.453 3.208 6.652 8.199 11.955 12.99 17.515C86 128.545 86 128.545 86 139c-4.437.088-8.875.14-13.312.188l-3.768.076c-12.812.1-21.97-2.075-31.92-10.264l-2.121-1.707c-7.772-6.954-15.174-19.421-16.11-29.877C18.159 84.404 18.163 72.86 24 61l.906-2.262C27.563 52.478 32.348 47.846 37 43l2.438-2.625C50.632 30 50.632 30 55 30"/><path fill="#613C8C" d="m88.938 9.75 2.939.055q3.562.07 7.123.195c-.572 2.788-.936 3.927-2.875 6.125-3.846 2.307-7.186 2.704-11.602 3.188-2.64.49-2.64.49-4.359 2.562C78.76 24.035 78.76 24.035 79 27a169 169 0 0 0 6 4 157 157 0 0 1 5.836 5.43l1.588 1.554a912 912 0 0 1 3.283 3.242 542 542 0 0 0 5.055 4.91q1.601 1.582 3.199 3.169l1.534 1.459c2.478 2.51 3.466 3.933 3.918 7.475C109 61 109 61 107.438 62.875c-4.051 1.87-7.447 1.767-11.692.398-3.617-1.428-7.151-2.992-10.668-4.652C78.121 55.458 72.634 54.324 65 55c-4.567-8.56-4.567-8.56-5-13l-.191-1.918c-.518-9.442 2.895-17.354 9.117-24.328 6.67-5.64 11.47-6.308 20.011-6.004"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,20 @@
<form id="search" method="{{ method or 'POST' }}" action="{{ url_for('search') }}" role="search">
<div id="search_header">
<div id="search_view">
<div class="search_box">
<input id="q" name="q" type="text" placeholder="{{ _('Search for...') }}" autocomplete="off" autocapitalize="none" spellcheck="false" autocorrect="off" dir="auto" value="{{ q or '' }}">
<button id="clear_search" type="reset" aria-label="{{ _('clear') }}"><span class="hide_if_nojs">{{ icon_big('close') }}</span><span class="show_if_nojs">{{ _('clear') }}</span></button>
<button id="send_search" type="submit" aria-label="{{ _('search') }}"><span class="hide_if_nojs">{{ icon_big('search') }}</span><span class="show_if_nojs">{{ _('search') }}</span></button>
<div class="autocomplete hide_if_nojs"><ul></ul></div>
</div>
</div>
</div>
{% for category in selected_categories %}
<input type="hidden" name="category_{{ category }}" value="1" >
{% endfor %}
<input type="hidden" name="language" value="{{ current_language }}" >
<input type="hidden" name="time_range" value="{{ time_range }}" >
<input type="hidden" name="safesearch" value="{{ safesearch }}" >
<input type="hidden" name="theme" value="{{ theme }}" >
{% if timeout_limit %}<input type="hidden" name="timeout_limit" value="{{ timeout_limit|e }}" >{% endif %}
</form>

View File

@@ -0,0 +1,148 @@
{% from 'simple/icons.html' import icon_big %}
{% from 'simple/new_issue.html' import new_issue with context %}
{% extends "simple/page_with_header.html" %}
{%- macro th_sort(column_order, column_name) -%}
{% if selected_engine_name %}
{{ column_name }}
{% elif column_order==sort_order %}
{{ icon_big('navigate-down') }} {{ column_name }}
{% else %}
<a href="{{ url_for('stats', sort=column_order) }}">{{ column_name }}</a>
{% endif %}
{%- endmacro -%}
{% block head %} {% endblock %}
{% block content %}
<h1>{% if selected_engine_name %}<a href="{{ url_for('stats') }}">{% endif %}{{ _('Engine stats') }}{% if selected_engine_name %}</a> - {{ selected_engine_name }}{% endif %}</h1>
{% if not engine_stats.get('time') %}
{{ _('There is currently no data available. ') }}
{% else %}
<table class="engine-stats">
<tr>
<th scope="col" class="engine-name">{{ th_sort('name', _("Engine name")) }}</th>
<th scope="col" class="engine-score">{{ th_sort('score', _('Scores')) }}</th>
<th scope="col" class="result-count">{{ th_sort('result_count', _('Result count')) }}</th>
<th scope="col" class="response-time">{{ th_sort('time', _('Response time')) }}</th>
<th scope="col" class="engine-reliability">{{ th_sort('reliability', _('Reliability')) }}</th>
</tr>
{% for engine_stat in engine_stats.get('time', []) %}
<tr>
<td class="engine-name"><a href="{{ url_for('stats', engine=engine_stat.name|e) }}">{{ engine_stat.name }}</a></td>
<td class="engine-score">
{% if engine_stat.score %}
<span>{{ engine_stat.score_per_result|round(1) }}</span>
{% endif %}
</td>
<td class="engine-result-count">
{%- if engine_stat.result_count -%}
<div class="bar-chart-value">{{- engine_stat.result_count | int -}}</div>{{- "" -}}
<div class="bar-chart-graph" aria-hidden="true">
<div class="bar-chart-bar bar{{ (100 * engine_stat.result_count / engine_stats.max_result_count)|round }}"></div>{{- "" -}}
</div>
{%- endif -%}
</td>
<td class="response-time">
{%- if engine_stat.total is not none -%}
<div class="bar-chart-value">{{- engine_stat.total | round(1) -}}</div>{{- "" -}}
<div class="bar-chart-graph" aria-labelledby="{{engine_stat.name}}_time" aria-hidden="true">
{% if engine_stat.http is not none and engine_stats.max_time %}<div class="bar-chart-serie1 bar{{ (100 * engine_stat.http / engine_stats.max_time)|round }}"></div>{%- endif -%}
{% if engine_stat.processing is not none and engine_stats.max_time %}<div class="bar-chart-serie2 bar{{ (100 * engine_stat.processing / engine_stats.max_time)|round }}"></div>{%- endif -%}
</div>
<div class="engine-tooltip" role="tooltip" id="{{engine_stat.name}}_time">{{- "" -}}
<table>
<tr>
<th scope="col"></th>
<th scope="col">{{ _('Total') }}</th>
<th scope="col">{{ _('HTTP') }}</th>
<th scope="col">{{ _('Processing') }}</th>
</tr>
<tr>
<th scope="col">{{ _('Median') }}</th>
<td>{{ engine_stat.total }}</td>
<td>{{ engine_stat.http or ''}}</td>
<td>{{ engine_stat.processing }}</td>
</tr>
<tr>
<th scope="col">{{ _('P80') }}</th>
<td>{{ engine_stat.total_p80 }}</td>
<td>{{ engine_stat.http_p80 or '' }}</td>
<td>{{ engine_stat.processing_p80 }}</td>
</tr>
<tr>
<th scope="col">{{ _('P95') }}</th>
<td>{{ engine_stat.total_p95 }}</td>
<td>{{ engine_stat.http_p95 or '' }}</td>
<td>{{ engine_stat.processing_p95 }}</td>
</tr>
</table>
</div>
{%- endif -%}
</td>
<td class="engine-reliability"> {{ engine_reliabilities.get(engine_stat.name, {}).get('reliability') }}</td>
</tr>
{% endfor %}
</table>
{% endif %}
{% if selected_engine_name %}
<div class="engine-errors">
{% for secondary in [False, True] %}
{% set ns = namespace(first=true) %}
{% for error in engine_reliabilities[selected_engine_name].errors %}
{% if secondary == error.secondary %}
{% if ns.first %}
{% set ns.first = false %}
<h2>{% if secondary %}{{ _('Warnings') }}{% else %}{{ _('Errors and exceptions') }}{% endif %}</h2>
{% endif %}
<table class="engine-error">
<tbody>
<tr>
{%- if error.exception_classname -%}
<th scope="row" class="engine-error-type">{{ _('Exception') }}</th><td>{{ error.exception_classname }}</td>
{%- elif error.log_message -%}
<th scope="row" class="engine-error-type">{{ _('Message') }}</th><td>{{ error.log_message }}</td>
{%- endif -%}
<th scope="row" class="engine-error-type">{{ _('Percentage') }}</th><td class="engine-error-type">{{ error.percentage }}</td>
</tr>
{% if error.log_parameters and error.log_parameters != (None, None, None) %}<tr><th scope="row">{{ _('Parameter') }}</th>{{- '' -}}
<td colspan="3">
{%- for param in error.log_parameters -%}
<span class="log_parameters">{{ param }}</span>
{%- endfor -%}
</td>
</tr>
{% endif %}
<tr><th scope="row">{{ _('Filename') }}</th><td colspan="3">{{ error.filename }}:{{ error.line_no }}</td></tr>
<tr><th scope="row">{{ _('Function') }}</th><td colspan="3">{{ error.function }}</td></tr>
<tr><th scope="row">{{ _('Code') }}</th><td colspan="3">{{ error.code }}</td></tr>
</tbody>
</table>
{% endif %}
{% endfor %}
{% endfor %}
{% if engine_reliabilities[selected_engine_name].checker %}
<h3>{{ _('Checker') }}</h3>
<table>
<tr>
<th scope="col" class="failed-test">{{ _('Failed test') }}</th>
<th scope="col">{{ _('Comment(s)') }}</th>
</tr>
{% for test_name, results in engine_reliabilities[selected_engine_name].checker.items() %}
<tr>
<td>{{ test_name }}</td>
<td>
{% for r in results %}<p>{{ r }}</p>{% endfor %}
</td>
</tr>
{% endfor %}
</table>
{% endif %}
{{ new_issue(selected_engine_name, engine_reliabilities[selected_engine_name]) }}
</div>
{% endif %}
{% endblock %}