feat: raise discography limit to 500 and paginate Discogs artist releases

Raise the album fetch limit from 50 to 500 across all three call sites
(artist-detail page, discography download modal, source-detail view).
Deezer/iTunes/Spotify already paginate internally; Discogs previously
fetched a single page capped at 200 raw rows.

Discogs is updated to paginate all pages (100 per request, Discogs max)
before filtering, so the limit applies to qualified albums rather than
raw API rows. The early-exit guard respects limit=0 as unlimited.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
dlynas 2026-05-08 13:51:27 -04:00
parent 09597eb6db
commit 78041ab66a
3 changed files with 26 additions and 10 deletions

View file

@ -126,7 +126,7 @@ def build_source_only_artist_detail(
allow_fallback=True, allow_fallback=True,
skip_cache=False, skip_cache=False,
max_pages=0, max_pages=0,
limit=50, limit=500,
artist_source_ids={source: artist_id}, artist_source_ids={source: artist_id},
dedup_variants=False, dedup_variants=False,
), ),

View file

@ -656,16 +656,32 @@ class DiscogsClient:
return result return result
def get_artist_albums(self, artist_id: str, album_type: str = 'album,single', limit: int = 50) -> List[Album]: def get_artist_albums(self, artist_id: str, album_type: str = 'album,single', limit: int = 500) -> List[Album]:
"""Get releases by an artist. Prefers master releases, filters features.""" """Get releases by an artist. Prefers master releases, filters features."""
# First get the artist name for feature filtering # First get the artist name for feature filtering
artist_data = self._api_get(f'/artists/{artist_id}') artist_data = self._api_get(f'/artists/{artist_id}')
artist_name = artist_data.get('name', '').lower() if artist_data else '' artist_name = artist_data.get('name', '').lower() if artist_data else ''
data = self._api_get(f'/artists/{artist_id}/releases', { # Paginate through all release pages (Discogs max per_page=100).
'sort': 'year', 'sort_order': 'desc', 'per_page': min(limit * 3, 200), # Collect everything before filtering so the limit applies to
}) # qualified albums, not raw API rows.
if not data or not data.get('releases'): PAGE_SIZE = 100
all_items: list = []
page = 1
while True:
data = self._api_get(f'/artists/{artist_id}/releases', {
'sort': 'year', 'sort_order': 'desc',
'per_page': PAGE_SIZE, 'page': page,
})
if not data or not data.get('releases'):
break
all_items.extend(data['releases'])
pagination = data.get('pagination', {})
if page >= pagination.get('pages', 1):
break
page += 1
if not all_items:
return [] return []
# Separate masters from individual releases — prefer masters (canonical versions) # Separate masters from individual releases — prefer masters (canonical versions)
@ -673,7 +689,7 @@ class DiscogsClient:
releases_no_master = [] releases_no_master = []
master_titles = set() master_titles = set()
for item in data['releases']: for item in all_items:
# Skip non-main roles # Skip non-main roles
role = item.get('role', 'Main').lower() role = item.get('role', 'Main').lower()
if role not in ('main', ''): if role not in ('main', ''):
@ -726,7 +742,7 @@ class DiscogsClient:
if album.album_type in allowed_types: if album.album_type in allowed_types:
albums.append(album) albums.append(album)
if len(albums) >= limit: if limit and len(albums) >= limit:
break break
except Exception as e: except Exception as e:
logger.debug(f"Error parsing Discogs artist release: {e}") logger.debug(f"Error parsing Discogs artist release: {e}")

View file

@ -8662,7 +8662,7 @@ def get_artist_detail(artist_id):
allow_fallback=True, allow_fallback=True,
skip_cache=False, skip_cache=False,
max_pages=0, max_pages=0,
limit=50, limit=500,
artist_source_ids=artist_source_ids, artist_source_ids=artist_source_ids,
), ),
) )
@ -9046,7 +9046,7 @@ def get_artist_discography(artist_id):
allow_fallback=True, allow_fallback=True,
skip_cache=False, skip_cache=False,
max_pages=0, max_pages=0,
limit=50, limit=500,
artist_source_ids=artist_source_ids or None, artist_source_ids=artist_source_ids or None,
), ),
) )