4 Commits

Author SHA1 Message Date
Markus Heiser
b299386d3e [fix] minor type hint issues (#5459)
Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
2025-11-20 18:35:43 +01:00
Markus Heiser
21a4622f23 [fix] utils.js_variable_to_python - partial revert of 156d1eb8c (#5458)
The JS string, whose encoding will be corrupted if all single quotes (followed
by a comma) are replaced with double quotes. Bug was introduced in PR #4573.

Here is a simple example in which the list get corrupted::

    >>> s = r"""[ 'foo\'', 'bar']"""
    >>> print(s)
    [ 'foo\'', 'bar']
    >>> print(s.replace("',", "\","))
    [ 'foo\'", 'bar']

Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
2025-11-20 18:32:27 +01:00
Bnyro
041f457dfa [fix] presearch engine: blocked by captcha on every request
Presearch responds with a Cloudflare captcha on each request when using HTTP2.
Using HTTP1.1, everything seems to work fine.

- other engines with the same issue: pixabay, uxwing
- closes https://github.com/searxng/searxng/issues/5438
2025-11-20 13:48:13 +01:00
Hermógenes Oliveira
af111e413c [fix] recoll engine: fix media preview
The results from the recoll engine were not displaying the usual
toggle for showing media previews. After the changes described bellow,
the toggle is displayed and works as expected.

In the JSON returned by recoll-webui, the field containing the
mimetype is actually `mtype`, not `mime`.

Furthermore, according to the documentation for the `File` class in
`searx/result_types/file.py`, `embedded` should contain the URL to the
media itself. The embedding of the media into the page for preview is
done in `searx/templates/simple/result_templates/file.html`.
2025-11-20 13:24:17 +01:00
5 changed files with 13 additions and 16 deletions

View File

@@ -89,6 +89,9 @@ time_range_support = True
send_accept_language_header = True
categories = ["general", "web"] # general, images, videos, news
# HTTP2 requests immediately get blocked by a CAPTCHA
enable_http2 = False
search_type = "search"
"""must be any of ``search``, ``images``, ``videos``, ``news``"""

View File

@@ -38,7 +38,7 @@ Implementations
import typing as t
from datetime import date, timedelta
from urllib.parse import urlencode, quote
from urllib.parse import urlencode
from searx.result_types import EngineResults
@@ -122,15 +122,14 @@ def response(resp: "SXNG_Response") -> EngineResults:
url = result.get("url", "").replace("file://" + mount_prefix, dl_prefix)
mtype = subtype = result.get("mime", "")
mtype = subtype = result.get("mtype", "")
if mtype:
mtype, subtype = (mtype.split("/", 1) + [""])[:2]
# facilitate preview support for known mime types
thumbnail = embedded = ""
if mtype in ["audio", "video"]:
embedded_url = '<{ttype} controls height="166px" ' + 'src="{url}" type="{mtype}"></{ttype}>'
embedded = embedded_url.format(ttype=mtype, url=quote(url.encode("utf8"), "/:"), mtype=result["mtype"])
embedded = url
if mtype in ["image"] and subtype in ["bmp", "gif", "jpeg", "png"]:
thumbnail = url

View File

@@ -30,7 +30,7 @@ import httpx
if typing.TYPE_CHECKING:
import searx.preferences
import searx.results
from searx.search.processors import ParamTypes
from searx.search.processors import OnlineParamTypes
class SXNG_Request(flask.Request):
@@ -83,4 +83,4 @@ class SXNG_Response(httpx.Response):
"""
ok: bool
search_params: "ParamTypes"
search_params: "OnlineParamTypes"

View File

@@ -35,7 +35,7 @@ class HTTPParams(t.TypedDict):
headers: dict[str, str]
"""HTTP header information."""
data: dict[str, str]
data: dict[str, str | int | dict[str, str | int]]
"""Sending `form encoded data`_.
.. _form encoded data:
@@ -56,7 +56,7 @@ class HTTPParams(t.TypedDict):
https://www.python-httpx.org/quickstart/#sending-json-encoded-data
"""
url: str
url: str | None
"""Requested url."""
cookies: dict[str, str]
@@ -200,7 +200,7 @@ class OnlineProcessor(EngineProcessor):
request_args["content"] = params["content"]
# send the request
response = req(params["url"], **request_args)
response = req(params["url"], **request_args) # pyright: ignore[reportArgumentType]
# check soft limit of the redirect count
if len(response.history) > soft_max_redirects:

View File

@@ -741,7 +741,7 @@ def detect_language(text: str, threshold: float = 0.3, only_search_languages: bo
return None
def js_variable_to_python(js_variable: str) -> str:
def js_variable_to_python(js_variable: str) -> t.Any:
"""Convert a javascript variable into JSON and then load the value
It does not deal with all cases, but it is good enough for now.
@@ -807,13 +807,8 @@ def js_variable_to_python(js_variable: str) -> str:
s = _JS_DECIMAL_RE.sub(":0.", s)
# replace the surogate character by colon
s = s.replace(chr(1), ':')
# replace single-quote followed by comma with double-quote and comma
# {"a": "\"12\"',"b": "13"}
# becomes
# {"a": "\"12\"","b": "13"}
s = s.replace("',", "\",")
# load the JSON and return the result
return json.loads(s) # pyright: ignore[reportAny]
return json.loads(s)
def parse_duration_string(duration_str: str) -> timedelta | None: