# 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