fix: show correct track counts and IPs in admin UI

Fixed Spotify playlists showing 0 tracks, filtered out playlist folders, and corrected session IPs to use X-Forwarded-For header.
This commit is contained in:
2026-02-09 18:15:59 -05:00
parent 88bf083386
commit 838151741f
3 changed files with 55 additions and 6 deletions

View File

@@ -2044,11 +2044,16 @@ public class AdminController : ControllerBase
trackStats = await GetPlaylistTrackStats(id!);
}
// Use actual track stats for configured playlists, otherwise use Jellyfin's count
var actualTrackCount = isConfigured
? trackStats.LocalTracks + trackStats.ExternalTracks
: childCount;
playlists.Add(new
{
id,
name,
trackCount = childCount,
trackCount = actualTrackCount,
linkedSpotifyId,
isConfigured,
localTracks = trackStats.LocalTracks,

View File

@@ -85,6 +85,10 @@ public class JellyfinSessionManager : IDisposable
_logger.LogDebug("Session created for {DeviceId}", deviceId);
// Track this session
var clientIp = headers["X-Forwarded-For"].FirstOrDefault()?.Split(',')[0].Trim()
?? headers["X-Real-IP"].FirstOrDefault()
?? "Unknown";
_sessions[deviceId] = new SessionInfo
{
DeviceId = deviceId,
@@ -92,7 +96,8 @@ public class JellyfinSessionManager : IDisposable
Device = device,
Version = version,
LastActivity = DateTime.UtcNow,
Headers = CloneHeaders(headers)
Headers = CloneHeaders(headers),
ClientIp = clientIp
};
// Start a WebSocket connection to Jellyfin on behalf of this client
@@ -222,6 +227,7 @@ public class JellyfinSessionManager : IDisposable
Client = s.Client,
Device = s.Device,
Version = s.Version,
ClientIp = s.ClientIp,
LastActivity = s.LastActivity,
InactiveMinutes = Math.Round((now - s.LastActivity).TotalMinutes, 1),
HasWebSocket = s.WebSocket != null,
@@ -565,6 +571,7 @@ public class JellyfinSessionManager : IDisposable
public ClientWebSocket? WebSocket { get; set; }
public string? LastPlayingItemId { get; set; }
public long? LastPlayingPositionTicks { get; set; }
public string? ClientIp { get; set; }
}
public void Dispose()

View File

@@ -838,6 +838,17 @@ public class SpotifyApiClient : IDisposable
continue;
}
// Check __typename to filter out folders and only include playlists
if (playlistItem.TryGetProperty("__typename", out var typename))
{
var typeStr = typename.GetString();
// Skip folders - only process Playlist types
if (typeStr != null && typeStr.Contains("Folder", StringComparison.OrdinalIgnoreCase))
{
continue;
}
}
// Get playlist URI/ID
string? uri = null;
if (playlistItem.TryGetProperty("uri", out var uriProp))
@@ -851,6 +862,12 @@ public class SpotifyApiClient : IDisposable
if (string.IsNullOrEmpty(uri)) continue;
// Skip if not a playlist URI (e.g., folders have different URI format)
if (!uri.StartsWith("spotify:playlist:", StringComparison.OrdinalIgnoreCase))
{
continue;
}
var spotifyId = uri.Replace("spotify:playlist:", "", StringComparison.OrdinalIgnoreCase);
var itemName = playlist.TryGetProperty("name", out var n) ? n.GetString() ?? "" : "";
@@ -862,13 +879,33 @@ public class SpotifyApiClient : IDisposable
continue;
}
// Get track count if available
// Get track count if available - try multiple possible paths
var trackCount = 0;
if (playlist.TryGetProperty("content", out var content) &&
content.TryGetProperty("totalCount", out var totalTrackCount))
if (playlist.TryGetProperty("content", out var content))
{
if (content.TryGetProperty("totalCount", out var totalTrackCount))
{
trackCount = totalTrackCount.GetInt32();
}
}
// Fallback: try attributes.itemCount
else if (playlist.TryGetProperty("attributes", out var attributes) &&
attributes.TryGetProperty("itemCount", out var itemCountProp))
{
trackCount = itemCountProp.GetInt32();
}
// Fallback: try totalCount directly
else if (playlist.TryGetProperty("totalCount", out var directTotalCount))
{
trackCount = directTotalCount.GetInt32();
}
// Log if we couldn't find track count for debugging
if (trackCount == 0)
{
_logger.LogDebug("Could not find track count for playlist {Name} (ID: {Id}). Response structure: {Json}",
itemName, spotifyId, playlist.GetRawText());
}
// Get owner name
string? ownerName = null;