# playlists/playlist_controller.py import streamlit as st import db from playlists.playlist_model import Playlist, RuleSet from playlists import playlist_db from views.label_views import video_filter_sidebar, video_list_view from views.video_views import show_video_row from models import Video def playlist_manual_editor(playlist: Playlist): """Permet de gérer les vidéos d'une playlist manuelle.""" st.subheader(f"🎞️ Édition manuelle : {playlist.name}") # Filtres standard pour explorer les vidéos filters = video_filter_sidebar() # Précharge les vidéos déjà incluses dans la playlist playlist_video_ids = db.get_video_file_names_in_playlist(playlist.id) # Récupère les vidéos filtrées df_videos = db.search_videos( label_names=filters["selected_labels"], day_of_week=filters["day_filter"], difficulty=filters["difficulty_filter"], **filters ) if df_videos.empty: st.info("Aucune vidéo trouvée avec ces filtres.") return videos = [Video(**row) for _, row in df_videos.iterrows()] st.write(f"🎬 {len(videos)} vidéo(s) disponibles.") # Affiche les vidéos avec boutons d’ajout/retrait à droite summary_map = summary_map = get_video_summary_cached() for video in videos[:50]: # limite de sécurité summary = summary_map.get(video.file_name, {"labels": [], "playlists": []}) preselected = summary["labels"] playlists = summary["playlists"] show_video_row( video, preselected_labels=preselected, editable_labels=False, editable_difficulty=False, editable_alias=False, playlist=playlist, playlist_video_ids=playlist_video_ids, video_playlists=playlists ) if st.button("📦 Charger plus"): st.session_state.video_page += 1 st.rerun() @st.cache_data(ttl=30) def get_video_summary_cached(): return playlist_db.load_video_summary_map() def playlist_dynamic_editor(playlist: Playlist): """Édite les règles d'une playlist dynamique et affiche le rendu en temps réel.""" st.subheader(f"⚙️ Playlist dynamique : {playlist.name}") rules = playlist.rules or RuleSet() labels = db.load_labels() rules.include_labels = st.multiselect("Inclure labels", labels, default=rules.include_labels) rules.exclude_labels = st.multiselect("Exclure labels", labels, default=rules.exclude_labels) all_playlists = playlist_db.load_all_playlists() name_to_id = {p.name: p.id for p in all_playlists} id_to_name = {p.id: p.name for p in all_playlists} default_include = [id_to_name.get(pid) for pid in rules.include_playlists if pid in id_to_name] default_exclude = [id_to_name.get(pid) for pid in rules.exclude_playlists if pid in id_to_name] selected_includes = st.multiselect("Inclure playlists", id_to_name.values(), default=default_include) selected_excludes = st.multiselect("Exclure playlists", id_to_name.values(), default=default_exclude) rules.include_playlists = [name_to_id[name] for name in selected_includes] rules.exclude_playlists = [name_to_id[name] for name in selected_excludes] col1, col2 = st.columns(2) with col1: use_delta = st.checkbox("⏱️ Utiliser un delta de jours", value=bool(rules.date_delta_days)) if use_delta: rules.date_delta_days = st.number_input( "Nombre de jours depuis aujourd’hui (négatif pour passé)", value=rules.date_delta_days or -15 ) rules.date_after = None rules.date_before = None else: rules.date_after = st.date_input("📅 Après le", value=rules.date_after or None) rules.date_before = st.date_input("📅 Avant le", value=rules.date_before or None) rules.date_delta_days = None with col2: rules.logic = st.radio("Logique de combinaison", ["AND", "OR"], index=0 if rules.logic == "AND" else 1) rules.label_logic = st.radio("Logique de combinaison entre labels", ["AND", "OR"], index=0 if rules.label_logic == "AND" else 1) # --- Enregistrement --- if st.button("💾 Enregistrer les règles"): playlist.rules = rules playlist.save() st.success("Règles mises à jour ✅") (st.rerun if hasattr(st, "rerun") else st.experimental_rerun)() st.markdown("---") st.subheader("🧩 Rendu de la playlist") rows = playlist_db.get_videos_for_playlist(playlist) if not rows: st.info("Aucune vidéo ne correspond aux règles actuelles.") return videos = [Video(**row) for row in rows] st.write(f"🎬 {len(videos)} vidéo(s) trouvée(s).") playlist_video_ids = db.get_video_file_names_in_playlist(playlist.id) summary_map = summary_map = get_video_summary_cached() for v in videos[:50]: summary = summary_map.get(v.file_name, {"labels": [], "playlists": []}) preselected = summary["labels"] playlists = summary["playlists"] show_video_row( v, preselected_labels=preselected, editable_labels=False, editable_difficulty=False, editable_alias=False, playlist=playlist, playlist_video_ids=playlist_video_ids, video_playlists=playlists ) if st.button("📦 Charger plus"): st.session_state.video_page += 1 st.rerun()