mirror of
https://github.com/SoPat712/allstarr.git
synced 2026-02-09 23:55:10 -05:00
Fix: Prioritize LOCAL tracks in Spotify playlist injection - match by name only
- Remove Spotify ID/ISRC matching (Jellyfin plugin doesn't add these) - Use ONLY fuzzy name matching (title + artist, 70% threshold) - LOCAL tracks ALWAYS used first before external providers - Include ALL tracks from Jellyfin playlist (even if not in Spotify) - Prevent duplicate track usage with HashSet tracking - AdminController also updated to match by name for Local/External badges - Better logging with emojis for debugging
This commit is contained in:
@@ -312,26 +312,65 @@ public class AdminController : ControllerBase
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
using var doc = JsonDocument.Parse(json);
|
||||
|
||||
var localSpotifyIds = new HashSet<string>();
|
||||
// Build list of local tracks (match by name only - no Spotify IDs!)
|
||||
var localTracks = new List<(string Title, string Artist)>();
|
||||
if (doc.RootElement.TryGetProperty("Items", out var items))
|
||||
{
|
||||
foreach (var item in items.EnumerateArray())
|
||||
{
|
||||
if (item.TryGetProperty("ProviderIds", out var providerIds) &&
|
||||
providerIds.TryGetProperty("Spotify", out var spotifyId))
|
||||
var title = item.TryGetProperty("Name", out var nameEl) ? nameEl.GetString() ?? "" : "";
|
||||
var artist = "";
|
||||
|
||||
if (item.TryGetProperty("Artists", out var artistsEl) && artistsEl.GetArrayLength() > 0)
|
||||
{
|
||||
var id = spotifyId.GetString();
|
||||
if (!string.IsNullOrEmpty(id))
|
||||
{
|
||||
localSpotifyIds.Add(id);
|
||||
}
|
||||
artist = artistsEl[0].GetString() ?? "";
|
||||
}
|
||||
else if (item.TryGetProperty("AlbumArtist", out var albumArtistEl))
|
||||
{
|
||||
artist = albumArtistEl.GetString() ?? "";
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(title))
|
||||
{
|
||||
localTracks.Add((title, artist));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mark tracks as local or external
|
||||
_logger.LogInformation("Found {Count} local tracks in Jellyfin playlist {Playlist}",
|
||||
localTracks.Count, decodedName);
|
||||
|
||||
// Match Spotify tracks to local tracks by name (fuzzy matching)
|
||||
foreach (var track in spotifyTracks)
|
||||
{
|
||||
var isLocal = false;
|
||||
|
||||
if (localTracks.Count > 0)
|
||||
{
|
||||
var bestMatch = localTracks
|
||||
.Select(local => new
|
||||
{
|
||||
Local = local,
|
||||
TitleScore = FuzzyMatcher.CalculateSimilarity(track.Title, local.Title),
|
||||
ArtistScore = FuzzyMatcher.CalculateSimilarity(track.PrimaryArtist, local.Artist)
|
||||
})
|
||||
.Select(x => new
|
||||
{
|
||||
x.Local,
|
||||
x.TitleScore,
|
||||
x.ArtistScore,
|
||||
TotalScore = (x.TitleScore * 0.7) + (x.ArtistScore * 0.3)
|
||||
})
|
||||
.OrderByDescending(x => x.TotalScore)
|
||||
.FirstOrDefault();
|
||||
|
||||
// Use 70% threshold (same as playback matching)
|
||||
if (bestMatch != null && bestMatch.TotalScore >= 70)
|
||||
{
|
||||
isLocal = true;
|
||||
}
|
||||
}
|
||||
|
||||
tracksWithStatus.Add(new
|
||||
{
|
||||
position = track.Position,
|
||||
@@ -342,7 +381,7 @@ public class AdminController : ControllerBase
|
||||
spotifyId = track.SpotifyId,
|
||||
durationMs = track.DurationMs,
|
||||
albumArtUrl = track.AlbumArtUrl,
|
||||
isLocal = localSpotifyIds.Contains(track.SpotifyId)
|
||||
isLocal = isLocal
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user