handle redirection for thumbnails.

This commit is contained in:
arabcoders 2025-08-27 19:52:35 +03:00
parent 19b78c9564
commit 283ed74f71
5 changed files with 41 additions and 11 deletions

View file

@ -43,19 +43,19 @@ async def get_thumbnail(request: Request, config: Config) -> Response:
return web.json_response(data={"error": str(e)}, status=web.HTTPForbidden.status_code)
try:
ytdlp_args = config.get_ytdlp_args()
opts = {
"proxy": ytdlp_args.get("proxy", None),
"headers": {
"User-Agent": ytdlp_args.get(
"user_agent", request.headers.get("User-Agent", random_user_agent())
),
"User-Agent": ytdlp_args.get("user_agent", request.headers.get("User-Agent", random_user_agent())),
},
}
async with httpx.AsyncClient(**opts) as client:
LOG.debug(f"Fetching thumbnail from '{url}'.")
response = await client.request(method="GET", url=url)
response = await client.request(method="GET", url=url, follow_redirects=True)
return web.Response(
body=response.content,
headers={
@ -122,6 +122,17 @@ async def get_background(request: Request, config: Config, cache: Cache) -> Resp
"User-Agent": ytdlp_args.get("user_agent", random_user_agent()),
},
}
try:
from httpx_curl_cffi import AsyncCurlTransport, CurlOpt
opts["transport"] = AsyncCurlTransport(
impersonate="chrome",
default_headers=True,
curl_options={CurlOpt.FRESH_CONNECT: True},
)
opts.pop("headers", None)
except Exception:
pass
async with httpx.AsyncClient(**opts) as client:
if backend.startswith("https://www.bing.com/HPImageArchive.aspx"):

View file

@ -39,6 +39,7 @@ dependencies = [
"apprise>=1.9.3",
"bgutil-ytdlp-pot-provider>=1.2.1",
"pycryptodome>=3.23.0",
"httpx-curl-cffi>=0.1.4",
]
[tool.ruff]

View file

@ -118,7 +118,8 @@
</span>
</div>
<div v-if="showThumbnails && item.extras.thumbnail">
<FloatingImage :image="uri('/api/thumbnail?url=' + encodePath(item.extras.thumbnail))"
<FloatingImage
:image="uri('/api/thumbnail?id=' + item._id + '&url=' + encodePath(item.extras.thumbnail))"
:title="`[${item.preset}] - ${item.title}`">
<div class="is-text-overflow">
<NuxtLink target="_blank" :href="item.url">{{ item.title }}</NuxtLink>
@ -276,20 +277,21 @@
<figure class="image is-3by1">
<span v-if="'finished' === item.status && item.filename" @click="playVideo(item)" class="play-overlay">
<div class="play-icon"></div>
<img @load="e => pImg(e)" :src="uri('/api/thumbnail?url=' + encodePath(item.extras.thumbnail))"
<img @load="e => pImg(e)"
:src="uri('/api/thumbnail?id=' + item._id + '&url=' + encodePath(item.extras.thumbnail))"
v-if="item.extras?.thumbnail" />
<img v-else src="/images/placeholder.png" />
</span>
<span v-else-if="isEmbedable(item.url)" @click="embed_url = getEmbedable(item.url) as string"
class="play-overlay">
<div class="play-icon embed-icon"></div>
<img @load="e => pImg(e)" :src="uri('/api/thumbnail?url=' + encodePath(item.extras.thumbnail))"
<img @load="e => pImg(e)" :src="uri('/api/thumbnail?id=' + item._id + '&url=' + encodePath(item.extras.thumbnail))"
v-if="item.extras?.thumbnail" />
<img v-else src="/images/placeholder.png" />
</span>
<template v-else>
<img @load="e => pImg(e)" v-if="item.extras?.thumbnail"
:src="uri('/api/thumbnail?url=' + encodePath(item.extras.thumbnail))" />
:src="uri('/api/thumbnail?id=' + item._id + '&url=' + encodePath(item.extras.thumbnail))" />
<img v-else src="/images/placeholder.png" />
</template>
</figure>

View file

@ -84,7 +84,7 @@
</span>
</div>
<div v-if="showThumbnails && item.extras?.thumbnail">
<FloatingImage :image="uri('/api/thumbnail?url=' + encodePath(item.extras.thumbnail))"
<FloatingImage :image="uri('/api/thumbnail?id=' + item._id + '&url=' + encodePath(item.extras.thumbnail))"
:title="item.title">
<div class="is-text-overflow">
<NuxtLink target="_blank" :href="item.url">{{ item.title }}</NuxtLink>
@ -206,13 +206,13 @@
<span v-if="isEmbedable(item.url)" @click="embed_url = getEmbedable(item.url) as string"
class="play-overlay">
<div class="play-icon embed-icon"></div>
<img @load="e => pImg(e)" :src="uri('/api/thumbnail?url=' + encodePath(item.extras.thumbnail))"
<img @load="e => pImg(e)" :src="uri('/api/thumbnail?id=' + item._id + '&url=' + encodePath(item.extras.thumbnail))"
v-if="item.extras?.thumbnail" />
<img v-else src="/images/placeholder.png" />
</span>
<template v-else>
<img @load="e => pImg(e)" v-if="item.extras?.thumbnail"
:src="uri('/api/thumbnail?url=' + encodePath(item.extras.thumbnail))" />
:src="uri('/api/thumbnail?id=' + item._id + '&url=' + encodePath(item.extras.thumbnail))" />
<img v-else src="/images/placeholder.png" />
</template>
</figure>

16
uv.lock
View file

@ -591,6 +591,20 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517 },
]
[[package]]
name = "httpx-curl-cffi"
version = "0.1.4"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "curl-cffi" },
{ name = "httpx" },
{ name = "typing-extensions" },
]
sdist = { url = "https://files.pythonhosted.org/packages/11/e9/42542f3f4bf9ba457f10dda6620dc3f56e77480722c67579a35956c5d2e2/httpx_curl_cffi-0.1.4.tar.gz", hash = "sha256:1e00b741b121b3781942d45781288f89842f41fe32a743e27672d7fc542c1cd1", size = 7907 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/d5/25/7a093edd86d0ea2cc0ff5570f74b00c603ce100303031a77f7d9db9aa80a/httpx_curl_cffi-0.1.4-py3-none-any.whl", hash = "sha256:bbd6e89abbf26a37c436d9a3d2c55ae646b78b0dcf4bc1be2f2451912e39d7b6", size = 8913 },
]
[[package]]
name = "humanfriendly"
version = "10.0"
@ -1394,6 +1408,7 @@ dependencies = [
{ name = "debugpy" },
{ name = "defusedxml" },
{ name = "httpx" },
{ name = "httpx-curl-cffi" },
{ name = "multidict" },
{ name = "mutagen" },
{ name = "platformdirs" },
@ -1432,6 +1447,7 @@ requires-dist = [
{ name = "debugpy", specifier = ">=1.8.1" },
{ name = "defusedxml", specifier = ">=0.7.1" },
{ name = "httpx" },
{ name = "httpx-curl-cffi", specifier = ">=0.1.4" },
{ name = "multidict", specifier = "==6.5.1" },
{ name = "mutagen" },
{ name = "platformdirs" },