diff --git a/backend/src/tools/media/routes.js b/backend/src/tools/media/routes.js index 14753f1..e674982 100644 --- a/backend/src/tools/media/routes.js +++ b/backend/src/tools/media/routes.js @@ -246,26 +246,28 @@ router.get('/movie/:id', authenticate, async (req, res) => { }); // POST /api/tools/media/xrel-check – Check ob deutsche Releases existieren -// Nimmt max 5 Filme pro Request (Frontend schickt mehrere kleine Batches) +// Filme EINZELN sequenziell prüfen um xREL Rate-Limit zu respektieren router.post('/xrel-check', authenticate, async (req, res) => { const movies = (req.body.movies || []).slice(0, 5); if (!movies.length) return res.json({}); const result = {}; - await Promise.all(movies.map(async m => { + for (const m of movies) { try { const extInfoId = await findExtInfoId(m.title, m.original_title); - if (!extInfoId) { result[m.id] = false; return; } + if (!extInfoId) { result[m.id] = false; continue; } // 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; } + if ((p2p.list || []).some(r => r.main_lang === 'german')) { result[m.id] = true; continue; } // 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; } - })); + // Kurze Pause zwischen Filmen – xREL Rate-Limit + await new Promise(r => setTimeout(r, 400)); + } res.json(result); }); diff --git a/frontend/src/tools/media.jsx b/frontend/src/tools/media.jsx index 5cb1166..02e2e88 100644 --- a/frontend/src/tools/media.jsx +++ b/frontend/src/tools/media.jsx @@ -271,10 +271,10 @@ function KinoGrid({ onOpenModal }) { let cancelled = false; const moviesMeta = movies.map(m => ({ id: m.id, title: m.title, original_title: m.original_title })); (async () => { - for (let i = 0; i < moviesMeta.length; i += 5) { + for (let i = 0; i < moviesMeta.length; i += 1) { if (cancelled) break; try { - const chunk = moviesMeta.slice(i, i + 5); + const chunk = moviesMeta.slice(i, i + 1); const result = await api('/tools/media/xrel-check', { method:'POST', body:{ movies: chunk } }); if (cancelled) break; const hits = Object.entries(result).filter(([,v]) => v).map(([k]) => Number(k)); @@ -340,10 +340,10 @@ function DemnächstGrid({ onOpenModal }) { let cancelled = false; const moviesMeta = allMovies.map(m => ({ id: m.id, title: m.title, original_title: m.original_title })); (async () => { - for (let i = 0; i < moviesMeta.length; i += 5) { + for (let i = 0; i < moviesMeta.length; i += 1) { if (cancelled) break; try { - const chunk = moviesMeta.slice(i, i + 5); + const chunk = moviesMeta.slice(i, i + 1); const result = await api('/tools/media/xrel-check', { method:'POST', body:{ movies: chunk } }); if (cancelled) break; const hits = Object.entries(result).filter(([,v]) => v).map(([k]) => Number(k));