diff --git a/web_server.py b/web_server.py index b4bde9b6..74f2aabf 100644 --- a/web_server.py +++ b/web_server.py @@ -11776,7 +11776,7 @@ class WebMetadataUpdateWorker: self.processed_count = 0 self.successful_count = 0 self.failed_count = 0 - self.max_workers = 4 + self.max_workers = 1 self.thread_lock = threading.Lock() def stop(self): @@ -11882,6 +11882,10 @@ class WebMetadataUpdateWorker: # Individual artist updates are tracked in progress but not shown as separate activity items # This prevents spam in the activity feed (unlike dashboard which shows these in a separate widget) + + # Add delay between artist processing to respect Spotify API rate limits + import time + time.sleep(1.0) # Mark as completed - equivalent to finished.emit metadata_update_state['status'] = 'completed' @@ -12647,7 +12651,7 @@ def merge_discography_data(owned_releases, spotify_discography): # Calculate track completion using Spotify track count spotify_track_count = spotify_release.get('track_count', 0) - owned_track_count = owned_release.get('track_count') or 0 + owned_track_count = owned_release.get('owned_tracks') or 0 if spotify_track_count > 0 and owned_track_count is not None: completion_percentage = (owned_track_count / spotify_track_count) * 100 diff --git a/webui/index.html b/webui/index.html index 40c81bb6..faafefec 100644 --- a/webui/index.html +++ b/webui/index.html @@ -749,6 +749,7 @@

Artist Name

+
diff --git a/webui/static/script.js b/webui/static/script.js index eaf6e0a8..d8a88f23 100644 --- a/webui/static/script.js +++ b/webui/static/script.js @@ -11288,9 +11288,9 @@ function retryLastSearch() { * Update artist detail header with artist info */ function updateArtistDetailHeader(artist) { - const imageElement = document.getElementById('artist-detail-image'); - const nameElement = document.getElementById('artist-detail-name'); - const genresElement = document.getElementById('artist-detail-genres'); + const imageElement = document.getElementById('search-artist-detail-image'); + const nameElement = document.getElementById('search-artist-detail-name'); + const genresElement = document.getElementById('search-artist-detail-genres'); if (imageElement && artist.image_url) { imageElement.style.backgroundImage = `url('${artist.image_url}')`; @@ -13993,7 +13993,7 @@ async function loadArtistDetailData(artistId, artistName) { showArtistDetailMain(false); // Update header with artist name - updateArtistDetailHeader(artistName); + updateArtistDetailPageHeader(artistName); try { // Call API to get artist discography data @@ -14032,7 +14032,7 @@ async function loadArtistDetailData(artistId, artistName) { } } -function updateArtistDetailHeader(artistName) { +function updateArtistDetailPageHeader(artistName) { // Update header title const headerTitle = document.getElementById("artist-detail-name"); if (headerTitle) { diff --git a/webui/static/style.css b/webui/static/style.css index 8b12fbb2..71e1774c 100644 --- a/webui/static/style.css +++ b/webui/static/style.css @@ -9412,6 +9412,13 @@ body { letter-spacing: -0.3px; } +.artist-genres-container { + display: flex; + flex-wrap: wrap; + gap: 8px; + margin-bottom: 24px; +} + .collection-overview { display: flex; flex-direction: column;