correct application of playlists rules
This commit is contained in:
109
app/playlists/sql_builder.py
Normal file
109
app/playlists/sql_builder.py
Normal file
@@ -0,0 +1,109 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user