From 98265883ac8c9411482f9da48f0bca4395511c95 Mon Sep 17 00:00:00 2001 From: Dicken Date: Sat, 4 Jul 2026 14:03:24 +0200 Subject: [PATCH] feat: Media Streaming - Admin Cache-Clear Button pro Anbieter --- backend/src/tools/media/routes.js | 14 +++++++++++++- frontend/src/tools/media.jsx | 31 +++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/backend/src/tools/media/routes.js b/backend/src/tools/media/routes.js index 6cf1419..73d3b7e 100644 --- a/backend/src/tools/media/routes.js +++ b/backend/src/tools/media/routes.js @@ -34,6 +34,9 @@ function cacheSet(key, value, ttlMs = 12 * 60 * 60 * 1000) { db.prepare('INSERT OR REPLACE INTO xrel_cache (cache_key,value,expires_at) VALUES (?,?,?)') .run(key, JSON.stringify(value), Date.now() + ttlMs); } +function cacheDelete(key) { + db.prepare('DELETE FROM xrel_cache WHERE cache_key=?').run(key); +} // ── TMDb ────────────────────────────────────────────────────────────────────── function getToken() { @@ -666,6 +669,15 @@ router.get('/streaming/:providerId/new', authenticate, async (req, res) => { } catch(e) { res.status(500).json({ error: e.message }); } }); +// ── Cache leeren für einen Provider (Admin) ────────────────────────────────── +router.post('/streaming/:providerId/clear-cache', authenticate, requireAdmin, (req, res) => { + const provider = STREAMING_PROVIDERS.find(p => p.id === req.params.providerId); + if (!provider) return res.status(404).json({ error: 'Unbekannter Anbieter' }); + cacheDelete(`streaming-top10:${provider.id}`); + cacheDelete(`streaming-new:${provider.id}`); + res.json({ ok: true, provider: provider.id }); +}); + router.get('/streaming/:providerId', authenticate, async (req, res) => { try { const provider = STREAMING_PROVIDERS.find(p => p.id === req.params.providerId); @@ -678,7 +690,7 @@ router.get('/streaming/:providerId', authenticate, async (req, res) => { // Nur Titel der letzten 2 Jahre (aktuelles Jahr - 1) // Für kleine Kataloge (HBO Max, WOW, RTL+) kein Jahresfilter — TMDb hat dort // zu wenige Titel mit korrekt erfasstem DE-Datum seit letztem Jahr - const SMALL_CATALOGS = new Set(['max', 'wow', 'rtlplus']); + const SMALL_CATALOGS = new Set(['max']); const minYear = new Date().getFullYear() - 1; const minDate = SMALL_CATALOGS.has(provider.id) ? null : `${minYear}-01-01`; diff --git a/frontend/src/tools/media.jsx b/frontend/src/tools/media.jsx index 4ef0b2f..b4b24bd 100644 --- a/frontend/src/tools/media.jsx +++ b/frontend/src/tools/media.jsx @@ -459,6 +459,28 @@ function StreamingGrid({ onOpenModal, xrelIds, onXrelLoaded, favIds: favIdsProp, const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(''); + const [clearing, setClearing] = useState(false); + + const isAdmin = (() => { + try { return JSON.parse(atob(localStorage.getItem('sk_token').split('.')[1])).role === 'admin'; } + catch { return false; } + })(); + + const clearCache = async () => { + if (!activeProvider || clearing) return; + setClearing(true); + try { + await api(`/tools/media/streaming/${activeProvider}/clear-cache`, { method:'POST', body:{} }); + // Neu laden + setData(null); setLoading(true); + const path = subTab === 'new' + ? `/tools/media/streaming/${activeProvider}/new` + : `/tools/media/streaming/${activeProvider}`; + const d = await api(path); + setData(d); + } catch(e) { setError(e.message); } + finally { setClearing(false); setLoading(false); } + }; useEffect(() => { api('/tools/media/streaming/providers') @@ -498,6 +520,15 @@ function StreamingGrid({ onOpenModal, xrelIds, onXrelLoaded, favIds: favIdsProp, }}>🆕 Neuerscheinungen + {isAdmin && activeProvider && ( + + )} + {subTab === 'top10' ? (
Top 10 Filme & Serien pro Anbieter (DE) · nur Titel ab {new Date().getFullYear()-1} · sortiert nach Popularität (Näherung, keine offiziellen Anbieter-Daten)