From 9076fbcc0b950a86d5bd6c587ce2ae01872a5e7a Mon Sep 17 00:00:00 2001 From: Dicken Date: Thu, 11 Jun 2026 02:01:35 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20xREL=20leere=20Cache-Eintr=C3=A4ge=20bei?= =?UTF-8?q?=20manuellem=20Suchen=20ignorieren,=20Titel=20als=20Query-Param?= =?UTF-8?q?s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/tools/media/routes.js | 31 ++++++++++++++++++++++--------- frontend/src/tools/media.jsx | 10 ++++++++-- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/backend/src/tools/media/routes.js b/backend/src/tools/media/routes.js index a2747a2..6754f5e 100644 --- a/backend/src/tools/media/routes.js +++ b/backend/src/tools/media/routes.js @@ -244,7 +244,7 @@ router.get('/movie/:id', authenticate, async (req, res) => { } catch(e) { res.status(500).json({ error: e.message }); } }); -// xREL on-demand – ?refresh=1 ignoriert den Cache (erneute Suche) +// xREL on-demand – ?refresh=1 ignoriert Cache, ?imdb_id=tt...&title=...&orig=... vermeidet TMDb-Calls router.get('/movie/:id/xrel', authenticate, async (req, res) => { try { const cacheKey = `xrel:tmdb:${req.params.id}`; @@ -252,18 +252,31 @@ router.get('/movie/:id/xrel', authenticate, async (req, res) => { if (!forceRefresh) { const cached = cacheGet(cacheKey); - if (cached !== undefined) return res.json({ xrel: cached, has_xrel: cached.length > 0 }); + // Nur nicht-leere Cache-Einträge sofort zurückgeben + // Leere Einträge → nochmal suchen (könnte Rate-Limit-Artefakt sein) + if (cached !== undefined && cached.length > 0) { + return res.json({ xrel: cached, has_xrel: true }); + } } else { - // Cache-Eintrag löschen für diesen Film db.prepare('DELETE FROM xrel_cache WHERE cache_key=?').run(cacheKey); } - const [detail, extIds] = await Promise.all([ - tmdb(`/movie/${req.params.id}`, { append_to_response: '' }).catch(()=>({})), - tmdb(`/movie/${req.params.id}/external_ids`).catch(()=>({})), - ]); - const imdbId = extIds.imdb_id || null; - const xrel = await getXrelData(req.params.id, imdbId, detail.title, detail.original_title); + // Titel + IMDb-ID aus Query-Params wenn vorhanden (spart 2 TMDb-Calls) + let imdbId = req.query.imdb_id || null; + let title = req.query.title || null; + let origTitle = req.query.orig || null; + + if (!title) { + const [detail, extIds] = await Promise.all([ + tmdb(`/movie/${req.params.id}`, { append_to_response: '' }).catch(()=>({})), + tmdb(`/movie/${req.params.id}/external_ids`).catch(()=>({})), + ]); + imdbId = extIds.imdb_id || null; + title = detail.title || null; + origTitle = detail.original_title || null; + } + + const xrel = await getXrelData(req.params.id, imdbId, title, origTitle); res.json({ xrel, has_xrel: xrel.length > 0 }); } catch(e) { res.status(500).json({ error: e.message }); } }); diff --git a/frontend/src/tools/media.jsx b/frontend/src/tools/media.jsx index 296b96d..f95f683 100644 --- a/frontend/src/tools/media.jsx +++ b/frontend/src/tools/media.jsx @@ -456,10 +456,16 @@ function MovieModal({ tmdbId, onClose, mobile, onHasXrel }) { }, [tmdbId]); const searchXrel = async (refresh = false) => { + if (!detail) return; setXrelLoading(true); try { - const url = `/tools/media/movie/${tmdbId}/xrel${refresh ? '?refresh=1' : ''}`; - const d = await api(url); + const params = new URLSearchParams({ + title: detail.title || '', + orig: detail.original_title || '', + imdb_id: detail.imdb_id || '', + }); + if (refresh) params.set('refresh', '1'); + const d = await api(`/tools/media/movie/${tmdbId}/xrel?${params}`); setXrel(d.xrel || []); if (d.has_xrel) onHasXrel?.(tmdbId); } catch(_) { setXrel([]); }