|
|
@ -6,6 +6,7 @@ using System.Globalization;
|
|
|
|
using System.Linq;
|
|
|
|
using System.Linq;
|
|
|
|
using System.Threading;
|
|
|
|
using System.Threading;
|
|
|
|
using Jellyfin.Data.Entities;
|
|
|
|
using Jellyfin.Data.Entities;
|
|
|
|
|
|
|
|
using Jellyfin.Extensions;
|
|
|
|
using Jellyfin.Server.Implementations;
|
|
|
|
using Jellyfin.Server.Implementations;
|
|
|
|
using MediaBrowser.Controller.Configuration;
|
|
|
|
using MediaBrowser.Controller.Configuration;
|
|
|
|
using MediaBrowser.Controller.Dto;
|
|
|
|
using MediaBrowser.Controller.Dto;
|
|
|
@ -65,7 +66,15 @@ namespace Emby.Server.Implementations.Library
|
|
|
|
foreach (var key in keys)
|
|
|
|
foreach (var key in keys)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
userData.Key = key;
|
|
|
|
userData.Key = key;
|
|
|
|
repository.UserData.Add(Map(userData, user.Id));
|
|
|
|
var userDataEntry = Map(userData, user.Id, item.Id);
|
|
|
|
|
|
|
|
if (repository.UserData.Any(f => f.ItemId == item.Id && f.UserId == user.Id && f.CustomDataKey == key))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
repository.UserData.Attach(userDataEntry).State = EntityState.Modified;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
repository.UserData.Add(userDataEntry);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
repository.SaveChanges();
|
|
|
|
repository.SaveChanges();
|
|
|
@ -131,11 +140,12 @@ namespace Emby.Server.Implementations.Library
|
|
|
|
SaveUserData(user, item, userData, reason, CancellationToken.None);
|
|
|
|
SaveUserData(user, item, userData, reason, CancellationToken.None);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private UserData Map(UserItemData dto, Guid userId)
|
|
|
|
private UserData Map(UserItemData dto, Guid userId, Guid itemId)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return new UserData()
|
|
|
|
return new UserData()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
ItemId = Guid.Parse(dto.Key),
|
|
|
|
ItemId = itemId,
|
|
|
|
|
|
|
|
CustomDataKey = dto.Key,
|
|
|
|
Item = null!,
|
|
|
|
Item = null!,
|
|
|
|
User = null!,
|
|
|
|
User = null!,
|
|
|
|
AudioStreamIndex = dto.AudioStreamIndex,
|
|
|
|
AudioStreamIndex = dto.AudioStreamIndex,
|
|
|
@ -155,7 +165,7 @@ namespace Emby.Server.Implementations.Library
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return new UserItemData()
|
|
|
|
return new UserItemData()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Key = dto.ItemId.ToString("D"),
|
|
|
|
Key = dto.CustomDataKey!,
|
|
|
|
AudioStreamIndex = dto.AudioStreamIndex,
|
|
|
|
AudioStreamIndex = dto.AudioStreamIndex,
|
|
|
|
IsFavorite = dto.IsFavorite,
|
|
|
|
IsFavorite = dto.IsFavorite,
|
|
|
|
LastPlayedDate = dto.LastPlayedDate,
|
|
|
|
LastPlayedDate = dto.LastPlayedDate,
|
|
|
@ -175,7 +185,10 @@ namespace Emby.Server.Implementations.Library
|
|
|
|
|
|
|
|
|
|
|
|
if (data is null)
|
|
|
|
if (data is null)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return null;
|
|
|
|
return new UserItemData()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Key = keys[0],
|
|
|
|
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return _userData.GetOrAdd(cacheKey, data);
|
|
|
|
return _userData.GetOrAdd(cacheKey, data);
|
|
|
@ -184,13 +197,9 @@ namespace Emby.Server.Implementations.Library
|
|
|
|
private UserItemData? GetUserDataInternal(Guid userId, List<string> keys)
|
|
|
|
private UserItemData? GetUserDataInternal(Guid userId, List<string> keys)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var key = keys.FirstOrDefault();
|
|
|
|
var key = keys.FirstOrDefault();
|
|
|
|
if (key is null || !Guid.TryParse(key, out var itemId))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
using var context = _repository.CreateDbContext();
|
|
|
|
using var context = _repository.CreateDbContext();
|
|
|
|
var userData = context.UserData.AsNoTracking().FirstOrDefault(e => e.ItemId == itemId && e.UserId.Equals(userId));
|
|
|
|
var userData = context.UserData.AsNoTracking().FirstOrDefault(e => e.CustomDataKey == key && e.UserId.Equals(userId));
|
|
|
|
|
|
|
|
|
|
|
|
if (userData is not null)
|
|
|
|
if (userData is not null)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -236,7 +245,7 @@ namespace Emby.Server.Implementations.Library
|
|
|
|
return null;
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var dto = GetUserItemDataDto(userData);
|
|
|
|
var dto = GetUserItemDataDto(userData, item.Id);
|
|
|
|
|
|
|
|
|
|
|
|
item.FillUserDataDtoValues(dto, userData, itemDto, user, options);
|
|
|
|
item.FillUserDataDtoValues(dto, userData, itemDto, user, options);
|
|
|
|
return dto;
|
|
|
|
return dto;
|
|
|
@ -246,9 +255,10 @@ namespace Emby.Server.Implementations.Library
|
|
|
|
/// Converts a UserItemData to a DTOUserItemData.
|
|
|
|
/// Converts a UserItemData to a DTOUserItemData.
|
|
|
|
/// </summary>
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="data">The data.</param>
|
|
|
|
/// <param name="data">The data.</param>
|
|
|
|
|
|
|
|
/// <param name="itemId">The the reference key to an Item.</param>
|
|
|
|
/// <returns>DtoUserItemData.</returns>
|
|
|
|
/// <returns>DtoUserItemData.</returns>
|
|
|
|
/// <exception cref="ArgumentNullException"><paramref name="data"/> is <c>null</c>.</exception>
|
|
|
|
/// <exception cref="ArgumentNullException"><paramref name="data"/> is <c>null</c>.</exception>
|
|
|
|
private UserItemDataDto GetUserItemDataDto(UserItemData data)
|
|
|
|
private UserItemDataDto GetUserItemDataDto(UserItemData data, Guid itemId)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
ArgumentNullException.ThrowIfNull(data);
|
|
|
|
ArgumentNullException.ThrowIfNull(data);
|
|
|
|
|
|
|
|
|
|
|
@ -261,6 +271,7 @@ namespace Emby.Server.Implementations.Library
|
|
|
|
Rating = data.Rating,
|
|
|
|
Rating = data.Rating,
|
|
|
|
Played = data.Played,
|
|
|
|
Played = data.Played,
|
|
|
|
LastPlayedDate = data.LastPlayedDate,
|
|
|
|
LastPlayedDate = data.LastPlayedDate,
|
|
|
|
|
|
|
|
ItemId = itemId,
|
|
|
|
Key = data.Key
|
|
|
|
Key = data.Key
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|