Merge pull request #333 from kettui/fix/completion-stream

Fix library artist details failing to fetch correct album information
pull/337/head
BoulderBadgeDad 4 weeks ago committed by GitHub
commit 9370d462ff
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -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,

@ -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,
},
),
]

@ -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

@ -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';

Loading…
Cancel
Save