correct application of playlists rules

This commit is contained in:
Gabriel Radureau
2025-10-16 17:18:58 +02:00
parent d2e2028610
commit 78313ffbef
17 changed files with 1098 additions and 247 deletions

View File

@@ -104,12 +104,19 @@ def search_videos(
end_date=None,
difficulty=None,
label_logic="OR",
include_playlists=None,
exclude_playlists=None,
logic="OR", # logique entre playlists incluses
**kwargs,
):
"""
Retourne une DataFrame filtrée selon les critères fournis.
label_logic: "OR" (au moins un label) ou "AND" (tous les labels).
label_logic: "OR" (au moins un label) ou "AND" (tous les labels)
logic: "OR" ou "AND" pour la combinaison de playlists incluses
"""
label_names = label_names or []
include_playlists = include_playlists or []
exclude_playlists = exclude_playlists or []
params = []
base_query = """
@@ -121,7 +128,6 @@ def search_videos(
# 🔖 Filtres par label
if label_names:
if label_logic == "AND":
# Toutes les étiquettes doivent être présentes
placeholders = ",".join("?" * len(label_names))
base_query += f"""
AND v.file_name IN (
@@ -135,7 +141,6 @@ def search_videos(
"""
params.extend(label_names)
else:
# OR : au moins une étiquette correspond
placeholders = ",".join("?" * len(label_names))
base_query += f"""
AND v.file_name IN (
@@ -147,6 +152,47 @@ def search_videos(
"""
params.extend(label_names)
# 🎵 Filtres par playlists incluses
if include_playlists:
placeholders = ",".join("?" * len(include_playlists))
if logic == "AND":
# Vidéos présentes dans TOUTES les playlists
base_query += f"""
AND v.file_name IN (
SELECT vp.video_file_name
FROM video_playlists vp
JOIN playlists p ON p.id = vp.playlist_id
WHERE p.id IN ({placeholders})
GROUP BY vp.video_file_name
HAVING COUNT(DISTINCT p.id) = {len(include_playlists)}
)
"""
params.extend(include_playlists)
else:
# Vidéos présentes dans AU MOINS une playlist
base_query += f"""
AND v.file_name IN (
SELECT vp.video_file_name
FROM video_playlists vp
JOIN playlists p ON p.id = vp.playlist_id
WHERE p.id IN ({placeholders})
)
"""
params.extend(include_playlists)
# ❌ Filtres par playlists exclues
if exclude_playlists:
placeholders = ",".join("?" * len(exclude_playlists))
base_query += f"""
AND v.file_name NOT IN (
SELECT vp.video_file_name
FROM video_playlists vp
JOIN playlists p ON p.id = vp.playlist_id
WHERE p.id IN ({placeholders})
)
"""
params.extend(exclude_playlists)
# 📆 Jour de la semaine
if day_of_week:
base_query += " AND v.day_of_week = ?"
@@ -177,6 +223,7 @@ def search_videos(
return pd.read_sql_query(base_query, conn, params=params)
def get_video_playlists(file_name):
with get_conn() as conn:
query = """
@@ -187,18 +234,41 @@ def get_video_playlists(file_name):
"""
return [row[0] for row in conn.execute(query, (file_name,))]
def get_videos_in_playlist(playlist_id):
def get_video_file_names_in_playlist(playlist_id):
"""Retourne un set de file_name pour une playlist donnée."""
with get_conn() as conn:
query = """
rows = conn.execute(
# "SELECT video_file_name FROM video_playlists WHERE playlist_id = ?",
"SELECT video_file_name FROM playlist_videos WHERE playlist_id = ?",
(playlist_id,)
).fetchall()
names = []
for r in rows:
if hasattr(r, "keys"):
names.append(r["video_file_name"])
else:
names.append(r[0])
return set(names)
def get_videos_in_playlist(playlist_id):
"""Retourne une liste d'objets Video complets pour une playlist donnée."""
import pandas as pd
from models import Video
with get_conn() as conn:
df = pd.read_sql_query("""
SELECT v.*
FROM videos v
JOIN video_playlists vp ON vp.video_file_name = v.file_name
WHERE vp.playlist_id = ?
ORDER BY vp.position
"""
return conn.execute(query, (playlist_id,)).fetchall()
ORDER BY vp.position ASC
""", conn, params=(playlist_id,))
return [Video(**row) for _, row in df.iterrows()]
def add_video_to_playlist(playlist_id, file_name):
print(dict(playlist_id=playlist_id, video_file_name=file_name),flush=True,)
with get_conn() as conn:
conn.execute("""
INSERT OR IGNORE INTO video_playlists (video_file_name, playlist_id, position)
@@ -209,4 +279,4 @@ def add_video_to_playlist(playlist_id, file_name):
def remove_video_from_playlist(playlist_id, file_name):
with get_conn() as conn:
conn.execute("DELETE FROM video_playlists WHERE playlist_id=? AND video_file_name=?", (playlist_id, file_name))
conn.commit()
conn.commit()