diff --git a/core/metadata_service.py b/core/metadata_service.py index 5b0a367b..eda5f6e7 100644 --- a/core/metadata_service.py +++ b/core/metadata_service.py @@ -276,18 +276,6 @@ def _build_discography_release_dict(release: Any, artist_id: str) -> Optional[Di if not release_id: return None - artist_ids = _extract_lookup_value(release, 'artist_ids') or [] - if isinstance(artist_ids, (str, bytes)): - artist_ids = [artist_ids] - else: - try: - artist_ids = list(artist_ids) - except TypeError: - artist_ids = [artist_ids] - - if artist_ids and str(artist_ids[0]) != str(artist_id): - return None - album_type = _extract_lookup_value(release, 'album_type', default='album') or 'album' release_date = _extract_lookup_value(release, 'release_date') @@ -551,7 +539,6 @@ def _build_artist_detail_release_card(release: Dict[str, Any]) -> Optional[Dict[ 'id': release_id, 'name': _extract_lookup_value(release, 'name', 'title', default=release_id), 'title': _extract_lookup_value(release, 'name', 'title', default=release_id), - 'spotify_id': release_id, 'album_type': album_type, 'image_url': _extract_lookup_value(release, 'image_url', 'thumb_url', 'cover_image'), 'year': release_year, diff --git a/tests/test_metadata_service_discography.py b/tests/test_metadata_service_discography.py index 391b5ebb..10d9235d 100644 --- a/tests/test_metadata_service_discography.py +++ b/tests/test_metadata_service_discography.py @@ -432,7 +432,6 @@ def test_get_artist_detail_discography_classifies_release_types(monkeypatch): assert [ep["id"] for ep in result["eps"]] == ["ep-1"] assert [single["id"] for single in result["singles"]] == ["single-1"] assert result["albums"][0]["title"] == "Album One" - assert result["albums"][0]["spotify_id"] == "album-1" assert result["albums"][0]["owned"] is None assert result["albums"][0]["track_completion"] == "checking" @@ -480,3 +479,45 @@ def test_get_artist_detail_discography_dedups_variant_releases(monkeypatch): assert [album["id"] for album in result["albums"]] == ["album-standard"] assert result["albums"][0]["title"] == "Variant Album" assert result["albums"][0]["track_count"] == 10 + + +def test_get_artist_discography_keeps_provider_artist_ids(monkeypatch): + class _SpotifyArtistIdClient(_FakeSourceClient): + def get_artist_albums(self, artist_id, **kwargs): + self.album_calls.append((artist_id, dict(kwargs))) + return [ + types.SimpleNamespace( + id="spotify-release-1", + name="Spotify Album", + release_date="2024-01-01", + album_type="album", + image_url="https://img.example/spotify-release-1.jpg", + total_tracks=9, + external_urls={"spotify": "https://example/spotify-release-1"}, + artist_ids=["7wzRaLHNSWIG8ZHK2hQljt"], + ) + ] + + spotify = _SpotifyArtistIdClient() + clients = {"spotify": spotify} + + monkeypatch.setattr(metadata_service, "get_primary_source", lambda: "spotify") + monkeypatch.setattr(metadata_service, "get_source_priority", lambda primary: [primary]) + monkeypatch.setattr(metadata_service, "get_client_for_source", lambda source: clients.get(source)) + + result = metadata_service.get_artist_discography("364555966", "Amarok", MetadataLookupOptions()) + + assert result["source"] == "spotify" + assert [album["id"] for album in result["albums"]] == ["spotify-release-1"] + assert spotify.album_calls == [ + ( + "364555966", + { + "album_type": "album,single", + "limit": 50, + "allow_fallback": False, + "skip_cache": False, + "max_pages": 0, + }, + ), + ] diff --git a/web_server.py b/web_server.py index 788f47d5..8ef88c2b 100644 --- a/web_server.py +++ b/web_server.py @@ -11924,7 +11924,7 @@ def library_completion_stream(): try: # Map Library field names to helper field names mapped = { - 'id': item.get('spotify_id', ''), + 'id': item['id'], 'name': item['title'], 'total_tracks': item.get('track_count', 0), 'album_type': item.get('album_type', 'album') @@ -11935,12 +11935,12 @@ def library_completion_stream(): else: result = check_album_completion(db, mapped, artist_name, source_override=source_override) - result['spotify_id'] = item.get('spotify_id', '') + result['id'] = item['id'] result['category'] = category result['type'] = 'completion' yield f"data: {json.dumps(result)}\n\n" except Exception as e: - yield f"data: {json.dumps({'type': 'completion', 'category': category, 'spotify_id': item.get('spotify_id', ''), 'status': 'error', 'owned_tracks': 0, 'expected_tracks': item.get('track_count', 0), 'completion_percentage': 0, 'confidence': 0.0, 'error': str(e)})}\n\n" + yield f"data: {json.dumps({'type': 'completion', 'category': category, 'id': item['id'], 'status': 'error', 'owned_tracks': 0, 'expected_tracks': item.get('track_count', 0), 'completion_percentage': 0, 'confidence': 0.0, 'error': str(e)})}\n\n" time.sleep(0.05) # 50ms between items for visible streaming diff --git a/webui/static/script.js b/webui/static/script.js index 8d6754ca..3418a9c9 100644 --- a/webui/static/script.js +++ b/webui/static/script.js @@ -45052,8 +45052,8 @@ function createReleaseCard(release) { const card = document.createElement("div"); const isChecking = release.owned === null; card.className = `release-card${isChecking ? " checking" : (release.owned ? "" : " missing")}`; - card.setAttribute("data-release-id", release.id || ""); - card.setAttribute("data-spotify-id", release.spotify_id || ""); + const releaseId = release.id || ""; + card.setAttribute("data-release-id", releaseId); // Store mutable reference so stream updates propagate to click handler card._releaseData = release; @@ -45243,7 +45243,7 @@ function createReleaseCard(release) { try { // Convert release object to album format expected by our function const albumData = { - id: rel.spotify_id || rel.id, + id: rel.id, name: rel.title, image_url: rel.image_url, release_date: rel.year ? `${rel.year}-01-01` : '', @@ -45415,7 +45415,8 @@ async function checkLibraryCompletion(artistName, discography) { } function updateLibraryReleaseCard(data) { - const card = document.querySelector(`[data-spotify-id="${data.spotify_id}"]`); + const releaseId = data.id || ""; + const card = document.querySelector(`[data-release-id="${releaseId}"]`); if (!card) return; const isOwned = data.status !== 'missing' && data.status !== 'error';