mirror of
https://github.com/SoPat712/allstarr.git
synced 2026-02-10 07:58:39 -05:00
Add local/external track columns to Jellyfin playlists, remove libraries filter
This commit is contained in:
@@ -697,7 +697,7 @@ public class AdminController : ControllerBase
|
||||
/// Get all playlists from Jellyfin
|
||||
/// </summary>
|
||||
[HttpGet("jellyfin/playlists")]
|
||||
public async Task<IActionResult> GetJellyfinPlaylists([FromQuery] string? userId = null, [FromQuery] string? parentId = null)
|
||||
public async Task<IActionResult> GetJellyfinPlaylists([FromQuery] string? userId = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(_jellyfinSettings.Url) || string.IsNullOrEmpty(_jellyfinSettings.ApiKey))
|
||||
{
|
||||
@@ -706,7 +706,7 @@ public class AdminController : ControllerBase
|
||||
|
||||
try
|
||||
{
|
||||
// Build URL with optional userId and parentId (library) filters
|
||||
// Build URL with optional userId filter
|
||||
var url = $"{_jellyfinSettings.Url}/Items?IncludeItemTypes=Playlist&Recursive=true&Fields=ProviderIds,ChildCount,RecursiveItemCount,SongCount";
|
||||
|
||||
if (!string.IsNullOrEmpty(userId))
|
||||
@@ -714,11 +714,6 @@ public class AdminController : ControllerBase
|
||||
url += $"&UserId={userId}";
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(parentId))
|
||||
{
|
||||
url += $"&ParentId={parentId}";
|
||||
}
|
||||
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, url);
|
||||
request.Headers.Add("X-Emby-Authorization", GetJellyfinAuthHeader());
|
||||
|
||||
@@ -758,13 +753,19 @@ public class AdminController : ControllerBase
|
||||
var isConfigured = configuredPlaylist != null;
|
||||
var linkedSpotifyId = configuredPlaylist?.Id;
|
||||
|
||||
// Fetch track details to categorize local vs external
|
||||
var trackStats = await GetPlaylistTrackStats(id!);
|
||||
|
||||
playlists.Add(new
|
||||
{
|
||||
id,
|
||||
name,
|
||||
trackCount = childCount,
|
||||
linkedSpotifyId,
|
||||
isConfigured
|
||||
isConfigured,
|
||||
localTracks = trackStats.LocalTracks,
|
||||
externalTracks = trackStats.ExternalTracks,
|
||||
externalAvailable = trackStats.ExternalAvailable
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -778,6 +779,94 @@ public class AdminController : ControllerBase
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get track statistics for a playlist (local vs external)
|
||||
/// </summary>
|
||||
private async Task<(int LocalTracks, int ExternalTracks, int ExternalAvailable)> GetPlaylistTrackStats(string playlistId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var url = $"{_jellyfinSettings.Url}/Playlists/{playlistId}/Items?Fields=ProviderIds,Path,MediaSources";
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, url);
|
||||
request.Headers.Add("X-Emby-Authorization", GetJellyfinAuthHeader());
|
||||
|
||||
var response = await _jellyfinHttpClient.SendAsync(request);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
return (0, 0, 0);
|
||||
}
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
using var doc = JsonDocument.Parse(json);
|
||||
|
||||
var localTracks = 0;
|
||||
var externalTracks = 0;
|
||||
var externalAvailable = 0;
|
||||
|
||||
if (doc.RootElement.TryGetProperty("Items", out var items))
|
||||
{
|
||||
foreach (var item in items.EnumerateArray())
|
||||
{
|
||||
// Check if track has a local path (is in user's library)
|
||||
var hasPath = item.TryGetProperty("Path", out var path) &&
|
||||
path.ValueKind == JsonValueKind.String &&
|
||||
!string.IsNullOrEmpty(path.GetString());
|
||||
|
||||
// Check MediaSources to see if it's a local file vs external
|
||||
var isLocal = false;
|
||||
if (item.TryGetProperty("MediaSources", out var mediaSources) &&
|
||||
mediaSources.ValueKind == JsonValueKind.Array)
|
||||
{
|
||||
foreach (var source in mediaSources.EnumerateArray())
|
||||
{
|
||||
if (source.TryGetProperty("Protocol", out var protocol))
|
||||
{
|
||||
var protocolStr = protocol.GetString();
|
||||
if (protocolStr == "File")
|
||||
{
|
||||
isLocal = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Also check if Path exists in MediaSource
|
||||
if (source.TryGetProperty("Path", out var sourcePath) &&
|
||||
sourcePath.ValueKind == JsonValueKind.String &&
|
||||
!string.IsNullOrEmpty(sourcePath.GetString()))
|
||||
{
|
||||
isLocal = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to checking Path property
|
||||
if (!isLocal && hasPath)
|
||||
{
|
||||
isLocal = true;
|
||||
}
|
||||
|
||||
if (isLocal)
|
||||
{
|
||||
localTracks++;
|
||||
}
|
||||
else
|
||||
{
|
||||
externalTracks++;
|
||||
// For now, if it's in the playlist but not local, it means a provider found it
|
||||
externalAvailable++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (localTracks, externalTracks, externalAvailable);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning(ex, "Failed to get track stats for playlist {PlaylistId}", playlistId);
|
||||
return (0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Link a Jellyfin playlist to a Spotify playlist
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user