feat(suggest): enrichissement web gratuit (Bing+Google) et titres Odysee Lighthouse

This commit is contained in:
2026-09-26 13:45:23 -04:00
parent 4578f5b887
commit d9c8a2e14e
5 changed files with 203 additions and 7 deletions
+17 -2
View File
@@ -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) {