Commit Graph
9 Commits
Author SHA1 Message Date
bruno 326455adfe feat: lives PeerTube/Rumble, page Admin, TTL par provider, import/export playlists
CI / build-and-test (push) Successful in 14m56s
#1 Live
- PeerTube: API native ?isLive=true (recherche sepiasearch + videos de chaine),
  mapPeertubeItem exporte la regle live (type/kind/isLive, viewers, jamais de
  duree), caps pt live:true, themes « En direct » branches pt/ru
- Rumble: mode 'live' de scrapeRumbleList (rumble.com/browse/live, SSR), items
  type:live + extraction channelId (/c/<slug>), route GET /api/rumble/live,
  onglet chaine live filtre par channelId (plafond page 1 = 50 directs)
- Odysee: N/A prouve (proxy na-backend sous jeton, probe 2026-10), caps inchangees
- Tests: npm run test:live (25 assertions), assertion adapter_contract mise a
  jour (seuls tw/pt/ru declarent live)

#2 Playlists natives
- Twitch: NON FAISABLE — probe avec token app valide: GET/POST /helix/playlists
  et /helix/playlists/{id}/videos -> 404 (controle /helix/users -> 400).
  Matrice README: Twitch/Odysee/Rumble en N/A avec preuves

#3 Quick wins
- Page Administration /#/admin (entree sidebar Informations + i18n nav.admin
  FR/EN): healthz + providers/metrics rendus (statut, yt-dlp, clés actives/
  bannies, anti-ban, cache par provider, compteurs 1h, quota du jour) ;
  healthz sert aussi sous /proxy/api/healthz
- TTL par provider: server/env-ttl.mjs (<BASE>_<P> -> <BASE> -> defaut, jamais
  nul), branche sur les caches details et transcripts ; suggest reste global
  (cle agregee multi-providers) ; tests npm run test:cache
- Import/Export playlists JSON: GET /playlists/export (newtube-playlists-v1,
  avant /playlists/:id) + POST /playlists/import (dedoublonnage par titre),
  boutons [Exporter] [Importer] sur la page listes de lecture

README: matrice fournisseurs (Live pt/ru OK, od N/A, playlists N/A prouves),
roadmap deplace en ✅ (Live, import/export, Admin, TTL) + 🟡 mis a jour.
2026-10-02 20:25:08 -04:00
bruno 4e44d85717 fix(rumble): le lien de nav /videos n'est plus pris pour une vidéo
CI / build-and-test (push) Canceled after 0s
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.
2026-10-02 08:57:41 -04:00
bruno 7fc1e1096d fix(rumble): un HTTP 404 net n'est pas un blocage Cloudflare
CI / build-and-test (push) Canceled after 0s
Probe live depuis le conteneur : rumble.com renvoie 404 (vraie page,
non-challenge) pour un id inexistant. fetchHtml les classait en échec
total, d'où deux régressions : 503 sur /video (les vidéos mortes ne
sont plus retirées des Shorts) et armement du cooldown 60 s pour toute
la maison au premier id bogus.

- fetchHtml retourne toute réponse nette non-challenge ; le statut est
  jugé par les appelants (tous dans le même fichier).
- rumbleFailureForStatus() exporté : 403 -> 503
  rumble_cloudflare_challenge (bandeau identique à la recherche),
  404/410 -> 404 rumble_not_found, 5xx -> 503 rumble_upstream_error.
  /video, /browse et /shorts passent par ce mapping.
- handler.search ne parse plus que du HTTP 200 : les pages 404 de
  Rumble embarquent des cartes de recommandation qui seraient
  autrement prises pour des résultats de recherche.
- Tests : 7 assertions sur le mapping (sans réseau), 64 au total.
2026-10-02 08:49:44 -04:00
bruno e48d76be57 refactor(rumble): un seul cœur de scraping, routeur fin, contrat 503 CF
CI / build-and-test (push) Successful in 14m57s
- server/providers/rumble.mjs devient l'unique implémentation : fetch
  (cookie jar __cf_bm + curl_cffi + cooldown global 60 s après un échec
  total), parsing liste/vidéo avec surcouche JSON-LD partagée, vues via
  parseRumbleViews partout (« 1,2K » n'est plus lu en 12 sur /api/rumble).
- server/rumble.mjs = couche HTTP mince : limiter 20/min, cache 60 s,
  5 routes qui délèguent au cœur ; /search passe par le registre de
  providers (cache SQLite, negative cache et channelRef partagés avec
  /api/search).
- Contrat d'erreur : un blocage Cloudflare est un 503
  rumble_cloudflare_challenge, plus jamais un 404 (qui faisait retirer
  les vidéos du flux Shorts lors d'un challenge) ; page reçue sans
  identité = 404 rumble_video_not_found.
- Code mort supprimé : scrapeRumbleVideo d'index.mjs (191 l., 3e
  implémentation jamais appelée), rumbleLimiter 10/min jamais monté,
  import cheerio devenu inutile. Net -238 lignes.
- Tests : parseur générique (vues, durées, ids /shorts/), contrat 503
  sans réseau via le cooldown, durées absentes -> undefined.
- Docs : API_MCP_GUIDE §5.5 (routes, rate-limit réel, erreurs) + note
  README « Rumble peut être temporairement absent selon le réseau ».
2026-10-02 08:36:48 -04:00
bruno 665a0f0ebd feat(providers): phases 7.3/7.4/7.6/8.1 — provenance, health, NDJSON, contrat unique
CI / build-and-test (push) Successful in 14m43s
7.3: capturedAt/source au registre + 6 adaptateurs + module provenance.ts + ?debug=1 (search-transport.mjs). 7.4: ProviderHealthService + badge source degradee. 7.6: squelettes par provider + snapshots progressifs + transport NDJSON /api/search. 8.1: ProviderAdapter unifie (search enveloppe + channelContent/channelMeta/capabilities) via getProviderAdapter + test de contrat offline.
2026-09-30 07:57:11 -04:00
bruno f443a470f9 feat: détection short par orientation vidéo
CI / build-and-test (push) Successful in 14m6s
Règle partagée front/back : flag natif, verticale stricte (ratio ≤ 0.8, ≤ 90 s), verticale sans durée jamais short, repli durée (70 YT / 75 autres). Dimensions alimentées par Dailymotion/Odysee/PeerTube, flag maison Rumble supprimé, condition innertube morte simplifiée. Shorts : langues utilisateur (UI + transcripts) via relevanceLanguage/languageOneOf/Twitch language, son activé par défaut.
2026-09-29 12:17:10 -04:00
bruno 97e5de74f5 feat(channel): page details chaine multi-providers avec onglets et infinite scroll
CI / build-and-test (push) Successful in 13m34s
- Strategy Pattern front: ChannelProviderInterface + 6 providers (yt/dm/tw/pt/od/ru) + factory (ids longs/courts)
- ChannelContentService: cache par onglet/tri/recherche (TTL 5min), pagination nextPage
- ChannelPage: header (banniere/avatar/subs/description ...plus), tabs dynamiques par capabilities, grilles videos/shorts 9:16/playlists/live, recherche debounced, tri recent/populaire, infinite scroll IntersectionObserver, skeletons/empty/error
- Backend: GET /api/channels/:provider/:id/content (videos/shorts/playlists/live) natif par provider
2026-09-25 10:15:12 -04:00
bruno 9a3983a253 chore: update Angular cache and TypeScript build info 2025-09-23 21:45:57 -04:00
bruno 4eb339eb22 chore: update Angular cache and TypeScript build info files 2025-09-22 09:34:22 -04:00