playlist edition

This commit is contained in:
Gabriel Radureau
2025-10-13 16:53:15 +02:00
parent 0fa5a30809
commit 65d63ec828
15 changed files with 550 additions and 137 deletions

View File

@@ -1,115 +1,30 @@
# app.py
import streamlit as st
import db
from models import Video
from views import show_video_thumbnail
from controllers import label_widget
from datetime import date
from views.label_views import video_filter_sidebar, video_list_view
from playlists import playlist_page
# ==========================
# 🧭 Configuration
# ==========================
st.set_page_config(page_title="Dance Video Manager", layout="wide")
st.title("💃 Dance Video Explorer")
st.sidebar.title("💃 Menu principal")
# --- Barre latérale : filtres dynamiques ---
st.sidebar.header("⚙️ Filtres et affichage")
max_height = st.sidebar.slider("Hauteur maximale (px)", 100, 800, 300, 50)
st.markdown(f"""
<style>
img, video {{
max-height: {max_height}px !important;
object-fit: contain;
border-radius: 8px;
transition: all 0.3s ease-in-out;
}}
.unlabeled {{
border: 3px solid #f39c12;
box-shadow: 0 0 10px #f39c12;
border-radius: 10px;
padding: 5px;
margin-bottom: 10px;
}}
</style>
""", unsafe_allow_html=True)
all_labels = db.load_labels()
unique_days = db.get_unique_days()
unique_difficulties = db.get_unique_difficulties()
unique_addresses = db.get_unique_addresses()
selected_labels = st.sidebar.multiselect("Filtrer par labels", all_labels)
day_filter = st.sidebar.selectbox(
"Jour de la semaine",
["Tous"] + unique_days
page = st.sidebar.radio(
"Navigation",
["Vidéos", "Playlists"],
key="nav_main"
)
difficulty_filter = st.sidebar.selectbox(
"Niveau de difficulté",
["Tous"] + unique_difficulties
)
# ==========================
# 🎬 PAGE : VIDÉOS
# ==========================
if page == "Vidéos":
st.title("🎬 Gestion et annotation des vidéos")
filters = video_filter_sidebar()
video_list_view(filters)
address_keyword = st.sidebar.selectbox(
"Adresse (mot-clé)",
[""] + unique_addresses
)
start_date = st.sidebar.date_input("Date de début", value=None)
end_date = st.sidebar.date_input("Date de fin", value=None)
show_unlabeled_only = st.sidebar.checkbox("Afficher uniquement les vidéos sans labels")
# --- Filtrage SQL ---
day_value = None if day_filter == "Tous" else day_filter
df_videos = db.search_videos(
label_names=selected_labels,
day_of_week=day_value,
address_keyword=address_keyword if address_keyword else None,
start_date=start_date.isoformat() if start_date else None,
end_date=end_date.isoformat() if end_date else None,
difficulty=difficulty_filter
)
if df_videos.empty:
st.warning("Aucune vidéo trouvée avec ces critères.")
st.stop()
# --- Chargement des labels et affichage lazy ---
video_labels_map = {row["file_name"]: db.load_video_labels(row["file_name"]) for _, row in df_videos.iterrows()}
if show_unlabeled_only:
df_videos = df_videos[df_videos["file_name"].apply(lambda fn: not video_labels_map.get(fn))]
videos = [Video(**row) for _, row in df_videos.iterrows()]
# --- Lazy loading ---
page_size = 20
if "video_page" not in st.session_state:
st.session_state.video_page = 1
start = 0
end = st.session_state.video_page * page_size
visible_videos = videos[start:end]
for video in visible_videos:
preselected = video_labels_map.get(video.file_name, [])
css_class = "unlabeled" if not preselected else ""
with st.container():
st.markdown(f"<div class='{css_class}'>", unsafe_allow_html=True)
col3 = show_video_thumbnail(video)
with col3:
label_widget(video, preselected=preselected)
# --- Sélecteur de difficulté ---
new_level = st.selectbox(
"🎚 Niveau de difficulté",
["Tout niveau", "Débutant", "Intermédiaire", "Avancé", "Star"],
index=["Tout niveau", "Débutant", "Intermédiaire", "Avancé", "Star"].index(video.difficulty_display),
key=f"diff_{video.file_name}"
)
if new_level != video.difficulty_display:
db.update_video_difficulty(video.file_name, new_level)
st.success(f"Niveau mis à jour pour {video.file_name}")
st.markdown("</div>", unsafe_allow_html=True)
# --- Bouton "Voir plus" ---
if end < len(videos):
if st.button("📦 Charger plus de vidéos"):
st.session_state.video_page += 1
st.rerun()
else:
st.info("✅ Toutes les vidéos sont affichées.")
# ==========================
# 🎵 PAGE : PLAYLISTS
# ==========================
elif page == "Playlists":
playlist_page.main()