@ -1,6 +1,7 @@
using System ;
using System ;
using System.ComponentModel.DataAnnotations ;
using System.ComponentModel.DataAnnotations ;
using System.Linq ;
using System.Linq ;
using System.Threading ;
using Jellyfin.Api.Extensions ;
using Jellyfin.Api.Extensions ;
using Jellyfin.Api.Helpers ;
using Jellyfin.Api.Helpers ;
using Jellyfin.Api.ModelBinders ;
using Jellyfin.Api.ModelBinders ;
@ -34,6 +35,7 @@ public class ItemsController : BaseJellyfinApiController
private readonly IDtoService _dtoService ;
private readonly IDtoService _dtoService ;
private readonly ILogger < ItemsController > _logger ;
private readonly ILogger < ItemsController > _logger ;
private readonly ISessionManager _sessionManager ;
private readonly ISessionManager _sessionManager ;
private readonly IUserDataManager _userDataRepository ;
/// <summary>
/// <summary>
/// Initializes a new instance of the <see cref="ItemsController"/> class.
/// Initializes a new instance of the <see cref="ItemsController"/> class.
@ -44,13 +46,15 @@ public class ItemsController : BaseJellyfinApiController
/// <param name="dtoService">Instance of the <see cref="IDtoService"/> interface.</param>
/// <param name="dtoService">Instance of the <see cref="IDtoService"/> interface.</param>
/// <param name="logger">Instance of the <see cref="ILogger"/> interface.</param>
/// <param name="logger">Instance of the <see cref="ILogger"/> interface.</param>
/// <param name="sessionManager">Instance of the <see cref="ISessionManager"/> interface.</param>
/// <param name="sessionManager">Instance of the <see cref="ISessionManager"/> interface.</param>
/// <param name="userDataRepository">Instance of the <see cref="IUserDataManager"/> interface.</param>
public ItemsController (
public ItemsController (
IUserManager userManager ,
IUserManager userManager ,
ILibraryManager libraryManager ,
ILibraryManager libraryManager ,
ILocalizationManager localization ,
ILocalizationManager localization ,
IDtoService dtoService ,
IDtoService dtoService ,
ILogger < ItemsController > logger ,
ILogger < ItemsController > logger ,
ISessionManager sessionManager )
ISessionManager sessionManager ,
IUserDataManager userDataRepository )
{
{
_userManager = userManager ;
_userManager = userManager ;
_libraryManager = libraryManager ;
_libraryManager = libraryManager ;
@ -58,6 +62,7 @@ public class ItemsController : BaseJellyfinApiController
_dtoService = dtoService ;
_dtoService = dtoService ;
_logger = logger ;
_logger = logger ;
_sessionManager = sessionManager ;
_sessionManager = sessionManager ;
_userDataRepository = userDataRepository ;
}
}
/// <summary>
/// <summary>
@ -881,4 +886,103 @@ public class ItemsController : BaseJellyfinApiController
itemsResult . TotalRecordCount ,
itemsResult . TotalRecordCount ,
returnItems ) ;
returnItems ) ;
}
}
/// <summary>
/// Get Item User Data.
/// </summary>
/// <param name="userId">The user id.</param>
/// <param name="itemId">The item id.</param>
/// <response code="200">item user data returned.</response>
/// <response code="404">When item is not found.</response>
/// <returns>Return Item <see cref="UserItemDataDto"/>.</returns>
[HttpGet("Users/{userId}/Items/{itemId}/UserData")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult < UserItemDataDto > GetItemUserData (
[FromRoute, Required] Guid userId ,
[FromRoute, Required] Guid itemId )
{
var user = _userManager . GetUserById ( userId ) ? ? throw new ResourceNotFoundException ( ) ;
var item = _libraryManager . GetItemById ( itemId ) ;
return ( item = = null ) ? NotFound ( ) : _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="played">Optional. Whether to mark the item as played.</param>
/// <param name="favorite">Optional. Whether to mark the item as favorite.</param>
/// <param name="likes">Optional. Whether mark the item as liked.</param>
/// <param name="rating">Optional. User item rating.</param>
/// <param name="playbackPositionTicks">Optional. User Item playback Position Ticks. 1 tick = 10000 ms.</param>
/// <param name="playCount">Item user data.</param>
/// <param name="lastPlayedDate">Optional. The date the item was played.</param>
/// <response code="200">update user data returned.</response>
/// <response code="404">When item is not found.</response>
/// <returns><see cref="UserItemDataDto"/>.</returns>
[HttpPost("Users/{userId}/Items/{itemId}/UserData")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult < UserItemDataDto > UpdateItemUserData (
[FromRoute, Required] Guid userId ,
[FromRoute, Required] Guid itemId ,
[FromQuery] bool? played ,
[FromQuery] bool? favorite ,
[FromQuery] bool? likes ,
[FromQuery] double? rating ,
[FromQuery] long? playbackPositionTicks ,
[FromQuery] int? playCount ,
[FromQuery, ModelBinder(typeof(LegacyDateTimeModelBinder))] DateTime ? lastPlayedDate )
{
var user = _userManager . GetUserById ( userId ) ? ? throw new ResourceNotFoundException ( ) ;
var item = _libraryManager . GetItemById ( itemId ) ;
if ( item = = null )
{
return NotFound ( ) ;
}
var userData = _userDataRepository . GetUserData ( user , item ) ;
if ( played . HasValue )
{
userData . Played = played . Value ;
}
if ( favorite . HasValue )
{
userData . IsFavorite = favorite . Value ;
}
if ( likes . HasValue )
{
userData . Likes = likes . Value ;
}
if ( rating . HasValue )
{
userData . Rating = rating . Value ;
}
if ( playbackPositionTicks . HasValue )
{
userData . PlaybackPositionTicks = playbackPositionTicks . Value ;
}
if ( playCount . HasValue )
{
userData . PlayCount = playCount . Value ;
}
if ( lastPlayedDate . HasValue )
{
userData . LastPlayedDate = lastPlayedDate . Value ;
}
_userDataRepository . SaveUserData ( user . Id , item , userData , UserDataSaveReason . UpdateUserData , CancellationToken . None ) ;
return _userDataRepository . GetUserDataDto ( item , user ) ;
}
}
}