diff --git a/backend/src/tools/media/routes.js b/backend/src/tools/media/routes.js index 26034c1..1af456f 100644 --- a/backend/src/tools/media/routes.js +++ b/backend/src/tools/media/routes.js @@ -253,33 +253,27 @@ router.get('/movie/:id', authenticate, async (req, res) => { } catch (e) { res.status(500).json({ error: e.message }); } }); -// POST /api/tools/media/xrel-check – Cover-Badge Batch-Check +// POST /api/tools/media/xrel-check – Check ob deutsche Releases existieren +// Nimmt max 5 Filme pro Request (Frontend schickt mehrere kleine Batches) router.post('/xrel-check', authenticate, async (req, res) => { - const movies = (req.body.movies || []).slice(0, 20); + const movies = (req.body.movies || []).slice(0, 5); if (!movies.length) return res.json({}); const result = {}; - // 3er-Batches - for (let i = 0; i < movies.length; i += 3) { - const chunk = movies.slice(i, i + 3); - await Promise.all(chunk.map(async m => { - try { - const extInfoId = await findExtInfoId(m.title, m.original_title); - if (!extInfoId) { result[m.id] = false; return; } - // Schnell-Check: nur P2P Seite 1 prüfen ob german vorhanden - const p2p = await xrelFetch('/p2p/releases.json', { ext_info_id: extInfoId, per_page: 25 }); - const p2pHit = (p2p.list || []).some(r => r.main_lang === 'german'); - if (p2pHit) { result[m.id] = true; return; } - // Auch Scene prüfen - const scene = await xrelFetch('/release/ext_info.json', { id: extInfoId, per_page: 25 }); - const sceneHit = (scene.list || []).some(r => /german|deutsch/i.test(r.dirname || '')); - result[m.id] = sceneHit; - } catch (_) { - result[m.id] = false; - } - })); - if (i + 3 < movies.length) await new Promise(r => setTimeout(r, 250)); - } + await Promise.all(movies.map(async m => { + try { + const extInfoId = await findExtInfoId(m.title, m.original_title); + if (!extInfoId) { result[m.id] = false; return; } + // P2P zuerst – main_lang ist zuverlässig + const p2p = await xrelFetch('/p2p/releases.json', { ext_info_id: extInfoId, per_page: 25 }, 8000); + if ((p2p.list || []).some(r => r.main_lang === 'german')) { result[m.id] = true; return; } + // Scene als Fallback + const scene = await xrelFetch('/release/ext_info.json', { id: extInfoId, per_page: 25 }, 8000); + result[m.id] = (scene.list || []).some(r => /german|deutsch/i.test(r.dirname || '')); + } catch (_) { + result[m.id] = false; + } + })); res.json(result); }); diff --git a/frontend/src/tools/media.jsx b/frontend/src/tools/media.jsx index 05c356f..4d00885 100644 --- a/frontend/src/tools/media.jsx +++ b/frontend/src/tools/media.jsx @@ -261,13 +261,19 @@ function KinoGrid({ onOpenModal }) { api('/tools/media/now-playing') .then(list => { setMovies(list); - // xREL-Batch-Check nach Laden - api('/tools/media/xrel-check', { - method: 'POST', - body: { movies: list.map(m => ({ id: m.id, title: m.title, original_title: m.original_title, release_date: m.release_date })) } - }).then(result => { - setXrelIds(new Set(Object.entries(result).filter(([,v]) => v).map(([k]) => Number(k)))); - }).catch(() => {}); + // xREL-Badge: progressive 5er-Batches + const moviesMeta = list.map(m => ({ id: m.id, title: m.title, original_title: m.original_title })); + for (let i = 0; i < moviesMeta.length; i += 5) { + const chunk = moviesMeta.slice(i, i + 5); + api('/tools/media/xrel-check', { method:'POST', body:{ movies: chunk } }) + .then(result => { + setXrelIds(prev => { + const next = new Set(prev); + Object.entries(result).forEach(([k,v]) => { if (v) next.add(Number(k)); }); + return next; + }); + }).catch(() => {}); + } }) .catch(e => setError(e.message)) .finally(() => setLoading(false)); @@ -320,12 +326,18 @@ function DemnächstGrid({ onOpenModal }) { .then(grps => { setGroups(grps); const allMovies = Object.values(grps).flat(); - api('/tools/media/xrel-check', { - method: 'POST', - body: { movies: allMovies.map(m => ({ id: m.id, title: m.title, original_title: m.original_title, release_date: m.release_date })) } - }).then(result => { - setXrelIds(new Set(Object.entries(result).filter(([,v]) => v).map(([k]) => Number(k)))); - }).catch(() => {}); + const moviesMeta = allMovies.map(m => ({ id: m.id, title: m.title, original_title: m.original_title })); + for (let i = 0; i < moviesMeta.length; i += 5) { + const chunk = moviesMeta.slice(i, i + 5); + api('/tools/media/xrel-check', { method:'POST', body:{ movies: chunk } }) + .then(result => { + setXrelIds(prev => { + const next = new Set(prev); + Object.entries(result).forEach(([k,v]) => { if (v) next.add(Number(k)); }); + return next; + }); + }).catch(() => {}); + } }) .catch(e => setError(e.message)) .finally(() => setLoading(false)); @@ -594,30 +606,23 @@ function MovieModal({ tmdbId, onClose, mobile }) {