Files
DanceVideos/app/playlists/sql_builder.py
2025-10-16 17:18:58 +02:00

110 lines
3.8 KiB
Python

# playlists/sql_builder.py
from typing import Tuple, List
from playlists.playlist_model import RuleSet
from datetime import datetime, timedelta
def build_sql_from_rules(rules: RuleSet) -> Tuple[str, List]:
"""
Construit une requête SQL complète (SELECT * FROM videos ...)
en fonction d'un RuleSet.
Retourne (sql_query, params).
"""
where = ["1=1"]
params = []
# --- DATES (delta prioritaire) ---
if rules.date_delta_days is not None:
try:
delta_days = int(rules.date_delta_days)
date_after = (datetime.now() + timedelta(days=delta_days)).strftime("%Y-%m-%d")
where.append("record_datetime >= ?")
params.append(date_after)
except (ValueError, TypeError) as e:
print(f"⚠️ [SQL Builder] Delta invalide ({rules.date_delta_days!r}) : {e}")
else:
if rules.date_after:
where.append("record_datetime >= ?")
params.append(rules.date_after)
if rules.date_before:
where.append("record_datetime <= ?")
params.append(rules.date_before)
# --- LABELS ---
if rules.include_labels:
placeholders = ",".join("?" * len(rules.include_labels))
if rules.label_logic == "AND":
where.append(f"""
file_name IN (
SELECT vl.video_file_name
FROM video_labels vl
JOIN labels l ON l.id = vl.label_id
WHERE l.name IN ({placeholders})
GROUP BY vl.video_file_name
HAVING COUNT(DISTINCT l.name) = {len(rules.include_labels)}
)
""")
else:
where.append(f"""
file_name IN (
SELECT vl.video_file_name
FROM video_labels vl
JOIN labels l ON l.id = vl.label_id
WHERE l.name IN ({placeholders})
)
""")
params.extend(rules.include_labels)
if rules.exclude_labels:
placeholders = ",".join("?" * len(rules.exclude_labels))
where.append(f"""
file_name NOT IN (
SELECT vl.video_file_name
FROM video_labels vl
JOIN labels l ON l.id = vl.label_id
WHERE l.name IN ({placeholders})
)
""")
params.extend(rules.exclude_labels)
# --- PLAYLISTS ---
if rules.include_playlists:
placeholders = ",".join("?" * len(rules.include_playlists))
where.append(f"""
file_name IN (
SELECT vp.video_file_name
FROM video_playlists vp
JOIN playlists p ON p.id = vp.playlist_id
WHERE p.name IN ({placeholders})
)
""")
params.extend(rules.include_playlists)
if rules.exclude_playlists:
placeholders = ",".join("?" * len(rules.exclude_playlists))
where.append(f"""
file_name NOT IN (
SELECT vp.video_file_name
FROM video_playlists vp
JOIN playlists p ON p.id = vp.playlist_id
WHERE p.name IN ({placeholders})
)
""")
params.extend(rules.exclude_playlists)
# --- DIFFICULTÉ ---
if rules.difficulty and rules.difficulty != "Tous":
where.append("difficulty_level = ?")
params.append(rules.difficulty)
# --- JOUR ---
if rules.day_of_week:
where.append("day_of_week = ?")
params.append(rules.day_of_week)
# --- ADRESSE ---
if rules.address_keyword:
where.append("address NOT LIKE '%unknown%' AND address LIKE ?")
params.append(f"%{rules.address_keyword}%")
sql = f"SELECT * FROM videos WHERE {' AND '.join(where)} ORDER BY record_datetime DESC"
return sql, params