84 lines
2.8 KiB
Python
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) |