diff options
| author | Ivan Gabaldon <igabaldon@inetol.net> | 2026-03-02 21:08:34 +0100 |
|---|---|---|
| committer | Markus Heiser <markus.heiser@darmarIT.de> | 2026-04-07 15:49:46 +0200 |
| commit | 08ef7a63d7ffd278dddd68cbb643f30d969a4329 (patch) | |
| tree | 2eee0e7423aff824687ca1094dfb13ed9e30018e | |
| parent | 346a46707701fe543ecd15da32ee5e209545e326 (diff) | |
[enh] engine: rework lingva
lingva.thedaviddelta.com instance is dead, use lingva.ml
| -rw-r--r-- | searx/engines/lingva.py | 120 | ||||
| -rw-r--r-- | searx/settings.yml | 3 |
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 |
