Files
LinedanceAfspiller/linedance-app/ui/bpm_worker.py
2026-04-22 10:00:12 +02:00

84 lines
2.8 KiB
Python

"""
bpm_worker.py — QThread til BPM-analyse i baggrunden.
Ny v0.9 arkitektur: sange er i songs, filer i files, libraries i libraries.
"""
import sqlite3
from PyQt6.QtCore import QThread, pyqtSignal
class BpmScanWorker(QThread):
progress = pyqtSignal(int, int) # done, total
finished = pyqtSignal(int) # antal analyseret
def __init__(self, library_id: int, db_path: str,
scan_all: bool = False):
super().__init__()
self._library_id = library_id
self._db_path = db_path
self._scan_all = scan_all
self._cancelled = False
def cancel(self):
self.requestInterruption()
self._cancelled = True
def run(self):
import time
self._cancelled = False
try:
from local.tag_reader import analyze_bpm
conn = sqlite3.connect(self._db_path)
conn.row_factory = sqlite3.Row
conn.execute("PRAGMA journal_mode=WAL")
# Ny arkitektur: JOIN songs + files + libraries
lib_row = conn.execute(
"SELECT path FROM libraries WHERE id=?", (self._library_id,)
).fetchone()
if not lib_row:
self.finished.emit(0)
conn.close()
return
lib_path = lib_row["path"]
if self._scan_all:
songs = conn.execute("""
SELECT s.id, f.local_path
FROM songs s
JOIN files f ON f.song_id = s.id AND f.file_missing = 0
WHERE f.local_path LIKE ?
""", (lib_path + "%",)).fetchall()
else:
songs = conn.execute("""
SELECT s.id, f.local_path
FROM songs s
JOIN files f ON f.song_id = s.id AND f.file_missing = 0
WHERE f.local_path LIKE ?
AND (s.bpm IS NULL OR s.bpm = 0)
""", (lib_path + "%",)).fetchall()
total = len(songs)
done = 0
for song in songs:
if self._cancelled or self.isInterruptionRequested():
break
try:
bpm = analyze_bpm(song["local_path"])
if bpm and bpm > 0:
conn.execute(
"UPDATE songs SET bpm=? WHERE id=?",
(int(round(bpm)), song["id"])
)
conn.commit()
except Exception:
pass
done += 1
self.progress.emit(done, total)
time.sleep(0.01)
conn.close()
self.finished.emit(done)
except Exception:
self.finished.emit(0)