mirror of
https://github.com/searxng/searxng
synced 2024-01-01 19:24:07 +01:00
Merge branch 'searxng:master' into master
This commit is contained in:
commit
1aca24f461
20 changed files with 539 additions and 80 deletions
|
@ -123,7 +123,7 @@ ${fedora_build}
|
|||
|
||||
# jump to SearXNG's working tree and install SearXNG into virtualenv
|
||||
(${SERVICE_USER})$ cd \"$SEARXNG_SRC\"
|
||||
(${SERVICE_USER})$ pip install -e .
|
||||
(${SERVICE_USER})$ pip install --use-pep517 --no-build-isolation -e .
|
||||
|
||||
|
||||
.. END manage.sh update_packages
|
||||
|
|
|
@ -61,7 +61,7 @@ working tree and release a ``make install`` to get a virtualenv with a
|
|||
$ make install
|
||||
PYENV [virtualenv] installing ./requirements*.txt into local/py3
|
||||
...
|
||||
PYENV [install] pip install -e 'searx[test]'
|
||||
PYENV [install] pip install --use-pep517 --no-build-isolation -e 'searx[test]'
|
||||
...
|
||||
Successfully installed searxng-2023.7.19+a446dea1b
|
||||
|
||||
|
@ -78,7 +78,7 @@ the check fails if you edit the requirements listed in
|
|||
...
|
||||
PYENV [virtualenv] installing ./requirements*.txt into local/py3
|
||||
...
|
||||
PYENV [install] pip install -e 'searx[test]'
|
||||
PYENV [install] pip install --use-pep517 --no-build-isolation -e 'searx[test]'
|
||||
...
|
||||
Successfully installed searxng-2023.7.19+a446dea1b
|
||||
|
||||
|
|
6
manage
6
manage
|
@ -233,7 +233,7 @@ gecko.driver() {
|
|||
build_msg INSTALL "geckodriver already installed"
|
||||
return
|
||||
fi
|
||||
PLATFORM="$(python3 -c 'import platform; print(platform.system().lower(), platform.architecture()[0])')"
|
||||
PLATFORM="$(python -c 'import platform; print(platform.system().lower(), platform.architecture()[0])')"
|
||||
case "$PLATFORM" in
|
||||
"linux 32bit" | "linux2 32bit") ARCH="linux32";;
|
||||
"linux 64bit" | "linux2 64bit") ARCH="linux64";;
|
||||
|
@ -299,8 +299,8 @@ pyenv.install() {
|
|||
|
||||
( set -e
|
||||
pyenv
|
||||
build_msg PYENV "[install] pip install -e 'searx${PY_SETUP_EXTRAS}'"
|
||||
"${PY_ENV_BIN}/python" -m pip install -e ".${PY_SETUP_EXTRAS}"
|
||||
build_msg PYENV "[install] pip install --use-pep517 --no-build-isolation -e 'searx${PY_SETUP_EXTRAS}'"
|
||||
"${PY_ENV_BIN}/python" -m pip install --use-pep517 --no-build-isolation -e ".${PY_SETUP_EXTRAS}"
|
||||
)
|
||||
local exit_val=$?
|
||||
if [ ! $exit_val -eq 0 ]; then
|
||||
|
|
|
@ -14,10 +14,16 @@ billion images `[tineye.com] <https://tineye.com/how>`_.
|
|||
|
||||
"""
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
from urllib.parse import urlencode
|
||||
from datetime import datetime
|
||||
from flask_babel import gettext
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
about = {
|
||||
"website": 'https://tineye.com',
|
||||
"wikidata_id": 'Q2382535',
|
||||
|
@ -34,7 +40,7 @@ categories = ['general']
|
|||
paging = True
|
||||
safesearch = False
|
||||
base_url = 'https://tineye.com'
|
||||
search_string = '/result_json/?page={page}&{query}'
|
||||
search_string = '/api/v1/result_json/?page={page}&{query}'
|
||||
|
||||
FORMAT_NOT_SUPPORTED = gettext(
|
||||
"Could not read that image url. This may be due to an unsupported file"
|
||||
|
@ -120,7 +126,7 @@ def parse_tineye_match(match_json):
|
|||
|
||||
crawl_date = backlink_json.get("crawl_date")
|
||||
if crawl_date:
|
||||
crawl_date = datetime.fromisoformat(crawl_date[:-3])
|
||||
crawl_date = datetime.strptime(crawl_date, '%Y-%m-%d')
|
||||
else:
|
||||
crawl_date = datetime.min
|
||||
|
||||
|
@ -150,29 +156,15 @@ def parse_tineye_match(match_json):
|
|||
|
||||
def response(resp):
|
||||
"""Parse HTTP response from TinEye."""
|
||||
results = []
|
||||
|
||||
try:
|
||||
# handle the 422 client side errors, and the possible 400 status code error
|
||||
if resp.status_code in (400, 422):
|
||||
json_data = resp.json()
|
||||
except Exception as exc: # pylint: disable=broad-except
|
||||
msg = "can't parse JSON response // %s" % exc
|
||||
logger.error(msg)
|
||||
json_data = {'error': msg}
|
||||
|
||||
# handle error codes from Tineye
|
||||
|
||||
if resp.is_error:
|
||||
if resp.status_code in (400, 422):
|
||||
|
||||
message = 'HTTP status: %s' % resp.status_code
|
||||
error = json_data.get('error')
|
||||
s_key = json_data.get('suggestions', {}).get('key', '')
|
||||
|
||||
if error and s_key:
|
||||
message = "%s (%s)" % (error, s_key)
|
||||
elif error:
|
||||
message = error
|
||||
suggestions = json_data.get('suggestions', {})
|
||||
message = f'HTTP Status Code: {resp.status_code}'
|
||||
|
||||
if resp.status_code == 422:
|
||||
s_key = suggestions.get('key', '')
|
||||
if s_key == "Invalid image URL":
|
||||
# test https://docs.searxng.org/_static/searxng-wordmark.svg
|
||||
message = FORMAT_NOT_SUPPORTED
|
||||
|
@ -182,16 +174,23 @@ def response(resp):
|
|||
elif s_key == 'Download Error':
|
||||
# test https://notexists
|
||||
message = DOWNLOAD_ERROR
|
||||
else:
|
||||
logger.warning("Unknown suggestion key encountered: %s", s_key)
|
||||
else: # 400
|
||||
description = suggestions.get('description')
|
||||
if isinstance(description, list):
|
||||
message = ','.join(description)
|
||||
|
||||
# see https://github.com/searxng/searxng/pull/1456#issuecomment-1193105023
|
||||
# results.append({'answer': message})
|
||||
logger.error(message)
|
||||
# see https://github.com/searxng/searxng/pull/1456#issuecomment-1193105023
|
||||
# results.append({'answer': message})
|
||||
logger.error(message)
|
||||
return []
|
||||
|
||||
return results
|
||||
# Raise for all other responses
|
||||
resp.raise_for_status()
|
||||
|
||||
resp.raise_for_status()
|
||||
|
||||
# append results from matches
|
||||
results = []
|
||||
json_data = resp.json()
|
||||
|
||||
for match_json in json_data['matches']:
|
||||
|
||||
|
|
133
searx/engines/yandex.py
Normal file
133
searx/engines/yandex.py
Normal file
|
@ -0,0 +1,133 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
"""Yandex (Web, images)"""
|
||||
|
||||
from json import loads
|
||||
from urllib.parse import urlencode
|
||||
from html import unescape
|
||||
from lxml import html
|
||||
from searx.exceptions import SearxEngineCaptchaException
|
||||
from searx.utils import humanize_bytes, eval_xpath, eval_xpath_list, extract_text, extr
|
||||
|
||||
|
||||
# Engine metadata
|
||||
about = {
|
||||
"website": 'https://yandex.com/',
|
||||
"wikidata_id": 'Q5281',
|
||||
"official_api_documentation": "?",
|
||||
"use_official_api": False,
|
||||
"require_api_key": False,
|
||||
"results": 'HTML',
|
||||
}
|
||||
|
||||
# Engine configuration
|
||||
categories = []
|
||||
paging = True
|
||||
search_type = ""
|
||||
|
||||
# Search URL
|
||||
base_url_web = 'https://yandex.com/search/site/'
|
||||
base_url_images = 'https://yandex.com/images/search'
|
||||
|
||||
results_xpath = '//li[contains(@class, "serp-item")]'
|
||||
url_xpath = './/a[@class="b-serp-item__title-link"]/@href'
|
||||
title_xpath = './/h3[@class="b-serp-item__title"]/a[@class="b-serp-item__title-link"]/span'
|
||||
content_xpath = './/div[@class="b-serp-item__content"]//div[@class="b-serp-item__text"]'
|
||||
|
||||
|
||||
def catch_bad_response(resp):
|
||||
if resp.url.path.startswith('/showcaptcha'):
|
||||
raise SearxEngineCaptchaException()
|
||||
|
||||
|
||||
def request(query, params):
|
||||
query_params_web = {
|
||||
"tmpl_version": "releases",
|
||||
"text": query,
|
||||
"web": "1",
|
||||
"frame": "1",
|
||||
"searchid": "3131712",
|
||||
}
|
||||
|
||||
query_params_images = {
|
||||
"text": query,
|
||||
"uinfo": "sw-1920-sh-1080-ww-1125-wh-999",
|
||||
}
|
||||
|
||||
if params['pageno'] > 1:
|
||||
query_params_web.update({"p": params["pageno"] - 1})
|
||||
query_params_images.update({"p": params["pageno"] - 1})
|
||||
|
||||
params["cookies"] = {'cookie': "yp=1716337604.sp.family%3A0#1685406411.szm.1:1920x1080:1920x999"}
|
||||
|
||||
if search_type == 'web':
|
||||
params['url'] = f"{base_url_web}?{urlencode(query_params_web)}"
|
||||
elif search_type == 'images':
|
||||
params['url'] = f"{base_url_images}?{urlencode(query_params_images)}"
|
||||
|
||||
return params
|
||||
|
||||
|
||||
def response(resp):
|
||||
if search_type == 'web':
|
||||
|
||||
catch_bad_response(resp)
|
||||
|
||||
dom = html.fromstring(resp.text)
|
||||
|
||||
results = []
|
||||
|
||||
for result in eval_xpath_list(dom, results_xpath):
|
||||
results.append(
|
||||
{
|
||||
'url': extract_text(eval_xpath(result, url_xpath)),
|
||||
'title': extract_text(eval_xpath(result, title_xpath)),
|
||||
'content': extract_text(eval_xpath(result, content_xpath)),
|
||||
}
|
||||
)
|
||||
|
||||
return results
|
||||
|
||||
if search_type == 'images':
|
||||
|
||||
catch_bad_response(resp)
|
||||
|
||||
html_data = html.fromstring(resp.text)
|
||||
html_sample = unescape(html.tostring(html_data, encoding='unicode'))
|
||||
|
||||
content_between_tags = extr(
|
||||
html_sample, '{"location":"/images/search/', 'advRsyaSearchColumn":null}}', default="fail"
|
||||
)
|
||||
json_data = '{"location":"/images/search/' + content_between_tags + 'advRsyaSearchColumn":null}}'
|
||||
|
||||
if content_between_tags == "fail":
|
||||
content_between_tags = extr(html_sample, '{"location":"/images/search/', 'false}}}')
|
||||
json_data = '{"location":"/images/search/' + content_between_tags + 'false}}}'
|
||||
|
||||
json_resp = loads(json_data)
|
||||
|
||||
results = []
|
||||
for _, item_data in json_resp['initialState']['serpList']['items']['entities'].items():
|
||||
title = item_data['snippet']['title']
|
||||
source = item_data['snippet']['url']
|
||||
thumb = item_data['image']
|
||||
fullsize_image = item_data['viewerData']['dups'][0]['url']
|
||||
height = item_data['viewerData']['dups'][0]['h']
|
||||
width = item_data['viewerData']['dups'][0]['w']
|
||||
filesize = item_data['viewerData']['dups'][0]['fileSizeInBytes']
|
||||
humanized_filesize = humanize_bytes(filesize)
|
||||
|
||||
results.append(
|
||||
{
|
||||
'title': title,
|
||||
'url': source,
|
||||
'img_src': fullsize_image,
|
||||
'filesize': humanized_filesize,
|
||||
'thumbnail_src': thumb,
|
||||
'template': 'images.html',
|
||||
'resolution': f'{width} x {height}',
|
||||
}
|
||||
)
|
||||
|
||||
return results
|
||||
|
||||
return []
|
87
searx/infopage/fr/about.md
Normal file
87
searx/infopage/fr/about.md
Normal file
|
@ -0,0 +1,87 @@
|
|||
# A propos de SearXNG
|
||||
|
||||
SearXNG est un [Métamoteur] qui agrège les résultats d'autres
|
||||
{{link('moteurs de recherche', 'preferences')}} tout en ne sauvegardant
|
||||
aucune informations à propos de ses utilisateurs.
|
||||
|
||||
Le projet SearXNG est maintenu par une communauté ouverte.
|
||||
Rejoignez-nous sur Matrix si vous avez des questions ou simplement pour
|
||||
discuter de SearXNG: [#searxng:matrix.org].
|
||||
|
||||
Aidez-nous à rendre SearXNG meilleur.
|
||||
|
||||
- Vous pouvez améliorer les traductions de SearXNG avec l'outil
|
||||
[Weblate].
|
||||
- Suivez le développement, contribuez au projet ou remontez des erreurs
|
||||
en utilisant le [dépôt de sources].
|
||||
- Pour obtenir de plus amples informations, consultez la documentation
|
||||
en ligne du [projet SearXNG].
|
||||
|
||||
## Pourquoi l'utiliser ?
|
||||
|
||||
- SearXNG ne vous fournira pas de résultats aussi personnalisés que
|
||||
Google, mais il ne générera pas non plus de suivi sur vous.
|
||||
- SearXNG ne se soucis pas des recherches que vous faites, ne partage
|
||||
aucune information avec des tiers et ne peut pas être utilisé contre
|
||||
vous.
|
||||
- SearXNG est un logiciel libre. Son code source est 100% ouvert et tout
|
||||
le mode est encouragé à l'améliorer.
|
||||
|
||||
Si vous êtes soucieux du respect de la vie privée et des libertés sur
|
||||
Internet, faites de SearXNG votre moteur de recherche par défaut. Vous
|
||||
pouvez aussi installer et utiliser SearXNG sur votre propre serveur.
|
||||
|
||||
## Comment le configurer comme moteur de recherche par défaut ?
|
||||
|
||||
SearXNG prend en charge [OpenSearch]. Pour plus d'informations sur la
|
||||
manière de modifier votre moteur de recherche par défaut, veuillez
|
||||
consulter la documentation de votre navigateur :
|
||||
|
||||
- [Firefox]
|
||||
- [Microsoft Edge] - Ce lien propose aussi les instructions pour les
|
||||
navigateurs Chrome et Safari.
|
||||
- Les navigateurs basés sur [Chromium] permettent d'ajouter des sites de
|
||||
navigation sans même y accéder.
|
||||
|
||||
Lorsqu'un moteur de recherche est ajouté, son nom doit être unique. Si
|
||||
vous ne pouvez pas ajouter un moteur de recherche, veuillez :
|
||||
|
||||
- Supprimer le doublon (le nom par défaut est SearXNG) ou bien
|
||||
- Contacter le propriétaire de l'instance que vous souhaitez utiliser
|
||||
afin qu'il modifie le nom de celle-ci.
|
||||
|
||||
## Comment ça marche ?
|
||||
|
||||
SearXNG est une reprise logicielle du projet [searx] [Métamoteur],
|
||||
lui-même inspiré du [projet Seeks]. Il assure la confidentialité en
|
||||
mélangeant vos recherches vers d'autres plateformes sans stocker aucune
|
||||
données de recherche. SearXNG peut être ajouté à la barre de recherche
|
||||
de votre navigateur et même être utilisé comme moteur de recherche par
|
||||
défaut.
|
||||
|
||||
Le lien "{{link('statistiques des moteurs', 'stats')}}" présente des
|
||||
informations anonymisées concernant l'utilisation des divers moteurs de
|
||||
recherche.
|
||||
|
||||
## Comment reprendre la main ?
|
||||
|
||||
SearXNG apprécie votre préoccupation concernant les traces de recherche.
|
||||
N'hésitez pas à utiliser le [dépôt de sources] et à maintenir votre
|
||||
propre instance de recherche.
|
||||
|
||||
Ajouter votre instance à la [liste d'instances
|
||||
publiques]({{get_setting('brand.public_instances')}}) afin d'aider
|
||||
d'autres personnes à protéger leur vie privée et rendre l'Internet plus
|
||||
libre. Plus Internet sera décentralisé, plus nous aurons de liberté !
|
||||
|
||||
[dépôt de sources]: {{GIT_URL}}
|
||||
[#searxng:matrix.org]: https://matrix.to/#/#searxng:matrix.org
|
||||
[projet SearXNG]: {{get_setting('brand.docs_url')}}
|
||||
[searx]: https://github.com/searx/searx
|
||||
[Métamoteur]: https://fr.wikipedia.org/wiki/M%C3%A9tamoteur
|
||||
[Weblate]: https://translate.codeberg.org/projects/searxng/
|
||||
[projet Seeks]: https://beniz.github.io/seeks/
|
||||
[OpenSearch]: https://github.com/dewitt/opensearch/blob/master/opensearch-1-1-draft-6.md
|
||||
[Firefox]: https://support.mozilla.org/en-US/kb/add-or-remove-search-engine-firefox
|
||||
[Microsoft Edge]: https://support.microsoft.com/en-us/help/4028574/microsoft-edge-change-the-default-search-engine
|
||||
[Chromium]: https://www.chromium.org/tab-to-search
|
97
searx/infopage/fr/search-syntax.md
Normal file
97
searx/infopage/fr/search-syntax.md
Normal file
|
@ -0,0 +1,97 @@
|
|||
# Syntaxe de recherche
|
||||
|
||||
SearXNG permet de modifier les catégories de recherche, les moteurs
|
||||
utilisés ou encore la langue de recherche par l'intermédiaire d'une
|
||||
syntaxe dédiée. La liste des moteurs de recherche, de catégories et de
|
||||
langues disponibles est accessible depuis la page de
|
||||
{{link('préférences', 'preferences')}}.
|
||||
|
||||
## `!` Spécifier un moteur ou une catégorie
|
||||
|
||||
Pour restreindre la recherche à un moteur ou une catégorie, utilisez le
|
||||
caractère "!". Voici quelques exemples d'utilisation :
|
||||
|
||||
- Rechercher **paris** sur Wikipédia.
|
||||
|
||||
- {{search('!wp paris')}}
|
||||
- {{search('!wikipedia paris')}}
|
||||
|
||||
- Rechercher **paris** dans la catégorie **Carte**.
|
||||
|
||||
- {{search('!map paris')}}
|
||||
|
||||
- Rechercher des **Images**.
|
||||
|
||||
- {{search('!images Wau Holland')}}
|
||||
|
||||
Les abréviations de moteurs et de langues sont aussi valides. Il est
|
||||
possible d'accumuler les moteurs et catégories dans une requête
|
||||
complexe. Par exemple, {{search('!map !ddg !wp paris')}} recherchera
|
||||
**paris** dans la catégorie **Carte** de DuckDuckGo et Wikipédia.
|
||||
|
||||
## `:` Spécifier une langue
|
||||
|
||||
Utilisez le préfixe ":" pour limiter la recherche à une langue en
|
||||
particulier. Par exemple :
|
||||
|
||||
- Rechercher dans les pages françaises de Wikipédia.
|
||||
|
||||
- {{search(':fr !wp Wau Holland')}}
|
||||
|
||||
## `!!<bang>` Recherches externes (!Bang)
|
||||
|
||||
SearXNG supporte les recherches [DuckDuckGo] de type "!Bang". Utilisez
|
||||
le préfixe "!!" pour être automatiquement redirigé vers un moteur de
|
||||
recherche externe. Par exemple :
|
||||
|
||||
- Rechercher sur Wikipédia en langue française.
|
||||
|
||||
- {{search('!!wfr Wau Holland')}}
|
||||
|
||||
Prenez garde au fait que de telles recherches sont exécutées directement
|
||||
sur le moteur externe. Dans ce cas, SearXNG ne peut pas protéger votre
|
||||
vie privée.
|
||||
|
||||
[DuckDuckGo]: https://duckduckgo.com/bang
|
||||
|
||||
## `!!` Redirection automatique
|
||||
|
||||
En utilisant "!!" suivi d'un ou plusieurs espaces lors de votre
|
||||
recherche, vous serez automatiquement redirigé vers le premier résultat
|
||||
de recherche. Cela correspondant au fonctionnement "J'ai de la chance"
|
||||
du moteur Google. Par exemple :
|
||||
|
||||
- Rechercher et être redirigé directement vers le premier lien
|
||||
correspondant.
|
||||
|
||||
- {{search('!! Wau Holland')}}
|
||||
|
||||
Prenez garde au fait qu'aucune vérification ne peut être faite
|
||||
concernant le premier lien retourné. Il pourrait même s'agir d'un site
|
||||
dangereux. Dans ce cas, SearXNG ne peut pas protéger votre vie
|
||||
privée. Soyez prudent en utilisant cette fonctionnalité.
|
||||
|
||||
## Requêtes spéciales
|
||||
|
||||
Dans la section _requêtes spéciales_ de la page de {{link('préférences',
|
||||
'preferences')}} se trouve une liste de mots clés à usage particulier.
|
||||
Par exemple :
|
||||
|
||||
- Générer une valeur aléatoire.
|
||||
|
||||
- {{search('random uuid')}}
|
||||
|
||||
- Calculer une moyenne.
|
||||
|
||||
- {{search('avg 123 548 2.04 24.2')}}
|
||||
|
||||
- Afficher la valeur de la variable _User-Agent_ utilisée par votre
|
||||
navigateur (doit être activé manuellement).
|
||||
|
||||
- {{search('user-agent')}}
|
||||
|
||||
- Convertir une chaîne de caractères en valeurs de hachage ("hash digests")
|
||||
(doit être activé manuellement).
|
||||
|
||||
- {{search('md5 lorem ipsum')}}
|
||||
- {{search('sha512 lorem ipsum')}}
|
|
@ -1,7 +1,19 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
# pylint: disable=too-many-branches
|
||||
"""In addition to rewriting/replace reslut URLs, the *hoostnames* plugin offers
|
||||
other features.
|
||||
"""
|
||||
.. attention::
|
||||
|
||||
The **"Hostname replace"** plugin has been replace by **"Hostnames
|
||||
plugin"**, see :pull:`3463` & :pull:`3552`.
|
||||
|
||||
The **Hostnames plugin** can be enabled by adding it to the
|
||||
``enabled_plugins`` **list** in the ``setting.yml`` like so.
|
||||
|
||||
.. code:: yaml
|
||||
|
||||
enabled_plugins:
|
||||
- 'Hostnames plugin'
|
||||
...
|
||||
|
||||
- ``hostnames.replace``: A **mapping** of regular expressions to hostnames to be
|
||||
replaced by other hostnames.
|
||||
|
|
|
@ -1852,6 +1852,22 @@ engines:
|
|||
engine: unsplash
|
||||
shortcut: us
|
||||
|
||||
- name: yandex
|
||||
engine: yandex
|
||||
categories: general
|
||||
search_type: web
|
||||
shortcut: yd
|
||||
disabled: true
|
||||
inactive: true
|
||||
|
||||
- name: yandex images
|
||||
engine: yandex
|
||||
categories: images
|
||||
search_type: images
|
||||
shortcut: ydi
|
||||
disabled: true
|
||||
inactive: true
|
||||
|
||||
- name: yandex music
|
||||
engine: yandex_music
|
||||
shortcut: ydm
|
||||
|
|
Binary file not shown.
|
@ -11,18 +11,19 @@
|
|||
# return42 <return42@users.noreply.translate.codeberg.org>, 2024.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: searx\n"
|
||||
"Project-Id-Version: searx\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2024-08-08 10:01+0000\n"
|
||||
"PO-Revision-Date: 2024-07-30 08:18+0000\n"
|
||||
"PO-Revision-Date: 2024-08-22 05:18+0000\n"
|
||||
"Last-Translator: ghose <ghose@users.noreply.translate.codeberg.org>\n"
|
||||
"Language-Team: Galician <https://translate.codeberg.org/projects/searxng/"
|
||||
"searxng/gl/>\n"
|
||||
"Language: gl\n"
|
||||
"Language-Team: Galician "
|
||||
"<https://translate.codeberg.org/projects/searxng/searxng/gl/>\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 5.6.2\n"
|
||||
"Generated-By: Babel 2.15.0\n"
|
||||
|
||||
#. CONSTANT_NAMES['NO_SUBGROUPING']
|
||||
|
@ -1308,7 +1309,7 @@ msgid ""
|
|||
"multiple categories"
|
||||
msgstr ""
|
||||
"Buscar inmediatamente se hai unha categoría seleccionada. Desactiva para "
|
||||
"elexir varias categorías"
|
||||
"elixir varias categorías"
|
||||
|
||||
#: searx/templates/simple/preferences/theme.html:2
|
||||
msgid "Theme"
|
||||
|
@ -1953,4 +1954,3 @@ msgstr "agochar vídeo"
|
|||
|
||||
#~ msgid "Hostname replace"
|
||||
#~ msgstr "Substituír servidor"
|
||||
|
||||
|
|
Binary file not shown.
|
@ -10,22 +10,23 @@
|
|||
# SecularSteve <fairfull.playing@gmail.com>, 2022, 2023.
|
||||
# return42 <markus.heiser@darmarit.de>, 2023.
|
||||
# return42 <return42@users.noreply.translate.codeberg.org>, 2024.
|
||||
# crnobog <crnobog@users.noreply.translate.codeberg.org>, 2024.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: searx\n"
|
||||
"Project-Id-Version: searx\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2024-08-08 10:01+0000\n"
|
||||
"PO-Revision-Date: 2024-04-18 13:18+0000\n"
|
||||
"Last-Translator: return42 <return42@users.noreply.translate.codeberg.org>"
|
||||
"\n"
|
||||
"PO-Revision-Date: 2024-08-21 01:18+0000\n"
|
||||
"Last-Translator: crnobog <crnobog@users.noreply.translate.codeberg.org>\n"
|
||||
"Language-Team: Serbian <https://translate.codeberg.org/projects/searxng/"
|
||||
"searxng/sr/>\n"
|
||||
"Language: sr\n"
|
||||
"Language-Team: Serbian "
|
||||
"<https://translate.codeberg.org/projects/searxng/searxng/sr/>\n"
|
||||
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
|
||||
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
|
||||
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
||||
"X-Generator: Weblate 5.6.2\n"
|
||||
"Generated-By: Babel 2.15.0\n"
|
||||
|
||||
#. CONSTANT_NAMES['NO_SUBGROUPING']
|
||||
|
@ -76,7 +77,7 @@ msgstr "радио"
|
|||
#. CATEGORY_NAMES['TV']
|
||||
#: searx/searxng.msg
|
||||
msgid "tv"
|
||||
msgstr ""
|
||||
msgstr "телевизија"
|
||||
|
||||
#. CATEGORY_NAMES['IT']
|
||||
#: searx/searxng.msg
|
||||
|
@ -176,62 +177,66 @@ msgstr "О нама"
|
|||
#. WEATHER_TERMS['AVERAGE TEMP.']
|
||||
#: searx/searxng.msg
|
||||
msgid "Average temp."
|
||||
msgstr ""
|
||||
msgstr "Просечна температура"
|
||||
|
||||
#. WEATHER_TERMS['CLOUD COVER']
|
||||
#: searx/searxng.msg
|
||||
msgid "Cloud cover"
|
||||
msgstr ""
|
||||
msgstr "Облачност"
|
||||
|
||||
#. WEATHER_TERMS['CONDITION']
|
||||
#: searx/searxng.msg
|
||||
msgid "Condition"
|
||||
msgstr ""
|
||||
msgstr "Стање"
|
||||
|
||||
#. WEATHER_TERMS['CURRENT CONDITION']
|
||||
#: searx/searxng.msg
|
||||
msgid "Current condition"
|
||||
msgstr ""
|
||||
msgstr "Тренутно стање"
|
||||
|
||||
#. WEATHER_TERMS['EVENING']
|
||||
#: searx/engines/wttr.py:100 searx/searxng.msg
|
||||
#, fuzzy
|
||||
msgid "Evening"
|
||||
msgstr "Vece"
|
||||
msgstr "Вече"
|
||||
|
||||
#. WEATHER_TERMS['FEELS LIKE']
|
||||
#: searx/searxng.msg
|
||||
msgid "Feels like"
|
||||
msgstr ""
|
||||
msgstr "Осећај"
|
||||
|
||||
#. WEATHER_TERMS['HUMIDITY']
|
||||
#: searx/searxng.msg
|
||||
msgid "Humidity"
|
||||
msgstr ""
|
||||
msgstr "Влажност"
|
||||
|
||||
#. WEATHER_TERMS['MAX TEMP.']
|
||||
#: searx/searxng.msg
|
||||
msgid "Max temp."
|
||||
msgstr ""
|
||||
msgstr "Највећа темп."
|
||||
|
||||
#. WEATHER_TERMS['MIN TEMP.']
|
||||
#: searx/searxng.msg
|
||||
msgid "Min temp."
|
||||
msgstr ""
|
||||
msgstr "Најмања темп."
|
||||
|
||||
#. WEATHER_TERMS['MORNING']
|
||||
#: searx/engines/wttr.py:100 searx/searxng.msg
|
||||
#, fuzzy
|
||||
msgid "Morning"
|
||||
msgstr "Jutro"
|
||||
msgstr "Јутро"
|
||||
|
||||
#. WEATHER_TERMS['NIGHT']
|
||||
#: searx/engines/wttr.py:100 searx/searxng.msg
|
||||
#, fuzzy
|
||||
msgid "Night"
|
||||
msgstr "Noc"
|
||||
msgstr "Ноћ"
|
||||
|
||||
#. WEATHER_TERMS['NOON']
|
||||
#: searx/engines/wttr.py:100 searx/searxng.msg
|
||||
#, fuzzy
|
||||
msgid "Noon"
|
||||
msgstr "Podne"
|
||||
msgstr "Подне"
|
||||
|
||||
#. WEATHER_TERMS['PRESSURE']
|
||||
#: searx/searxng.msg
|
||||
|
@ -1934,4 +1939,3 @@ msgstr "сакриј видео"
|
|||
|
||||
#~ msgid "Hostname replace"
|
||||
#~ msgstr "Замени име хостинга"
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ class TestEnginesInit(SearxTestCase): # pylint: disable=missing-class-docstring
|
|||
def tearDownClass(cls):
|
||||
settings['outgoing']['using_tor_proxy'] = False
|
||||
settings['outgoing']['extra_proxy_timeout'] = 0
|
||||
engines.load_engines([])
|
||||
|
||||
def test_initialize_engines_default(self):
|
||||
engine_list = [
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
# pylint: disable=missing-module-docstring, invalid-name
|
||||
|
||||
from copy import copy
|
||||
import logging
|
||||
|
||||
import searx.search
|
||||
from searx.search import SearchQuery, EngineRef
|
||||
|
@ -46,8 +47,13 @@ class SearchQueryTestCase(SearxTestCase): # pylint: disable=missing-class-docst
|
|||
class SearchTestCase(SearxTestCase): # pylint: disable=missing-class-docstring
|
||||
def setUp(self):
|
||||
|
||||
log = logging.getLogger("searx")
|
||||
log_lev = log.level
|
||||
log.setLevel(logging.ERROR)
|
||||
from searx import webapp # pylint: disable=import-outside-toplevel
|
||||
|
||||
log.setLevel(log_lev)
|
||||
|
||||
self.app = webapp.app
|
||||
|
||||
@classmethod
|
||||
|
|
102
tests/unit/test_tineye.py
Normal file
102
tests/unit/test_tineye.py
Normal file
|
@ -0,0 +1,102 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
# pylint: disable=missing-module-docstring
|
||||
|
||||
|
||||
from datetime import datetime
|
||||
from unittest.mock import Mock
|
||||
from requests import HTTPError
|
||||
from searx.engines import load_engines, tineye
|
||||
from tests import SearxTestCase
|
||||
|
||||
|
||||
class TinEyeTests(SearxTestCase): # pylint: disable=missing-class-docstring
|
||||
|
||||
def setUp(self):
|
||||
load_engines([{'name': 'tineye', 'engine': 'tineye', 'shortcut': 'tin', 'timeout': 9.0, 'disabled': True}])
|
||||
|
||||
def tearDown(self):
|
||||
load_engines([])
|
||||
|
||||
def test_status_code_raises(self):
|
||||
response = Mock()
|
||||
response.status_code = 401
|
||||
response.raise_for_status.side_effect = HTTPError()
|
||||
self.assertRaises(HTTPError, lambda: tineye.response(response))
|
||||
|
||||
def test_returns_empty_list_for_422(self):
|
||||
response = Mock()
|
||||
response.json.return_value = {}
|
||||
response.status_code = 422
|
||||
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_format_for_422(self):
|
||||
response = Mock()
|
||||
response.json.return_value = {"suggestions": {"key": "Invalid image URL"}}
|
||||
response.status_code = 422
|
||||
response.raise_for_status.side_effect = HTTPError()
|
||||
|
||||
with self.assertLogs(tineye.logger) as assert_logs_context:
|
||||
tineye.response(response)
|
||||
self.assertIn(tineye.FORMAT_NOT_SUPPORTED, ','.join(assert_logs_context.output))
|
||||
|
||||
def test_logs_signature_for_422(self):
|
||||
response = Mock()
|
||||
response.json.return_value = {"suggestions": {"key": "NO_SIGNATURE_ERROR"}}
|
||||
response.status_code = 422
|
||||
response.raise_for_status.side_effect = HTTPError()
|
||||
|
||||
with self.assertLogs(tineye.logger) as assert_logs_context:
|
||||
tineye.response(response)
|
||||
self.assertIn(tineye.NO_SIGNATURE_ERROR, ','.join(assert_logs_context.output))
|
||||
|
||||
def test_logs_download_for_422(self):
|
||||
response = Mock()
|
||||
response.json.return_value = {"suggestions": {"key": "Download Error"}}
|
||||
response.status_code = 422
|
||||
response.raise_for_status.side_effect = HTTPError()
|
||||
|
||||
with self.assertLogs(tineye.logger) as assert_logs_context:
|
||||
tineye.response(response)
|
||||
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):
|
||||
description = 'There was a problem with that request. Error ID: ad5fc955-a934-43c1-8187-f9a61d301645'
|
||||
response = Mock()
|
||||
response.json.return_value = {"suggestions": {"description": [description], "title": "Oops! We're sorry!"}}
|
||||
response.status_code = 400
|
||||
response.raise_for_status.side_effect = HTTPError()
|
||||
|
||||
with self.assertLogs(tineye.logger) as assert_logs_context:
|
||||
tineye.response(response)
|
||||
self.assertIn(description, ','.join(assert_logs_context.output))
|
||||
|
||||
def test_crawl_date_parses(self):
|
||||
date_str = '2020-05-25'
|
||||
date = datetime.strptime(date_str, '%Y-%m-%d')
|
||||
response = Mock()
|
||||
response.json.return_value = {
|
||||
'matches': [
|
||||
{
|
||||
'backlinks': [
|
||||
{
|
||||
'crawl_date': date_str,
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
response.status_code = 200
|
||||
results = tineye.response(response)
|
||||
self.assertEqual(date, results[0]['publishedDate'])
|
|
@ -1,6 +1,7 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
# pylint: disable=missing-module-docstring
|
||||
|
||||
import logging
|
||||
import json
|
||||
from urllib.parse import ParseResult
|
||||
from mock import Mock
|
||||
|
@ -20,8 +21,13 @@ class ViewsTestCase(SearxTestCase): # pylint: disable=missing-class-docstring,
|
|||
|
||||
self.setattr4test(searx.search.processors, 'initialize_processor', dummy)
|
||||
|
||||
log = logging.getLogger("searx")
|
||||
log_lev = log.level
|
||||
log.setLevel(logging.ERROR)
|
||||
from searx import webapp # pylint: disable=import-outside-toplevel
|
||||
|
||||
log.setLevel(log_lev)
|
||||
|
||||
webapp.app.config['TESTING'] = True # to get better error messages
|
||||
self.app = webapp.app.test_client()
|
||||
|
||||
|
|
|
@ -663,8 +663,8 @@ pyenv.install() {
|
|||
pyenv
|
||||
fi
|
||||
for i in ${PYOBJECTS}; do
|
||||
build_msg PYENV "[install] pip install -e '$i${PY_SETUP_EXTRAS}'"
|
||||
"${PY_ENV_BIN}/python" -m pip install -e "$i${PY_SETUP_EXTRAS}"
|
||||
build_msg PYENV "[install] pip install --use-pep517 --no-build-isolation -e '$i${PY_SETUP_EXTRAS}'"
|
||||
"${PY_ENV_BIN}/python" -m pip install --use-pep517 --no-build-isolation -e "$i${PY_SETUP_EXTRAS}"
|
||||
done
|
||||
fi
|
||||
pyenv.install.OK
|
||||
|
@ -1674,7 +1674,7 @@ EOF
|
|||
}
|
||||
|
||||
# apt packages
|
||||
LXC_BASE_PACKAGES_debian="bash git build-essential python3 python3-venv"
|
||||
LXC_BASE_PACKAGES_debian="bash git build-essential python3 python3-venv python-is-python3"
|
||||
|
||||
# pacman packages
|
||||
LXC_BASE_PACKAGES_arch="bash git base-devel python"
|
||||
|
|
|
@ -41,7 +41,7 @@ EOF
|
|||
}
|
||||
|
||||
go.ls(){
|
||||
python3 <<EOF
|
||||
python <<EOF
|
||||
import sys, json, requests
|
||||
resp = requests.get("${GO_DL_URL}/?mode=json&include=all")
|
||||
for ver in json.loads(resp.text):
|
||||
|
@ -67,7 +67,7 @@ go.ver_info(){
|
|||
# os: [darwin|freebsd|linux|windows]
|
||||
# arch: [amd64|arm64|386|armv6l|ppc64le|s390x]
|
||||
|
||||
python3 - "$@" <<EOF
|
||||
python - "$@" <<EOF
|
||||
import sys, json, requests
|
||||
resp = requests.get("${GO_DL_URL}/?mode=json&include=all")
|
||||
for ver in json.loads(resp.text):
|
||||
|
|
|
@ -96,13 +96,8 @@ case $DIST_ID-$DIST_VERS in
|
|||
SEARXNG_BUILD_PACKAGES="${SEARXNG_BUILD_PACKAGES_debian}"
|
||||
APACHE_PACKAGES="$APACHE_PACKAGES libapache2-mod-proxy-uwsgi"
|
||||
;;
|
||||
ubuntu-20.04)
|
||||
# https://wiki.ubuntu.com/FocalFossa/ReleaseNotes#Python3_by_default
|
||||
SEARXNG_PACKAGES="${SEARXNG_PACKAGES_debian} python-is-python3"
|
||||
SEARXNG_BUILD_PACKAGES="${SEARXNG_BUILD_PACKAGES_debian}"
|
||||
;;
|
||||
ubuntu-*|debian-*)
|
||||
SEARXNG_PACKAGES="${SEARXNG_PACKAGES_debian}"
|
||||
SEARXNG_PACKAGES="${SEARXNG_PACKAGES_debian} python-is-python3"
|
||||
SEARXNG_BUILD_PACKAGES="${SEARXNG_BUILD_PACKAGES_debian}"
|
||||
;;
|
||||
arch-*)
|
||||
|
@ -453,6 +448,7 @@ searxng.install.clone() {
|
|||
|
||||
# clone repo and add a safe.directory entry to git's system config / see
|
||||
# https://github.com/searxng/searxng/issues/1251
|
||||
git config --system --add safe.directory "${REPO_ROOT}/.git"
|
||||
git_clone "$REPO_ROOT" "${SEARXNG_SRC}" \
|
||||
"$GIT_BRANCH" "${SERVICE_USER}"
|
||||
git config --system --add safe.directory "${SEARXNG_SRC}"
|
||||
|
@ -489,7 +485,7 @@ searxng.install.pyenv() {
|
|||
info_msg "create pyenv in ${SEARXNG_PYENV}"
|
||||
tee_stderr 0.1 <<EOF | sudo -H -u "${SERVICE_USER}" -i 2>&1 | prefix_stdout "$_service_prefix"
|
||||
rm -rf "${SEARXNG_PYENV}"
|
||||
python3 -m venv "${SEARXNG_PYENV}"
|
||||
python -m venv "${SEARXNG_PYENV}"
|
||||
grep -qFs -- 'source ${SEARXNG_PYENV}/bin/activate' ~/.profile \
|
||||
|| echo 'source ${SEARXNG_PYENV}/bin/activate' >> ~/.profile
|
||||
EOF
|
||||
|
@ -505,7 +501,7 @@ pip install -U setuptools
|
|||
pip install -U wheel
|
||||
pip install -U pyyaml
|
||||
cd ${SEARXNG_SRC}
|
||||
pip install -e .
|
||||
pip install --use-pep517 --no-build-isolation -e .
|
||||
EOF
|
||||
}
|
||||
|
||||
|
@ -573,7 +569,7 @@ pip install -U pip
|
|||
pip install -U setuptools
|
||||
pip install -U wheel
|
||||
pip install -U pyyaml
|
||||
pip install -U -e .
|
||||
pip install -U --use-pep517 --no-build-isolation -e .
|
||||
EOF
|
||||
rst_para "update instance's settings.yml from ${SEARXNG_SETTINGS_PATH}"
|
||||
DEFAULT_SELECT=2 \
|
||||
|
|
Loading…
Add table
Reference in a new issue