diff options
| author | Warry <FunWarry@users.noreply.github.com> | 2025-12-04 12:03:31 +0100 |
|---|---|---|
| committer | Warry <FunWarry@users.noreply.github.com> | 2025-12-04 12:03:31 +0100 |
| commit | 75868b32d07aafe46b69649d2da0dc2c833f112d (patch) | |
| tree | 970a50f4cbf141af0e5e0856e087e347f3b5be48 /tidal_dl_ng/gui_covers.py | |
| parent | 428d34056be16ed9d28597253b333dfbd7f21a47 (diff) | |
| download | tidal-dl-ng-75868b32d07aafe46b69649d2da0dc2c833f112d.tar.gz | |
refactor: Restructure GUI components into separate modules for improved maintainability
Diffstat (limited to 'tidal_dl_ng/gui_covers.py')
| -rw-r--r-- | tidal_dl_ng/gui_covers.py | 161 |
1 files changed, 0 insertions, 161 deletions
diff --git a/tidal_dl_ng/gui_covers.py b/tidal_dl_ng/gui_covers.py deleted file mode 100644 index 858ab11..0000000 --- a/tidal_dl_ng/gui_covers.py +++ /dev/null @@ -1,161 +0,0 @@ -"""Cover management for GUI - Handles cover loading, caching and display.""" - -from contextlib import suppress - -from PySide6 import QtGui - -from tidal_dl_ng.cache import CoverPixmapCache -from tidal_dl_ng.download import Download -from tidal_dl_ng.helper.path import resource_path -from tidal_dl_ng.logger import logger_gui -from tidal_dl_ng.worker import Worker - - -class CoverManager: - """Manages cover art loading, caching and display operations.""" - - def __init__(self, parent_window, threadpool, info_tab_widget): - """Initialize the cover manager. - - Args: - parent_window: Main window instance - threadpool: QThreadPool for async operations - info_tab_widget: InfoTabWidget instance for display - """ - self.parent = parent_window - self.threadpool = threadpool - self.info_tab = info_tab_widget - self.cache = CoverPixmapCache() - self.cover_url_current = "" - - def load_cover(self, media, use_cache_check: bool = True): - """Load and display cover for media item. - - Args: - media: Media object (Track, Album, etc.) - use_cache_check: If True, check cache before loading - """ - if use_cache_check: - # Try cache first for instant display - cover_url = self._get_cover_url(media) - if cover_url: - if cover_url == self.cover_url_current: - return # Already displayed - - cached_pixmap = self.cache.get(cover_url) - if cached_pixmap: - self._display_cover(cached_pixmap, cover_url) - return - - # Load asynchronously - worker = Worker(self._load_cover_async, media) - self.threadpool.start(worker) - - def _load_cover_async(self, media): - """Load cover in background thread.""" - # Emit spinner on tab widget instead of InfoTabWidget (which is QObject, not QWidget) - tab_widget = self.info_tab.tab_widget if hasattr(self.info_tab, "tab_widget") else None - if tab_widget: - self.parent.s_spinner_start.emit(tab_widget) - - try: - cover_url = self._get_cover_url(media) - - if cover_url and self.cover_url_current != cover_url: - # Check cache again (thread-safe) - cached_pixmap = self.cache.get(cover_url) - if cached_pixmap: - self._display_cover(cached_pixmap, cover_url) - else: - # Download and cache - data_cover = Download.cover_data(cover_url) - pixmap = QtGui.QPixmap() - pixmap.loadFromData(data_cover) - self.cache.set(cover_url, pixmap) - self._display_cover(pixmap, cover_url) - elif not cover_url: - self._display_default_cover() - except Exception as e: - logger_gui.warning(f"Failed to load cover: {e}") - self._display_default_cover() - finally: - self.parent.s_spinner_stop.emit() - - def _get_cover_url(self, media) -> str | None: - """Extract cover URL from media object.""" - with suppress(Exception): - if hasattr(media, "album") and media.album: - return media.album.image() - if hasattr(media, "image") and callable(getattr(media, "image", None)): - return media.image() - return None - - def _display_cover(self, pixmap: QtGui.QPixmap, url: str): - """Display a pixmap on the info tab.""" - self.info_tab.set_cover_pixmap(pixmap) - self.info_tab.cover_url_current = url - self.cover_url_current = url - - def _display_default_cover(self): - """Display default cover image.""" - path_image = resource_path("tidal_dl_ng/ui/default_album_image.png") - pixmap = QtGui.QPixmap(path_image) - self.info_tab.set_cover_pixmap(pixmap) - self.info_tab.cover_url_current = "" - self.cover_url_current = "" - - def preload_covers_for_playlist(self, items: list) -> None: - """Preload cover pixmaps for a list of tracks in background. - - Args: - items: List of Track/Video objects to preload covers for. - """ - - def worker() -> None: - # Extract unique cover URLs - cover_urls = set() - for item in items[:50]: # Limit to first 50 - with suppress(Exception): - url = self._get_cover_url(item) - if url: - cover_urls.add(url) - - # Preload each unique cover - for cover_url in cover_urls: - if self.cache.get(cover_url): - continue # Already cached - - with suppress(Exception): - data_cover = Download.cover_data(cover_url) - pixmap = QtGui.QPixmap() - pixmap.loadFromData(data_cover) - self.cache.set(cover_url, pixmap) - logger_gui.debug(f"Preloaded cover: {cover_url[:50]}...") - - worker_obj = Worker(worker) - self.threadpool.start(worker_obj) - - def _queue_cover_fetch(self, media): - """Queue a cover fetch operation for a media item.""" - with suppress(Exception): - # previously try/except/pass - self.threadpool.start(Worker(self.load_cover, media)) - - def _fetch_cover_pixmap(self, media, use_cache_check: bool): - """Fetch cover pixmap for media, with optional cache check.""" - with suppress(Exception): - # previously try/except/continue inside loop - pixmap = self.cache.get(self._get_cover_url(media)) - if pixmap: - return pixmap - - # If not in cache, download cover - cover_url = self._get_cover_url(media) - if cover_url: - data_cover = Download.cover_data(cover_url) - pixmap = QtGui.QPixmap() - pixmap.loadFromData(data_cover) - self.cache.set(cover_url, pixmap) - return pixmap - - return None |
