fix: xREL 3 Suchstrategien, normalisierte Queries, debug-xrel3 Endpoint
This commit is contained in:
@@ -126,36 +126,64 @@ async function getXrelData(tmdbId, imdbId, title, originalTitle) {
|
||||
const cached = cacheGet(cacheKey);
|
||||
if (cached !== undefined) return cached;
|
||||
|
||||
// Alle Suchen parallel – originaltitel und deutsch gleichzeitig
|
||||
const clean = (s) => (s||'').replace(/[*#!?:]/g,'').trim().toLowerCase();
|
||||
const queries = [originalTitle, title].filter(Boolean).filter((v,i,a) => a.indexOf(v)===i);
|
||||
const clean = (s) => normalizeUmlauts(s||'').replace(/[*#!?:]/g,'').trim().toLowerCase();
|
||||
|
||||
const searchResults = await Promise.all(queries.map(async q => {
|
||||
// Suchqueries: original, deutsch, und normalisierte Varianten
|
||||
// Wichtig: xREL nutzt oft den englischen Originaltitel auch bei deutschen Filmen
|
||||
const rawQueries = [originalTitle, title].filter(Boolean).filter((v,i,a) => a.indexOf(v)===i);
|
||||
// Normalisierte Versionen (Umlaute) als zusätzliche Queries
|
||||
const normQueries = rawQueries.map(q => normalizeUmlauts(q).replace(/[*#!?:]/g,'').trim())
|
||||
.filter(q => !rawQueries.map(r => r.replace(/[*#!?:]/g,'').trim()).includes(q));
|
||||
const allQueries = [...rawQueries, ...normQueries].filter(Boolean).filter((v,i,a) => a.indexOf(v)===i);
|
||||
|
||||
// Alle parallel suchen
|
||||
const searchResults = await Promise.all(allQueries.map(async q => {
|
||||
try {
|
||||
return await xrelFetch('/search/ext_info.json', {
|
||||
q: normalizeUmlauts(q).replace(/[*#!?:]/g,''), type:'movie', limit:10
|
||||
});
|
||||
return {
|
||||
q,
|
||||
data: await xrelFetch('/search/ext_info.json', {
|
||||
q: normalizeUmlauts(q).replace(/[*#!?:]/g,''), type:'movie', limit:10
|
||||
})
|
||||
};
|
||||
} catch(_) { return null; }
|
||||
}));
|
||||
|
||||
let extInfoId = null;
|
||||
// IMDb-URI Match zuerst
|
||||
|
||||
// Strategie 1: IMDb-URI exakter Match (zuverlässigste Methode)
|
||||
if (imdbId) {
|
||||
for (const data of searchResults) {
|
||||
const hit = (data?.results||[]).find(h => (h.uris||[]).includes(`imdb:${imdbId}`));
|
||||
if (hit?.id) { extInfoId = hit.id; break; }
|
||||
}
|
||||
}
|
||||
// Exakter Titel-Match als Fallback
|
||||
if (!extInfoId) {
|
||||
for (const data of searchResults) {
|
||||
const hit = (data?.results||[]).find(h => clean(h.title)===clean(queries[0]) || clean(h.alt_title)===clean(queries[0]));
|
||||
for (const r of searchResults) {
|
||||
if (!r) continue;
|
||||
const hit = (r.data?.results||[]).find(h => (h.uris||[]).includes(`imdb:${imdbId}`));
|
||||
if (hit?.id) { extInfoId = hit.id; break; }
|
||||
}
|
||||
}
|
||||
|
||||
// Strategie 2: Exakter Titel-Match
|
||||
if (!extInfoId) {
|
||||
cacheSet(cacheKey, [], 60*60*1000); // 1h für nicht gefunden
|
||||
for (const r of searchResults) {
|
||||
if (!r) continue;
|
||||
const hit = (r.data?.results||[]).find(h =>
|
||||
clean(h.title) === clean(r.q) || clean(h.alt_title) === clean(r.q)
|
||||
);
|
||||
if (hit?.id) { extInfoId = hit.id; break; }
|
||||
}
|
||||
}
|
||||
|
||||
// Strategie 3: Einziger Treffer bei IMDb-Suche (nur wenn exakt 1 Ergebnis)
|
||||
if (!extInfoId && imdbId) {
|
||||
for (const r of searchResults) {
|
||||
if (!r) continue;
|
||||
const results = r.data?.results || [];
|
||||
if (results.length === 1 && results[0].type === 'movie') {
|
||||
extInfoId = results[0].id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!extInfoId) {
|
||||
cacheSet(cacheKey, [], 60*60*1000);
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -331,4 +359,36 @@ router.put('/settings', authenticate, requireAdmin, (req, res) => {
|
||||
});
|
||||
|
||||
|
||||
// DEBUG – nach Test entfernen
|
||||
router.get('/debug-xrel3', authenticate, async (req, res) => {
|
||||
const title = req.query.title || '';
|
||||
const orig = req.query.orig || '';
|
||||
const imdb_id = req.query.imdb_id || null;
|
||||
const log = { title, orig, imdb_id };
|
||||
try {
|
||||
const clean = (s) => normalizeUmlauts(s||'').replace(/[*#!?:]/g,'').trim().toLowerCase();
|
||||
const rawQueries = [orig, title].filter(Boolean).filter((v,i,a) => a.indexOf(v)===i);
|
||||
const normQueries = rawQueries.map(q => normalizeUmlauts(q).replace(/[*#!?:]/g,'').trim())
|
||||
.filter(q => !rawQueries.map(r => r.replace(/[*#!?:]/g,'').trim()).includes(q));
|
||||
log.rawQueries = rawQueries;
|
||||
log.normQueries = normQueries;
|
||||
log.allQueries = [...rawQueries, ...normQueries].filter(Boolean).filter((v,i,a) => a.indexOf(v)===i);
|
||||
|
||||
const results = [];
|
||||
for (const q of log.allQueries) {
|
||||
try {
|
||||
const data = await xrelFetch('/search/ext_info.json', {
|
||||
q: normalizeUmlauts(q).replace(/[*#!?:]/g,''), type:'movie', limit:5
|
||||
});
|
||||
results.push({
|
||||
query: normalizeUmlauts(q).replace(/[*#!?:]/g,''),
|
||||
hits: (data.results||[]).map(h => ({ id: h.id, title: h.title, alt_title: h.alt_title, uris: h.uris }))
|
||||
});
|
||||
} catch(e) { results.push({ query: q, error: e.message }); }
|
||||
}
|
||||
log.searchResults = results;
|
||||
} catch(e) { log.error = e.message; }
|
||||
res.json(log);
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
||||
Reference in New Issue
Block a user