1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
|
using MediaBrowser.Common.Events;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Server.Implementations.Library
{
/// <summary>
/// Class UserDataManager
/// </summary>
public class UserDataManager : IUserDataManager
{
public event EventHandler<UserDataSaveEventArgs> UserDataSaved;
private readonly ConcurrentDictionary<string, UserItemData> _userData = new ConcurrentDictionary<string, UserItemData>();
private readonly ILogger _logger;
public UserDataManager(ILogManager logManager)
{
_logger = logManager.GetLogger(GetType().Name);
}
/// <summary>
/// Gets or sets the repository.
/// </summary>
/// <value>The repository.</value>
public IUserDataRepository Repository { get; set; }
/// <summary>
/// Saves the user data.
/// </summary>
/// <param name="userId">The user id.</param>
/// <param name="item">The item.</param>
/// <param name="userData">The user data.</param>
/// <param name="reason">The reason.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
/// <exception cref="System.ArgumentNullException">userData
/// or
/// cancellationToken
/// or
/// userId
/// or
/// key</exception>
public async Task SaveUserData(Guid userId, IHasUserData item, UserItemData userData, UserDataSaveReason reason, CancellationToken cancellationToken)
{
if (userData == null)
{
throw new ArgumentNullException("userData");
}
if (item == null)
{
throw new ArgumentNullException("item");
}
if (userId == Guid.Empty)
{
throw new ArgumentNullException("userId");
}
cancellationToken.ThrowIfCancellationRequested();
var key = item.GetUserDataKey();
try
{
await Repository.SaveUserData(userId, key, userData, cancellationToken).ConfigureAwait(false);
var newValue = userData;
// Once it succeeds, put it into the dictionary to make it available to everyone else
_userData.AddOrUpdate(GetCacheKey(userId, key), newValue, delegate { return newValue; });
}
catch (Exception ex)
{
_logger.ErrorException("Error saving user data", ex);
throw;
}
EventHelper.FireEventIfNotNull(UserDataSaved, this, new UserDataSaveEventArgs
{
Key = key,
UserData = userData,
SaveReason = reason,
UserId = userId,
Item = item
}, _logger);
}
/// <summary>
/// Gets the user data.
/// </summary>
/// <param name="userId">The user id.</param>
/// <param name="key">The key.</param>
/// <returns>Task{UserItemData}.</returns>
public UserItemData GetUserData(Guid userId, string key)
{
if (userId == Guid.Empty)
{
throw new ArgumentNullException("userId");
}
if (string.IsNullOrEmpty(key))
{
throw new ArgumentNullException("key");
}
return _userData.GetOrAdd(GetCacheKey(userId, key), keyName => Repository.GetUserData(userId, key));
}
/// <summary>
/// Gets the internal key.
/// </summary>
/// <param name="userId">The user id.</param>
/// <param name="key">The key.</param>
/// <returns>System.String.</returns>
private string GetCacheKey(Guid userId, string key)
{
return userId + key;
}
public UserItemDataDto GetUserDataDto(IHasUserData item, User user)
{
var userData = GetUserData(user.Id, item.GetUserDataKey());
var dto = GetUserItemDataDto(userData);
item.FillUserDataDtoValues(dto, userData, user);
return dto;
}
/// <summary>
/// Converts a UserItemData to a DTOUserItemData
/// </summary>
/// <param name="data">The data.</param>
/// <returns>DtoUserItemData.</returns>
/// <exception cref="System.ArgumentNullException"></exception>
private UserItemDataDto GetUserItemDataDto(UserItemData data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
return new UserItemDataDto
{
IsFavorite = data.IsFavorite,
Likes = data.Likes,
PlaybackPositionTicks = data.PlaybackPositionTicks,
PlayCount = data.PlayCount,
Rating = data.Rating,
Played = data.Played,
LastPlayedDate = data.LastPlayedDate,
Key = data.Key
};
}
}
}
|