mirror of
https://github.com/R0m1k3/xtremflow.git
synced 2026-10-21 22:18:04 +02:00
Multi-IPTV : chaque fonction utilise la playlist sélectionnée
Le serveur ignorait l'IPTV choisie : direct, VOD, guide, enregistrements, season passes et Auto NBA passaient tous par la playlist la plus récente (ou celle du premier utilisateur pour la capture FFmpeg), et les enregistrements s'affichaient sous toutes les playlists. - get_playlist respecte ?playlist=<id> (prioritaire) puis l'en-tête X-Playlist-Id, avec contrôle du propriétaire (admin : toutes). - Sessions FFmpeg HLS/VOD séparées par IPTV (même stream_id possible) ; le m3u8 propage ?playlist= aux segments, redirections et bascule .ts → HLS du lecteur web aussi. - tv_recordings, season_passes, auto_rules : colonne playlist_id (migrations v4-v6) ; lignes existantes rattachées à la playlist la plus récente de leur propriétaire ; URL de capture avec ?playlist= ; listes filtrées par IPTV ; une règle NBA par IPTV. - Proxy /api/xtream : cache d'allowlist par playlist, paramètre retiré avant l'appel au panneau ; CORS autorise X-Playlist-Id. - Client : AuthedHttp envoie X-Playlist-Id ; XtreamService ajoute ?playlist= aux flux, à l'EPG et aux appels xtream-api (cache distinct). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
29b4e11d13
commit
4f978755fd
15 files changed
+501
-70
No files matched your search
@@ -454,8 +454,16 @@ impl RecordingScheduler {
|
||||
.unwrap_or("contains")
|
||||
.to_string();
|
||||
|
||||
// Playlist du PROPRIÉTAIRE du pass, résolue au moment du scan.
|
||||
let playlists = self.db.get_playlists(&user_id);
|
||||
// IPTV du pass ; à défaut (pass ancien), la plus récente du
|
||||
// propriétaire, résolue au moment du scan.
|
||||
let pass_playlist_id = field("playlist_id");
|
||||
let playlists: Vec<crate::models::Playlist> = self
|
||||
.db
|
||||
.get_playlist_by_id(&pass_playlist_id)
|
||||
.filter(|p| p.user_id == user_id)
|
||||
.into_iter()
|
||||
.chain(self.db.get_playlists(&user_id))
|
||||
.collect();
|
||||
let Some(playlist) = playlists.first() else {
|
||||
println!(
|
||||
"[SeasonPass] Aucune playlist pour le propriétaire du pass \"{show_title}\", scan ignoré"
|
||||
@@ -544,9 +552,12 @@ impl RecordingScheduler {
|
||||
break;
|
||||
}
|
||||
|
||||
self.db
|
||||
let stream_url = crate::models::stream_url_for_playlist(&stream_url, &playlist.id);
|
||||
let rec = self
|
||||
.db
|
||||
.create_recording(&user_id, &channel_id, &stream_url, &title, start, end)
|
||||
.map_err(|e| e.to_string())?;
|
||||
self.db.set_recording_playlist(&rec.id, &playlist.id);
|
||||
created += 1;
|
||||
println!(
|
||||
"[SeasonPass] ✓ Planifié automatiquement: \"{title}\" le {}",
|
||||
@@ -1272,6 +1283,7 @@ mod tests {
|
||||
file_path: None,
|
||||
error_reason: None,
|
||||
source_rule_id: None,
|
||||
playlist_id: None,
|
||||
created_at: start,
|
||||
updated_at: start,
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user