summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Gabaldon <igabaldon@inetol.net>2026-03-02 21:08:34 +0100
committerMarkus Heiser <markus.heiser@darmarIT.de>2026-04-07 15:49:46 +0200
commit08ef7a63d7ffd278dddd68cbb643f30d969a4329 (patch)
tree2eee0e7423aff824687ca1094dfb13ed9e30018e
parent346a46707701fe543ecd15da32ee5e209545e326 (diff)
[enh] engine: rework lingva
lingva.thedaviddelta.com instance is dead, use lingva.ml
-rw-r--r--searx/engines/lingva.py120
-rw-r--r--searx/settings.yml3
2 files changed, 73 insertions, 50 deletions
diff --git a/searx/engines/lingva.py b/searx/engines/lingva.py
index 156e37d89..c0ca14b10 100644
--- a/searx/engines/lingva.py
+++ b/searx/engines/lingva.py
@@ -1,74 +1,96 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
-"""Lingva (alternative Google Translate frontend)"""
+"""`Lingva Translate`_ is an alternative front-end for Google Translate,
+serving as a free and open source translator with over a hundred
+languages available.
+
+.. _Lingva Translate: https://github.com/thedaviddelta/lingva-translate
+"""
+
+import typing as t
from searx.result_types import EngineResults
-about = {
- "website": 'https://lingva.ml',
+if t.TYPE_CHECKING:
+ from searx.extended_types import SXNG_Response
+ from searx.search.processors.online_dictionary import OnlineDictParams
+
+about: dict[str, t.Any] = {
+ "website": "https://github.com/thedaviddelta/lingva-translate",
"wikidata_id": None,
- "official_api_documentation": 'https://github.com/thedaviddelta/lingva-translate#public-apis',
+ "official_api_documentation": "https://github.com/thedaviddelta/lingva-translate#public-apis",
"use_official_api": True,
"require_api_key": False,
- "results": 'JSON',
+ "results": "JSON",
}
-engine_type = 'online_dictionary'
-categories = ['general', 'translate']
+categories: list[str] = ["general", "translate"]
+engine_type = "online_dictionary"
+
+base_url = "https://lingva.ml"
+
-url = "https://lingva.thedaviddelta.com"
+def request(_query: str, params: "OnlineDictParams") -> None:
+ from_lang = params["from_lang"][1]
+ to_lang = params["to_lang"][1]
+ query = params["query"]
+ params["url"] = f"{base_url}/api/v1/{from_lang}/{to_lang}/{query}"
-def request(_query, params):
- params['url'] = f"{url}/api/v1/{params['from_lang'][1]}/{params['to_lang'][1]}/{params['query']}"
- return params
+def response(resp: "SXNG_Response") -> EngineResults:
+ res = EngineResults()
+ json_resp = resp.json()
-def response(resp) -> EngineResults:
- results = EngineResults()
+ params: "OnlineDictParams" = resp.search_params # type: ignore[assignment]
+ from_lang = params["from_lang"][1]
+ to_lang = params["to_lang"][1]
+ query = params["query"]
- result = resp.json()
- info = result["info"]
- from_to_prefix = "%s-%s " % (resp.search_params['from_lang'][1], resp.search_params['to_lang'][1])
+ translation = json_resp.get("translation")
+ if not translation:
+ return res
- if "typo" in info:
- results.append({"suggestion": from_to_prefix + info["typo"]})
+ info: dict[str, t.Any] | None = json_resp.get("info")
- if 'definitions' in info: # pylint: disable=too-many-nested-blocks
- for definition in info['definitions']:
- for item in definition.get('list', []):
- for synonym in item.get('synonyms', []):
- results.append({"suggestion": from_to_prefix + synonym})
+ from_to_prefix = f"{from_lang}-{to_lang} "
- data = []
+ translations: list[EngineResults.types.Translations.Item] = []
- for definition in info['definitions']:
- for translation in definition['list']:
- data.append(
- results.types.Translations.Item(
- text=result['translation'],
- definitions=[translation['definition']] if translation['definition'] else [],
- examples=[translation['example']] if translation['example'] else [],
- synonyms=translation['synonyms'],
+ if info:
+ if "typo" in info:
+ res.add(res.types.LegacyResult(suggestion=from_to_prefix + info["typo"]))
+
+ for definition in info.get("definitions", []):
+ for item in definition.get("list", []):
+ for synonym in item.get("synonyms", []):
+ res.add(res.types.LegacyResult(suggestion=from_to_prefix + synonym))
+
+ translations.append(
+ EngineResults.types.Translations.Item(
+ text=translation,
+ definitions=[item["definition"]] if item.get("definition") else [],
+ examples=[item["example"]] if item.get("example") else [],
+ synonyms=item.get("synonyms", []),
+ )
)
- )
-
- for translation in info["extraTranslations"]:
- for word in translation["list"]:
- data.append(
- results.types.Translations.Item(
- text=word['word'],
- definitions=word['meanings'],
+
+ for extra_translation in info.get("extraTranslations", []):
+ for word in extra_translation.get("list", []):
+ translations.append(
+ EngineResults.types.Translations.Item(
+ text=word["word"],
+ definitions=word.get("meanings", []),
+ )
)
- )
- if not data and result['translation']:
- data.append(results.types.Translations.Item(text=result['translation']))
+ if not translations:
+ translations.append(EngineResults.types.Translations.Item(text=translation))
- params = resp.search_params
- results.add(
- results.types.Translations(
- translations=data,
- url=f"{url}/{params['from_lang'][1]}/{params['to_lang'][1]}/{params['query']}",
+ res.add(
+ res.types.Translations(
+ translations=translations,
+ url=f"{base_url}/{from_lang}/{to_lang}/{query}",
)
)
- return results
+
+ return res
diff --git a/searx/settings.yml b/searx/settings.yml
index 225cdfed1..eff8839d2 100644
--- a/searx/settings.yml
+++ b/searx/settings.yml
@@ -1310,8 +1310,9 @@ engines:
- name: lingva
engine: lingva
shortcut: lv
+ timeout: 6.0
# set lingva instance in url, by default it will use the official instance
- # url: https://lingva.thedaviddelta.com
+ # url: https://lingva.ml
- name: lobste.rs
engine: xpath