[enh] engine: rework lingva

lingva.thedaviddelta.com instance is dead, use lingva.ml
This commit is contained in:
Ivan Gabaldon
2026-03-02 21:08:34 +01:00
committed by Markus Heiser
parent 346a467077
commit 08ef7a63d7
2 changed files with 72 additions and 49 deletions

View File

@@ -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"
url = "https://lingva.thedaviddelta.com"
base_url = "https://lingva.ml"
def request(_query, params):
params['url'] = f"{url}/api/v1/{params['from_lang'][1]}/{params['to_lang'][1]}/{params['query']}"
return params
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 response(resp) -> EngineResults:
results = EngineResults()
def response(resp: "SXNG_Response") -> EngineResults:
res = EngineResults()
json_resp = resp.json()
result = resp.json()
info = result["info"]
from_to_prefix = "%s-%s " % (resp.search_params['from_lang'][1], resp.search_params['to_lang'][1])
params: "OnlineDictParams" = resp.search_params # type: ignore[assignment]
from_lang = params["from_lang"][1]
to_lang = params["to_lang"][1]
query = params["query"]
if "typo" in info:
results.append({"suggestion": from_to_prefix + info["typo"]})
translation = json_resp.get("translation")
if not translation:
return res
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})
info: dict[str, t.Any] | None = json_resp.get("info")
data = []
from_to_prefix = f"{from_lang}-{to_lang} "
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'],
translations: list[EngineResults.types.Translations.Item] = []
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

View File

@@ -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