mirror of
https://github.com/SoPat712/allstarr.git
synced 2026-02-09 23:55:10 -05:00
Fix external mapping: add Map to External button for external tracks, fetch metadata from provider, set searchQuery for missing tracks
This commit is contained in:
@@ -640,7 +640,7 @@ public class AdminController : ControllerBase
|
|||||||
albumArtUrl = track.AlbumArtUrl,
|
albumArtUrl = track.AlbumArtUrl,
|
||||||
isLocal = isLocal,
|
isLocal = isLocal,
|
||||||
externalProvider = externalProvider,
|
externalProvider = externalProvider,
|
||||||
searchQuery = isLocal == false ? $"{track.Title} {track.PrimaryArtist}" : null,
|
searchQuery = isLocal != true ? $"{track.Title} {track.PrimaryArtist}" : null, // Set for both external and missing
|
||||||
isManualMapping = isManualMapping,
|
isManualMapping = isManualMapping,
|
||||||
manualMappingType = manualMappingType,
|
manualMappingType = manualMappingType,
|
||||||
manualMappingId = manualMappingId
|
manualMappingId = manualMappingId
|
||||||
@@ -740,7 +740,7 @@ public class AdminController : ControllerBase
|
|||||||
albumArtUrl = track.AlbumArtUrl,
|
albumArtUrl = track.AlbumArtUrl,
|
||||||
isLocal = isLocal,
|
isLocal = isLocal,
|
||||||
externalProvider = externalProvider,
|
externalProvider = externalProvider,
|
||||||
searchQuery = isLocal == false ? $"{track.Title} {track.PrimaryArtist}" : null
|
searchQuery = isLocal != true ? $"{track.Title} {track.PrimaryArtist}" : null // Set for both external and missing
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1031,11 +1031,15 @@ public class AdminController : ControllerBase
|
|||||||
|
|
||||||
_logger.LogInformation("Cleared playlist caches for {Playlist} to force rebuild", decodedName);
|
_logger.LogInformation("Cleared playlist caches for {Playlist} to force rebuild", decodedName);
|
||||||
|
|
||||||
// Fetch the mapped Jellyfin track details to return to the UI
|
// Fetch the mapped track details to return to the UI
|
||||||
string? trackTitle = null;
|
string? trackTitle = null;
|
||||||
string? trackArtist = null;
|
string? trackArtist = null;
|
||||||
string? trackAlbum = null;
|
string? trackAlbum = null;
|
||||||
|
bool isLocalMapping = hasJellyfinMapping;
|
||||||
|
|
||||||
|
if (hasJellyfinMapping)
|
||||||
|
{
|
||||||
|
// Fetch Jellyfin track details
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var userId = _jellyfinSettings.UserId;
|
var userId = _jellyfinSettings.UserId;
|
||||||
@@ -1071,6 +1075,33 @@ public class AdminController : ControllerBase
|
|||||||
{
|
{
|
||||||
_logger.LogWarning(ex, "Failed to fetch mapped track details, but mapping was saved");
|
_logger.LogWarning(ex, "Failed to fetch mapped track details, but mapping was saved");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Fetch external provider track details
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var metadataService = HttpContext.RequestServices.GetRequiredService<IMusicMetadataService>();
|
||||||
|
var externalSong = await metadataService.GetSongAsync(request.ExternalProvider!, request.ExternalId!);
|
||||||
|
|
||||||
|
if (externalSong != null)
|
||||||
|
{
|
||||||
|
trackTitle = externalSong.Title;
|
||||||
|
trackArtist = externalSong.Artist;
|
||||||
|
trackAlbum = externalSong.Album;
|
||||||
|
_logger.LogInformation("✓ Fetched external track metadata: {Title} by {Artist}", trackTitle, trackArtist);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.LogWarning("Failed to fetch external track metadata for {Provider} ID {Id}",
|
||||||
|
request.ExternalProvider, request.ExternalId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogWarning(ex, "Failed to fetch external track metadata, but mapping was saved");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Trigger immediate playlist rebuild with the new mapping
|
// Trigger immediate playlist rebuild with the new mapping
|
||||||
if (_matchingService != null)
|
if (_matchingService != null)
|
||||||
@@ -1104,11 +1135,12 @@ public class AdminController : ControllerBase
|
|||||||
// Return success with track details if available
|
// Return success with track details if available
|
||||||
var mappedTrack = new
|
var mappedTrack = new
|
||||||
{
|
{
|
||||||
id = request.JellyfinId,
|
id = hasJellyfinMapping ? request.JellyfinId : request.ExternalId,
|
||||||
title = trackTitle ?? "Unknown",
|
title = trackTitle ?? "Unknown",
|
||||||
artist = trackArtist ?? "Unknown",
|
artist = trackArtist ?? "Unknown",
|
||||||
album = trackAlbum ?? "Unknown",
|
album = trackAlbum ?? "Unknown",
|
||||||
isLocal = true
|
isLocal = isLocalMapping,
|
||||||
|
externalProvider = hasExternalMapping ? request.ExternalProvider : null
|
||||||
};
|
};
|
||||||
|
|
||||||
return Ok(new
|
return Ok(new
|
||||||
|
|||||||
@@ -1799,7 +1799,7 @@
|
|||||||
if (t.isManualMapping && t.manualMappingType === 'external') {
|
if (t.isManualMapping && t.manualMappingType === 'external') {
|
||||||
statusBadge += '<span class="status-badge" style="font-size:0.75rem;padding:2px 8px;margin-left:4px;background:var(--info);color:white;"><span class="status-dot" style="background:white;"></span>Manual</span>';
|
statusBadge += '<span class="status-badge" style="font-size:0.75rem;padding:2px 8px;margin-left:4px;background:var(--info);color:white;"><span class="status-dot" style="background:white;"></span>Manual</span>';
|
||||||
}
|
}
|
||||||
// Add manual map button for external tracks using data attributes
|
// Add both mapping buttons for external tracks using data attributes
|
||||||
const firstArtist = (t.artists && t.artists.length > 0) ? t.artists[0] : '';
|
const firstArtist = (t.artists && t.artists.length > 0) ? t.artists[0] : '';
|
||||||
mapButton = `<button class="small map-track-btn"
|
mapButton = `<button class="small map-track-btn"
|
||||||
data-playlist-name="${escapeHtml(name)}"
|
data-playlist-name="${escapeHtml(name)}"
|
||||||
@@ -1807,7 +1807,14 @@
|
|||||||
data-title="${escapeHtml(t.title || '')}"
|
data-title="${escapeHtml(t.title || '')}"
|
||||||
data-artist="${escapeHtml(firstArtist)}"
|
data-artist="${escapeHtml(firstArtist)}"
|
||||||
data-spotify-id="${escapeHtml(t.spotifyId || '')}"
|
data-spotify-id="${escapeHtml(t.spotifyId || '')}"
|
||||||
style="margin-left:8px;font-size:0.75rem;padding:4px 8px;">Map to Local</button>`;
|
style="margin-left:8px;font-size:0.75rem;padding:4px 8px;">Map to Local</button>
|
||||||
|
<button class="small map-external-btn"
|
||||||
|
data-playlist-name="${escapeHtml(name)}"
|
||||||
|
data-position="${t.position}"
|
||||||
|
data-title="${escapeHtml(t.title || '')}"
|
||||||
|
data-artist="${escapeHtml(firstArtist)}"
|
||||||
|
data-spotify-id="${escapeHtml(t.spotifyId || '')}"
|
||||||
|
style="margin-left:4px;font-size:0.75rem;padding:4px 8px;background:var(--warning);border-color:var(--warning);">Map to External</button>`;
|
||||||
} else {
|
} else {
|
||||||
// isLocal is null/undefined - track is missing (not found locally or externally)
|
// isLocal is null/undefined - track is missing (not found locally or externally)
|
||||||
statusBadge = '<span class="status-badge" style="font-size:0.75rem;padding:2px 8px;margin-left:8px;background:var(--bg-tertiary);color:var(--text-secondary);"><span class="status-dot" style="background:var(--text-secondary);"></span>Missing</span>';
|
statusBadge = '<span class="status-badge" style="font-size:0.75rem;padding:2px 8px;margin-left:8px;background:var(--bg-tertiary);color:var(--text-secondary);"><span class="status-dot" style="background:var(--text-secondary);"></span>Missing</span>';
|
||||||
|
|||||||
Reference in New Issue
Block a user