aboutsummaryrefslogtreecommitdiff
path: root/Jellyfin.Api/Controllers/ItemsController.cs
diff options
context:
space:
mode:
authorCody Robibero <cody@robibe.ro>2024-03-03 13:51:31 -0700
committerGitHub <noreply@github.com>2024-03-03 13:51:31 -0700
commit6e5ec99ea10557c141ed8d755e672cef628d35f0 (patch)
treedc3aff5d566811d7f52030c10b25fdb1a02b9b5e /Jellyfin.Api/Controllers/ItemsController.cs
parent8d40d431e8e5b067a535e564362b902480a13259 (diff)
Move userId in API from route to optional query parameter (#11074)
* Move userId in API from route to optional query parameter * Standardize UserViewsController * Move userId to query in ImageController * Move userId to query in ItemsController * Move userId to query in PlaystateController * Move userId to query in SuggestionsController * Move userId from route to query in UserLibraryController * Clean up routes * Move userId to query in UserController * fix bad merge --------- Co-authored-by: Niels van Velzen <git@ndat.nl>
Diffstat (limited to 'Jellyfin.Api/Controllers/ItemsController.cs')
-rw-r--r--Jellyfin.Api/Controllers/ItemsController.cs130
1 files changed, 114 insertions, 16 deletions
diff --git a/Jellyfin.Api/Controllers/ItemsController.cs b/Jellyfin.Api/Controllers/ItemsController.cs
index d10fba920..26ae1a820 100644
--- a/Jellyfin.Api/Controllers/ItemsController.cs
+++ b/Jellyfin.Api/Controllers/ItemsController.cs
@@ -612,8 +612,10 @@ public class ItemsController : BaseJellyfinApiController
/// <param name="enableImages">Optional, include image information in output.</param>
/// <returns>A <see cref="QueryResult{BaseItemDto}"/> with the items.</returns>
[HttpGet("Users/{userId}/Items")]
+ [Obsolete("Kept for backwards compatibility")]
+ [ApiExplorerSettings(IgnoreApi = true)]
[ProducesResponseType(StatusCodes.Status200OK)]
- public ActionResult<QueryResult<BaseItemDto>> GetItemsByUserId(
+ public ActionResult<QueryResult<BaseItemDto>> GetItemsByUserIdLegacy(
[FromRoute] Guid userId,
[FromQuery] string? maxOfficialRating,
[FromQuery] bool? hasThemeSong,
@@ -699,8 +701,7 @@ public class ItemsController : BaseJellyfinApiController
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] Guid[] genreIds,
[FromQuery] bool enableTotalRecordCount = true,
[FromQuery] bool? enableImages = true)
- {
- return GetItems(
+ => GetItems(
userId,
maxOfficialRating,
hasThemeSong,
@@ -786,7 +787,6 @@ public class ItemsController : BaseJellyfinApiController
genreIds,
enableTotalRecordCount,
enableImages);
- }
/// <summary>
/// Gets items based on a query.
@@ -808,10 +808,10 @@ public class ItemsController : BaseJellyfinApiController
/// <param name="excludeActiveSessions">Optional. Whether to exclude the currently active sessions.</param>
/// <response code="200">Items returned.</response>
/// <returns>A <see cref="QueryResult{BaseItemDto}"/> with the items that are resumable.</returns>
- [HttpGet("Users/{userId}/Items/Resume")]
+ [HttpGet("UserItems/Resume")]
[ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult<QueryResult<BaseItemDto>> GetResumeItems(
- [FromRoute, Required] Guid userId,
+ [FromQuery] Guid? userId,
[FromQuery] int? startIndex,
[FromQuery] int? limit,
[FromQuery] string? searchTerm,
@@ -827,7 +827,8 @@ public class ItemsController : BaseJellyfinApiController
[FromQuery] bool? enableImages = true,
[FromQuery] bool excludeActiveSessions = false)
{
- var user = _userManager.GetUserById(userId);
+ var requestUserId = RequestHelpers.GetUserId(User, userId);
+ var user = _userManager.GetUserById(requestUserId);
if (user is null)
{
return NotFound();
@@ -854,7 +855,7 @@ public class ItemsController : BaseJellyfinApiController
if (excludeActiveSessions)
{
excludeItemIds = _sessionManager.Sessions
- .Where(s => s.UserId.Equals(userId) && s.NowPlayingItem is not null)
+ .Where(s => s.UserId.Equals(requestUserId) && s.NowPlayingItem is not null)
.Select(s => s.NowPlayingItem.Id)
.ToArray();
}
@@ -888,6 +889,63 @@ public class ItemsController : BaseJellyfinApiController
}
/// <summary>
+ /// Gets items based on a query.
+ /// </summary>
+ /// <param name="userId">The user id.</param>
+ /// <param name="startIndex">The start index.</param>
+ /// <param name="limit">The item limit.</param>
+ /// <param name="searchTerm">The search term.</param>
+ /// <param name="parentId">Specify this to localize the search to a specific item or folder. Omit to use the root.</param>
+ /// <param name="fields">Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimited. Options: Budget, Chapters, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines.</param>
+ /// <param name="mediaTypes">Optional. Filter by MediaType. Allows multiple, comma delimited.</param>
+ /// <param name="enableUserData">Optional. Include user data.</param>
+ /// <param name="imageTypeLimit">Optional. The max number of images to return, per image type.</param>
+ /// <param name="enableImageTypes">Optional. The image types to include in the output.</param>
+ /// <param name="excludeItemTypes">Optional. If specified, results will be filtered based on item type. This allows multiple, comma delimited.</param>
+ /// <param name="includeItemTypes">Optional. If specified, results will be filtered based on the item type. This allows multiple, comma delimited.</param>
+ /// <param name="enableTotalRecordCount">Optional. Enable the total record count.</param>
+ /// <param name="enableImages">Optional. Include image information in output.</param>
+ /// <param name="excludeActiveSessions">Optional. Whether to exclude the currently active sessions.</param>
+ /// <response code="200">Items returned.</response>
+ /// <returns>A <see cref="QueryResult{BaseItemDto}"/> with the items that are resumable.</returns>
+ [HttpGet("Users/{userId}/Items/Resume")]
+ [Obsolete("Kept for backwards compatibility")]
+ [ApiExplorerSettings(IgnoreApi = true)]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ public ActionResult<QueryResult<BaseItemDto>> GetResumeItemsLegacy(
+ [FromRoute, Required] Guid userId,
+ [FromQuery] int? startIndex,
+ [FromQuery] int? limit,
+ [FromQuery] string? searchTerm,
+ [FromQuery] Guid? parentId,
+ [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields,
+ [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] MediaType[] mediaTypes,
+ [FromQuery] bool? enableUserData,
+ [FromQuery] int? imageTypeLimit,
+ [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ImageType[] enableImageTypes,
+ [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] BaseItemKind[] excludeItemTypes,
+ [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] BaseItemKind[] includeItemTypes,
+ [FromQuery] bool enableTotalRecordCount = true,
+ [FromQuery] bool? enableImages = true,
+ [FromQuery] bool excludeActiveSessions = false)
+ => GetResumeItems(
+ userId,
+ startIndex,
+ limit,
+ searchTerm,
+ parentId,
+ fields,
+ mediaTypes,
+ enableUserData,
+ imageTypeLimit,
+ enableImageTypes,
+ excludeItemTypes,
+ includeItemTypes,
+ enableTotalRecordCount,
+ enableImages,
+ excludeActiveSessions);
+
+ /// <summary>
/// Get Item User Data.
/// </summary>
/// <param name="userId">The user id.</param>
@@ -895,25 +953,44 @@ public class ItemsController : BaseJellyfinApiController
/// <response code="200">return item user data.</response>
/// <response code="404">Item is not found.</response>
/// <returns>Return <see cref="UserItemDataDto"/>.</returns>
- [HttpGet("Users/{userId}/Items/{itemId}/UserData")]
+ [HttpGet("UserItems/{itemId}/UserData")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult<UserItemDataDto> GetItemUserData(
- [FromRoute, Required] Guid userId,
+ [FromQuery] Guid? userId,
[FromRoute, Required] Guid itemId)
{
- if (!RequestHelpers.AssertCanUpdateUser(_userManager, User, userId, true))
+ var requestUserId = RequestHelpers.GetUserId(User, userId);
+ if (!RequestHelpers.AssertCanUpdateUser(_userManager, User, requestUserId, true))
{
return StatusCode(StatusCodes.Status403Forbidden, "User is not allowed to view this item user data.");
}
- var user = _userManager.GetUserById(userId) ?? throw new ResourceNotFoundException();
+ var user = _userManager.GetUserById(requestUserId) ?? throw new ResourceNotFoundException();
var item = _libraryManager.GetItemById(itemId);
return (item == null) ? NotFound() : _userDataRepository.GetUserDataDto(item, user);
}
/// <summary>
+ /// Get Item User Data.
+ /// </summary>
+ /// <param name="userId">The user id.</param>
+ /// <param name="itemId">The item id.</param>
+ /// <response code="200">return item user data.</response>
+ /// <response code="404">Item is not found.</response>
+ /// <returns>Return <see cref="UserItemDataDto"/>.</returns>
+ [HttpGet("Users/{userId}/Items/{itemId}/UserData")]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status404NotFound)]
+ [Obsolete("Kept for backwards compatibility")]
+ [ApiExplorerSettings(IgnoreApi = true)]
+ public ActionResult<UserItemDataDto> GetItemUserDataLegacy(
+ [FromRoute, Required] Guid userId,
+ [FromRoute, Required] Guid itemId)
+ => GetItemUserData(userId, itemId);
+
+ /// <summary>
/// Update Item User Data.
/// </summary>
/// <param name="userId">The user id.</param>
@@ -922,20 +999,21 @@ public class ItemsController : BaseJellyfinApiController
/// <response code="200">return updated user item data.</response>
/// <response code="404">Item is not found.</response>
/// <returns>Return <see cref="UserItemDataDto"/>.</returns>
- [HttpPost("Users/{userId}/Items/{itemId}/UserData")]
+ [HttpPost("UserItems/{itemId}/UserData")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult<UserItemDataDto> UpdateItemUserData(
- [FromRoute, Required] Guid userId,
+ [FromQuery] Guid? userId,
[FromRoute, Required] Guid itemId,
[FromBody, Required] UpdateUserItemDataDto userDataDto)
{
- if (!RequestHelpers.AssertCanUpdateUser(_userManager, User, userId, true))
+ var requestUserId = RequestHelpers.GetUserId(User, userId);
+ if (!RequestHelpers.AssertCanUpdateUser(_userManager, User, requestUserId, true))
{
return StatusCode(StatusCodes.Status403Forbidden, "User is not allowed to update this item user data.");
}
- var user = _userManager.GetUserById(userId) ?? throw new ResourceNotFoundException();
+ var user = _userManager.GetUserById(requestUserId) ?? throw new ResourceNotFoundException();
var item = _libraryManager.GetItemById(itemId);
if (item == null)
{
@@ -946,4 +1024,24 @@ public class ItemsController : BaseJellyfinApiController
return _userDataRepository.GetUserDataDto(item, user);
}
+
+ /// <summary>
+ /// Update Item User Data.
+ /// </summary>
+ /// <param name="userId">The user id.</param>
+ /// <param name="itemId">The item id.</param>
+ /// <param name="userDataDto">New user data object.</param>
+ /// <response code="200">return updated user item data.</response>
+ /// <response code="404">Item is not found.</response>
+ /// <returns>Return <see cref="UserItemDataDto"/>.</returns>
+ [HttpPost("Users/{userId}/Items/{itemId}/UserData")]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status404NotFound)]
+ [Obsolete("Kept for backwards compatibility")]
+ [ApiExplorerSettings(IgnoreApi = true)]
+ public ActionResult<UserItemDataDto> UpdateItemUserDataLegacy(
+ [FromRoute, Required] Guid userId,
+ [FromRoute, Required] Guid itemId,
+ [FromBody, Required] UpdateUserItemDataDto userDataDto)
+ => UpdateItemUserData(userId, itemId, userDataDto);
}