[mod] brave-based engines: reuse result parsing methods (#6688)

Many engines use the JSON results from Brave (e.g. Brave, BraveAPI, Tusksearch
and more), so the result parsing logic is always the same. This PR deduplicates
this code.
This commit is contained in:
Bnyro
2026-09-10 12:32:22 +02:00
committed by Markus Heiser
parent 2ed96e6fcf
commit 4d9c982cda
3 changed files with 36 additions and 107 deletions

View File

@@ -9,12 +9,11 @@ from json import loads
import random
import typing as t
from urllib.parse import urlencode
from dateutil import parser
from searx.result_types import EngineResults
from searx.engines.brave import parse_image_result, parse_news_result, parse_search_result, parse_video_result
from searx.exceptions import SearxEngineAPIException
from searx.network import get
from searx.utils import html_to_text
from searx.result_types import EngineResults
if t.TYPE_CHECKING:
from searx.extended_types import SXNG_Response
@@ -32,7 +31,8 @@ about = {
paging = True
categories = ["general"]
tusk_categ = "web"
TuskCategType = t.Literal["web", "images", "videos", "news"]
tusk_categ: TuskCategType = "web"
"""Category to search in. Can be either "web", "images", "videos" or "news"."""
@@ -40,7 +40,7 @@ api_url = "https://api.tusksearch.com"
def setup(_: dict[str, t.Any]) -> bool | None:
if tusk_categ not in ("web", "images", "videos", "news"):
if tusk_categ not in t.get_args(TuskCategType):
raise ValueError("invalid search type: %s" % tusk_categ)
@@ -103,64 +103,24 @@ def request(query: str, params: "OnlineParams") -> None:
def response(resp: "SXNG_Response"):
res = EngineResults()
json_resp = resp.json()["results"]
if tusk_categ == "web":
for result in (json_resp.get("web") or {}).get("results", []):
res.add(
res.types.MainResult(
url=result["url"],
title=html_to_text(result["title"]),
content=html_to_text(result["description"]),
thumbnail=(result["thumbnail"] or {}).get("src") or "",
)
)
elif tusk_categ == "news":
for result in (json_resp.get("news") or {}).get("results", []):
publishedDate = None
try:
publishedDate = parser.parse(result["age"])
except parser.ParserError:
pass
res.add(
res.types.MainResult(
url=result["url"],
title=html_to_text(result["title"]),
content=html_to_text(result["description"]),
thumbnail=result["thumbnail"]["src"],
publishedDate=publishedDate,
)
)
elif tusk_categ == "videos":
for result in (json_resp.get("videos") or {}).get("results", []):
publishedDate = None
try:
publishedDate = parser.parse(result["age"])
except parser.ParserError:
pass
res.add(
res.types.Video(
url=result["url"],
title=html_to_text(result["title"]),
content=html_to_text(result["description"]),
thumbnail=result["thumbnail"]["src"],
publishedDate=publishedDate,
length=result["video"].get("duration"),
)
)
elif tusk_categ == "images":
for result in json_resp:
res.add(
res.types.Image(
url=result["url"],
title=html_to_text(result["title"]),
img_src=result["properties"]["url"],
thumbnail_src=result["thumbnail"]["src"],
)
)
res = EngineResults()
match tusk_categ:
case "web":
results = (json_resp.get("web") or {}).get("results", [])
for result in results:
res.add(parse_search_result(result))
case "news":
results = (json_resp.get("news") or {}).get("results", [])
for result in results:
res.add(parse_news_result(result))
case "videos":
results = (json_resp.get("videos") or {}).get("results", [])
for result in results:
res.add(parse_video_result(result))
case "images":
for result in json_resp:
res.add(parse_image_result(result))
return res