fix: Badge=Release-Cache unified, 3er-Batches parallel, COMPLETE.BLURAY filter korrekt
This commit is contained in:
@@ -262,48 +262,22 @@ router.get('/movie/:id/xrel', authenticate, async (req, res) => {
|
|||||||
} catch(e) { res.status(500).json({ error: e.message }); }
|
} catch(e) { res.status(500).json({ error: e.message }); }
|
||||||
});
|
});
|
||||||
|
|
||||||
// Badge-Check: nur prüfen ob ext_info_id existiert (1 Call statt 3)
|
// Badge-Check: bis zu 3 Filme parallel, cached in xrel:tmdb:ID
|
||||||
// Volle Releases werden erst beim Modal-Öffnen geladen
|
|
||||||
router.post('/xrel-check', authenticate, async (req, res) => {
|
router.post('/xrel-check', authenticate, async (req, res) => {
|
||||||
const movies = (req.body.movies||[]).slice(0,1);
|
const movies = (req.body.movies||[]).slice(0,3);
|
||||||
if (!movies.length) return res.json({});
|
if (!movies.length) return res.json({});
|
||||||
const m = movies[0];
|
|
||||||
|
|
||||||
// Wenn volle Daten bereits gecacht: sofort antworten
|
|
||||||
const fullCacheKey = `xrel:tmdb:${m.id}`;
|
|
||||||
const fullCached = cacheGet(fullCacheKey);
|
|
||||||
if (fullCached !== undefined) return res.json({ [m.id]: fullCached.length > 0 });
|
|
||||||
|
|
||||||
// Sonst: nur ext_info_id suchen (Badge-only Cache, 6h)
|
|
||||||
const badgeCacheKey = `xrel:badge:${m.id}`;
|
|
||||||
const badgeCached = cacheGet(badgeCacheKey);
|
|
||||||
if (badgeCached !== undefined) return res.json({ [m.id]: badgeCached });
|
|
||||||
|
|
||||||
|
const result = {};
|
||||||
|
await Promise.all(movies.map(async m => {
|
||||||
|
const cacheKey = `xrel:tmdb:${m.id}`;
|
||||||
|
const cached = cacheGet(cacheKey);
|
||||||
|
if (cached !== undefined) { result[m.id] = cached.length > 0; return; }
|
||||||
try {
|
try {
|
||||||
const clean = (s) => (s||'').replace(/[*#!?:]/g,'').trim().toLowerCase();
|
const xrel = await getXrelData(m.id, m.imdb_id||null, m.title, m.original_title);
|
||||||
const queries = [m.original_title, m.title].filter(Boolean).filter((v,i,a) => a.indexOf(v)===i);
|
result[m.id] = xrel.length > 0;
|
||||||
const searchResults = await Promise.all(queries.map(async q => {
|
} catch(_) { result[m.id] = false; }
|
||||||
try { return await xrelFetch('/search/ext_info.json', { q: q.replace(/[*#!?:]/g,''), type:'movie', limit:10 }); }
|
|
||||||
catch(_) { return null; }
|
|
||||||
}));
|
}));
|
||||||
|
res.json(result);
|
||||||
let found = false;
|
|
||||||
// IMDb match
|
|
||||||
if (m.imdb_id) {
|
|
||||||
for (const data of searchResults) {
|
|
||||||
if ((data?.results||[]).some(h => (h.uris||[]).includes(`imdb:${m.imdb_id}`))) { found = true; break; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Titel-match Fallback
|
|
||||||
if (!found) {
|
|
||||||
for (const data of searchResults) {
|
|
||||||
if ((data?.results||[]).some(h => clean(h.title)===clean(queries[0]) || clean(h.alt_title)===clean(queries[0]))) { found = true; break; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cacheSet(badgeCacheKey, found, 6*60*60*1000);
|
|
||||||
res.json({ [m.id]: found });
|
|
||||||
} catch(_) { res.json({ [m.id]: false }); }
|
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get('/favorites', authenticate, (req, res) => {
|
router.get('/favorites', authenticate, (req, res) => {
|
||||||
|
|||||||
@@ -303,12 +303,13 @@ function KinoGrid({ onOpenModal }) {
|
|||||||
const moviesMeta = movies.map(m => ({ id: m.id, title: m.title, original_title: m.original_title }));
|
const moviesMeta = movies.map(m => ({ id: m.id, title: m.title, original_title: m.original_title }));
|
||||||
let active = true;
|
let active = true;
|
||||||
(async () => {
|
(async () => {
|
||||||
for (const m of moviesMeta) {
|
for (let bi = 0; bi < moviesMeta.length; bi += 3) {
|
||||||
if (!active) break;
|
if (!active) break;
|
||||||
|
const chunk = moviesMeta.slice(bi, bi + 3);
|
||||||
try {
|
try {
|
||||||
const result = await api('/tools/media/xrel-check', { method:'POST', body:{ movies: [m] } });
|
const result = await api('/tools/media/xrel-check', { method:'POST', body:{ movies: chunk } });
|
||||||
if (!active) break;
|
if (!active) break;
|
||||||
if (result[m.id]) setXrelIds(prev => new Set([...prev, m.id]));
|
chunk.forEach(m => { if (result[m.id]) setXrelIds(prev => new Set([...prev, m.id])); });
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
@@ -371,12 +372,13 @@ function DemnächstGrid({ onOpenModal }) {
|
|||||||
const moviesMeta = allMovies.map(m => ({ id: m.id, title: m.title, original_title: m.original_title }));
|
const moviesMeta = allMovies.map(m => ({ id: m.id, title: m.title, original_title: m.original_title }));
|
||||||
let active = true;
|
let active = true;
|
||||||
(async () => {
|
(async () => {
|
||||||
for (const m of moviesMeta) {
|
for (let bi = 0; bi < moviesMeta.length; bi += 3) {
|
||||||
if (!active) break;
|
if (!active) break;
|
||||||
|
const chunk = moviesMeta.slice(bi, bi + 3);
|
||||||
try {
|
try {
|
||||||
const result = await api('/tools/media/xrel-check', { method:'POST', body:{ movies: [m] } });
|
const result = await api('/tools/media/xrel-check', { method:'POST', body:{ movies: chunk } });
|
||||||
if (!active) break;
|
if (!active) break;
|
||||||
if (result[m.id]) setXrelIds(prev => new Set([...prev, m.id]));
|
chunk.forEach(m => { if (result[m.id]) setXrelIds(prev => new Set([...prev, m.id])); });
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|||||||
Reference in New Issue
Block a user