""" Songlist management utilities. Handles songlist loading, tracking, and songlist-specific operations. """ import json from datetime import datetime from pathlib import Path from karaoke_downloader.data_path_manager import get_data_path_manager from karaoke_downloader.server_manager import ( check_and_mark_server_duplicate, is_song_marked_as_server_duplicate, is_song_on_server, load_server_duplicates_tracking, load_server_songs, ) def load_songlist(songlist_path=None): if songlist_path is None: songlist_path = str(get_data_path_manager().get_songlist_path()) songlist_file = Path(songlist_path) if not songlist_file.exists(): print(f"⚠️ Songlist file not found: {songlist_path}") return [] try: with open(songlist_file, "r", encoding="utf-8") as f: data = json.load(f) all_songs = [] seen = set() for category in data: if "songs" in category: for song in category["songs"]: if "artist" in song and "title" in song: artist = song["artist"].strip() title = song["title"].strip() key = f"{artist.lower()}_{normalize_title(title)}" if key in seen: continue seen.add(key) all_songs.append( { "artist": artist, "title": title, "position": song.get("position", 0), } ) print(f"📋 Loaded {len(all_songs)} unique songs from songlist (deduplicated)") return all_songs except (json.JSONDecodeError, FileNotFoundError) as e: print(f"⚠️ Could not load songlist: {e}") return [] def normalize_title(title): normalized = title.replace("(Karaoke Version)", "").replace("(Karaoke)", "").strip() return " ".join(normalized.split()).lower() def load_songlist_tracking(tracking_path=None): if tracking_path is None: tracking_path = str(get_data_path_manager().get_songlist_tracking_path()) tracking_file = Path(tracking_path) if not tracking_file.exists(): return {} try: with open(tracking_file, "r", encoding="utf-8") as f: return json.load(f) except (json.JSONDecodeError, FileNotFoundError) as e: print(f"⚠️ Could not load songlist tracking: {e}") return {} def save_songlist_tracking(tracking, tracking_path=None): if tracking_path is None: tracking_path = str(get_data_path_manager().get_songlist_tracking_path()) try: with open(tracking_path, "w", encoding="utf-8") as f: json.dump(tracking, f, indent=2, ensure_ascii=False) except Exception as e: print(f"⚠️ Could not save songlist tracking: {e}") def is_songlist_song_downloaded(tracking, artist, title): key = f"{artist.lower()}_{normalize_title(title)}" return key in tracking def mark_songlist_song_downloaded(tracking, artist, title, channel_name, file_path): key = f"{artist.lower()}_{normalize_title(title)}" tracking[key] = { "artist": artist, "title": title, "channel": channel_name, "file_path": str(file_path), "downloaded_at": datetime.now().isoformat(), } save_songlist_tracking(tracking)