Merge branch 'searxng:master' into master

This commit is contained in:
Sepehr Rasouli 2024-09-23 16:35:35 +03:30 committed by GitHub
commit 0202a13268
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
26 changed files with 214 additions and 122 deletions

View File

@ -2,9 +2,9 @@
Why use a private instance? Why use a private instance?
=========================== ===========================
.. sidebar:: Is it worth to run my own instance? .. sidebar:: Is running my own instance worth it?
\.\. is a common question among SearXNG users. Before answering this \.\.\.is a common question among SearXNG users. Before answering this
question, see what options a SearXNG user has. question, see what options a SearXNG user has.
.. contents:: .. contents::
@ -12,13 +12,13 @@ Why use a private instance?
:local: :local:
:backlinks: entry :backlinks: entry
Public instances are open to everyone who has access to its URL. Usually, these Public instances are open to everyone who has access to their URL. Usually, they
are operated by unknown parties (from the users' point of view). Private are operated by unknown parties (from the users' point of view). Private
instances can be used by a select group of people. It is for example a SearXNG of instances can be used by a select group of people, such as a SearXNG instance for a
group of friends or a company which can be accessed through VPN. Also it can be group of friends, or a company which can be accessed through a VPN. Instances can also be
single user one which runs on the user's laptop. single-user instances, which run locally on the user's machine.
To gain more insight on how these instances work let's dive into how SearXNG To gain more insight on how these instances work, let's dive into how SearXNG
protects its users. protects its users.
.. _SearXNG protect privacy: .. _SearXNG protect privacy:
@ -26,26 +26,26 @@ protects its users.
How does SearXNG protect privacy? How does SearXNG protect privacy?
================================= =================================
SearXNG protects the privacy of its users in multiple ways regardless of the type SearXNG protects the privacy of its users in multiple ways, regardless of the type
of the instance (private, public). Removal of private data from search requests of the instance (private or public). Removal of private data from search requests
comes in three forms: comes in three forms:
1. removal of private data from requests going to search services 1. Removing private data from requests going to search services
2. not forwarding anything from a third party services through search services 2. Not forwarding anything from third party services through search services
(e.g. advertisement) (e.g. advertisement)
3. removal of private data from requests going to the result pages 3. Removing private data from requests going to the results pages
Removing private data means not sending cookies to external search engines and Removing private data means not sending cookies to external search engines and
generating a random browser profile for every request. Thus, it does not matter generating a random browser profile for every request. Thus, it does not matter
if a public or private instance handles the request, because it is anonymized in if a public or private instance handles the request, because it is anonymized in
both cases. IP addresses will be the IP of the instance. But SearXNG can be both cases. The IP address used will be the IP of the instance, but SearXNG can also be
configured to use proxy or Tor. `Result proxy configured to use proxy or Tor. `Result proxy
<https://github.com/asciimoo/morty>`__ is supported, too. <https://github.com/asciimoo/morty>`__ is supported, too.
SearXNG does not serve ads or tracking content unlike most search services. So SearXNG does not serve ads or tracking content, unlike most search services. Therefore,
private data is not forwarded to third parties who might monetize it. Besides private data is not forwarded to third parties who might monetize it. Besides
protecting users from search services, both referring page and search query are protecting users from search services, both the referring page and search query are
hidden from visited result pages. hidden from the results pages being visited.
What are the consequences of using public instances? What are the consequences of using public instances?
@ -53,11 +53,11 @@ What are the consequences of using public instances?
If someone uses a public instance, they have to trust the administrator of that If someone uses a public instance, they have to trust the administrator of that
instance. This means that the user of the public instance does not know whether instance. This means that the user of the public instance does not know whether
their requests are logged, aggregated and sent or sold to a third party. their requests are logged, aggregated, and sent or sold to a third party.
Also, public instances without proper protection are more vulnerable to abusing Also, public instances without proper protection are more vulnerable to abuse of
the search service, In this case the external service in exchange returns the search service, which may cause the external service to enforce
CAPTCHAs or bans the IP of the instance. Thus, search requests return less CAPTCHAs or to ban the IP address of the instance. Thus, search requests would return less
results. results.
I see. What about private instances? I see. What about private instances?
@ -67,10 +67,10 @@ If users run their :ref:`own instances <installation>`, everything is in their
control: the source code, logging settings and private data. Unknown instance control: the source code, logging settings and private data. Unknown instance
administrators do not have to be trusted. administrators do not have to be trusted.
Furthermore, as the default settings of their instance is editable, there is no Furthermore, as the default settings of their instance are editable, there is no
need to use cookies to tailor SearXNG to their needs. So preferences will not be need to use cookies to tailor SearXNG to their needs and preferences will not
reset to defaults when clearing browser cookies. As settings are stored on reset to defaults when clearing browser cookies. As settings are stored on
their computer, it will not be accessible to others as long as their computer is the user's computer, they will not be accessible to others as long as their computer is
not compromised. not compromised.
Conclusion Conclusion
@ -80,7 +80,7 @@ Always use an instance which is operated by people you trust. The privacy
features of SearXNG are available to users no matter what kind of instance they features of SearXNG are available to users no matter what kind of instance they
use. use.
If someone is on the go or just wants to try SearXNG for the first time public For those on the go, or just wanting to try SearXNG for the first time, public
instances are the best choices. Additionally, public instance are making a instances are the best choice. Public instances are also making the
world a better place, because those who cannot or do not want to run an world a better place by giving those who cannot, or do not want to, run an
instance, have access to a privacy respecting search service. instance access to a privacy-respecting search service.

View File

@ -22,4 +22,4 @@ wlc==1.15
coloredlogs==15.0.1 coloredlogs==15.0.1
docutils<=0.21; python_version == '3.8' docutils<=0.21; python_version == '3.8'
docutils>=0.21.2; python_version > '3.8' docutils>=0.21.2; python_version > '3.8'
parameterized==0.9.0

View File

@ -0,0 +1,68 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
"""Cloudflare AI engine"""
from json import loads, dumps
from searx.exceptions import SearxEngineAPIException
about = {
"website": 'https://ai.cloudflare.com',
"wikidata_id": None,
"official_api_documentation": 'https://developers.cloudflare.com/workers-ai',
"use_official_api": True,
"require_api_key": True,
"results": 'JSON',
}
cf_account_id = ''
cf_ai_api = ''
cf_ai_gateway = ''
cf_ai_model = ''
cf_ai_model_display_name = 'Cloudflare AI'
# Assistant messages hint to the AI about the desired output format. Not all models support this role.
cf_ai_model_assistant = 'Keep your answers as short and effective as possible.'
# System messages define the AI's personality. You can use them to set rules and how you expect the AI to behave.
cf_ai_model_system = 'You are a self-aware language model who is honest and direct about any question from the user.'
def request(query, params):
params['query'] = query
params['url'] = f'https://gateway.ai.cloudflare.com/v1/{cf_account_id}/{cf_ai_gateway}/workers-ai/{cf_ai_model}'
params['method'] = 'POST'
params['headers']['Authorization'] = f'Bearer {cf_ai_api}'
params['headers']['Content-Type'] = 'application/json'
params['data'] = dumps(
{
'messages': [
{'role': 'assistant', 'content': cf_ai_model_assistant},
{'role': 'system', 'content': cf_ai_model_system},
{'role': 'user', 'content': params['query']},
]
}
).encode('utf-8')
return params
def response(resp):
results = []
json = loads(resp.text)
if 'error' in json:
raise SearxEngineAPIException('Cloudflare AI error: ' + json['error'])
if 'result' in json:
results.append(
{
'content': json['result']['response'],
'infobox': cf_ai_model_display_name,
}
)
return results

View File

@ -482,6 +482,23 @@ engines:
# to show premium or plus results too: # to show premium or plus results too:
# skip_premium: false # skip_premium: false
- name: cloudflareai
engine: cloudflareai
shortcut: cfai
# get api token and accont id from https://developers.cloudflare.com/workers-ai/get-started/rest-api/
cf_account_id: 'your_cf_accout_id'
cf_ai_api: 'your_cf_api'
# create your ai gateway by https://developers.cloudflare.com/ai-gateway/get-started/creating-gateway/
cf_ai_gateway: 'your_cf_ai_gateway_name'
# find the model name from https://developers.cloudflare.com/workers-ai/models/#text-generation
cf_ai_model: 'ai_model_name'
# custom your preferences
# cf_ai_model_display_name: 'Cloudflare AI'
# cf_ai_model_assistant: 'prompts_for_assistant_role'
# cf_ai_model_system: 'prompts_for_system_role'
timeout: 30
disabled: true
# - name: core.ac.uk # - name: core.ac.uk
# engine: core # engine: core
# categories: science # categories: science

View File

@ -8,7 +8,7 @@
{%- macro tab_header(name, id, label, checked) -%} {%- macro tab_header(name, id, label, checked) -%}
<input type="radio" name="{{ name }}" id="tab-{{ id }}" {% if checked is sameas true %}checked="checked"{% endif %}> <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> <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-labelledby="tab-label-{{ id }}" aria-hidden="false"> <section id="tab-content-{{ id }}" role="tabpanel" aria-hidden="false">
{%- endmacro -%} {%- endmacro -%}
{%- macro tab_footer() -%} {%- macro tab_footer() -%}
@ -27,11 +27,11 @@
{%- endif -%} {%- endif -%}
{%- endmacro -%} {%- endmacro -%}
{%- macro checkbox_onoff_reversed(name, checked) -%} {%- macro checkbox_onoff_reversed(name, checked, labelledby) -%}
<input type="checkbox" {{- ' ' -}} <input type="checkbox" {{- ' ' -}}
name="{{ name }}" {{- ' ' -}} name="{{ name }}" {{- ' ' -}}
id="{{ name }}" {{- ' ' -}} id="{{ name }}" {{- ' ' -}}
aria-labelledby="pref_{{ name }}"{{- ' ' -}} {%- if labelledby -%} aria-labelledby="{{ labelledby }}"{{- ' ' -}}{%- endif -%}
class="checkbox-onoff reversed-checkbox"{{- ' ' -}} class="checkbox-onoff reversed-checkbox"{{- ' ' -}}
{%- if checked -%} checked{%- endif -%}> {%- if checked -%} checked{%- endif -%}>
{%- endmacro -%} {%- endmacro -%}
@ -42,9 +42,9 @@
<fieldset>{{- '' -}} <fieldset>{{- '' -}}
<legend>{{ _(plugin.name) }}</legend>{{- '' -}} <legend>{{ _(plugin.name) }}</legend>{{- '' -}}
<div class="value"> <div class="value">
{{- checkbox_onoff_reversed('plugin_' + plugin.id, plugin.id not in allowed_plugins) -}} {{- checkbox_onoff_reversed('plugin_' + plugin.id, plugin.id not in allowed_plugins, 'plugin_labelledby' + plugin.id) -}}
</div>{{- '' -}} </div>{{- '' -}}
<div class="description"> <div class="description" id="{{ 'plugin_labelledby' + plugin.id }}">
{{- _(plugin.description) -}} {{- _(plugin.description) -}}
</div>{{- '' -}} </div>{{- '' -}}
</fieldset> </fieldset>
@ -90,7 +90,7 @@
<td class="{{ label }}">{{- '' -}} <td class="{{ label }}">{{- '' -}}
{%- if stats[engine_name].time != None -%} {%- if stats[engine_name].time != None -%}
<span class="stacked-bar-chart-value">{{- stats[engine_name].time -}}</span>{{- '' -}} <span class="stacked-bar-chart-value">{{- stats[engine_name].time -}}</span>{{- '' -}}
<span class="stacked-bar-chart" aria-labelledby="{{engine_name}}_chart" aria-hidden="true"> <span class="stacked-bar-chart" aria-hidden="true">
{%- if max_rate95 is not none and max_rate95 > 0 -%} {%- 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-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-rate80 bar{{ (100 * ((stats[engine_name].rate80 - stats[engine_name].time) / max_rate95))|round }}"></div>{{- '' -}}
@ -127,7 +127,7 @@
{%- if checker_result or errors -%} {%- if checker_result or errors -%}
<td class="{{ label }} column-reliability">{{- '' -}} <td class="{{ label }} column-reliability">{{- '' -}}
<a href="{{ url_for('stats', engine=engine_name|e) }}">{{- '' -}} <a href="{{ url_for('stats', engine=engine_name|e) }}">{{- '' -}}
<span aria-labelledby="{{engine_name}}_reliability"> <span>
{{- icon_big('warning', 'The engine is not reliabled') }} {{ r -}} {{- icon_big('warning', 'The engine is not reliabled') }} {{ r -}}
</span>{{- '' -}} </span>{{- '' -}}
</a>{{- '' -}} </a>{{- '' -}}

View File

@ -33,10 +33,10 @@
{%- for plugin in plugins -%} {%- for plugin in plugins -%}
{%- if plugin.preference_section == 'query' -%} {%- if plugin.preference_section == 'query' -%}
<tr>{{- '' -}} <tr>{{- '' -}}
<td class="checkbox-col">{{- checkbox_onoff_reversed('plugin_' + plugin.id, plugin.id not in allowed_plugins) -}}</td>{{- '' -}} <td class="checkbox-col">{{- checkbox_onoff_reversed('plugin_' + plugin.id, plugin.id not in allowed_plugins, 'plugin_labelledby' + plugin.id) -}}</td>{{- '' -}}
<td>{{ plugin.query_keywords|join(', ') }}</td>{{- '' -}} <td>{{ plugin.query_keywords|join(', ') }}</td>{{- '' -}}
<td>{{ _(plugin.name) }}</td>{{- '' -}} <td>{{ _(plugin.name) }}</td>{{- '' -}}
<td>{{ _(plugin.description) }}</td>{{- '' -}} <td id="{{ 'plugin_labelledby' + plugin.id }}">{{ _(plugin.description) }}</td>{{- '' -}}
<td>{{ plugin.query_examples }}</td>{{- '' -}} <td>{{ plugin.query_examples }}</td>{{- '' -}}
</tr> </tr>
{%- endif -%} {%- endif -%}

View File

@ -8,7 +8,7 @@
{%- if preferences.get_value('center_alignment') -%} {%- if preferences.get_value('center_alignment') -%}
checked checked
{%- endif -%}{{- ' ' -}} {%- endif -%}{{- ' ' -}}
/>{{- '' -}} >{{- '' -}}
</p>{{- '' -}} </p>{{- '' -}}
<div class="description"> <div class="description">
{{- _('Displays results in the center of the page (Oscar layout).') -}} {{- _('Displays results in the center of the page (Oscar layout).') -}}

View File

@ -8,7 +8,7 @@
{%- if preferences.get_value('image_proxy') -%} {%- if preferences.get_value('image_proxy') -%}
checked checked
{%- endif -%}{{- ' ' -}} {%- endif -%}{{- ' ' -}}
/>{{- '' -}} >{{- '' -}}
</p>{{- '' -}} </p>{{- '' -}}
<div class="description"> <div class="description">
{{- _('Proxying image results through SearXNG') -}} {{- _('Proxying image results through SearXNG') -}}

View File

@ -8,9 +8,9 @@
{%- if preferences.get_value('infinite_scroll') -%} {%- if preferences.get_value('infinite_scroll') -%}
checked checked
{%- endif -%}{{- ' ' -}} {%- endif -%}{{- ' ' -}}
/>{{- '' -}} >{{- '' -}}
</p>{{- '' -}} </p>{{- '' -}}
<div class="description"> <div class="description" id="pref_infinite_scroll">
{{- _('Automatically load next page when scrolling to bottom of current page') -}} {{- _('Automatically load next page when scrolling to bottom of current page') -}}
</div>{{- '' -}} </div>{{- '' -}}
</fieldset>{{- '' -}} </fieldset>{{- '' -}}

View File

@ -8,7 +8,7 @@
{%- if preferences.get_value('query_in_title') -%} {%- if preferences.get_value('query_in_title') -%}
checked checked
{%- endif -%}{{- ' ' -}} {%- endif -%}{{- ' ' -}}
/>{{- '' -}} >{{- '' -}}
</p>{{- '' -}} </p>{{- '' -}}
<div class="description"> <div class="description">
{{- _("When enabled, the result page's title contains your query. Your browser can record this title") -}} {{- _("When enabled, the result page's title contains your query. Your browser can record this title") -}}

View File

@ -8,7 +8,7 @@
{%- if preferences.get_value('results_on_new_tab') -%} {%- if preferences.get_value('results_on_new_tab') -%}
checked checked
{%- endif -%}{{- ' ' -}} {%- endif -%}{{- ' ' -}}
/>{{- ' ' -}} >{{- ' ' -}}
</p>{{- '' -}} </p>{{- '' -}}
<div class="description"> <div class="description">
{{- _('Open result links on new browser tabs') -}} {{- _('Open result links on new browser tabs') -}}

View File

@ -8,9 +8,9 @@
{%- if preferences.get_value('search_on_category_select') -%} {%- if preferences.get_value('search_on_category_select') -%}
checked checked
{%- endif -%}{{- ' ' -}} {%- endif -%}{{- ' ' -}}
/>{{- '' -}} >{{- '' -}}
</p>{{- '' -}} </p>{{- '' -}}
<div class="description"> <div class="description" id="pref_search_on_category_select">
{{- _('Perform search immediately if a category selected. Disable to select multiple categories') -}} {{- _('Perform search immediately if a category selected. Disable to select multiple categories') -}}
</div>{{- '' -}} </div>{{- '' -}}
</fieldset>{{- '' -}} </fieldset>{{- '' -}}

View File

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

View File

@ -23,16 +23,17 @@ msgstr ""
"Project-Id-Version: searx\n" "Project-Id-Version: searx\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-09-03 15:52+0000\n" "POT-Creation-Date: 2024-09-03 15:52+0000\n"
"PO-Revision-Date: 2024-07-30 08:18+0000\n" "PO-Revision-Date: 2024-09-15 14:18+0000\n"
"Last-Translator: nebras <nebras@users.noreply.translate.codeberg.org>\n" "Last-Translator: return42 <return42@users.noreply.translate.codeberg.org>\n"
"Language-Team: Arabic <https://translate.codeberg.org/projects/searxng/"
"searxng/ar/>\n"
"Language: ar\n" "Language: ar\n"
"Language-Team: Arabic "
"<https://translate.codeberg.org/projects/searxng/searxng/ar/>\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : "
"n%100>=3 && n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
"&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n"
"X-Generator: Weblate 5.7.2\n"
"Generated-By: Babel 2.16.0\n" "Generated-By: Babel 2.16.0\n"
#. CONSTANT_NAMES['NO_SUBGROUPING'] #. CONSTANT_NAMES['NO_SUBGROUPING']
@ -929,7 +930,7 @@ msgstr "رسائل من محركات البحث"
#: searx/templates/simple/elements/engines_msg.html:7 #: searx/templates/simple/elements/engines_msg.html:7
msgid "seconds" msgid "seconds"
msgstr "" msgstr "ثواني"
#: searx/templates/simple/elements/search_url.html:3 #: searx/templates/simple/elements/search_url.html:3
msgid "Search URL" msgid "Search URL"
@ -1942,4 +1943,3 @@ msgstr "إخفاء الفيديو"
#~ msgid "Engines cannot retrieve results" #~ msgid "Engines cannot retrieve results"
#~ msgstr "لم تتمكن محركات البحث من العثور على أية نتيجة" #~ msgstr "لم تتمكن محركات البحث من العثور على أية نتيجة"

View File

@ -19,7 +19,7 @@ msgstr ""
"Project-Id-Version: searx\n" "Project-Id-Version: searx\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-09-03 15:52+0000\n" "POT-Creation-Date: 2024-09-03 15:52+0000\n"
"PO-Revision-Date: 2024-09-05 06:18+0000\n" "PO-Revision-Date: 2024-09-15 14:18+0000\n"
"Last-Translator: Fjuro <fjuro@alius.cz>\n" "Last-Translator: Fjuro <fjuro@alius.cz>\n"
"Language-Team: Czech <https://translate.codeberg.org/projects/searxng/" "Language-Team: Czech <https://translate.codeberg.org/projects/searxng/"
"searxng/cs/>\n" "searxng/cs/>\n"
@ -29,7 +29,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n " "Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n "
"<= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;\n" "<= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;\n"
"X-Generator: Weblate 5.7\n" "X-Generator: Weblate 5.7.2\n"
"Generated-By: Babel 2.16.0\n" "Generated-By: Babel 2.16.0\n"
#. CONSTANT_NAMES['NO_SUBGROUPING'] #. CONSTANT_NAMES['NO_SUBGROUPING']
@ -1220,7 +1220,7 @@ msgstr "Uložit"
#: searx/templates/simple/preferences/footer.html:9 #: searx/templates/simple/preferences/footer.html:9
msgid "Reset defaults" msgid "Reset defaults"
msgstr "obnovit výchozí" msgstr "Obnovit výchozí"
#: searx/templates/simple/preferences/footer.html:13 #: searx/templates/simple/preferences/footer.html:13
msgid "Back" msgid "Back"
@ -1301,15 +1301,15 @@ msgstr "Filtrovat obsah"
#: searx/templates/simple/preferences/search_on_category_select.html:2 #: searx/templates/simple/preferences/search_on_category_select.html:2
msgid "Search on category select" msgid "Search on category select"
msgstr "Spustit hledaní při výběru kategorie" msgstr "Spustit vyhledávání při výběru kategorie"
#: searx/templates/simple/preferences/search_on_category_select.html:14 #: searx/templates/simple/preferences/search_on_category_select.html:14
msgid "" msgid ""
"Perform search immediately if a category selected. Disable to select " "Perform search immediately if a category selected. Disable to select "
"multiple categories" "multiple categories"
msgstr "" msgstr ""
"Pokud je vybrána kategorii, ihned proveďte vyhledávání. Zakažte pro " "Pokud je vybrána kategorie, ihned provést vyhledávání. Zakažte pro vybrání "
"vybrání několika kategorií" "několika kategorií"
#: searx/templates/simple/preferences/theme.html:2 #: searx/templates/simple/preferences/theme.html:2
msgid "Theme" msgid "Theme"

View File

@ -27,7 +27,7 @@ msgstr ""
"Project-Id-Version: searx\n" "Project-Id-Version: searx\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-09-03 15:52+0000\n" "POT-Creation-Date: 2024-09-03 15:52+0000\n"
"PO-Revision-Date: 2024-09-05 06:18+0000\n" "PO-Revision-Date: 2024-09-15 14:18+0000\n"
"Last-Translator: return42 <return42@users.noreply.translate.codeberg.org>\n" "Last-Translator: return42 <return42@users.noreply.translate.codeberg.org>\n"
"Language-Team: German <https://translate.codeberg.org/projects/searxng/" "Language-Team: German <https://translate.codeberg.org/projects/searxng/"
"searxng/de/>\n" "searxng/de/>\n"
@ -36,13 +36,13 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n" "Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.7\n" "X-Generator: Weblate 5.7.2\n"
"Generated-By: Babel 2.16.0\n" "Generated-By: Babel 2.16.0\n"
#. CONSTANT_NAMES['NO_SUBGROUPING'] #. CONSTANT_NAMES['NO_SUBGROUPING']
#: searx/searxng.msg #: searx/searxng.msg
msgid "without further subgrouping" msgid "without further subgrouping"
msgstr "keine weitere Untergruppierung" msgstr "ohne weitere Untergruppierung"
#. CONSTANT_NAMES['DEFAULT_CATEGORY'] #. CONSTANT_NAMES['DEFAULT_CATEGORY']
#: searx/searxng.msg #: searx/searxng.msg
@ -97,7 +97,7 @@ msgstr "IT"
#. CATEGORY_NAMES['NEWS'] #. CATEGORY_NAMES['NEWS']
#: searx/searxng.msg #: searx/searxng.msg
msgid "news" msgid "news"
msgstr "Neuigkeiten" msgstr "Nachrichten"
#. CATEGORY_NAMES['MAP'] #. CATEGORY_NAMES['MAP']
#: searx/searxng.msg #: searx/searxng.msg
@ -277,7 +277,7 @@ msgstr "Sichtweite"
#. WEATHER_TERMS['WIND'] #. WEATHER_TERMS['WIND']
#: searx/searxng.msg #: searx/searxng.msg
msgid "Wind" msgid "Wind"
msgstr "Sturm" msgstr "Wind"
#. SOCIAL_MEDIA_TERMS['SUBSCRIBERS'] #. SOCIAL_MEDIA_TERMS['SUBSCRIBERS']
#: searx/searxng.msg #: searx/searxng.msg
@ -366,7 +366,7 @@ msgstr "Suchfehler"
#: searx/webutils.py:36 #: searx/webutils.py:36
msgid "timeout" msgid "timeout"
msgstr "Timeout" msgstr "Zeitüberschreitung"
#: searx/webutils.py:37 #: searx/webutils.py:37
msgid "parsing error" msgid "parsing error"

View File

@ -32,21 +32,22 @@
# gallegonovato <gallegonovato@users.noreply.translate.codeberg.org>, 2024. # gallegonovato <gallegonovato@users.noreply.translate.codeberg.org>, 2024.
# tiziodcaio <tiziodcaio@users.noreply.translate.codeberg.org>, 2024. # tiziodcaio <tiziodcaio@users.noreply.translate.codeberg.org>, 2024.
# return42 <return42@users.noreply.translate.codeberg.org>, 2024. # return42 <return42@users.noreply.translate.codeberg.org>, 2024.
# kny5 <kny5@users.noreply.translate.codeberg.org>, 2024.
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: searx\n" "Project-Id-Version: searx\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-09-03 15:52+0000\n" "POT-Creation-Date: 2024-09-03 15:52+0000\n"
"PO-Revision-Date: 2024-08-03 22:18+0000\n" "PO-Revision-Date: 2024-09-15 14:18+0000\n"
"Last-Translator: gallegonovato " "Last-Translator: kny5 <kny5@users.noreply.translate.codeberg.org>\n"
"<gallegonovato@users.noreply.translate.codeberg.org>\n" "Language-Team: Spanish <https://translate.codeberg.org/projects/searxng/"
"searxng/es/>\n"
"Language: es\n" "Language: es\n"
"Language-Team: Spanish "
"<https://translate.codeberg.org/projects/searxng/searxng/es/>\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.7.2\n"
"Generated-By: Babel 2.16.0\n" "Generated-By: Babel 2.16.0\n"
#. CONSTANT_NAMES['NO_SUBGROUPING'] #. CONSTANT_NAMES['NO_SUBGROUPING']
@ -948,7 +949,7 @@ msgstr "Mensajes de los motores de búsqueda"
#: searx/templates/simple/elements/engines_msg.html:7 #: searx/templates/simple/elements/engines_msg.html:7
msgid "seconds" msgid "seconds"
msgstr "" msgstr "segundos"
#: searx/templates/simple/elements/search_url.html:3 #: searx/templates/simple/elements/search_url.html:3
msgid "Search URL" msgid "Search URL"
@ -1987,4 +1988,3 @@ msgstr "ocultar video"
#~ msgid "Engines cannot retrieve results" #~ msgid "Engines cannot retrieve results"
#~ msgstr "Los motores no pueden obtener resultados" #~ msgstr "Los motores no pueden obtener resultados"

View File

@ -16,13 +16,14 @@
# return42 <return42@users.noreply.translate.codeberg.org>, 2024. # return42 <return42@users.noreply.translate.codeberg.org>, 2024.
# tegcope <tegcope@users.noreply.translate.codeberg.org>, 2024. # tegcope <tegcope@users.noreply.translate.codeberg.org>, 2024.
# Thecode764 <Thecode764@users.noreply.translate.codeberg.org>, 2024. # Thecode764 <Thecode764@users.noreply.translate.codeberg.org>, 2024.
# MPBDev <MPBDev@users.noreply.translate.codeberg.org>, 2024.
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: searx\n" "Project-Id-Version: searx\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-09-03 15:52+0000\n" "POT-Creation-Date: 2024-09-03 15:52+0000\n"
"PO-Revision-Date: 2024-09-05 06:18+0000\n" "PO-Revision-Date: 2024-09-16 18:18+0000\n"
"Last-Translator: return42 <return42@users.noreply.translate.codeberg.org>\n" "Last-Translator: MPBDev <MPBDev@users.noreply.translate.codeberg.org>\n"
"Language-Team: Persian <https://translate.codeberg.org/projects/searxng/" "Language-Team: Persian <https://translate.codeberg.org/projects/searxng/"
"searxng/fa/>\n" "searxng/fa/>\n"
"Language: fa_IR\n" "Language: fa_IR\n"
@ -30,7 +31,7 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n" "Plural-Forms: nplurals=2; plural=n > 1;\n"
"X-Generator: Weblate 5.7\n" "X-Generator: Weblate 5.7.2\n"
"Generated-By: Babel 2.16.0\n" "Generated-By: Babel 2.16.0\n"
#. CONSTANT_NAMES['NO_SUBGROUPING'] #. CONSTANT_NAMES['NO_SUBGROUPING']
@ -206,22 +207,22 @@ msgstr "عصر"
#. WEATHER_TERMS['FEELS LIKE'] #. WEATHER_TERMS['FEELS LIKE']
#: searx/searxng.msg #: searx/searxng.msg
msgid "Feels like" msgid "Feels like"
msgstr "" msgstr "حس می‌دهد مانند"
#. WEATHER_TERMS['HUMIDITY'] #. WEATHER_TERMS['HUMIDITY']
#: searx/searxng.msg #: searx/searxng.msg
msgid "Humidity" msgid "Humidity"
msgstr "" msgstr "رطوبت"
#. WEATHER_TERMS['MAX TEMP.'] #. WEATHER_TERMS['MAX TEMP.']
#: searx/searxng.msg #: searx/searxng.msg
msgid "Max temp." msgid "Max temp."
msgstr "" msgstr "نهایت دما"
#. WEATHER_TERMS['MIN TEMP.'] #. WEATHER_TERMS['MIN TEMP.']
#: searx/searxng.msg #: searx/searxng.msg
msgid "Min temp." msgid "Min temp."
msgstr "" msgstr "حداقل دما"
#. WEATHER_TERMS['MORNING'] #. WEATHER_TERMS['MORNING']
#: searx/engines/wttr.py:100 searx/searxng.msg #: searx/engines/wttr.py:100 searx/searxng.msg
@ -241,42 +242,44 @@ msgstr "ظهر"
#. WEATHER_TERMS['PRESSURE'] #. WEATHER_TERMS['PRESSURE']
#: searx/searxng.msg #: searx/searxng.msg
msgid "Pressure" msgid "Pressure"
msgstr "" msgstr "فشار"
#. WEATHER_TERMS['SUNRISE'] #. WEATHER_TERMS['SUNRISE']
#: searx/searxng.msg #: searx/searxng.msg
msgid "Sunrise" msgid "Sunrise"
msgstr "" msgstr "طلوع"
#. WEATHER_TERMS['SUNSET'] #. WEATHER_TERMS['SUNSET']
#: searx/searxng.msg #: searx/searxng.msg
msgid "Sunset" msgid "Sunset"
msgstr "" msgstr "غروب"
#. WEATHER_TERMS['TEMPERATURE'] #. WEATHER_TERMS['TEMPERATURE']
#: searx/searxng.msg #: searx/searxng.msg
msgid "Temperature" msgid "Temperature"
msgstr "" msgstr "دما"
#. WEATHER_TERMS['UV INDEX'] #. WEATHER_TERMS['UV INDEX']
#: searx/searxng.msg #: searx/searxng.msg
#, fuzzy
msgid "UV index" msgid "UV index"
msgstr "" msgstr "مقدار اشعه UV"
#. WEATHER_TERMS['VISIBILITY'] #. WEATHER_TERMS['VISIBILITY']
#: searx/searxng.msg #: searx/searxng.msg
#, fuzzy
msgid "Visibility" msgid "Visibility"
msgstr "" msgstr "دید"
#. WEATHER_TERMS['WIND'] #. WEATHER_TERMS['WIND']
#: searx/searxng.msg #: searx/searxng.msg
msgid "Wind" msgid "Wind"
msgstr "" msgstr "باد"
#. SOCIAL_MEDIA_TERMS['SUBSCRIBERS'] #. SOCIAL_MEDIA_TERMS['SUBSCRIBERS']
#: searx/searxng.msg #: searx/searxng.msg
msgid "subscribers" msgid "subscribers"
msgstr "" msgstr "دنبال کننده‌ها"
#. SOCIAL_MEDIA_TERMS['POSTS'] #. SOCIAL_MEDIA_TERMS['POSTS']
#: searx/searxng.msg #: searx/searxng.msg
@ -305,33 +308,38 @@ msgstr "جمعیت"
#. SOCIAL_MEDIA_TERMS['POINTS'] #. SOCIAL_MEDIA_TERMS['POINTS']
#: searx/searxng.msg #: searx/searxng.msg
#, fuzzy
msgid "points" msgid "points"
msgstr "" msgstr "امتیاز‌ّا"
#. SOCIAL_MEDIA_TERMS['TITLE'] #. SOCIAL_MEDIA_TERMS['TITLE']
#: searx/searxng.msg #: searx/searxng.msg
#, fuzzy
msgid "title" msgid "title"
msgstr "" msgstr "موضوع"
#. SOCIAL_MEDIA_TERMS['AUTHOR'] #. SOCIAL_MEDIA_TERMS['AUTHOR']
#: searx/searxng.msg #: searx/searxng.msg
msgid "author" msgid "author"
msgstr "" msgstr "نگارنده"
#. SOCIAL_MEDIA_TERMS['THREAD OPEN'] #. SOCIAL_MEDIA_TERMS['THREAD OPEN']
#: searx/engines/discourse.py:149 searx/searxng.msg #: searx/engines/discourse.py:149 searx/searxng.msg
#, fuzzy
msgid "open" msgid "open"
msgstr "" msgstr "باز"
#. SOCIAL_MEDIA_TERMS['THREAD CLOSED'] #. SOCIAL_MEDIA_TERMS['THREAD CLOSED']
#: searx/engines/discourse.py:149 searx/searxng.msg #: searx/engines/discourse.py:149 searx/searxng.msg
#, fuzzy
msgid "closed" msgid "closed"
msgstr "" msgstr "بسته شده"
#. SOCIAL_MEDIA_TERMS['THREAD ANSWERED'] #. SOCIAL_MEDIA_TERMS['THREAD ANSWERED']
#: searx/engines/discourse.py:160 searx/searxng.msg #: searx/engines/discourse.py:160 searx/searxng.msg
#, fuzzy
msgid "answered" msgid "answered"
msgstr "" msgstr "جواب داده شده"
#: searx/webapp.py:330 #: searx/webapp.py:330
msgid "No item found" msgid "No item found"
@ -510,8 +518,9 @@ msgid "File quality"
msgstr "کیفیت فایل" msgstr "کیفیت فایل"
#: searx/plugins/calculator.py:12 #: searx/plugins/calculator.py:12
#, fuzzy
msgid "Calculate mathematical expressions via the search bar" msgid "Calculate mathematical expressions via the search bar"
msgstr "" msgstr "محاسبه عبارت‌های ریاضی در نوار جست و جو"
#: searx/plugins/hash_plugin.py:10 #: searx/plugins/hash_plugin.py:10
msgid "Converts strings to different hash digests." msgid "Converts strings to different hash digests."
@ -522,12 +531,15 @@ msgid "hash digest"
msgstr "چکیدهٔ هش" msgstr "چکیدهٔ هش"
#: searx/plugins/hostnames.py:103 #: searx/plugins/hostnames.py:103
#, fuzzy
msgid "Hostnames plugin" msgid "Hostnames plugin"
msgstr "" msgstr "افزونه های hostname"
#: searx/plugins/hostnames.py:104 #: searx/plugins/hostnames.py:104
#, fuzzy
msgid "Rewrite hostnames, remove results or prioritize them based on the hostname" msgid "Rewrite hostnames, remove results or prioritize them based on the hostname"
msgstr "" msgstr ""
"باز نویسی hostname ها. حذف‌کردن نتایج یا مرتب کردن آنها بر اساس hostname"
#: searx/plugins/oa_doi_rewrite.py:12 #: searx/plugins/oa_doi_rewrite.py:12
msgid "Open Access DOI rewrite" msgid "Open Access DOI rewrite"
@ -554,12 +566,14 @@ msgstr ""
"عامل کاربری شما را نشان می دهد." "عامل کاربری شما را نشان می دهد."
#: searx/plugins/self_info.py:28 #: searx/plugins/self_info.py:28
#, fuzzy
msgid "Your IP is: " msgid "Your IP is: "
msgstr "" msgstr "آی‌پی شما: "
#: searx/plugins/self_info.py:31 #: searx/plugins/self_info.py:31
#, fuzzy
msgid "Your user-agent is: " msgid "Your user-agent is: "
msgstr "" msgstr "یوزر-ایجنت شما: "
#: searx/plugins/tor_check.py:24 #: searx/plugins/tor_check.py:24
msgid "Tor check plugin" msgid "Tor check plugin"
@ -603,8 +617,9 @@ msgid "Remove trackers arguments from the returned URL"
msgstr "آرگومان های ردیاب ها را از URL برگشتی حذف کنید" msgstr "آرگومان های ردیاب ها را از URL برگشتی حذف کنید"
#: searx/plugins/unit_converter.py:29 #: searx/plugins/unit_converter.py:29
#, fuzzy
msgid "Convert between units" msgid "Convert between units"
msgstr "" msgstr "تبدیل بین واحد‌ها"
#: searx/templates/simple/404.html:4 #: searx/templates/simple/404.html:4
msgid "Page not found" msgid "Page not found"
@ -671,7 +686,7 @@ msgstr "طول"
#: searx/templates/simple/macros.html:36 #: searx/templates/simple/macros.html:36
msgid "Views" msgid "Views"
msgstr "" msgstr "بازدید‌ها"
#: searx/templates/simple/macros.html:37 #: searx/templates/simple/macros.html:37
#: searx/templates/simple/result_templates/files.html:34 #: searx/templates/simple/result_templates/files.html:34
@ -929,7 +944,7 @@ msgstr "پیام های موتور جستجوها"
#: searx/templates/simple/elements/engines_msg.html:7 #: searx/templates/simple/elements/engines_msg.html:7
msgid "seconds" msgid "seconds"
msgstr "" msgstr "ثانیه‌ها"
#: searx/templates/simple/elements/search_url.html:3 #: searx/templates/simple/elements/search_url.html:3
msgid "Search URL" msgid "Search URL"
@ -1175,11 +1190,11 @@ msgstr ""
#: searx/templates/simple/preferences/engines.html:15 #: searx/templates/simple/preferences/engines.html:15
msgid "Enable all" msgid "Enable all"
msgstr "" msgstr "فعال‌سازی همه"
#: searx/templates/simple/preferences/engines.html:16 #: searx/templates/simple/preferences/engines.html:16
msgid "Disable all" msgid "Disable all"
msgstr "" msgstr "غیرفعال‌سازی همه"
#: searx/templates/simple/preferences/engines.html:25 #: searx/templates/simple/preferences/engines.html:25
msgid "!bang" msgid "!bang"

View File

@ -29,7 +29,7 @@ msgstr ""
"Project-Id-Version: searx\n" "Project-Id-Version: searx\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-09-03 15:52+0000\n" "POT-Creation-Date: 2024-09-03 15:52+0000\n"
"PO-Revision-Date: 2024-09-05 06:18+0000\n" "PO-Revision-Date: 2024-09-15 14:18+0000\n"
"Last-Translator: return42 <return42@users.noreply.translate.codeberg.org>\n" "Last-Translator: return42 <return42@users.noreply.translate.codeberg.org>\n"
"Language-Team: French <https://translate.codeberg.org/projects/searxng/" "Language-Team: French <https://translate.codeberg.org/projects/searxng/"
"searxng/fr/>\n" "searxng/fr/>\n"
@ -38,7 +38,7 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n" "Plural-Forms: nplurals=2; plural=n > 1;\n"
"X-Generator: Weblate 5.7\n" "X-Generator: Weblate 5.7.2\n"
"Generated-By: Babel 2.16.0\n" "Generated-By: Babel 2.16.0\n"
#. CONSTANT_NAMES['NO_SUBGROUPING'] #. CONSTANT_NAMES['NO_SUBGROUPING']
@ -940,7 +940,7 @@ msgstr "Messages des moteurs de recherche"
#: searx/templates/simple/elements/engines_msg.html:7 #: searx/templates/simple/elements/engines_msg.html:7
msgid "seconds" msgid "seconds"
msgstr "s" msgstr "secondes"
#: searx/templates/simple/elements/search_url.html:3 #: searx/templates/simple/elements/search_url.html:3
msgid "Search URL" msgid "Search URL"

View File

@ -5,6 +5,7 @@
from datetime import datetime from datetime import datetime
from unittest.mock import Mock from unittest.mock import Mock
from requests import HTTPError from requests import HTTPError
from parameterized import parameterized
from searx.engines import load_engines, tineye from searx.engines import load_engines, tineye
from tests import SearxTestCase from tests import SearxTestCase
@ -23,12 +24,12 @@ class TinEyeTests(SearxTestCase): # pylint: disable=missing-class-docstring
response.raise_for_status.side_effect = HTTPError() response.raise_for_status.side_effect = HTTPError()
self.assertRaises(HTTPError, lambda: tineye.response(response)) self.assertRaises(HTTPError, lambda: tineye.response(response))
def test_returns_empty_list_for_422(self): @parameterized.expand([(400), (422)])
def test_returns_empty_list(self, status_code):
response = Mock() response = Mock()
response.json.return_value = {} response.json.return_value = {}
response.status_code = 422 response.status_code = status_code
response.raise_for_status.side_effect = HTTPError() response.raise_for_status.side_effect = HTTPError()
with self.assertLogs(tineye.logger) as _dev_null:
results = tineye.response(response) results = tineye.response(response)
self.assertEqual(0, len(results)) self.assertEqual(0, len(results))
@ -62,15 +63,6 @@ class TinEyeTests(SearxTestCase): # pylint: disable=missing-class-docstring
tineye.response(response) tineye.response(response)
self.assertIn(tineye.DOWNLOAD_ERROR, ','.join(assert_logs_context.output)) self.assertIn(tineye.DOWNLOAD_ERROR, ','.join(assert_logs_context.output))
def test_empty_list_for_400(self):
response = Mock()
response.json.return_value = {}
response.status_code = 400
response.raise_for_status.side_effect = HTTPError()
with self.assertLogs(tineye.logger) as _dev_null:
results = tineye.response(response)
self.assertEqual(0, len(results))
def test_logs_description_for_400(self): def test_logs_description_for_400(self):
description = 'There was a problem with that request. Error ID: ad5fc955-a934-43c1-8187-f9a61d301645' description = 'There was a problem with that request. Error ID: ad5fc955-a934-43c1-8187-f9a61d301645'
response = Mock() response = Mock()