feat: Erscheinungsdaten direkt von xREL (us-cine/de-cine/us-web etc.)
This commit is contained in:
@@ -66,28 +66,28 @@ function extractFSK(rd) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const RELEASE_TYPE_LABEL = { 2:'Kino (limited)', 3:'Kinostart', 4:'Web', 5:'Retail', 6:'TV' };
|
||||
// xREL release_date type labels
|
||||
const XREL_DATE_LABEL = {
|
||||
'us-cine': 'Kinostart (US)',
|
||||
'de-cine': 'Kinostart (DE)',
|
||||
'us-web': 'Web (US)',
|
||||
'de-web': 'Web (DE)',
|
||||
'us-disc': 'Disc (US)',
|
||||
'de-disc': 'Disc (DE)',
|
||||
'us-tv': 'TV (US)',
|
||||
'de-tv': 'TV (DE)',
|
||||
};
|
||||
|
||||
function extractReleaseDates(rd) {
|
||||
if (!rd?.results) return [];
|
||||
// Nur DE und US, Typen 2-5 (kein Premiere=1, kein TV=6)
|
||||
const entries = [];
|
||||
for (const country of ['DE', 'US']) {
|
||||
const c = rd.results.find(r => r.iso_3166_1 === country);
|
||||
if (!c) continue;
|
||||
for (const r of c.release_dates) {
|
||||
if (!r.release_date) continue;
|
||||
const label = RELEASE_TYPE_LABEL[r.type];
|
||||
if (!label) continue;
|
||||
entries.push({
|
||||
country,
|
||||
label: `${label} (${country})`,
|
||||
date: r.release_date.slice(0, 10),
|
||||
});
|
||||
}
|
||||
}
|
||||
entries.sort((a, b) => a.date.localeCompare(b.date));
|
||||
return entries;
|
||||
// Holt xREL Erscheinungsdaten für eine ext_info_id
|
||||
async function getXrelReleaseDates(extInfoId) {
|
||||
try {
|
||||
const data = await xrelFetch('/ext_info/info.json', { id: extInfoId, type: 'movie' });
|
||||
if (!Array.isArray(data.release_dates)) return [];
|
||||
return data.release_dates
|
||||
.filter(r => XREL_DATE_LABEL[r.type] && r.date)
|
||||
.map(r => ({ label: XREL_DATE_LABEL[r.type], date: r.date }))
|
||||
.sort((a, b) => a.date.localeCompare(b.date));
|
||||
} catch(_) { return []; }
|
||||
}
|
||||
async function fetchAllPages(path, maxPages = 3) {
|
||||
const first = await tmdb(path, { page: 1 });
|
||||
@@ -232,8 +232,10 @@ async function getXrelData(tmdbId, imdbId, title, originalTitle) {
|
||||
|
||||
results.sort((a,b) => (b.date||'').localeCompare(a.date||''));
|
||||
const top5 = results.slice(0, 5);
|
||||
cacheSet(cacheKey, top5, top5.length > 0 ? 12*60*60*1000 : 60*60*1000);
|
||||
return top5;
|
||||
const payload = { releases: top5, dates: xrelDates };
|
||||
const ttl = (top5.length > 0 || xrelDates.length > 0) ? 12*60*60*1000 : 60*60*1000;
|
||||
cacheSet(cacheKey, payload, ttl);
|
||||
return payload;
|
||||
}
|
||||
|
||||
// ── Routes ────────────────────────────────────────────────────────────────────
|
||||
@@ -286,7 +288,6 @@ router.get('/movie/:id', authenticate, async (req, res) => {
|
||||
backdrop_path: detail.backdrop_path, release_date: detail.release_date,
|
||||
runtime: detail.runtime, vote_average: detail.vote_average,
|
||||
genres: (detail.genres||[]).map(g => g.name), fsk,
|
||||
release_dates: extractReleaseDates(detail.release_dates),
|
||||
cast: (detail.credits?.cast||[]).slice(0,8).map(a => a.name),
|
||||
director: detail.credits?.crew?.find(c => c.job==='Director')?.name||null,
|
||||
tmdb_url: `https://www.themoviedb.org/movie/${detail.id}`,
|
||||
@@ -307,8 +308,12 @@ router.get('/movie/:id/xrel', authenticate, async (req, res) => {
|
||||
// Bei refresh=1 oder leerem Cache: xREL aufrufen
|
||||
if (!forceRefresh) {
|
||||
const cached = cacheGet(cacheKey);
|
||||
if (cached !== undefined && cached.length > 0) {
|
||||
return res.json({ xrel: cached, has_xrel: true });
|
||||
if (cached !== undefined) {
|
||||
const releases = cached?.releases || cached || [];
|
||||
const dates = cached?.dates || [];
|
||||
if (releases.length > 0 || dates.length > 0) {
|
||||
return res.json({ xrel: releases, dates, has_xrel: releases.length > 0 });
|
||||
}
|
||||
}
|
||||
}
|
||||
// Cache löschen bei refresh (damit neu gecacht wird)
|
||||
@@ -332,8 +337,10 @@ router.get('/movie/:id/xrel', authenticate, async (req, res) => {
|
||||
origTitle = detail.original_title || null;
|
||||
}
|
||||
|
||||
const xrel = await getXrelData(req.params.id, imdbId, title, origTitle);
|
||||
res.json({ xrel, has_xrel: xrel.length > 0 });
|
||||
const payload = await getXrelData(req.params.id, imdbId, title, origTitle);
|
||||
const releases = payload?.releases || [];
|
||||
const dates = payload?.dates || [];
|
||||
res.json({ xrel: releases, dates, has_xrel: releases.length > 0 });
|
||||
} catch(e) { res.status(500).json({ error: e.message }); }
|
||||
});
|
||||
|
||||
@@ -346,7 +353,9 @@ router.get('/xrel-cached', authenticate, (req, res) => {
|
||||
const result = {};
|
||||
for (const id of ids) {
|
||||
const cached = cacheGet(`xrel:tmdb:${id}`);
|
||||
result[id] = cached !== undefined && cached.length > 0;
|
||||
if (cached === undefined) { result[id] = false; continue; }
|
||||
const releases = cached?.releases || cached || [];
|
||||
result[id] = releases.length > 0;
|
||||
}
|
||||
res.json(result);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user