fix: artist, album, songs image problem fixed with new ID format

This commit is contained in:
V1ck3s
2025-12-12 00:25:17 +01:00
committed by Vickes
parent d183853cb2
commit 55727f206f
5 changed files with 114 additions and 41 deletions

View File

@@ -474,7 +474,8 @@ public class SubsonicController : ControllerBase
}
/// <summary>
/// Proxies external covers. Tries album first since same ID could match a different track on Deezer.
/// Proxies external covers. Uses type from ID to determine which API to call.
/// Format: ext-{provider}-{type}-{id} (e.g., ext-deezer-artist-259, ext-deezer-album-96126)
/// </summary>
[HttpGet, HttpPost]
[Route("rest/getCoverArt")]
@@ -489,7 +490,7 @@ public class SubsonicController : ControllerBase
return NotFound();
}
var (isExternal, provider, externalId) = _localLibraryService.ParseSongId(id);
var (isExternal, provider, type, externalId) = _localLibraryService.ParseExternalId(id);
if (!isExternal)
{
@@ -507,28 +508,43 @@ public class SubsonicController : ControllerBase
string? coverUrl = null;
var album = await _metadataService.GetAlbumAsync(provider!, externalId!);
if (album?.CoverArtUrl != null)
// Use type to determine which API to call first
switch (type)
{
coverUrl = album.CoverArtUrl;
}
if (coverUrl == null)
{
var song = await _metadataService.GetSongAsync(provider!, externalId!);
if (song?.CoverArtUrl != null)
{
coverUrl = song.CoverArtUrl;
}
}
if (coverUrl == null)
{
var artist = await _metadataService.GetArtistAsync(provider!, externalId!);
if (artist?.ImageUrl != null)
{
coverUrl = artist.ImageUrl;
}
case "artist":
var artist = await _metadataService.GetArtistAsync(provider!, externalId!);
if (artist?.ImageUrl != null)
{
coverUrl = artist.ImageUrl;
}
break;
case "album":
var album = await _metadataService.GetAlbumAsync(provider!, externalId!);
if (album?.CoverArtUrl != null)
{
coverUrl = album.CoverArtUrl;
}
break;
case "song":
default:
// For songs, try to get from song first, then album
var song = await _metadataService.GetSongAsync(provider!, externalId!);
if (song?.CoverArtUrl != null)
{
coverUrl = song.CoverArtUrl;
}
else
{
// Fallback: try album with same ID (legacy behavior)
var albumFallback = await _metadataService.GetAlbumAsync(provider!, externalId!);
if (albumFallback?.CoverArtUrl != null)
{
coverUrl = albumFallback.CoverArtUrl;
}
}
break;
}
if (coverUrl != null)

View File

@@ -221,19 +221,19 @@ public class DeezerMetadataService : IMusicMetadataService
return new Song
{
Id = $"ext-deezer-{externalId}",
Id = $"ext-deezer-song-{externalId}",
Title = track.GetProperty("title").GetString() ?? "",
Artist = track.TryGetProperty("artist", out var artist)
? artist.GetProperty("name").GetString() ?? ""
: "",
ArtistId = track.TryGetProperty("artist", out var artistForId)
? $"ext-deezer-{artistForId.GetProperty("id").GetInt64()}"
? $"ext-deezer-artist-{artistForId.GetProperty("id").GetInt64()}"
: null,
Album = track.TryGetProperty("album", out var album)
? album.GetProperty("title").GetString() ?? ""
: "",
AlbumId = track.TryGetProperty("album", out var albumForId)
? $"ext-deezer-{albumForId.GetProperty("id").GetInt64()}"
? $"ext-deezer-album-{albumForId.GetProperty("id").GetInt64()}"
: null,
Duration = track.TryGetProperty("duration", out var duration)
? duration.GetInt32()
@@ -255,13 +255,13 @@ public class DeezerMetadataService : IMusicMetadataService
return new Album
{
Id = $"ext-deezer-{externalId}",
Id = $"ext-deezer-album-{externalId}",
Title = album.GetProperty("title").GetString() ?? "",
Artist = album.TryGetProperty("artist", out var artist)
? artist.GetProperty("name").GetString() ?? ""
: "",
ArtistId = album.TryGetProperty("artist", out var artistForId)
? $"ext-deezer-{artistForId.GetProperty("id").GetInt64()}"
? $"ext-deezer-artist-{artistForId.GetProperty("id").GetInt64()}"
: null,
Year = album.TryGetProperty("release_date", out var releaseDate)
? int.TryParse(releaseDate.GetString()?.Split('-')[0], out var year) ? year : null
@@ -289,7 +289,7 @@ public class DeezerMetadataService : IMusicMetadataService
return new Artist
{
Id = $"ext-deezer-{externalId}",
Id = $"ext-deezer-artist-{externalId}",
Name = artist.GetProperty("name").GetString() ?? "",
ImageUrl = artist.TryGetProperty("picture_medium", out var picture)
? picture.GetString()

View File

@@ -30,6 +30,13 @@ public interface ILocalLibraryService
/// </summary>
(bool isExternal, string? provider, string? externalId) ParseSongId(string songId);
/// <summary>
/// Parse un ID externe pour extraire le provider, le type et l'ID
/// Format: ext-{provider}-{type}-{id} (ex: ext-deezer-artist-259, ext-deezer-album-96126, ext-deezer-song-12345)
/// Also supports legacy format: ext-{provider}-{id} (assumes song type)
/// </summary>
(bool isExternal, string? provider, string? type, string? externalId) ParseExternalId(string id);
/// <summary>
/// Déclenche un scan de la bibliothèque Subsonic
/// </summary>
@@ -129,16 +136,42 @@ public class LocalLibraryService : ILocalLibraryService
public (bool isExternal, string? provider, string? externalId) ParseSongId(string songId)
{
if (songId.StartsWith("ext-"))
var (isExternal, provider, type, externalId) = ParseExternalId(songId);
return (isExternal, provider, externalId);
}
public (bool isExternal, string? provider, string? type, string? externalId) ParseExternalId(string id)
{
if (!id.StartsWith("ext-"))
{
var parts = songId.Split('-', 3);
if (parts.Length == 3)
{
return (true, parts[1], parts[2]);
}
return (false, null, null, null);
}
return (false, null, null);
var parts = id.Split('-');
// Known types for the new format
var knownTypes = new HashSet<string> { "song", "album", "artist" };
// New format: ext-{provider}-{type}-{id} (e.g., ext-deezer-artist-259)
// Only use new format if parts[2] is a known type
if (parts.Length >= 4 && knownTypes.Contains(parts[2]))
{
var provider = parts[1];
var type = parts[2];
var externalId = string.Join("-", parts.Skip(3)); // Handle IDs with dashes
return (true, provider, type, externalId);
}
// Legacy format: ext-{provider}-{id} (assumes "song" type for backward compatibility)
// This handles both 3-part IDs and 4+ part IDs where parts[2] is NOT a known type
if (parts.Length >= 3)
{
var provider = parts[1];
var externalId = string.Join("-", parts.Skip(2)); // Everything after provider is the ID
return (true, provider, "song", externalId);
}
return (false, null, null, null);
}
private async Task<Dictionary<string, LocalSongMapping>> LoadMappingsAsync()