From 4e44d857173c680b4b636e221e46d57ffca2d2e1 Mon Sep 17 00:00:00 2001 From: Bruno Charest Date: Fri, 2 Oct 2026 08:57:41 -0400 Subject: [PATCH] =?UTF-8?q?fix(rumble):=20le=20lien=20de=20nav=20/videos?= =?UTF-8?q?=20n'est=20plus=20pris=20pour=20une=20vid=C3=A9o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Le scan générique acceptait tout href /^\/v/ dont le regex d'id matchait : `/videos` donnait `videoId: "videos"` — une fausse carte en tête du flux /shorts (pré-validée puis retirée, mais visible le temps du résolve). Probe live : 32/32 vrais ids rumble portent au moins un chiffre, seul /videos n'en a pas. Garde « >=1 chiffre » dans l'id, plafond documenté (un id sans chiffre ferait sauter sa carte). Effet de bord heureux : la branche /video/123 (isLegacy) était morte depuis toujours — le regex capturait « video » avant elle — elle redevient accessible. Tests : lien /videos ajouté au fixture du flux, 64 assertions vertes. --- server/providers/rumble.mjs | 8 +++++++- server/tests/rumble-ld.test.mjs | 5 ++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/server/providers/rumble.mjs b/server/providers/rumble.mjs index f3c895b..ae48459 100644 --- a/server/providers/rumble.mjs +++ b/server/providers/rumble.mjs @@ -626,8 +626,14 @@ export function parseCardsHtml(html, { mode = 'browse' } = {}) { $(linkSelector).each((_idx, el) => { const href = ($(el).attr('href') || '').split('?')[0]; // On préfère STRICTEMENT l’ID /vXXXX (aussi après /shorts/). + // ≥1 chiffre exigé : les vrais ids en portent toujours (probe 2026-10 : + // 32/32 sur /shorts + /videos), alors que les liens de nav (`/videos`) + // passeraient le regex et sortiraient une fausse carte « videoId: videos ». + // La branche /video/123 (isLegacy) ne devient accessible que grâce à ça : + // sans ce garde-fou, le regex capturait 'video' et l'ID s'échappait jamais. + // ponytail: si Rumble émettait un id sans chiffre, sa carte est sautée. const m = /\/(v[0-9A-Za-z]+)(?:[-/.]|$)/.exec(href); - const id = m?.[1] || null; + const id = m && /[0-9]/.test(m[1]) ? m[1] : null; // Fallback /video/123 : on ne convertit pas ici, /video/:id normalise par parse de page. const isLegacy = !id && /^\/video\//.test(href); if (!id && !isLegacy) return; diff --git a/server/tests/rumble-ld.test.mjs b/server/tests/rumble-ld.test.mjs index 2d28005..1023379 100644 --- a/server/tests/rumble-ld.test.mjs +++ b/server/tests/rumble-ld.test.mjs @@ -146,13 +146,16 @@ const cardsHtml = `

Titre B

+
+

Featured Channels

+

Titre C

`; const browseCards = parseCardsHtml(cardsHtml, { mode: 'browse' }); -eq(browseCards.length, 2, 'cards browse: /vXXXX lu, /shorts/ ignoré'); +eq(browseCards.length, 2, 'cards browse: /vXXXX lu, /shorts/ et /videos (nav) ignorés'); eq(browseCards[0].id, 'vAAA11', 'cards: id = vXXXX avant le slug -titre'); eq(browseCards[0].views, 1200, 'cards: vues « 1,2K » -> 1200 (bug parseur legacy corrigé)'); eq(browseCards[0].duration, 90, 'cards: durée depuis data-value');