feat(suggest): enrichissement web gratuit (Bing+Google) et titres Odysee Lighthouse
This commit is contained in:
+17
-2
@@ -17,6 +17,7 @@ import axios from 'axios';
|
||||
import rumbleRouter from './rumble.mjs';
|
||||
import { providerRegistry, validateProviders } from './providers/registry.mjs';
|
||||
import { dedupeSuggestGroups } from './suggest.mjs';
|
||||
import { fetchWebSuggest, fetchOdyseeLighthouseSuggest } from './suggest-web.mjs';
|
||||
import { pickTrack, parseTrackText, parseVtt, dedupeTranscriptLines, orderedTracks, translatedFallbacks, firstPerLanguage, normalizeTranscriptProvider, transcriptTrackExt, looksLikeHtmlError } from './transcript.mjs';
|
||||
import {
|
||||
getUserByUsername,
|
||||
@@ -2596,6 +2597,13 @@ app.get('/api/search/suggest', suggestLimiter, async (req, res) => {
|
||||
const cacheKey = `suggest:${validProviders.join(',')}:${q.toLowerCase()}:${limit}`;
|
||||
const cached = suggestCacheGet(cacheKey);
|
||||
if (cached) return res.json(cached);
|
||||
// Enrichissement gratuit (sans clé) lancé en parallèle du fan-out
|
||||
// providers : suggestions web génériques (Bing + Google) + vrais titres
|
||||
// vidéo Odysee (Lighthouse) quand `od` est demandé. Jamais bloquant.
|
||||
const webEnabled = String(process.env.SUGGEST_WEB_ENABLED ?? '1') !== '0';
|
||||
const wantOdysee = validProviders.includes('od');
|
||||
const webPromise = webEnabled ? fetchWebSuggest(q, { limit }) : Promise.resolve([]);
|
||||
const lighthousePromise = wantOdysee ? fetchOdyseeLighthouseSuggest(q, { limit }) : Promise.resolve([]);
|
||||
const results = await Promise.allSettled(
|
||||
validProviders.map((providerId) => {
|
||||
const mod = providerRegistry[providerId];
|
||||
@@ -2603,6 +2611,7 @@ app.get('/api/search/suggest', suggestLimiter, async (req, res) => {
|
||||
return Promise.resolve().then(() => mod.suggest(q, { limit }));
|
||||
})
|
||||
);
|
||||
const [webRes, lightRes] = await Promise.allSettled([webPromise, lighthousePromise]);
|
||||
const groups = {};
|
||||
results.forEach((result, index) => {
|
||||
const providerId = validProviders[index];
|
||||
@@ -2615,8 +2624,14 @@ app.get('/api/search/suggest', suggestLimiter, async (req, res) => {
|
||||
groups[providerId] = [];
|
||||
}
|
||||
});
|
||||
// La même occurrence n'est renvoyée qu'une fois (premier provider gagne).
|
||||
const data = { q, groups: dedupeSuggestGroups(groups, validProviders) };
|
||||
if (wantOdysee && lightRes.status === 'fulfilled' && Array.isArray(lightRes.value) && lightRes.value.length > 0) {
|
||||
groups.od = [...(groups.od || []), ...lightRes.value].slice(0, limit);
|
||||
}
|
||||
if (webEnabled && webRes.status === 'fulfilled' && Array.isArray(webRes.value) && webRes.value.length > 0) {
|
||||
groups.web = webRes.value.slice(0, limit);
|
||||
}
|
||||
// La même occurrence n'est renvoyée qu'une fois (providers d'abord, web en dernier).
|
||||
const data = { q, groups: dedupeSuggestGroups(groups, [...validProviders, 'web']) };
|
||||
suggestCacheSet(cacheKey, data);
|
||||
return res.json(data);
|
||||
} catch (e) {
|
||||
|
||||
Reference in New Issue
Block a user