🐛 | 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

This commit is contained in:
2026-06-04 16:22:29 +03:00
parent d8ebd6186c
commit 7e9f78ce88
3 changed files with 10 additions and 4 deletions

View File

@@ -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))

View File

@@ -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:

View File

@@ -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)