Merge pull request #333 from kettui/fix/completion-stream
Fix library artist details failing to fetch correct album information
This commit is contained in:
commit
9370d462ff
4 changed files with 50 additions and 21 deletions
|
|
@ -276,18 +276,6 @@ def _build_discography_release_dict(release: Any, artist_id: str) -> Optional[Di
|
||||||
if not release_id:
|
if not release_id:
|
||||||
return None
|
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'
|
album_type = _extract_lookup_value(release, 'album_type', default='album') or 'album'
|
||||||
release_date = _extract_lookup_value(release, 'release_date')
|
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,
|
'id': release_id,
|
||||||
'name': _extract_lookup_value(release, 'name', 'title', default=release_id),
|
'name': _extract_lookup_value(release, 'name', 'title', default=release_id),
|
||||||
'title': _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,
|
'album_type': album_type,
|
||||||
'image_url': _extract_lookup_value(release, 'image_url', 'thumb_url', 'cover_image'),
|
'image_url': _extract_lookup_value(release, 'image_url', 'thumb_url', 'cover_image'),
|
||||||
'year': release_year,
|
'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 [ep["id"] for ep in result["eps"]] == ["ep-1"]
|
||||||
assert [single["id"] for single in result["singles"]] == ["single-1"]
|
assert [single["id"] for single in result["singles"]] == ["single-1"]
|
||||||
assert result["albums"][0]["title"] == "Album One"
|
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]["owned"] is None
|
||||||
assert result["albums"][0]["track_completion"] == "checking"
|
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 [album["id"] for album in result["albums"]] == ["album-standard"]
|
||||||
assert result["albums"][0]["title"] == "Variant Album"
|
assert result["albums"][0]["title"] == "Variant Album"
|
||||||
assert result["albums"][0]["track_count"] == 10
|
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:
|
try:
|
||||||
# Map Library field names to helper field names
|
# Map Library field names to helper field names
|
||||||
mapped = {
|
mapped = {
|
||||||
'id': item.get('spotify_id', ''),
|
'id': item['id'],
|
||||||
'name': item['title'],
|
'name': item['title'],
|
||||||
'total_tracks': item.get('track_count', 0),
|
'total_tracks': item.get('track_count', 0),
|
||||||
'album_type': item.get('album_type', 'album')
|
'album_type': item.get('album_type', 'album')
|
||||||
|
|
@ -11935,12 +11935,12 @@ def library_completion_stream():
|
||||||
else:
|
else:
|
||||||
result = check_album_completion(db, mapped, artist_name, source_override=source_override)
|
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['category'] = category
|
||||||
result['type'] = 'completion'
|
result['type'] = 'completion'
|
||||||
yield f"data: {json.dumps(result)}\n\n"
|
yield f"data: {json.dumps(result)}\n\n"
|
||||||
except Exception as e:
|
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
|
time.sleep(0.05) # 50ms between items for visible streaming
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45052,8 +45052,8 @@ function createReleaseCard(release) {
|
||||||
const card = document.createElement("div");
|
const card = document.createElement("div");
|
||||||
const isChecking = release.owned === null;
|
const isChecking = release.owned === null;
|
||||||
card.className = `release-card${isChecking ? " checking" : (release.owned ? "" : " missing")}`;
|
card.className = `release-card${isChecking ? " checking" : (release.owned ? "" : " missing")}`;
|
||||||
card.setAttribute("data-release-id", release.id || "");
|
const releaseId = release.id || "";
|
||||||
card.setAttribute("data-spotify-id", release.spotify_id || "");
|
card.setAttribute("data-release-id", releaseId);
|
||||||
// Store mutable reference so stream updates propagate to click handler
|
// Store mutable reference so stream updates propagate to click handler
|
||||||
card._releaseData = release;
|
card._releaseData = release;
|
||||||
|
|
||||||
|
|
@ -45243,7 +45243,7 @@ function createReleaseCard(release) {
|
||||||
try {
|
try {
|
||||||
// Convert release object to album format expected by our function
|
// Convert release object to album format expected by our function
|
||||||
const albumData = {
|
const albumData = {
|
||||||
id: rel.spotify_id || rel.id,
|
id: rel.id,
|
||||||
name: rel.title,
|
name: rel.title,
|
||||||
image_url: rel.image_url,
|
image_url: rel.image_url,
|
||||||
release_date: rel.year ? `${rel.year}-01-01` : '',
|
release_date: rel.year ? `${rel.year}-01-01` : '',
|
||||||
|
|
@ -45415,7 +45415,8 @@ async function checkLibraryCompletion(artistName, discography) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateLibraryReleaseCard(data) {
|
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;
|
if (!card) return;
|
||||||
|
|
||||||
const isOwned = data.status !== 'missing' && data.status !== 'error';
|
const isOwned = data.status !== 'missing' && data.status !== 'error';
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue