mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-04-24 14:08:44 -04:00
Refactored api call logic handling.
This commit is contained in:
parent
250e795c3b
commit
2a25c5a2e3
4 changed files with 97 additions and 52 deletions
|
@ -6,6 +6,7 @@ using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.Reflection;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Jellyfin.Data.Entities;
|
using Jellyfin.Data.Entities;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
|
@ -81,6 +82,42 @@ namespace Emby.Server.Implementations.Library
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SaveUserData(User user, BaseItem item, UserDataDto userDataDto, UserDataSaveReason reason)
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(user);
|
||||||
|
ArgumentNullException.ThrowIfNull(item);
|
||||||
|
ArgumentNullException.ThrowIfNull(reason);
|
||||||
|
ArgumentNullException.ThrowIfNull(userDataDto);
|
||||||
|
|
||||||
|
var userData = GetUserData(user, item);
|
||||||
|
|
||||||
|
var parentProperties = userDataDto.GetType().GetProperties();
|
||||||
|
var childProperties = userData.GetType().GetProperties();
|
||||||
|
|
||||||
|
foreach (var parentProperty in parentProperties)
|
||||||
|
{
|
||||||
|
foreach (var childProperty in childProperties)
|
||||||
|
{
|
||||||
|
if (parentProperty.Name != childProperty.Name)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var value = parentProperty.GetValue(userDataDto, null);
|
||||||
|
|
||||||
|
if (value is null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
childProperty.SetValue(userData, value, null);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SaveUserData(user, item, userData, reason, CancellationToken.None);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Save the provided user data for the given user. Batch operation. Does not fire any events or update the cache.
|
/// Save the provided user data for the given user. Batch operation. Does not fire any events or update the cache.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -913,13 +913,7 @@ public class ItemsController : BaseJellyfinApiController
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="userId">The user id.</param>
|
/// <param name="userId">The user id.</param>
|
||||||
/// <param name="itemId">The item id.</param>
|
/// <param name="itemId">The item id.</param>
|
||||||
/// <param name="played">Optional. Whether to mark the item as played.</param>
|
/// <param name="userDataDto">New user data object.</param>
|
||||||
/// <param name="favorite">Optional. Whether to mark the item as favorite.</param>
|
|
||||||
/// <param name="likes">Optional. Whether to mark the item as liked.</param>
|
|
||||||
/// <param name="rating">Optional. User item rating.</param>
|
|
||||||
/// <param name="playbackPositionTicks">Optional. Item playback position ticks. 1 tick = 10000 ms.</param>
|
|
||||||
/// <param name="playCount">Optional. How many times the user played the item.</param>
|
|
||||||
/// <param name="lastPlayedDate">Optional. The date the item was played.</param>
|
|
||||||
/// <response code="200">return updated user item data.</response>
|
/// <response code="200">return updated user item data.</response>
|
||||||
/// <response code="404">Item is not found.</response>
|
/// <response code="404">Item is not found.</response>
|
||||||
/// <returns>Return <see cref="UserItemDataDto"/>.</returns>
|
/// <returns>Return <see cref="UserItemDataDto"/>.</returns>
|
||||||
|
@ -929,14 +923,13 @@ public class ItemsController : BaseJellyfinApiController
|
||||||
public ActionResult<UserItemDataDto> UpdateItemUserData(
|
public ActionResult<UserItemDataDto> UpdateItemUserData(
|
||||||
[FromRoute, Required] Guid userId,
|
[FromRoute, Required] Guid userId,
|
||||||
[FromRoute, Required] Guid itemId,
|
[FromRoute, Required] Guid itemId,
|
||||||
[FromQuery] bool? played,
|
[FromBody, Required] UserDataDto userDataDto)
|
||||||
[FromQuery] bool? favorite,
|
|
||||||
[FromQuery] bool? likes,
|
|
||||||
[FromQuery] double? rating,
|
|
||||||
[FromQuery] long? playbackPositionTicks,
|
|
||||||
[FromQuery] int? playCount,
|
|
||||||
[FromQuery, ModelBinder(typeof(LegacyDateTimeModelBinder))] DateTime? lastPlayedDate)
|
|
||||||
{
|
{
|
||||||
|
if (!RequestHelpers.AssertCanUpdateUser(_userManager, User, userId, 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(userId) ?? throw new ResourceNotFoundException();
|
||||||
var item = _libraryManager.GetItemById(itemId);
|
var item = _libraryManager.GetItemById(itemId);
|
||||||
if (item == null)
|
if (item == null)
|
||||||
|
@ -944,44 +937,7 @@ public class ItemsController : BaseJellyfinApiController
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
var userData = _userDataRepository.GetUserData(user, item);
|
_userDataRepository.SaveUserData(user, item, userDataDto, UserDataSaveReason.UpdateUserData);
|
||||||
|
|
||||||
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);
|
return _userDataRepository.GetUserDataDto(item, user);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,15 @@ namespace MediaBrowser.Controller.Library
|
||||||
|
|
||||||
void SaveUserData(User user, BaseItem item, UserItemData userData, UserDataSaveReason reason, CancellationToken cancellationToken);
|
void SaveUserData(User user, BaseItem item, UserItemData userData, UserDataSaveReason reason, CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Save the provided user data for the given user.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="user">The user.</param>
|
||||||
|
/// <param name="item">The item.</param>
|
||||||
|
/// <param name="userDataDto">The reason for updating the user data.</param>
|
||||||
|
/// <param name="reason">The reason.</param>
|
||||||
|
void SaveUserData(User user, BaseItem item, UserDataDto userDataDto, UserDataSaveReason reason);
|
||||||
|
|
||||||
UserItemData GetUserData(User user, BaseItem item);
|
UserItemData GetUserData(User user, BaseItem item);
|
||||||
|
|
||||||
UserItemData GetUserData(Guid userId, BaseItem item);
|
UserItemData GetUserData(Guid userId, BaseItem item);
|
||||||
|
|
43
MediaBrowser.Model/Dto/UserDataDto.cs
Normal file
43
MediaBrowser.Model/Dto/UserDataDto.cs
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
#nullable disable
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace MediaBrowser.Model.Dto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Class UserDataDto extends UserItemDataDto to allow nullable members.
|
||||||
|
/// This change allow us to implement the new /Users/{UserId}/Items/{ItemId}/UserData endpoint.
|
||||||
|
/// This object allows the requestor to update all or specific user data fields without altering the non-nullable members state.
|
||||||
|
/// </summary>
|
||||||
|
public class UserDataDto : UserItemDataDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the playback position ticks.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The playback position ticks.</value>
|
||||||
|
public new long? PlaybackPositionTicks { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the play count.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The play count.</value>
|
||||||
|
public new int? PlayCount { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a value indicating whether this instance is favorite.
|
||||||
|
/// </summary>
|
||||||
|
/// <value><c>true</c> if this instance is favorite; otherwise, <c>false</c>.</value>
|
||||||
|
public new bool? IsFavorite { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a value indicating whether this <see cref="UserItemDataDto" /> is likes.
|
||||||
|
/// </summary>
|
||||||
|
/// <value><c>null</c> if [likes] contains no value, <c>true</c> if [likes]; otherwise, <c>false</c>.</value>
|
||||||
|
public new bool? Likes { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a value indicating whether this <see cref="UserItemDataDto" /> is played.
|
||||||
|
/// </summary>
|
||||||
|
/// <value><c>true</c> if played; otherwise, <c>false</c>.</value>
|
||||||
|
public new bool? Played { get; set; }
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue