diff --git a/core/metadata_service.py b/core/metadata_service.py index eda5f6e7..fbe04ad1 100644 --- a/core/metadata_service.py +++ b/core/metadata_service.py @@ -34,6 +34,7 @@ class MetadataLookupOptions: skip_cache: bool = False max_pages: int = 0 limit: int = 50 + artist_source_ids: Optional[Dict[str, str]] = None # ============================================================================= @@ -166,7 +167,7 @@ def get_artist_albums_for_source( released albums to show up immediately. """ client = get_client_for_source(source) - if not client or not artist_id or not hasattr(client, 'get_artist_albums'): + if not client or not hasattr(client, 'get_artist_albums'): return None def _fetch_for_artist(target_artist_id: str): @@ -181,9 +182,12 @@ def get_artist_albums_for_source( return client.get_artist_albums(target_artist_id, **kwargs) try: - albums = _fetch_for_artist(artist_id) or [] - if albums: - return albums + if artist_id: + albums = _fetch_for_artist(artist_id) or [] + if albums: + return albums + else: + albums = [] if not artist_name: return albums @@ -451,6 +455,7 @@ def get_artist_discography( """ options = options or MetadataLookupOptions() source_priority = _get_source_chain_for_lookup(options) + source_artist_ids = options.artist_source_ids or {} albums: List[Any] = [] active_source: Optional[str] = None @@ -461,10 +466,15 @@ def get_artist_discography( if not client: continue + source_artist_id = (source_artist_ids.get(source) or '').strip() + lookup_artist_id = source_artist_id if source_artist_id else (artist_id if not source_artist_ids else '') + if source_artist_id: + logger.debug("Using %s artist id %s for discography lookup", source, source_artist_id) + try: albums = get_artist_albums_for_source( source, - artist_id, + lookup_artist_id, artist_name=artist_name, limit=options.limit, skip_cache=options.skip_cache, diff --git a/tests/test_metadata_service_discography.py b/tests/test_metadata_service_discography.py index 10d9235d..48767063 100644 --- a/tests/test_metadata_service_discography.py +++ b/tests/test_metadata_service_discography.py @@ -1,5 +1,6 @@ import sys import types +import sqlite3 import pytest @@ -42,6 +43,7 @@ if "config.settings" not in sys.modules: from core import metadata_service from core.metadata_service import MetadataLookupOptions +from database.music_database import MusicDatabase @pytest.fixture(autouse=True) @@ -521,3 +523,56 @@ def test_get_artist_discography_keeps_provider_artist_ids(monkeypatch): }, ), ] + + +def test_get_artist_discography_prefers_source_specific_artist_ids(monkeypatch): + class _SourceIdClient(_FakeSourceClient): + def __init__(self, source_id, *args, **kwargs): + super().__init__(*args, **kwargs) + self.source_id = source_id + + def get_artist_albums(self, artist_id, **kwargs): + self.album_calls.append((artist_id, dict(kwargs))) + if artist_id == self.source_id: + return [ + _album(f"{self.source_id}-album-1", f"{self.source_id} Album", "2024-01-01") + ] + return [] + + spotify = _SourceIdClient("spotify-artist-1") + deezer = _SourceIdClient("deezer-artist-1") + clients = { + "spotify": spotify, + "deezer": deezer, + } + + monkeypatch.setattr(metadata_service, "get_primary_source", lambda: "spotify") + monkeypatch.setattr(metadata_service, "get_source_priority", lambda primary: [primary, "deezer"]) + monkeypatch.setattr(metadata_service, "get_client_for_source", lambda source: clients.get(source)) + + result = metadata_service.get_artist_discography( + "artist-1", + "Artist One", + MetadataLookupOptions( + artist_source_ids={ + "spotify": "spotify-artist-1", + "deezer": "deezer-artist-1", + } + ), + ) + + assert result["source"] == "spotify" + assert [album["id"] for album in result["albums"]] == ["spotify-artist-1-album-1"] + assert spotify.album_calls == [ + ( + "spotify-artist-1", + { + "album_type": "album,single", + "limit": 50, + "allow_fallback": False, + "skip_cache": False, + "max_pages": 0, + }, + ) + ] + assert deezer.album_calls == [] diff --git a/web_server.py b/web_server.py index 8ef88c2b..bed0dc67 100644 --- a/web_server.py +++ b/web_server.py @@ -10836,6 +10836,14 @@ def get_artist_detail(artist_id): try: from core.metadata_service import MetadataLookupOptions, get_artist_detail_discography as _get_artist_detail_discography + artist_source_ids = { + 'spotify': artist_info.get('spotify_artist_id'), + 'deezer': artist_info.get('deezer_id'), + 'itunes': artist_info.get('itunes_artist_id'), + 'discogs': artist_info.get('discogs_id'), + 'hydrabase': artist_info.get('soul_id'), + } + artist_detail_discography = _get_artist_detail_discography( artist_id, artist_name=artist_info['name'], @@ -10844,6 +10852,7 @@ def get_artist_detail(artist_id): skip_cache=False, max_pages=0, limit=50, + artist_source_ids=artist_source_ids, ), )