Igen
This commit is contained in:
@@ -148,97 +148,22 @@ class LibraryWatcher:
|
||||
self._running = False
|
||||
|
||||
def add_library(self, path: str) -> int:
|
||||
"""Tilføj et nyt bibliotek — scanner i baggrundstråd med egen DB-forbindelse."""
|
||||
"""Tilføj et nyt bibliotek — alt kører i baggrundstråd."""
|
||||
library_id = add_library(path)
|
||||
|
||||
if self._observer and self._running:
|
||||
handler = MusicLibraryHandler(library_id, self.on_change)
|
||||
self._observer.schedule(handler, path, recursive=True)
|
||||
def _bg(lib_id, lib_path):
|
||||
# Registrer watchdog — kan blokere lidt på Windows med mange filer
|
||||
if self._observer and self._running:
|
||||
try:
|
||||
handler = MusicLibraryHandler(lib_id, self.on_change)
|
||||
self._observer.schedule(handler, lib_path, recursive=True)
|
||||
except Exception as e:
|
||||
logger.error(f"Watchdog schedule fejl: {e}")
|
||||
|
||||
# Scan i baggrundstråd med daemon=True så den ikke blokerer programlukning
|
||||
def _scan_in_background(lib_id, lib_path):
|
||||
try:
|
||||
import sqlite3
|
||||
from local.local_db import DB_PATH, is_supported, get_file_modified_at
|
||||
from local.tag_reader import read_tags
|
||||
import os
|
||||
# Scan
|
||||
self._full_scan_library(lib_id, lib_path)
|
||||
|
||||
# Åbn egen forbindelse — deler ikke med GUI-tråden
|
||||
conn = sqlite3.connect(str(DB_PATH))
|
||||
conn.row_factory = sqlite3.Row
|
||||
|
||||
base = Path(lib_path)
|
||||
if not self._path_accessible(base):
|
||||
conn.close()
|
||||
return
|
||||
|
||||
known = {
|
||||
row["local_path"]: row["file_modified_at"]
|
||||
for row in conn.execute(
|
||||
"SELECT local_path, file_modified_at FROM songs WHERE library_id=?",
|
||||
(lib_id,)
|
||||
).fetchall()
|
||||
}
|
||||
|
||||
processed = 0
|
||||
for dirpath, _, filenames in os.walk(str(base), followlinks=False):
|
||||
for filename in filenames:
|
||||
file_path = Path(dirpath) / filename
|
||||
if not is_supported(file_path):
|
||||
continue
|
||||
path_str = str(file_path)
|
||||
disk_modified = get_file_modified_at(file_path)
|
||||
if path_str not in known or known[path_str] != disk_modified:
|
||||
try:
|
||||
tags = read_tags(file_path)
|
||||
tags["library_id"] = lib_id
|
||||
# Upsert via direkte SQL på denne forbindelse
|
||||
import uuid, json
|
||||
existing = conn.execute(
|
||||
"SELECT id FROM songs WHERE local_path=?",
|
||||
(path_str,)
|
||||
).fetchone()
|
||||
extra = json.dumps(tags.get("extra_tags", {}), ensure_ascii=False)
|
||||
if existing:
|
||||
conn.execute("""
|
||||
UPDATE songs SET library_id=?, title=?, artist=?,
|
||||
album=?, bpm=?, duration_sec=?, file_format=?,
|
||||
file_modified_at=?, file_missing=0, extra_tags=?
|
||||
WHERE id=?
|
||||
""", (lib_id, tags.get("title",""), tags.get("artist",""),
|
||||
tags.get("album",""), tags.get("bpm",0),
|
||||
tags.get("duration_sec",0), tags.get("file_format",""),
|
||||
disk_modified, extra, existing["id"]))
|
||||
song_id = existing["id"]
|
||||
else:
|
||||
song_id = str(uuid.uuid4())
|
||||
conn.execute("""
|
||||
INSERT INTO songs (id, library_id, local_path, title,
|
||||
artist, album, bpm, duration_sec, file_format,
|
||||
file_modified_at, extra_tags)
|
||||
VALUES (?,?,?,?,?,?,?,?,?,?,?)
|
||||
""", (song_id, lib_id, path_str, tags.get("title",""),
|
||||
tags.get("artist",""), tags.get("album",""),
|
||||
tags.get("bpm",0), tags.get("duration_sec",0),
|
||||
tags.get("file_format",""), disk_modified, extra))
|
||||
conn.commit()
|
||||
processed += 1
|
||||
if self.on_change:
|
||||
self.on_change("upserted", path_str, song_id)
|
||||
except Exception as e:
|
||||
logger.error(f"Scan fejl: {file_path}: {e}")
|
||||
|
||||
conn.execute(
|
||||
"UPDATE libraries SET last_full_scan=datetime('now') WHERE id=?",
|
||||
(lib_id,)
|
||||
)
|
||||
conn.commit()
|
||||
conn.close()
|
||||
logger.info(f"Bibliotek scannet: {lib_path} — {processed} filer")
|
||||
except Exception as e:
|
||||
logger.error(f"Baggrunds-scan fejl: {e}")
|
||||
|
||||
t = threading.Thread(target=_scan_in_background, args=(library_id, path), daemon=True)
|
||||
t = threading.Thread(target=_bg, args=(library_id, path), daemon=True)
|
||||
t.start()
|
||||
return library_id
|
||||
|
||||
|
||||
Reference in New Issue
Block a user