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
|
# jump to SearXNG's working tree and install SearXNG into virtualenv
|
||||||
(${SERVICE_USER})$ cd \"$SEARXNG_SRC\"
|
(${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
|
.. END manage.sh update_packages
|
||||||
|
|
|
@ -61,7 +61,7 @@ working tree and release a ``make install`` to get a virtualenv with a
|
||||||
$ make install
|
$ make install
|
||||||
PYENV [virtualenv] installing ./requirements*.txt into local/py3
|
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
|
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 [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
|
Successfully installed searxng-2023.7.19+a446dea1b
|
||||||
|
|
||||||
|
|
6
manage
6
manage
|
@ -233,7 +233,7 @@ gecko.driver() {
|
||||||
build_msg INSTALL "geckodriver already installed"
|
build_msg INSTALL "geckodriver already installed"
|
||||||
return
|
return
|
||||||
fi
|
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
|
case "$PLATFORM" in
|
||||||
"linux 32bit" | "linux2 32bit") ARCH="linux32";;
|
"linux 32bit" | "linux2 32bit") ARCH="linux32";;
|
||||||
"linux 64bit" | "linux2 64bit") ARCH="linux64";;
|
"linux 64bit" | "linux2 64bit") ARCH="linux64";;
|
||||||
|
@ -299,8 +299,8 @@ pyenv.install() {
|
||||||
|
|
||||||
( set -e
|
( set -e
|
||||||
pyenv
|
pyenv
|
||||||
build_msg PYENV "[install] pip install -e 'searx${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 -e ".${PY_SETUP_EXTRAS}"
|
"${PY_ENV_BIN}/python" -m pip install --use-pep517 --no-build-isolation -e ".${PY_SETUP_EXTRAS}"
|
||||||
)
|
)
|
||||||
local exit_val=$?
|
local exit_val=$?
|
||||||
if [ ! $exit_val -eq 0 ]; then
|
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 urllib.parse import urlencode
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from flask_babel import gettext
|
from flask_babel import gettext
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
import logging
|
||||||
|
|
||||||
|
logger = logging.getLogger()
|
||||||
|
|
||||||
about = {
|
about = {
|
||||||
"website": 'https://tineye.com',
|
"website": 'https://tineye.com',
|
||||||
"wikidata_id": 'Q2382535',
|
"wikidata_id": 'Q2382535',
|
||||||
|
@ -34,7 +40,7 @@ categories = ['general']
|
||||||
paging = True
|
paging = True
|
||||||
safesearch = False
|
safesearch = False
|
||||||
base_url = 'https://tineye.com'
|
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(
|
FORMAT_NOT_SUPPORTED = gettext(
|
||||||
"Could not read that image url. This may be due to an unsupported file"
|
"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")
|
crawl_date = backlink_json.get("crawl_date")
|
||||||
if crawl_date:
|
if crawl_date:
|
||||||
crawl_date = datetime.fromisoformat(crawl_date[:-3])
|
crawl_date = datetime.strptime(crawl_date, '%Y-%m-%d')
|
||||||
else:
|
else:
|
||||||
crawl_date = datetime.min
|
crawl_date = datetime.min
|
||||||
|
|
||||||
|
@ -150,29 +156,15 @@ def parse_tineye_match(match_json):
|
||||||
|
|
||||||
def response(resp):
|
def response(resp):
|
||||||
"""Parse HTTP response from TinEye."""
|
"""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()
|
json_data = resp.json()
|
||||||
except Exception as exc: # pylint: disable=broad-except
|
suggestions = json_data.get('suggestions', {})
|
||||||
msg = "can't parse JSON response // %s" % exc
|
message = f'HTTP Status Code: {resp.status_code}'
|
||||||
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
|
|
||||||
|
|
||||||
|
if resp.status_code == 422:
|
||||||
|
s_key = suggestions.get('key', '')
|
||||||
if s_key == "Invalid image URL":
|
if s_key == "Invalid image URL":
|
||||||
# test https://docs.searxng.org/_static/searxng-wordmark.svg
|
# test https://docs.searxng.org/_static/searxng-wordmark.svg
|
||||||
message = FORMAT_NOT_SUPPORTED
|
message = FORMAT_NOT_SUPPORTED
|
||||||
|
@ -182,16 +174,23 @@ def response(resp):
|
||||||
elif s_key == 'Download Error':
|
elif s_key == 'Download Error':
|
||||||
# test https://notexists
|
# test https://notexists
|
||||||
message = DOWNLOAD_ERROR
|
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
|
# see https://github.com/searxng/searxng/pull/1456#issuecomment-1193105023
|
||||||
# results.append({'answer': message})
|
# results.append({'answer': message})
|
||||||
logger.error(message)
|
logger.error(message)
|
||||||
|
return []
|
||||||
|
|
||||||
return results
|
# Raise for all other responses
|
||||||
|
resp.raise_for_status()
|
||||||
|
|
||||||
resp.raise_for_status()
|
results = []
|
||||||
|
json_data = resp.json()
|
||||||
# append results from matches
|
|
||||||
|
|
||||||
for match_json in json_data['matches']:
|
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
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
# pylint: disable=too-many-branches
|
# 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
|
- ``hostnames.replace``: A **mapping** of regular expressions to hostnames to be
|
||||||
replaced by other hostnames.
|
replaced by other hostnames.
|
||||||
|
|
|
@ -1852,6 +1852,22 @@ engines:
|
||||||
engine: unsplash
|
engine: unsplash
|
||||||
shortcut: us
|
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
|
- name: yandex music
|
||||||
engine: yandex_music
|
engine: yandex_music
|
||||||
shortcut: ydm
|
shortcut: ydm
|
||||||
|
|
Binary file not shown.
|
@ -11,18 +11,19 @@
|
||||||
# return42 <return42@users.noreply.translate.codeberg.org>, 2024.
|
# return42 <return42@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-08-08 10:01+0000\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"
|
"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: 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"
|
"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.6.2\n"
|
||||||
"Generated-By: Babel 2.15.0\n"
|
"Generated-By: Babel 2.15.0\n"
|
||||||
|
|
||||||
#. CONSTANT_NAMES['NO_SUBGROUPING']
|
#. CONSTANT_NAMES['NO_SUBGROUPING']
|
||||||
|
@ -1308,7 +1309,7 @@ msgid ""
|
||||||
"multiple categories"
|
"multiple categories"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Buscar inmediatamente se hai unha categoría seleccionada. Desactiva para "
|
"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
|
#: searx/templates/simple/preferences/theme.html:2
|
||||||
msgid "Theme"
|
msgid "Theme"
|
||||||
|
@ -1953,4 +1954,3 @@ msgstr "agochar vídeo"
|
||||||
|
|
||||||
#~ msgid "Hostname replace"
|
#~ msgid "Hostname replace"
|
||||||
#~ msgstr "Substituír servidor"
|
#~ msgstr "Substituír servidor"
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -10,22 +10,23 @@
|
||||||
# SecularSteve <fairfull.playing@gmail.com>, 2022, 2023.
|
# SecularSteve <fairfull.playing@gmail.com>, 2022, 2023.
|
||||||
# return42 <markus.heiser@darmarit.de>, 2023.
|
# return42 <markus.heiser@darmarit.de>, 2023.
|
||||||
# return42 <return42@users.noreply.translate.codeberg.org>, 2024.
|
# return42 <return42@users.noreply.translate.codeberg.org>, 2024.
|
||||||
|
# crnobog <crnobog@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-08-08 10:01+0000\n"
|
"POT-Creation-Date: 2024-08-08 10:01+0000\n"
|
||||||
"PO-Revision-Date: 2024-04-18 13:18+0000\n"
|
"PO-Revision-Date: 2024-08-21 01:18+0000\n"
|
||||||
"Last-Translator: return42 <return42@users.noreply.translate.codeberg.org>"
|
"Last-Translator: crnobog <crnobog@users.noreply.translate.codeberg.org>\n"
|
||||||
"\n"
|
"Language-Team: Serbian <https://translate.codeberg.org/projects/searxng/"
|
||||||
|
"searxng/sr/>\n"
|
||||||
"Language: 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"
|
"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=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"
|
"Generated-By: Babel 2.15.0\n"
|
||||||
|
|
||||||
#. CONSTANT_NAMES['NO_SUBGROUPING']
|
#. CONSTANT_NAMES['NO_SUBGROUPING']
|
||||||
|
@ -76,7 +77,7 @@ msgstr "радио"
|
||||||
#. CATEGORY_NAMES['TV']
|
#. CATEGORY_NAMES['TV']
|
||||||
#: searx/searxng.msg
|
#: searx/searxng.msg
|
||||||
msgid "tv"
|
msgid "tv"
|
||||||
msgstr ""
|
msgstr "телевизија"
|
||||||
|
|
||||||
#. CATEGORY_NAMES['IT']
|
#. CATEGORY_NAMES['IT']
|
||||||
#: searx/searxng.msg
|
#: searx/searxng.msg
|
||||||
|
@ -176,62 +177,66 @@ msgstr "О нама"
|
||||||
#. WEATHER_TERMS['AVERAGE TEMP.']
|
#. WEATHER_TERMS['AVERAGE TEMP.']
|
||||||
#: searx/searxng.msg
|
#: searx/searxng.msg
|
||||||
msgid "Average temp."
|
msgid "Average temp."
|
||||||
msgstr ""
|
msgstr "Просечна температура"
|
||||||
|
|
||||||
#. WEATHER_TERMS['CLOUD COVER']
|
#. WEATHER_TERMS['CLOUD COVER']
|
||||||
#: searx/searxng.msg
|
#: searx/searxng.msg
|
||||||
msgid "Cloud cover"
|
msgid "Cloud cover"
|
||||||
msgstr ""
|
msgstr "Облачност"
|
||||||
|
|
||||||
#. WEATHER_TERMS['CONDITION']
|
#. WEATHER_TERMS['CONDITION']
|
||||||
#: searx/searxng.msg
|
#: searx/searxng.msg
|
||||||
msgid "Condition"
|
msgid "Condition"
|
||||||
msgstr ""
|
msgstr "Стање"
|
||||||
|
|
||||||
#. WEATHER_TERMS['CURRENT CONDITION']
|
#. WEATHER_TERMS['CURRENT CONDITION']
|
||||||
#: searx/searxng.msg
|
#: searx/searxng.msg
|
||||||
msgid "Current condition"
|
msgid "Current condition"
|
||||||
msgstr ""
|
msgstr "Тренутно стање"
|
||||||
|
|
||||||
#. WEATHER_TERMS['EVENING']
|
#. WEATHER_TERMS['EVENING']
|
||||||
#: searx/engines/wttr.py:100 searx/searxng.msg
|
#: searx/engines/wttr.py:100 searx/searxng.msg
|
||||||
|
#, fuzzy
|
||||||
msgid "Evening"
|
msgid "Evening"
|
||||||
msgstr "Vece"
|
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
|
||||||
|
#, fuzzy
|
||||||
msgid "Morning"
|
msgid "Morning"
|
||||||
msgstr "Jutro"
|
msgstr "Јутро"
|
||||||
|
|
||||||
#. WEATHER_TERMS['NIGHT']
|
#. WEATHER_TERMS['NIGHT']
|
||||||
#: searx/engines/wttr.py:100 searx/searxng.msg
|
#: searx/engines/wttr.py:100 searx/searxng.msg
|
||||||
|
#, fuzzy
|
||||||
msgid "Night"
|
msgid "Night"
|
||||||
msgstr "Noc"
|
msgstr "Ноћ"
|
||||||
|
|
||||||
#. WEATHER_TERMS['NOON']
|
#. WEATHER_TERMS['NOON']
|
||||||
#: searx/engines/wttr.py:100 searx/searxng.msg
|
#: searx/engines/wttr.py:100 searx/searxng.msg
|
||||||
|
#, fuzzy
|
||||||
msgid "Noon"
|
msgid "Noon"
|
||||||
msgstr "Podne"
|
msgstr "Подне"
|
||||||
|
|
||||||
#. WEATHER_TERMS['PRESSURE']
|
#. WEATHER_TERMS['PRESSURE']
|
||||||
#: searx/searxng.msg
|
#: searx/searxng.msg
|
||||||
|
@ -1934,4 +1939,3 @@ msgstr "сакриј видео"
|
||||||
|
|
||||||
#~ msgid "Hostname replace"
|
#~ msgid "Hostname replace"
|
||||||
#~ msgstr "Замени име хостинга"
|
#~ msgstr "Замени име хостинга"
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ class TestEnginesInit(SearxTestCase): # pylint: disable=missing-class-docstring
|
||||||
def tearDownClass(cls):
|
def tearDownClass(cls):
|
||||||
settings['outgoing']['using_tor_proxy'] = False
|
settings['outgoing']['using_tor_proxy'] = False
|
||||||
settings['outgoing']['extra_proxy_timeout'] = 0
|
settings['outgoing']['extra_proxy_timeout'] = 0
|
||||||
|
engines.load_engines([])
|
||||||
|
|
||||||
def test_initialize_engines_default(self):
|
def test_initialize_engines_default(self):
|
||||||
engine_list = [
|
engine_list = [
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
# pylint: disable=missing-module-docstring, invalid-name
|
# pylint: disable=missing-module-docstring, invalid-name
|
||||||
|
|
||||||
from copy import copy
|
from copy import copy
|
||||||
|
import logging
|
||||||
|
|
||||||
import searx.search
|
import searx.search
|
||||||
from searx.search import SearchQuery, EngineRef
|
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
|
class SearchTestCase(SearxTestCase): # pylint: disable=missing-class-docstring
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
|
||||||
|
log = logging.getLogger("searx")
|
||||||
|
log_lev = log.level
|
||||||
|
log.setLevel(logging.ERROR)
|
||||||
from searx import webapp # pylint: disable=import-outside-toplevel
|
from searx import webapp # pylint: disable=import-outside-toplevel
|
||||||
|
|
||||||
|
log.setLevel(log_lev)
|
||||||
|
|
||||||
self.app = webapp.app
|
self.app = webapp.app
|
||||||
|
|
||||||
@classmethod
|
@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
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
# pylint: disable=missing-module-docstring
|
# pylint: disable=missing-module-docstring
|
||||||
|
|
||||||
|
import logging
|
||||||
import json
|
import json
|
||||||
from urllib.parse import ParseResult
|
from urllib.parse import ParseResult
|
||||||
from mock import Mock
|
from mock import Mock
|
||||||
|
@ -20,8 +21,13 @@ class ViewsTestCase(SearxTestCase): # pylint: disable=missing-class-docstring,
|
||||||
|
|
||||||
self.setattr4test(searx.search.processors, 'initialize_processor', dummy)
|
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
|
from searx import webapp # pylint: disable=import-outside-toplevel
|
||||||
|
|
||||||
|
log.setLevel(log_lev)
|
||||||
|
|
||||||
webapp.app.config['TESTING'] = True # to get better error messages
|
webapp.app.config['TESTING'] = True # to get better error messages
|
||||||
self.app = webapp.app.test_client()
|
self.app = webapp.app.test_client()
|
||||||
|
|
||||||
|
|
|
@ -663,8 +663,8 @@ pyenv.install() {
|
||||||
pyenv
|
pyenv
|
||||||
fi
|
fi
|
||||||
for i in ${PYOBJECTS}; do
|
for i in ${PYOBJECTS}; do
|
||||||
build_msg PYENV "[install] 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 -e "$i${PY_SETUP_EXTRAS}"
|
"${PY_ENV_BIN}/python" -m pip install --use-pep517 --no-build-isolation -e "$i${PY_SETUP_EXTRAS}"
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
pyenv.install.OK
|
pyenv.install.OK
|
||||||
|
@ -1674,7 +1674,7 @@ EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
# apt packages
|
# 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
|
# pacman packages
|
||||||
LXC_BASE_PACKAGES_arch="bash git base-devel python"
|
LXC_BASE_PACKAGES_arch="bash git base-devel python"
|
||||||
|
|
|
@ -41,7 +41,7 @@ EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
go.ls(){
|
go.ls(){
|
||||||
python3 <<EOF
|
python <<EOF
|
||||||
import sys, json, requests
|
import sys, json, requests
|
||||||
resp = requests.get("${GO_DL_URL}/?mode=json&include=all")
|
resp = requests.get("${GO_DL_URL}/?mode=json&include=all")
|
||||||
for ver in json.loads(resp.text):
|
for ver in json.loads(resp.text):
|
||||||
|
@ -67,7 +67,7 @@ go.ver_info(){
|
||||||
# os: [darwin|freebsd|linux|windows]
|
# os: [darwin|freebsd|linux|windows]
|
||||||
# arch: [amd64|arm64|386|armv6l|ppc64le|s390x]
|
# arch: [amd64|arm64|386|armv6l|ppc64le|s390x]
|
||||||
|
|
||||||
python3 - "$@" <<EOF
|
python - "$@" <<EOF
|
||||||
import sys, json, requests
|
import sys, json, requests
|
||||||
resp = requests.get("${GO_DL_URL}/?mode=json&include=all")
|
resp = requests.get("${GO_DL_URL}/?mode=json&include=all")
|
||||||
for ver in json.loads(resp.text):
|
for ver in json.loads(resp.text):
|
||||||
|
|
|
@ -96,13 +96,8 @@ case $DIST_ID-$DIST_VERS in
|
||||||
SEARXNG_BUILD_PACKAGES="${SEARXNG_BUILD_PACKAGES_debian}"
|
SEARXNG_BUILD_PACKAGES="${SEARXNG_BUILD_PACKAGES_debian}"
|
||||||
APACHE_PACKAGES="$APACHE_PACKAGES libapache2-mod-proxy-uwsgi"
|
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-*)
|
ubuntu-*|debian-*)
|
||||||
SEARXNG_PACKAGES="${SEARXNG_PACKAGES_debian}"
|
SEARXNG_PACKAGES="${SEARXNG_PACKAGES_debian} python-is-python3"
|
||||||
SEARXNG_BUILD_PACKAGES="${SEARXNG_BUILD_PACKAGES_debian}"
|
SEARXNG_BUILD_PACKAGES="${SEARXNG_BUILD_PACKAGES_debian}"
|
||||||
;;
|
;;
|
||||||
arch-*)
|
arch-*)
|
||||||
|
@ -453,6 +448,7 @@ searxng.install.clone() {
|
||||||
|
|
||||||
# clone repo and add a safe.directory entry to git's system config / see
|
# clone repo and add a safe.directory entry to git's system config / see
|
||||||
# https://github.com/searxng/searxng/issues/1251
|
# https://github.com/searxng/searxng/issues/1251
|
||||||
|
git config --system --add safe.directory "${REPO_ROOT}/.git"
|
||||||
git_clone "$REPO_ROOT" "${SEARXNG_SRC}" \
|
git_clone "$REPO_ROOT" "${SEARXNG_SRC}" \
|
||||||
"$GIT_BRANCH" "${SERVICE_USER}"
|
"$GIT_BRANCH" "${SERVICE_USER}"
|
||||||
git config --system --add safe.directory "${SEARXNG_SRC}"
|
git config --system --add safe.directory "${SEARXNG_SRC}"
|
||||||
|
@ -489,7 +485,7 @@ searxng.install.pyenv() {
|
||||||
info_msg "create pyenv in ${SEARXNG_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"
|
tee_stderr 0.1 <<EOF | sudo -H -u "${SERVICE_USER}" -i 2>&1 | prefix_stdout "$_service_prefix"
|
||||||
rm -rf "${SEARXNG_PYENV}"
|
rm -rf "${SEARXNG_PYENV}"
|
||||||
python3 -m venv "${SEARXNG_PYENV}"
|
python -m venv "${SEARXNG_PYENV}"
|
||||||
grep -qFs -- 'source ${SEARXNG_PYENV}/bin/activate' ~/.profile \
|
grep -qFs -- 'source ${SEARXNG_PYENV}/bin/activate' ~/.profile \
|
||||||
|| echo 'source ${SEARXNG_PYENV}/bin/activate' >> ~/.profile
|
|| echo 'source ${SEARXNG_PYENV}/bin/activate' >> ~/.profile
|
||||||
EOF
|
EOF
|
||||||
|
@ -505,7 +501,7 @@ pip install -U setuptools
|
||||||
pip install -U wheel
|
pip install -U wheel
|
||||||
pip install -U pyyaml
|
pip install -U pyyaml
|
||||||
cd ${SEARXNG_SRC}
|
cd ${SEARXNG_SRC}
|
||||||
pip install -e .
|
pip install --use-pep517 --no-build-isolation -e .
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -573,7 +569,7 @@ pip install -U pip
|
||||||
pip install -U setuptools
|
pip install -U setuptools
|
||||||
pip install -U wheel
|
pip install -U wheel
|
||||||
pip install -U pyyaml
|
pip install -U pyyaml
|
||||||
pip install -U -e .
|
pip install -U --use-pep517 --no-build-isolation -e .
|
||||||
EOF
|
EOF
|
||||||
rst_para "update instance's settings.yml from ${SEARXNG_SETTINGS_PATH}"
|
rst_para "update instance's settings.yml from ${SEARXNG_SETTINGS_PATH}"
|
||||||
DEFAULT_SELECT=2 \
|
DEFAULT_SELECT=2 \
|
||||||
|
|
Loading…
Add table
Reference in a new issue