🐛 | Fix prefetch bug (str vs int), move json import to module level, add missing type hints
Some checks failed
SonarQube Code Quality Scan / SonarQube Scan (push) Failing after 1m20s
Some checks failed
SonarQube Code Quality Scan / SonarQube Scan (push) Failing after 1m20s
This commit is contained in:
@@ -84,13 +84,13 @@ def save_volume(volume: int) -> None:
|
|||||||
save_config(dict(SETTINGS))
|
save_config(dict(SETTINGS))
|
||||||
|
|
||||||
|
|
||||||
def save_setting(key: str, value) -> None:
|
def save_setting(key: str, value: object) -> None:
|
||||||
"""Persist a single setting and update the in-memory SETTINGS dict."""
|
"""Persist a single setting and update the in-memory SETTINGS dict."""
|
||||||
SETTINGS[key] = value
|
SETTINGS[key] = value
|
||||||
save_config(dict(SETTINGS))
|
save_config(dict(SETTINGS))
|
||||||
|
|
||||||
|
|
||||||
def get_setting(key: str):
|
def get_setting(key: str) -> object:
|
||||||
"""Return a setting value from the in-memory dict."""
|
"""Return a setting value from the in-memory dict."""
|
||||||
return SETTINGS.get(key, DEFAULT_CONFIG.get(key))
|
return SETTINGS.get(key, DEFAULT_CONFIG.get(key))
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
"""SQLite-backed database for song history, favourites, and play stats."""
|
"""SQLite-backed database for song history, favourites, and play stats."""
|
||||||
|
|
||||||
|
import json
|
||||||
import sqlite3
|
import sqlite3
|
||||||
import threading
|
import threading
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
@@ -87,7 +88,6 @@ class MusicDB:
|
|||||||
duration: int = 0,
|
duration: int = 0,
|
||||||
thumbnail: Optional[str] = None) -> None:
|
thumbnail: Optional[str] = None) -> None:
|
||||||
"""Record that a song was played (upsert + history row)."""
|
"""Record that a song was played (upsert + history row)."""
|
||||||
import json
|
|
||||||
artists_json = json.dumps(artists, ensure_ascii=False)
|
artists_json = json.dumps(artists, ensure_ascii=False)
|
||||||
album_json = json.dumps(album) if album else None
|
album_json = json.dumps(album) if album else None
|
||||||
with self._lock:
|
with self._lock:
|
||||||
|
|||||||
@@ -414,6 +414,8 @@ class AudioPlayer(QObject):
|
|||||||
self._active_task_id: Optional[int] = None
|
self._active_task_id: Optional[int] = None
|
||||||
# The task ID of the in-progress prefetch (if any).
|
# The task ID of the in-progress prefetch (if any).
|
||||||
self._prefetch_task_id: Optional[int] = None
|
self._prefetch_task_id: Optional[int] = None
|
||||||
|
# The video_id being prefetched (used to avoid duplicate prefetches).
|
||||||
|
self._prefetch_video_id: Optional[str] = None
|
||||||
# Cache of prefetched results: video_id → resolved dict with _local_path.
|
# Cache of prefetched results: video_id → resolved dict with _local_path.
|
||||||
self._prefetch_cache: dict[str, dict] = {}
|
self._prefetch_cache: dict[str, dict] = {}
|
||||||
|
|
||||||
@@ -616,6 +618,7 @@ class AudioPlayer(QObject):
|
|||||||
self._worker.cancel_requested.emit()
|
self._worker.cancel_requested.emit()
|
||||||
self._active_task_id = None
|
self._active_task_id = None
|
||||||
self._prefetch_task_id = None
|
self._prefetch_task_id = None
|
||||||
|
self._prefetch_video_id = None
|
||||||
|
|
||||||
@Slot(int, dict)
|
@Slot(int, dict)
|
||||||
def _on_download_succeeded(self, task_id: int, song: dict) -> None:
|
def _on_download_succeeded(self, task_id: int, song: dict) -> None:
|
||||||
@@ -647,6 +650,7 @@ class AudioPlayer(QObject):
|
|||||||
# ── Stale check for prefetch download ────────────────────────
|
# ── Stale check for prefetch download ────────────────────────
|
||||||
if task_id == self._prefetch_task_id:
|
if task_id == self._prefetch_task_id:
|
||||||
self._prefetch_task_id = None
|
self._prefetch_task_id = None
|
||||||
|
self._prefetch_video_id = None
|
||||||
|
|
||||||
vid = song.get("videoId") or song.get("video_id", "")
|
vid = song.get("videoId") or song.get("video_id", "")
|
||||||
# Only cache if the song is still in the active queue.
|
# Only cache if the song is still in the active queue.
|
||||||
@@ -680,6 +684,7 @@ class AudioPlayer(QObject):
|
|||||||
self._try_next_song()
|
self._try_next_song()
|
||||||
elif task_id == self._prefetch_task_id:
|
elif task_id == self._prefetch_task_id:
|
||||||
self._prefetch_task_id = None
|
self._prefetch_task_id = None
|
||||||
|
self._prefetch_video_id = None
|
||||||
log.debug("Prefetch failed for task %d (harmless)", task_id)
|
log.debug("Prefetch failed for task %d (harmless)", task_id)
|
||||||
else:
|
else:
|
||||||
log.debug("Ignoring stale download failure for task %d", task_id)
|
log.debug("Ignoring stale download failure for task %d", task_id)
|
||||||
@@ -818,7 +823,7 @@ class AudioPlayer(QObject):
|
|||||||
# Already cached or already downloading.
|
# Already cached or already downloading.
|
||||||
if vid in self._prefetch_cache:
|
if vid in self._prefetch_cache:
|
||||||
return
|
return
|
||||||
if vid == self._prefetch_task_id:
|
if vid == self._prefetch_video_id:
|
||||||
return
|
return
|
||||||
# Don't prefetch if it's already the active download target.
|
# Don't prefetch if it's already the active download target.
|
||||||
if self._active_task_id is not None:
|
if self._active_task_id is not None:
|
||||||
@@ -831,6 +836,7 @@ class AudioPlayer(QObject):
|
|||||||
task_id = self._next_task_id
|
task_id = self._next_task_id
|
||||||
self._next_task_id += 1
|
self._next_task_id += 1
|
||||||
self._prefetch_task_id = task_id
|
self._prefetch_task_id = task_id
|
||||||
|
self._prefetch_video_id = vid
|
||||||
|
|
||||||
self._worker.download_requested.emit(task_id, next_song)
|
self._worker.download_requested.emit(task_id, next_song)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user