Fix UI freeze on iPod mount/track-load and add content_hash/sync-metadata
- Move mount_device, get_device_info, and track scanning to background WorkerThread (new 'mount_and_load' task type) so the UI stays responsive - Fix DeviceMonitor auto-poll to run detect_devices() in a background thread - Refactor _on_device_detection_finished and _on_mount_clicked to use the new worker; remove synchronous _set_device_mounted - Avoid double scan (get_track_count + get_all_tracks) — scan once in worker - Add content_hash fingerprint to _scan_ipod_files and library_cache for track matching - Add update_track_metadata / _write_databases_from_tracks with artwork override support in Nano7Database - Add 'Sync Metadata' button and context menu action in LibraryTab
This commit is contained in:
+28
-9
@@ -1,13 +1,25 @@
|
||||
import logging
|
||||
from typing import Set
|
||||
|
||||
from PyQt6.QtCore import QObject, QTimer, pyqtSignal
|
||||
from PyQt6.QtCore import QObject, QTimer, QThread, pyqtSignal
|
||||
|
||||
from ipod_device import IPodDevice
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class _DetectWorker(QThread):
|
||||
finished = pyqtSignal(object)
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
devices = IPodDevice().detect_devices()
|
||||
self.finished.emit(devices)
|
||||
except Exception:
|
||||
logger.exception("Device detection failed")
|
||||
self.finished.emit([])
|
||||
|
||||
|
||||
class DeviceMonitor(QObject):
|
||||
|
||||
state_changed = pyqtSignal(list)
|
||||
@@ -17,6 +29,7 @@ class DeviceMonitor(QObject):
|
||||
self.timer = QTimer(self)
|
||||
self.timer.timeout.connect(self._poll)
|
||||
self._device_ids: Set[str] = set()
|
||||
self._poll_worker = None
|
||||
|
||||
def start(self, interval_ms: int = 3000):
|
||||
self._device_ids.clear()
|
||||
@@ -25,14 +38,20 @@ class DeviceMonitor(QObject):
|
||||
|
||||
def stop(self):
|
||||
self.timer.stop()
|
||||
if self._poll_worker and self._poll_worker.isRunning():
|
||||
self._poll_worker.quit()
|
||||
self._poll_worker.wait(3000)
|
||||
self._device_ids.clear()
|
||||
|
||||
def _poll(self):
|
||||
try:
|
||||
devices = IPodDevice().detect_devices()
|
||||
current_ids = {d["id"] for d in devices}
|
||||
if current_ids != self._device_ids:
|
||||
self._device_ids = current_ids
|
||||
self.state_changed.emit(devices)
|
||||
except Exception:
|
||||
logger.exception("DeviceMonitor poll failed")
|
||||
if self._poll_worker and self._poll_worker.isRunning():
|
||||
return
|
||||
self._poll_worker = _DetectWorker()
|
||||
self._poll_worker.finished.connect(self._on_devices_detected)
|
||||
self._poll_worker.start()
|
||||
|
||||
def _on_devices_detected(self, devices):
|
||||
current_ids = {d["id"] for d in devices}
|
||||
if current_ids != self._device_ids:
|
||||
self._device_ids = current_ids
|
||||
self.state_changed.emit(devices)
|
||||
|
||||
Reference in New Issue
Block a user