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