mirror of
https://github.com/searxng/searxng.git
synced 2026-06-16 06:46:52 +02:00
[chore] complete and normalize the attributes of engine objects (#6258)
Drop outdated engine attributes: supported_languages, language_aliases Complete, normalize and document the type definitions for the engine-module and engine-class. For the ``engine.about`` section of the configuration, a type check is performed based on structure ``searx.enginelib.EngineAbout``. The property ``engine.about.language`` no longer exists; existing values have been migrated to ``engine.language``. Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
This commit is contained in:
committed by
Markus Heiser
parent
b3e08f2a44
commit
6c9dcd4242
@@ -58,8 +58,8 @@ Configured Engines
|
||||
{% for mod in engines %}
|
||||
|
||||
* - `{{mod.name}} <{{mod.about and mod.about.website}}>`_
|
||||
{%- if mod.about and mod.about.language %}
|
||||
({{mod.about.language | upper}})
|
||||
{%- if mod.language %}
|
||||
({{mod.language | upper}})
|
||||
{%- endif %}
|
||||
- ``!{{mod.shortcut}}``
|
||||
- {%- if 'searx.engines.' + mod.__name__ in documented_modules %}
|
||||
|
||||
+76
-63
@@ -41,7 +41,7 @@ if t.TYPE_CHECKING:
|
||||
from searx.enginelib.traits import EngineTraits
|
||||
from searx.extended_types import SXNG_Response
|
||||
from searx.result_types import EngineResults
|
||||
from searx.search.processors import OfflineParamTypes, OnlineParamTypes
|
||||
from searx.search.processors import OfflineParamTypes, OnlineParamTypes, ProcessorType
|
||||
|
||||
ENGINES_CACHE: ExpireCacheSQLite = ExpireCacheSQLite.build_cache(
|
||||
ExpireCacheCfg(
|
||||
@@ -180,7 +180,7 @@ class EngineCache:
|
||||
return ENGINES_CACHE.secret_hash(name=name)
|
||||
|
||||
|
||||
class EngineAbout(msgspec.Struct):
|
||||
class EngineAbout(msgspec.Struct, kw_only=True):
|
||||
"""Additional fields describing the engine.
|
||||
|
||||
.. code:: yaml
|
||||
@@ -213,12 +213,11 @@ class EngineAbout(msgspec.Struct):
|
||||
results: str = ""
|
||||
"""Data format of the source (online-engines: of the response)."""
|
||||
|
||||
language: str = ""
|
||||
"""If the engine supports only one language, this language is specified
|
||||
here (``en``, ``de``, ``"no"`` or ..); otherwise, the value remains empty.
|
||||
description: str = ""
|
||||
"""Brief description of the engine and where it gets its data from.
|
||||
|
||||
For the YAML configuration: think of the `YAML-Norway problem
|
||||
<https://ruuda.nl/2023/the-yaml-document-from-hell#the-norway-problem>`_
|
||||
This value should only be set as long as no description of the data source
|
||||
is available via a :py:obj:`EngineAbout.wikidata_id`.
|
||||
"""
|
||||
|
||||
|
||||
@@ -227,6 +226,8 @@ class Engine(abc.ABC): # pylint: disable=too-few-public-methods
|
||||
|
||||
Further documentation see :ref:`general engine configuration`.
|
||||
|
||||
The defaults are taken from :py:obj:`searx.engines.ENGINE_DEFAULT_ARGS`.
|
||||
|
||||
.. hint::
|
||||
|
||||
This class is currently never initialized and only used for type hinting.
|
||||
@@ -234,49 +235,27 @@ class Engine(abc.ABC): # pylint: disable=too-few-public-methods
|
||||
|
||||
logger: logging.Logger
|
||||
|
||||
# Common options in the engine module
|
||||
# Common options of the engine module
|
||||
|
||||
engine_type: str
|
||||
engine_type: "ProcessorType" = "online"
|
||||
"""Type of the engine (:ref:`searx.search.processors`)"""
|
||||
|
||||
paging: bool
|
||||
paging: bool = False
|
||||
"""Engine supports multiple pages."""
|
||||
|
||||
max_page: int = 0
|
||||
"""If the engine supports paging, then this is the value for the last page
|
||||
that is still supported. ``0`` means unlimited numbers of pages."""
|
||||
|
||||
time_range_support: bool
|
||||
time_range_support: bool = False
|
||||
"""Engine supports search time range."""
|
||||
|
||||
safesearch: bool
|
||||
safesearch: bool = False
|
||||
"""Engine supports SafeSearch"""
|
||||
|
||||
language_support: bool
|
||||
language_support: bool = False
|
||||
"""Engine supports languages (locales) search."""
|
||||
|
||||
language: str
|
||||
"""For an engine, when there is ``language: ...`` in the YAML settings the engine
|
||||
does support only this one language:
|
||||
|
||||
.. code:: yaml
|
||||
|
||||
- name: google french
|
||||
engine: google
|
||||
language: fr
|
||||
"""
|
||||
|
||||
region: str
|
||||
"""For an engine, when there is ``region: ...`` in the YAML settings the engine
|
||||
does support only this one region::
|
||||
|
||||
.. code:: yaml
|
||||
|
||||
- name: google belgium
|
||||
engine: google
|
||||
region: fr-BE
|
||||
"""
|
||||
|
||||
fetch_traits: "Callable[[EngineTraits, bool], None]"
|
||||
"""Function to to fetch engine's traits from origin."""
|
||||
|
||||
@@ -285,9 +264,6 @@ class Engine(abc.ABC): # pylint: disable=too-few-public-methods
|
||||
|
||||
# settings.yml
|
||||
|
||||
categories: list[str]
|
||||
"""Specifies to which :ref:`engine categories` the engine should be added."""
|
||||
|
||||
name: str
|
||||
"""Name that will be used across SearXNG to define this engine. In settings, on
|
||||
the result page .."""
|
||||
@@ -297,6 +273,43 @@ class Engine(abc.ABC): # pylint: disable=too-few-public-methods
|
||||
this search engine (file name from :origin:`searx/engines` without
|
||||
``.py``)."""
|
||||
|
||||
categories: list[str] = ["general"]
|
||||
"""Specifies to which :ref:`engine categories` the engine should be added."""
|
||||
|
||||
language: str = ""
|
||||
"""If the engine supports only one language, this language is specified here
|
||||
(``en``, ``de``, ``"no"`` or ..); otherwise, the value remains empty. For
|
||||
the YAML configuration: think of the `YAML-Norway problem
|
||||
<https://ruuda.nl/2023/the-yaml-document-from-hell#the-norway-problem>`_
|
||||
|
||||
.. code:: yaml
|
||||
|
||||
- name: google norway
|
||||
engine: google
|
||||
language: "no"
|
||||
|
||||
Depending on ``language_support``, this value has similar but also slightly
|
||||
different meanings.
|
||||
|
||||
- When ``language_support`` is **true**, the map of
|
||||
:py:obj:`traits.EngineTraits.languages` is reduced to the selected
|
||||
language
|
||||
|
||||
- When ``language_support`` is **false**, then the implementation of the
|
||||
engine only supports this one ``language``
|
||||
"""
|
||||
|
||||
region: str = ""
|
||||
"""For an engine, when there is ``region: ...`` in the YAML settings the engine
|
||||
does support only this one region::
|
||||
|
||||
.. code:: yaml
|
||||
|
||||
- name: google belgium
|
||||
engine: google
|
||||
region: fr-BE
|
||||
"""
|
||||
|
||||
enable_http: bool
|
||||
"""Enable HTTP (by default only HTTPS is enabled)."""
|
||||
|
||||
@@ -309,6 +322,31 @@ class Engine(abc.ABC): # pylint: disable=too-few-public-methods
|
||||
display_error_messages: bool
|
||||
"""Display error messages on the web UI."""
|
||||
|
||||
disabled: bool = False
|
||||
"""To disable by default the engine, but not deleting it. It will allow the
|
||||
user to manually activate it in the settings."""
|
||||
|
||||
inactive: bool = False
|
||||
"""Remove the engine from the settings (*disabled & removed*)."""
|
||||
|
||||
about: EngineAbout = EngineAbout()
|
||||
"""Additional fields describing the engine."""
|
||||
|
||||
using_tor_proxy: bool = False
|
||||
"""Using tor proxy (``true``) or not (``false``) for this engine."""
|
||||
|
||||
send_accept_language_header: bool = True
|
||||
"""When this option is activated (default), the language (locale) that is
|
||||
selected by the user is used to build and send a ``Accept-Language`` header
|
||||
in the request to the origin search engine."""
|
||||
|
||||
tokens: list[str] = []
|
||||
"""A list of secret tokens to make this engine *private*, more details see
|
||||
:ref:`private engines`."""
|
||||
|
||||
weight: float = 1.0
|
||||
"""Weighting of the results of this engine (:ref:`weight <settings engines>`)."""
|
||||
|
||||
proxies: dict[str, dict[str, str]]
|
||||
"""Set proxies for a specific engine (YAML):
|
||||
|
||||
@@ -319,31 +357,6 @@ class Engine(abc.ABC): # pylint: disable=too-few-public-methods
|
||||
https: socks5://proxy:port
|
||||
"""
|
||||
|
||||
disabled: bool
|
||||
"""To disable by default the engine, but not deleting it. It will allow the
|
||||
user to manually activate it in the settings."""
|
||||
|
||||
inactive: bool
|
||||
"""Remove the engine from the settings (*disabled & removed*)."""
|
||||
|
||||
about: EngineAbout
|
||||
"""Additional fields describing the engine."""
|
||||
|
||||
using_tor_proxy: bool
|
||||
"""Using tor proxy (``true``) or not (``false``) for this engine."""
|
||||
|
||||
send_accept_language_header: bool
|
||||
"""When this option is activated (default), the language (locale) that is
|
||||
selected by the user is used to build and send a ``Accept-Language`` header
|
||||
in the request to the origin search engine."""
|
||||
|
||||
tokens: list[str]
|
||||
"""A list of secret tokens to make this engine *private*, more details see
|
||||
:ref:`private engines`."""
|
||||
|
||||
weight: int
|
||||
"""Weighting of the results of this engine (:ref:`weight <settings engines>`)."""
|
||||
|
||||
def setup(self, engine_settings: dict[str, t.Any]) -> bool: # pylint: disable=unused-argument
|
||||
"""Dynamic setup of the engine settings.
|
||||
|
||||
|
||||
+15
-12
@@ -142,11 +142,11 @@ class EngineTraits:
|
||||
"""
|
||||
|
||||
if self.data_type == "traits_v1":
|
||||
self._set_traits_v1(engine)
|
||||
self._set_traits_v1(engine) # pyright: ignore[reportArgumentType]
|
||||
else:
|
||||
raise TypeError("engine traits of type %s is unknown" % self.data_type)
|
||||
|
||||
def _set_traits_v1(self, engine: "Engine | types.ModuleType") -> None:
|
||||
def _set_traits_v1(self, engine: "Engine") -> None:
|
||||
# For an engine, when there is `language: ...` in the YAML settings the engine
|
||||
# does support only this one language (region)::
|
||||
#
|
||||
@@ -159,22 +159,25 @@ class EngineTraits:
|
||||
|
||||
_msg = "settings.yml - engine: '%s' / %s: '%s' not supported"
|
||||
|
||||
languages = traits.languages
|
||||
if hasattr(engine, "language"):
|
||||
if engine.language not in languages:
|
||||
raise ValueError(_msg % (engine.name, "language", engine.language))
|
||||
traits.languages = {engine.language: languages[engine.language]}
|
||||
if engine.language:
|
||||
if engine.language_support:
|
||||
if not len(traits.languages) > 1:
|
||||
raise ValueError(
|
||||
f"engine {engine.name}: activated language_support with just one or less languages"
|
||||
)
|
||||
if engine.language not in traits.languages:
|
||||
raise ValueError(_msg % (engine.name, "language", engine.language))
|
||||
traits.languages = {engine.language: traits.languages[engine.language]}
|
||||
|
||||
regions = traits.regions
|
||||
if hasattr(engine, "region"):
|
||||
if engine.region not in regions:
|
||||
if engine.region:
|
||||
if engine.region not in traits.regions:
|
||||
raise ValueError(_msg % (engine.name, "region", engine.region))
|
||||
traits.regions = {engine.region: regions[engine.region]}
|
||||
traits.regions = {engine.region: traits.regions[engine.region]}
|
||||
|
||||
engine.language_support = bool(traits.languages or traits.regions)
|
||||
|
||||
# set the copied & modified traits in engine's namespace
|
||||
engine.traits = traits # pyright: ignore[reportAttributeAccessIssue]
|
||||
engine.traits = traits
|
||||
|
||||
|
||||
class EngineTraitsMap(dict[str, EngineTraits]):
|
||||
|
||||
@@ -22,8 +22,8 @@ about = {
|
||||
"use_official_api": False,
|
||||
"require_api_key": False,
|
||||
"results": "HTML",
|
||||
"language": "zh",
|
||||
}
|
||||
language = "zh"
|
||||
|
||||
# Engine Configuration
|
||||
categories = ["general"]
|
||||
|
||||
@@ -5,19 +5,19 @@ intended monkey patching of the engine modules.
|
||||
.. attention::
|
||||
|
||||
Monkey-patching modules is a practice from the past that shouldn't be
|
||||
expanded upon. In the long run, there should be an engine class that can be
|
||||
inherited. However, as long as this class doesn't exist, and as long as all
|
||||
engine modules aren't converted to an engine class, these builtin types will
|
||||
still be needed.
|
||||
expanded upon. In the long run, engines should be instances of
|
||||
:py:obj:`searx.enginelib.Engine`. However, as long as long as all engine
|
||||
modules aren't converted to this class, these builtin types will still be
|
||||
needed.
|
||||
"""
|
||||
|
||||
import logging
|
||||
from searx.enginelib import traits as _traits
|
||||
|
||||
logger: logging.Logger
|
||||
supported_languages: str
|
||||
language_aliases: str
|
||||
language_support: bool
|
||||
language: str
|
||||
region: str
|
||||
traits: _traits.EngineTraits
|
||||
|
||||
# from searx.engines.ENGINE_DEFAULT_ARGS
|
||||
|
||||
@@ -17,37 +17,44 @@ from os.path import realpath, dirname
|
||||
|
||||
import types
|
||||
import inspect
|
||||
import msgspec
|
||||
|
||||
from searx import logger, settings
|
||||
from searx.utils import load_module
|
||||
|
||||
if t.TYPE_CHECKING:
|
||||
from searx.enginelib import Engine
|
||||
from searx.enginelib import Engine, EngineAbout
|
||||
|
||||
logger = logger.getChild('engines')
|
||||
ENGINE_DIR = dirname(realpath(__file__))
|
||||
|
||||
# Defaults for the namespace of an engine module, see load_engine()
|
||||
ENGINE_DEFAULT_ARGS: dict[str, int | str | list[t.Any] | dict[str, t.Any] | bool] = {
|
||||
ENGINE_DEFAULT_ARGS: dict[str, t.Any] = {
|
||||
# Common options in the engine module
|
||||
"engine_type": "online",
|
||||
"paging": False,
|
||||
"max_page": 0,
|
||||
"time_range_support": False,
|
||||
"safesearch": False,
|
||||
"language_support": False,
|
||||
# settings.yml
|
||||
"categories": ["general"],
|
||||
"language": "",
|
||||
"region": "",
|
||||
"enable_http": False,
|
||||
"shortcut": "-",
|
||||
"timeout": settings["outgoing"]["request_timeout"],
|
||||
"display_error_messages": True,
|
||||
"disabled": False,
|
||||
"inactive": False,
|
||||
"about": {},
|
||||
"about": EngineAbout(),
|
||||
"using_tor_proxy": False,
|
||||
"send_accept_language_header": True,
|
||||
"tokens": [],
|
||||
"max_page": 0,
|
||||
"weight": 1.0,
|
||||
}
|
||||
"""Default values that are set in an engine of type *module*, please compare
|
||||
with the class :py:obj:`searx.enginelib.Engine`."""
|
||||
|
||||
# set automatically when an engine does not have any tab category
|
||||
DEFAULT_CATEGORY = 'other'
|
||||
|
||||
@@ -178,13 +185,27 @@ def set_loggers(engine: "Engine|types.ModuleType", engine_name: str):
|
||||
|
||||
def update_engine_attributes(engine: "Engine | types.ModuleType", engine_data: dict[str, t.Any]):
|
||||
# set engine attributes from engine_data
|
||||
|
||||
kvargs: dict[str, t.Any]
|
||||
if isinstance(engine.about, EngineAbout):
|
||||
kvargs = {**msgspec.to_builtins(engine.about), **engine_data.get("about", {})}
|
||||
else:
|
||||
kvargs = {**engine.about, **engine_data.get("about", {})}
|
||||
|
||||
try:
|
||||
engine.about = EngineAbout(**kvargs)
|
||||
except TypeError as exc:
|
||||
raise TypeError(
|
||||
f"engine {engine_data['name']} ({engine_data['engine']}) - in the about section --> {exc}"
|
||||
) from exc
|
||||
|
||||
for param_name, param_value in engine_data.items():
|
||||
if param_name == "about":
|
||||
continue
|
||||
if param_name == 'categories':
|
||||
if isinstance(param_value, str):
|
||||
param_value = list(map(str.strip, param_value.split(',')))
|
||||
engine.categories = param_value # type: ignore
|
||||
elif hasattr(engine, 'about') and param_name == 'about':
|
||||
engine.about = {**engine.about, **engine_data['about']} # type: ignore
|
||||
else:
|
||||
setattr(engine, param_name, param_value)
|
||||
|
||||
|
||||
@@ -16,12 +16,12 @@ about = {
|
||||
"use_official_api": False,
|
||||
"require_api_key": False,
|
||||
"results": "HTML",
|
||||
"language": "zh",
|
||||
}
|
||||
|
||||
# Engine Configuration
|
||||
categories = ["videos"]
|
||||
paging = True
|
||||
language = "zh"
|
||||
|
||||
# Base URL
|
||||
base_url = "https://www.acfun.cn"
|
||||
|
||||
@@ -42,8 +42,8 @@ about = {
|
||||
'use_official_api': False,
|
||||
'require_api_key': False,
|
||||
'results': 'HTML',
|
||||
'language': 'it',
|
||||
}
|
||||
language = "it"
|
||||
|
||||
|
||||
def request(query, params):
|
||||
|
||||
@@ -54,8 +54,8 @@ about = {
|
||||
"use_official_api": True,
|
||||
"require_api_key": True,
|
||||
"results": "JSON",
|
||||
"language": "en",
|
||||
}
|
||||
language = "en"
|
||||
|
||||
CACHE: EngineCache
|
||||
"""Persistent (SQLite) key/value cache that deletes its values after ``expire``
|
||||
|
||||
@@ -23,8 +23,8 @@ about = {
|
||||
"use_official_api": False,
|
||||
"require_api_key": False,
|
||||
"results": "JSON",
|
||||
"language": "zh",
|
||||
}
|
||||
language = "zh"
|
||||
|
||||
paging = True
|
||||
categories = []
|
||||
|
||||
@@ -13,8 +13,8 @@ about = {
|
||||
'use_official_api': False,
|
||||
'require_api_key': False,
|
||||
'results': 'JSON',
|
||||
'language': 'de',
|
||||
}
|
||||
language = "de"
|
||||
|
||||
paging = True
|
||||
categories = ['general']
|
||||
|
||||
@@ -10,8 +10,8 @@ about = {
|
||||
'use_official_api': False,
|
||||
'require_api_key': False,
|
||||
'results': 'JSON',
|
||||
'language': 'de',
|
||||
}
|
||||
language = "de"
|
||||
|
||||
paging = True
|
||||
categories = []
|
||||
|
||||
@@ -70,13 +70,13 @@ about = {
|
||||
"use_official_api": False,
|
||||
"require_api_key": False,
|
||||
"results": "JSON",
|
||||
"language": "zh",
|
||||
}
|
||||
|
||||
paging = True
|
||||
time_range_support = True
|
||||
results_per_page = 10
|
||||
categories = []
|
||||
language = "zh"
|
||||
|
||||
ChinasoCategoryType = t.Literal['news', 'videos', 'images']
|
||||
"""ChinaSo supports news, videos, images search.
|
||||
|
||||
@@ -24,7 +24,7 @@ import typing as t
|
||||
import json
|
||||
|
||||
from searx.result_types import EngineResults
|
||||
from searx.enginelib import EngineCache
|
||||
from searx.enginelib import EngineCache, EngineAbout
|
||||
|
||||
if t.TYPE_CHECKING:
|
||||
from searx.search.processors import RequestParams
|
||||
@@ -35,13 +35,11 @@ categories = ["general"]
|
||||
disabled = True
|
||||
timeout = 2.0
|
||||
|
||||
about = {
|
||||
"wikidata_id": None,
|
||||
"official_api_documentation": None,
|
||||
"use_official_api": False,
|
||||
"require_api_key": False,
|
||||
"results": "JSON",
|
||||
}
|
||||
language = "en"
|
||||
about = EngineAbout(
|
||||
results="JSON",
|
||||
description="Demo offline engine Engine with results in the English language.",
|
||||
)
|
||||
|
||||
# if there is a need for globals, use a leading underline
|
||||
_my_offline_engine: str = ""
|
||||
|
||||
@@ -25,6 +25,7 @@ import typing as t
|
||||
|
||||
from urllib.parse import urlencode
|
||||
from searx.result_types import EngineResults
|
||||
from searx.enginelib import EngineAbout
|
||||
|
||||
if t.TYPE_CHECKING:
|
||||
from searx.extended_types import SXNG_Response
|
||||
@@ -43,14 +44,14 @@ page_size = 20
|
||||
search_api = "https://api.artic.edu/api/v1/artworks/search"
|
||||
image_api = "https://www.artic.edu/iiif/2/"
|
||||
|
||||
about = {
|
||||
"website": "https://www.artic.edu",
|
||||
"wikidata_id": "Q239303",
|
||||
"official_api_documentation": "http://api.artic.edu/docs/",
|
||||
"use_official_api": True,
|
||||
"require_api_key": False,
|
||||
"results": "JSON",
|
||||
}
|
||||
about = EngineAbout(
|
||||
website="https://www.artic.edu",
|
||||
wikidata_id="Q239303",
|
||||
official_api_documentation="http://api.artic.edu/docs/",
|
||||
use_official_api=True,
|
||||
require_api_key=False,
|
||||
results="JSON",
|
||||
)
|
||||
|
||||
|
||||
# if there is a need for globals, use a leading underline
|
||||
|
||||
@@ -11,8 +11,8 @@ about = {
|
||||
'use_official_api': False,
|
||||
'require_api_key': False,
|
||||
'results': 'HTML',
|
||||
'language': 'de',
|
||||
}
|
||||
language = "de"
|
||||
|
||||
categories = []
|
||||
paging = True
|
||||
|
||||
@@ -14,8 +14,8 @@ about = {
|
||||
"use_official_api": False,
|
||||
"require_api_key": False,
|
||||
"results": 'HTML',
|
||||
"language": 'de',
|
||||
}
|
||||
language = "de"
|
||||
|
||||
categories = ['dictionaries']
|
||||
paging = True
|
||||
|
||||
@@ -55,7 +55,7 @@ about = {
|
||||
'official_api_documentation': 'https://www.elastic.co/guide/en/elasticsearch/reference/current/search-search.html',
|
||||
'use_official_api': True,
|
||||
'require_api_key': False,
|
||||
'format': 'JSON',
|
||||
"results": "JSON",
|
||||
}
|
||||
|
||||
base_url = 'http://localhost:9200'
|
||||
|
||||
@@ -27,8 +27,8 @@ about = {
|
||||
'official_api_documentation': None,
|
||||
'require_api_key': False,
|
||||
'results': 'HTML',
|
||||
'language': 'de',
|
||||
}
|
||||
language = "de"
|
||||
paging = True
|
||||
categories = ['shopping']
|
||||
|
||||
|
||||
@@ -34,8 +34,8 @@ about = {
|
||||
"use_official_api": True,
|
||||
"require_api_key": False,
|
||||
"results": "JSON",
|
||||
"language": "it",
|
||||
}
|
||||
language = "it"
|
||||
|
||||
|
||||
def request(query, params):
|
||||
|
||||
@@ -16,8 +16,8 @@ about = {
|
||||
"use_official_api": False,
|
||||
"require_api_key": False,
|
||||
"results": 'HTML',
|
||||
"language": 'fr',
|
||||
}
|
||||
language = "fr"
|
||||
|
||||
# engine dependent config
|
||||
categories = ['videos']
|
||||
|
||||
@@ -14,9 +14,9 @@ about = {
|
||||
"use_official_api": False,
|
||||
"require_api_key": False,
|
||||
"results": "JSON",
|
||||
"language": "zh",
|
||||
}
|
||||
|
||||
language = "zh"
|
||||
paging = True
|
||||
time_range_support = True
|
||||
categories = ["videos"]
|
||||
|
||||
@@ -13,8 +13,8 @@ about = {
|
||||
"use_official_api": True,
|
||||
"require_api_key": False,
|
||||
"results": 'JSON',
|
||||
"language": 'ja',
|
||||
}
|
||||
language = "ja"
|
||||
|
||||
categories = ['dictionaries']
|
||||
paging = False
|
||||
|
||||
@@ -79,6 +79,9 @@ from json import loads
|
||||
from urllib.parse import urlencode
|
||||
from searx.utils import to_string, html_to_text
|
||||
from searx.network import raise_for_httperror
|
||||
from searx.enginelib import EngineAbout
|
||||
|
||||
about = EngineAbout()
|
||||
|
||||
search_url = None
|
||||
"""
|
||||
|
||||
@@ -11,9 +11,9 @@ about = {
|
||||
"use_official_api": True,
|
||||
"require_api_key": False,
|
||||
"results": 'JSON',
|
||||
"language": "de",
|
||||
}
|
||||
|
||||
language = "de"
|
||||
categories = ['videos']
|
||||
paging = True
|
||||
time_range_support = False
|
||||
|
||||
@@ -35,8 +35,9 @@ about = {
|
||||
'use_official_api': False,
|
||||
'require_api_key': False,
|
||||
'results': 'JSON',
|
||||
'language': 'de',
|
||||
}
|
||||
language = "de"
|
||||
|
||||
paging = True
|
||||
categories = ["movies"]
|
||||
|
||||
|
||||
@@ -26,8 +26,8 @@ about = {
|
||||
"use_official_api": False,
|
||||
"require_api_key": False,
|
||||
"results": "HTML",
|
||||
"language": "ko",
|
||||
}
|
||||
language = "ko"
|
||||
|
||||
categories = []
|
||||
paging = True
|
||||
|
||||
@@ -13,8 +13,8 @@ about = {
|
||||
"use_official_api": False,
|
||||
"require_api_key": False,
|
||||
"results": "HTML",
|
||||
"language": "ja",
|
||||
}
|
||||
language = "ja"
|
||||
|
||||
categories = ["videos"]
|
||||
paging = True
|
||||
|
||||
@@ -28,7 +28,7 @@ search_string = 'api/?{query}&limit={limit}'
|
||||
result_base_url = 'https://openstreetmap.org/{osm_type}/{osm_id}'
|
||||
|
||||
# list of supported languages
|
||||
supported_languages = ['de', 'en', 'fr', 'it']
|
||||
photon_supported_languages = ["de", "en", "fr", "it"]
|
||||
|
||||
|
||||
# do search-request
|
||||
@@ -37,7 +37,7 @@ def request(query, params):
|
||||
|
||||
if params['language'] != 'all':
|
||||
language = params['language'].split('_')[0]
|
||||
if language in supported_languages:
|
||||
if language in photon_supported_languages:
|
||||
params['url'] = params['url'] + "&lang=" + language
|
||||
|
||||
# using SearXNG User-Agent
|
||||
|
||||
@@ -77,7 +77,7 @@ from searx.utils import gen_useragent, html_to_text, parse_duration_string
|
||||
|
||||
about = {
|
||||
"website": "https://presearch.io",
|
||||
"wikidiata_id": "Q7240905",
|
||||
"wikidata_id": "Q7240905",
|
||||
"official_api_documentation": "https://docs.presearch.io/nodes/api",
|
||||
"use_official_api": False,
|
||||
"require_api_key": False,
|
||||
|
||||
@@ -16,8 +16,8 @@ about = {
|
||||
"use_official_api": False,
|
||||
"require_api_key": False,
|
||||
"results": "HTML",
|
||||
"language": "zh",
|
||||
}
|
||||
language = "zh"
|
||||
|
||||
# Engine Configuration
|
||||
categories = []
|
||||
|
||||
@@ -13,8 +13,8 @@ about = {
|
||||
"use_official_api": False,
|
||||
"require_api_key": False,
|
||||
"results": 'JSON',
|
||||
'language': 'fr',
|
||||
}
|
||||
language = "fr"
|
||||
|
||||
categories = ['movies']
|
||||
paging = True
|
||||
|
||||
@@ -19,8 +19,8 @@ about = {
|
||||
"use_official_api": False,
|
||||
"require_api_key": False,
|
||||
"results": "HTML",
|
||||
"language": "cz",
|
||||
}
|
||||
language = "cz"
|
||||
|
||||
categories = ['general', 'web']
|
||||
base_url = 'https://search.seznam.cz/'
|
||||
|
||||
@@ -16,8 +16,8 @@ about = {
|
||||
"use_official_api": False,
|
||||
"require_api_key": False,
|
||||
"results": "HTML",
|
||||
"language": "zh",
|
||||
}
|
||||
language = "zh"
|
||||
|
||||
# Engine Configuration
|
||||
categories = ["general"]
|
||||
|
||||
@@ -11,8 +11,8 @@ about = {
|
||||
"use_official_api": False,
|
||||
"require_api_key": False,
|
||||
"results": "JSON",
|
||||
"language": "zh",
|
||||
}
|
||||
language = "zh"
|
||||
|
||||
categories = ["videos"]
|
||||
paging = True
|
||||
|
||||
@@ -14,8 +14,8 @@ about = {
|
||||
"use_official_api": False,
|
||||
"require_api_key": False,
|
||||
"results": "HTML",
|
||||
"language": "zh",
|
||||
}
|
||||
language = "zh"
|
||||
|
||||
# Engine Configuration
|
||||
categories = ["news"]
|
||||
|
||||
@@ -27,8 +27,9 @@ about = {
|
||||
'use_official_api': True,
|
||||
'require_api_key': False,
|
||||
'results': 'JSON',
|
||||
'language': 'de',
|
||||
}
|
||||
language = "de"
|
||||
|
||||
categories = ['general', 'news']
|
||||
paging = True
|
||||
|
||||
|
||||
@@ -16,20 +16,17 @@ from lxml import html
|
||||
|
||||
from searx.utils import eval_xpath_list, eval_xpath, extract_text, get_embeded_stream_url, ElementType
|
||||
from searx.result_types import EngineResults
|
||||
from searx.enginelib import EngineAbout
|
||||
|
||||
if t.TYPE_CHECKING:
|
||||
from searx.extended_types import SXNG_Response
|
||||
from searx.search.processors import OnlineParams
|
||||
|
||||
about = {
|
||||
"website": "https://www.t-online.de",
|
||||
"wikidata_id": "Q590940",
|
||||
"official_api_documentation": None,
|
||||
"use_official_api": False,
|
||||
"require_api_key": False,
|
||||
"results": "HTML",
|
||||
"language": "de",
|
||||
}
|
||||
about = EngineAbout(
|
||||
website="https://www.t-online.de",
|
||||
wikidata_id="Q590940",
|
||||
results="HTML",
|
||||
)
|
||||
|
||||
paging = True
|
||||
time_range_support = True
|
||||
@@ -44,6 +41,8 @@ time_range_map = {"day": "d", "week": "w", "month": "m", "year": "y"}
|
||||
# use "tonline" to only search for results from t-online news articles
|
||||
tonline_channel_map = {"images": "flickr", "videos": "yt"}
|
||||
|
||||
language = "de"
|
||||
|
||||
|
||||
def init(_):
|
||||
if tonline_categ not in ("web", "images", "videos", "news"):
|
||||
|
||||
@@ -76,6 +76,9 @@ from lxml import html
|
||||
from searx.utils import extract_text, extract_url, eval_xpath, eval_xpath_list
|
||||
from searx.network import raise_for_httperror
|
||||
from searx.result_types import EngineResults
|
||||
from searx.enginelib import EngineAbout
|
||||
|
||||
about = EngineAbout()
|
||||
|
||||
search_url = None
|
||||
"""
|
||||
|
||||
@@ -11,6 +11,7 @@ __all__ = [
|
||||
"PROCESSORS",
|
||||
"ParamTypes",
|
||||
"RequestParams",
|
||||
"ProcessorType",
|
||||
]
|
||||
|
||||
import typing as t
|
||||
@@ -27,6 +28,14 @@ from .online_url_search import OnlineUrlSearchProcessor, OnlineUrlSearchParams
|
||||
|
||||
logger = logger.getChild("search.processors")
|
||||
|
||||
ProcessorType = t.Literal[
|
||||
"offline",
|
||||
"online",
|
||||
"online_currency",
|
||||
"online_dictionary",
|
||||
"online_url_search",
|
||||
]
|
||||
|
||||
OnlineParamTypes: t.TypeAlias = OnlineParams | OnlineDictParams | OnlineCurrenciesParams | OnlineUrlSearchParams
|
||||
OfflineParamTypes: t.TypeAlias = RequestParams
|
||||
ParamTypes: t.TypeAlias = OfflineParamTypes | OnlineParamTypes
|
||||
|
||||
+4
-4
@@ -330,12 +330,12 @@ engines:
|
||||
url_xpath: ./a/@href
|
||||
title_xpath: ./a/h3
|
||||
content_xpath: ./div
|
||||
language: "no"
|
||||
about:
|
||||
website: https://abcnyheter.no
|
||||
use_official_api: false
|
||||
require_api_key: false
|
||||
results: HTML
|
||||
language: "no"
|
||||
|
||||
- name: acfun
|
||||
engine: acfun
|
||||
@@ -2808,13 +2808,13 @@ engines:
|
||||
shortcut: rel
|
||||
categories: general
|
||||
disabled: true
|
||||
language: de
|
||||
about:
|
||||
website: https://reloado.com
|
||||
official_api_documentation:
|
||||
use_official_api: false
|
||||
require_api_key: false
|
||||
results: HTML
|
||||
language: de
|
||||
|
||||
- name: repology
|
||||
engine: repology
|
||||
@@ -2927,13 +2927,13 @@ engines:
|
||||
content_xpath: //div[@class="synonyms-list-group"]
|
||||
title_xpath: //div[@class="upper-synonyms"]/a
|
||||
no_result_for_http_status: [404]
|
||||
language: de
|
||||
about:
|
||||
website: https://www.woxikon.de/
|
||||
wikidata_id: # No Wikidata ID
|
||||
use_official_api: false
|
||||
require_api_key: false
|
||||
results: HTML
|
||||
language: de
|
||||
|
||||
- name: tootfinder
|
||||
engine: tootfinder
|
||||
@@ -2988,13 +2988,13 @@ engines:
|
||||
content_xpath: //li/div[@class="searchresult"]
|
||||
categories: general
|
||||
disabled: true
|
||||
language: fr
|
||||
about:
|
||||
website: https://wikimini.org/
|
||||
wikidata_id: Q3568032
|
||||
use_official_api: false
|
||||
require_api_key: false
|
||||
results: HTML
|
||||
language: fr
|
||||
|
||||
- name: wttr.in
|
||||
engine: wttr
|
||||
|
||||
@@ -60,8 +60,8 @@
|
||||
{%- endif -%}
|
||||
<label for="{{ engine_id }}">
|
||||
{{- ' ' -}}{{- search_engine.name -}}
|
||||
{%- if search_engine.about and search_engine.about.language -%}
|
||||
{{- ' ' -}}({{search_engine.about.language | upper}})
|
||||
{%- if search_engine.language -%}
|
||||
{{- ' ' -}}({{search_engine.language | upper}})
|
||||
{%- endif -%}
|
||||
</label>
|
||||
{{- engine_about(search_engine) -}}
|
||||
|
||||
+3
-4
@@ -1075,10 +1075,9 @@ def engine_descriptions():
|
||||
result[engine] = description
|
||||
|
||||
# overwrite by about:description (from settings)
|
||||
for engine_name, engine_mod in engines.items():
|
||||
descr = getattr(engine_mod, 'about', {}).get('description', None)
|
||||
if descr is not None:
|
||||
result[engine_name] = [descr, "SearXNG config"]
|
||||
for eng_name, eng_obj in engines.items():
|
||||
if eng_obj.about.description:
|
||||
result[eng_name] = [eng_obj.about.description, "SearXNG config"]
|
||||
|
||||
return jsonify(result)
|
||||
|
||||
|
||||
+1
-1
@@ -323,7 +323,7 @@ def group_engines_in_tab(engines: "Iterable[Engine]") -> List[Tuple[str, "Iterab
|
||||
return (group[0] == NO_SUBGROUPING, group[0].lower())
|
||||
|
||||
def engine_sort_key(engine):
|
||||
return (engine.about.get('language', ''), engine.name)
|
||||
return (engine.language, engine.name)
|
||||
|
||||
tabs = list(get_setting('categories_as_tabs').keys())
|
||||
subgroups = itertools.groupby(sorted(engines, key=get_subgroup), get_subgroup)
|
||||
|
||||
@@ -36,7 +36,7 @@ test.pylint() {
|
||||
build_msg TEST "[pylint] ./searx/engines"
|
||||
# shellcheck disable=SC2086
|
||||
pylint ${PYLINT_OPTIONS} ${PYLINT_VERBOSE} \
|
||||
--additional-builtins="traits,supported_languages,language_aliases,logger,categories" \
|
||||
--additional-builtins="traits,logger,categories" \
|
||||
searx/engines
|
||||
|
||||
build_msg TEST "[pylint] ./searx ./searxng_extra ./tests"
|
||||
|
||||
Reference in New Issue
Block a user