mirror of
https://github.com/SoPat712/allstarr.git
synced 2026-02-09 23:55:10 -05:00
Fix: Add on-demand external track search when cache is empty
- Search external providers in real-time if no cached match exists - Use fuzzy matching (60% threshold) for external tracks - Ensures external tracks are always available even without pre-matching - Local tracks still prioritized first (70% threshold)
This commit is contained in:
@@ -2973,12 +2973,13 @@ public class JellyfinController : ControllerBase
|
||||
}
|
||||
|
||||
// ONLY if no local track exists, check for external match
|
||||
var matched = orderedTracks.FirstOrDefault(t => t.SpotifyId == spotifyTrack.SpotifyId);
|
||||
// First check pre-matched cache
|
||||
var matched = orderedTracks?.FirstOrDefault(t => t.SpotifyId == spotifyTrack.SpotifyId);
|
||||
if (matched != null)
|
||||
{
|
||||
finalTracks.Add(matched.MatchedSong);
|
||||
externalUsedCount++;
|
||||
_logger.LogInformation("📥 #{Pos} '{Title}' by {Artist} → EXTERNAL: {Provider}/{Id}",
|
||||
_logger.LogInformation("📥 #{Pos} '{Title}' by {Artist} → EXTERNAL (cached): {Provider}/{Id}",
|
||||
spotifyTrack.Position,
|
||||
spotifyTrack.Title,
|
||||
spotifyTrack.PrimaryArtist,
|
||||
@@ -2987,9 +2988,65 @@ public class JellyfinController : ControllerBase
|
||||
}
|
||||
else
|
||||
{
|
||||
skippedCount++;
|
||||
_logger.LogWarning("❌ #{Pos} '{Title}' by {Artist} → NO MATCH (not in Jellyfin, not in external cache)",
|
||||
spotifyTrack.Position, spotifyTrack.Title, spotifyTrack.PrimaryArtist);
|
||||
// No cached match - search external providers on-demand
|
||||
try
|
||||
{
|
||||
var query = $"{spotifyTrack.Title} {spotifyTrack.PrimaryArtist}";
|
||||
var searchResults = await _metadataService.SearchSongsAsync(query, limit: 5);
|
||||
|
||||
if (searchResults.Count > 0)
|
||||
{
|
||||
// Fuzzy match to find best result
|
||||
var bestExternalMatch = searchResults
|
||||
.Select(song => new
|
||||
{
|
||||
Song = song,
|
||||
TitleScore = FuzzyMatcher.CalculateSimilarity(spotifyTrack.Title, song.Title),
|
||||
ArtistScore = FuzzyMatcher.CalculateSimilarity(spotifyTrack.PrimaryArtist, song.Artist)
|
||||
})
|
||||
.Select(x => new
|
||||
{
|
||||
x.Song,
|
||||
x.TitleScore,
|
||||
x.ArtistScore,
|
||||
TotalScore = (x.TitleScore * 0.6) + (x.ArtistScore * 0.4)
|
||||
})
|
||||
.OrderByDescending(x => x.TotalScore)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (bestExternalMatch != null && bestExternalMatch.TotalScore >= 60)
|
||||
{
|
||||
finalTracks.Add(bestExternalMatch.Song);
|
||||
externalUsedCount++;
|
||||
_logger.LogInformation("📥 #{Pos} '{Title}' by {Artist} → EXTERNAL (on-demand): {Provider}/{Id} (score: {Score:F1}%)",
|
||||
spotifyTrack.Position,
|
||||
spotifyTrack.Title,
|
||||
spotifyTrack.PrimaryArtist,
|
||||
bestExternalMatch.Song.ExternalProvider,
|
||||
bestExternalMatch.Song.ExternalId,
|
||||
bestExternalMatch.TotalScore);
|
||||
}
|
||||
else
|
||||
{
|
||||
skippedCount++;
|
||||
_logger.LogWarning("❌ #{Pos} '{Title}' by {Artist} → NO MATCH (best external score: {Score:F1}%, need 60%)",
|
||||
spotifyTrack.Position, spotifyTrack.Title, spotifyTrack.PrimaryArtist,
|
||||
bestExternalMatch?.TotalScore ?? 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
skippedCount++;
|
||||
_logger.LogWarning("❌ #{Pos} '{Title}' by {Artist} → NO MATCH (no external results)",
|
||||
spotifyTrack.Position, spotifyTrack.Title, spotifyTrack.PrimaryArtist);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
skippedCount++;
|
||||
_logger.LogError(ex, "❌ #{Pos} '{Title}' by {Artist} → ERROR searching external providers",
|
||||
spotifyTrack.Position, spotifyTrack.Title, spotifyTrack.PrimaryArtist);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user