Mappehåndtering

This commit is contained in:
2026-04-12 14:29:54 +02:00
parent bdb1f5915a
commit a9915c0cc9
6 changed files with 486 additions and 137 deletions

View File

@@ -8,8 +8,9 @@ from PyQt6.QtWidgets import (
QSizePolicy, QMenuBar, QMenu, QStatusBar, QFileDialog,
QMessageBox,
)
from PyQt6.QtCore import Qt, QTimer
from PyQt6.QtCore import Qt, QTimer, QThread
from PyQt6.QtGui import QAction
from pathlib import Path
from ui.vu_meter import VUMeter
from ui.playlist_panel import PlaylistPanel
@@ -78,7 +79,8 @@ class MainWindow(QMainWindow):
self._current_idx = -1
self._song_ended = False
self._demo_active = False
self._watcher = None
self._watcher = None
self._scan_workers = [] # Hold referencer til aktive scan-tråde
self._scan_worker = None
self._api_url: str | None = None
self._api_token: str | None = None
@@ -92,6 +94,7 @@ class MainWindow(QMainWindow):
self._connect_player_signals()
self._library_loaded.connect(self._apply_library)
self._db_ready.connect(self._on_db_ready)
self._build_menu()
self._build_ui()
self._build_statusbar()
@@ -383,8 +386,7 @@ class MainWindow(QMainWindow):
try:
from local.local_db import init_db
init_db()
# Trigger library load via signal
self._library_loaded.emit([]) # tomt signal = "DB klar, load nu"
self._db_ready.emit()
except Exception as e:
pass
@@ -431,7 +433,8 @@ class MainWindow(QMainWindow):
QTimer.singleShot(200, self._reload_library)
# Signal til at opdatere biblioteket fra baggrundstråd
_library_loaded = __import__('PyQt6.QtCore', fromlist=['pyqtSignal']).pyqtSignal(list)
_library_loaded = __import__('PyQt6.QtCore', fromlist=['pyqtSignal']).pyqtSignal(list)
_db_ready = __import__('PyQt6.QtCore', fromlist=['pyqtSignal']).pyqtSignal()
_file_changed_signal = __import__('PyQt6.QtCore', fromlist=['pyqtSignal']).pyqtSignal()
def _reload_library(self):
@@ -483,12 +486,12 @@ class MainWindow(QMainWindow):
except Exception:
pass
def _on_db_ready(self):
"""DB er initialiseret — indlæs bibliotek og start post-init."""
self._reload_library()
self._post_init()
def _apply_library(self, songs: list):
if not songs:
# Tomt signal = DB er klar, start library load og post-init
self._reload_library()
self._post_init()
return
self._library_panel.load_songs(songs)
count = len(songs)
self._set_status(
@@ -496,7 +499,7 @@ class MainWindow(QMainWindow):
)
def _post_init(self):
"""Kør efter DB er initialiseret — gendan state."""
"""Kør efter DB er initialiseret — gendan state og start scan."""
try:
restored = self._playlist_panel.restore_active_playlist()
if restored:
@@ -513,11 +516,48 @@ class MainWindow(QMainWindow):
except Exception:
pass
# Periodisk reload af bibliotek hvert 10. sekund — fanger ny-scannede sange
self._auto_reload_timer = QTimer(self)
self._auto_reload_timer.setInterval(10000)
self._auto_reload_timer.timeout.connect(self._reload_library)
self._auto_reload_timer.start()
# Scan 30 sek efter opstart — fanger ændringer siden sidst
QTimer.singleShot(30000, self.start_background_scan)
def start_background_scan(self):
"""Start scanning af alle aktive biblioteker i baggrunden."""
try:
import sqlite3
from local.local_db import DB_PATH
from ui.scan_worker import ScanWorker
conn = sqlite3.connect(str(DB_PATH))
conn.row_factory = sqlite3.Row
libs = conn.execute(
"SELECT id, path FROM libraries WHERE is_active=1"
).fetchall()
conn.close()
pending = [lib for lib in libs if Path(lib["path"]).exists()]
if not pending:
return
self._set_status("Scanner biblioteker i baggrunden...", 4000)
self._scan_workers = []
finished_count = [0]
def on_one_finished(count, p):
finished_count[0] += 1
self._set_status(f"Scanning færdig — {count} filer", 4000)
# Ryd færdige workers ud
self._scan_workers = [w for w in self._scan_workers
if w.isRunning()]
for lib in pending:
worker = ScanWorker(lib["id"], lib["path"], str(DB_PATH),
overwrite_bpm=False)
worker.finished.connect(on_one_finished)
worker.start()
worker.setPriority(QThread.Priority.LowestPriority)
self._scan_workers.append(worker)
except Exception:
pass
def add_library_path(self, path: str):
try:
@@ -984,9 +1024,15 @@ class MainWindow(QMainWindow):
if self._scan_worker and self._scan_worker.isRunning():
self._scan_worker.quit()
self._scan_worker.wait(2000)
try:
if self._watcher:
self._watcher.stop()
except Exception:
pass
# Stop scan workers
if hasattr(self, "_scan_workers"):
for w in self._scan_workers:
if w.isRunning():
w.cancel()
# Stop watchdog subprocess
if hasattr(self, "_watchdog_proc") and self._watchdog_proc:
try:
self._watchdog_proc.terminate()
except Exception:
pass
event.accept()