diff --git a/linedance-app/local/scanner.py b/linedance-app/local/scanner.py index 4ffe05bf..eb3b6422 100644 --- a/linedance-app/local/scanner.py +++ b/linedance-app/local/scanner.py @@ -104,6 +104,7 @@ def scan_library(library_id: int, library_path: str, db_path: str, """, (library_id, tags.get("title",""), tags.get("artist",""), tags.get("album",""), bpm, tags.get("duration_sec",0), tags.get("file_format",""), mtime, extra, existing["id"])) + song_id = existing["id"] else: song_id = str(uuid.uuid4()) conn.execute(""" @@ -117,6 +118,30 @@ def scan_library(library_id: int, library_path: str, db_path: str, tags.get("duration_sec",0), tags.get("file_format",""), mtime, extra)) + # Importer dans-tags fra filen hvis de ikke allerede er i DB + file_dances = tags.get("dances", []) + if file_dances: + existing_dances = conn.execute( + "SELECT COUNT(*) FROM song_dances WHERE song_id=?", (song_id,) + ).fetchone()[0] + if existing_dances == 0: + for order, dance_name in enumerate(file_dances, start=1): + dance_row = conn.execute( + "SELECT id FROM dances WHERE name=? COLLATE NOCASE LIMIT 1", + (dance_name,) + ).fetchone() + if not dance_row: + cur = conn.execute( + "INSERT INTO dances (name) VALUES (?)", (dance_name,) + ) + dance_id = cur.lastrowid + else: + dance_id = dance_row["id"] + conn.execute( + "INSERT OR IGNORE INTO song_dances (song_id, dance_id, dance_order) VALUES (?,?,?)", + (song_id, dance_id, order) + ) + conn.commit() except Exception as e: logger.warning(f"Scan fejl {fp.name}: {e}") diff --git a/linedance-app/local/sync_manager.py b/linedance-app/local/sync_manager.py index b8a3156d..9c3d678d 100644 --- a/linedance-app/local/sync_manager.py +++ b/linedance-app/local/sync_manager.py @@ -79,51 +79,6 @@ class SyncManager: ) except Exception: pass - # Importer brugerens egne dans-tags - for tag in data.get("song_tags", []): - title = tag.get("song_title", "") - artist = tag.get("song_artist", "") - dance_name = tag.get("dance_name", "") - level_name = tag.get("level_name", "") - if not title or not dance_name: - continue - song = conn.execute( - "SELECT id FROM songs WHERE title=? AND artist=? LIMIT 1", - (title, artist) - ).fetchone() - if not song: - continue - level_row = conn.execute( - "SELECT id FROM dance_levels WHERE name=? COLLATE NOCASE LIMIT 1", - (level_name,) - ).fetchone() if level_name else None - level_id = level_row["id"] if level_row else None - dance_row = conn.execute( - "SELECT id FROM dances WHERE name=? AND level_id IS ? LIMIT 1", - (dance_name, level_id) - ).fetchone() - if not dance_row: - cur = conn.execute( - "INSERT OR IGNORE INTO dances (name, level_id) VALUES (?,?)", - (dance_name, level_id) - ) - dance_id = cur.lastrowid - else: - dance_id = dance_row["id"] - existing = conn.execute( - "SELECT id FROM song_dances WHERE song_id=? AND dance_id=?", - (song["id"], dance_id) - ).fetchone() - if not existing: - max_order = conn.execute( - "SELECT COALESCE(MAX(dance_order),0) FROM song_dances WHERE song_id=?", - (song["id"],) - ).fetchone()[0] - conn.execute( - "INSERT INTO song_dances (song_id, dance_id, dance_order) VALUES (?,?,?)", - (song["id"], dance_id, max_order + 1) - ) - conn.commit() conn.close() @@ -323,21 +278,39 @@ class SyncManager: ) pl_id = cur.lastrowid - # Indsæt sange med lokal matching + # Indsæt sange — opret dem lokalt hvis de ikke findes endnu + position = 1 for song_data in pl.get("songs", []): + title = song_data.get("title", "") + artist = song_data.get("artist", "") + if not title: + continue + # Find sangen lokalt local = conn.execute( - "SELECT id FROM songs WHERE title=? AND artist=? AND file_missing=0 LIMIT 1", - (song_data["title"], song_data["artist"]) + "SELECT id FROM songs WHERE title=? AND artist=? LIMIT 1", + (title, artist) ).fetchone() - if local: - conn.execute(""" - INSERT INTO playlist_songs - (playlist_id, song_id, position, status, is_workshop, dance_override) - VALUES (?,?,?,?,?,?) - """, (pl_id, local["id"], song_data["position"], - song_data.get("status","pending"), - 1 if song_data.get("is_workshop") else 0, - song_data.get("dance_override","") or "")) + if not local: + # Opret som file_missing=1 — kobles til rigtig fil ved næste scan + import uuid + new_id = str(uuid.uuid4()) + conn.execute( + "INSERT OR IGNORE INTO songs (id, title, artist, file_missing) VALUES (?,?,?,1)", + (new_id, title, artist) + ) + local_id = new_id + else: + local_id = local["id"] + + conn.execute(""" + INSERT OR IGNORE INTO playlist_songs + (playlist_id, song_id, position, status, is_workshop, dance_override) + VALUES (?,?,?,?,?,?) + """, (pl_id, local_id, position, + song_data.get("status","pending"), + 1 if song_data.get("is_workshop") else 0, + song_data.get("dance_override","") or "")) + position += 1 conn.commit() conn.close() diff --git a/linedance-app/local/tag_reader.py b/linedance-app/local/tag_reader.py index 3df1ee8e..c6456078 100644 --- a/linedance-app/local/tag_reader.py +++ b/linedance-app/local/tag_reader.py @@ -14,6 +14,8 @@ Understøttede formater og danse-tag support: Danse gemmes ALTID i SQLite uanset format. Fil-skrivning er kun muligt for de formater der understøtter custom tags. """ +import logging +logger = logging.getLogger(__name__) import os from datetime import datetime, timezone @@ -27,7 +29,7 @@ try: MUTAGEN_AVAILABLE = True except ImportError: MUTAGEN_AVAILABLE = False - print("Advarsel: mutagen ikke installeret — tag-læsning deaktiveret") + logger.warning("mutagen ikke installeret — tag-læsning deaktiveret") # Filtyper vi høster metadata fra @@ -323,7 +325,7 @@ def _write_vorbis_dances(path: Path, dances: list[str]) -> bool: audio.save() return True except Exception as e: - print(f"Vorbis skrivefejl {path}: {e}") + logger.warning(f"Vorbis skrivefejl {path}: {e}") return False @@ -336,7 +338,7 @@ def _write_m4a_dances(path: Path, dances: list[str]) -> bool: audio.save() return True except Exception as e: - print(f"M4A skrivefejl {path}: {e}") + logger.warning(f"M4A skrivefejl {path}: {e}") return False @@ -368,10 +370,10 @@ def analyze_bpm(path: str | Path) -> float | None: bpm = float(tempo) return round(bpm, 1) if bpm > 0 else None except ImportError: - print("librosa ikke installeret — installer med: pip install librosa") + logger.warning("librosa ikke installeret — installer med: pip install librosa") return None except Exception as e: - print(f"BPM-analyse fejl for {path}: {e}") + logger.warning(f"BPM-analyse fejl for {path}: {e}") return None