diff --git a/allstarr/Controllers/JellyfinController.cs b/allstarr/Controllers/JellyfinController.cs index 95f74fc..13e2fc8 100644 --- a/allstarr/Controllers/JellyfinController.cs +++ b/allstarr/Controllers/JellyfinController.cs @@ -1130,11 +1130,20 @@ public class JellyfinController : ControllerBase /// /// Marks an item as favorite. For playlists, triggers a full download. + /// Supports both /Users/{userId}/FavoriteItems/{itemId} and /UserFavoriteItems/{itemId}?userId=xxx /// [HttpPost("Users/{userId}/FavoriteItems/{itemId}")] - public async Task MarkFavorite(string userId, string itemId) + [HttpPost("UserFavoriteItems/{itemId}")] + public async Task MarkFavorite(string itemId, string? userId = null) { - _logger.LogInformation("MarkFavorite called: userId={UserId}, itemId={ItemId}", userId, itemId); + // Get userId from query string if not in path + if (string.IsNullOrEmpty(userId)) + { + userId = Request.Query["userId"].ToString(); + } + + _logger.LogInformation("MarkFavorite called: userId={UserId}, itemId={ItemId}, route={Route}", + userId, itemId, Request.Path); // Check if this is an external playlist - trigger download if (PlaylistIdHelper.IsExternalPlaylist(itemId)) @@ -1195,7 +1204,13 @@ public class JellyfinController : ControllerBase } // For local Jellyfin items, proxy the request through - var endpoint = $"Users/{userId}/FavoriteItems/{itemId}"; + // Use the official Jellyfin endpoint format + var endpoint = $"UserFavoriteItems/{itemId}"; + if (!string.IsNullOrEmpty(userId)) + { + endpoint = $"{endpoint}?userId={userId}"; + } + _logger.LogInformation("Proxying favorite request to Jellyfin: {Endpoint}", endpoint); var result = await _proxyService.PostJsonAsync(endpoint, "{}", Request.Headers); @@ -1211,11 +1226,20 @@ public class JellyfinController : ControllerBase /// /// Removes an item from favorites. + /// Supports both /Users/{userId}/FavoriteItems/{itemId} and /UserFavoriteItems/{itemId}?userId=xxx /// [HttpDelete("Users/{userId}/FavoriteItems/{itemId}")] - public async Task UnmarkFavorite(string userId, string itemId) + [HttpDelete("UserFavoriteItems/{itemId}")] + public async Task UnmarkFavorite(string itemId, string? userId = null) { - _logger.LogInformation("UnmarkFavorite called: userId={UserId}, itemId={ItemId}", userId, itemId); + // Get userId from query string if not in path + if (string.IsNullOrEmpty(userId)) + { + userId = Request.Query["userId"].ToString(); + } + + _logger.LogInformation("UnmarkFavorite called: userId={UserId}, itemId={ItemId}, route={Route}", + userId, itemId, Request.Path); // External items can't be unfavorited (they're not really favorited in Jellyfin) var (isExternal, _, _) = _localLibraryService.ParseSongId(itemId); @@ -1230,7 +1254,13 @@ public class JellyfinController : ControllerBase } // Proxy to Jellyfin to unfavorite - var endpoint = $"Users/{userId}/FavoriteItems/{itemId}"; + // Use the official Jellyfin endpoint format + var endpoint = $"UserFavoriteItems/{itemId}"; + if (!string.IsNullOrEmpty(userId)) + { + endpoint = $"{endpoint}?userId={userId}"; + } + _logger.LogInformation("Proxying unfavorite request to Jellyfin: {Endpoint}", endpoint); var result = await _proxyService.DeleteAsync(endpoint, Request.Headers);