Files
xtremflow/lib/core/api/channel_logo.dart
T
MichaelandClaude Opus 5 9843999809 Logos des chaînes : repli par nom quand l'hébergeur de picons tombe
L'hébergeur des picons du fournisseur (51.158.145.100) répond toujours
503 sur toutes ses URL. Couper le flot de requêtes ne suffisait pas : la
grille restait sans logo. Pire, le pixel transparent servi en 200 était
pris pour une image valide par Flutter, qui n'affichait plus son icône
de repli — d'où des tuiles entièrement vides.

- Nouvelle route `/api/logo?src=…&name=…` : URL du panneau d'abord (via
  le proxy, mêmes protections anti-SSRF et même mémoire des hôtes
  morts), puis recherche par nom dans le dépôt public tv-logo/tv-logos
- Appariement par nom : préfixe pays et suffixes de qualité ignorés,
  `+` → `plus`, variante plus longue (`bein-sports-1-french`), puis
  marque sans numéro pour les canaux événementiels. Aucune approximation
  sur un mot seul
- Liste de logos en cache 24 h (API GitHub : 60 requêtes/h non
  authentifiées), 15 min de recul après échec, images en mémoire
- Image indisponible : 410 mis en cache au lieu du pixel. 410 et non
  404 : la Cascade du serveur rattrape les 404 et renvoyait celui du
  handler statique, sans cache-control
- Client (grille bureau, mobile, enregistrements) : logo toujours
  demandé au backend, nom compris, même sans stream_icon. L'onglet
  Enregistrements chargeait l'URL http brute, bloquée en HTTPS

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-19 13:39:01 +02:00

21 lines
803 B
Dart

/// URL du logo d'une chaîne, servie par le backend (`/api/logo`).
///
/// Le backend tente d'abord [streamIcon] (l'URL fournie par le panneau), puis
/// cherche un logo par [name] quand l'hébergeur de picons du revendeur ne
/// répond pas. Le nom est donc transmis même sans `stream_icon` : c'est
/// souvent le seul moyen d'obtenir un logo.
///
/// Une chaîne sans logo trouvé reçoit un statut d'erreur : l'`errorBuilder`
/// de l'`Image.network` appelante affiche alors son propre repli.
String channelLogoUrl({required String streamIcon, required String name}) {
final icon = streamIcon.trim();
return Uri(
path: '/api/logo',
queryParameters: {
if (icon.startsWith('http://') || icon.startsWith('https://'))
'src': icon,
'name': name,
},
).toString();
}