UserLibraryService.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629
  1. using MediaBrowser.Controller.Entities;
  2. using MediaBrowser.Controller.Entities.Movies;
  3. using MediaBrowser.Controller.Library;
  4. using MediaBrowser.Model.Dto;
  5. using MediaBrowser.Model.Querying;
  6. using ServiceStack.ServiceHost;
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Linq;
  10. using System.Threading;
  11. using System.Threading.Tasks;
  12. namespace MediaBrowser.Api.UserLibrary
  13. {
  14. /// <summary>
  15. /// Class GetItem
  16. /// </summary>
  17. [Route("/Users/{UserId}/Items/{Id}", "GET")]
  18. [Api(Description = "Gets an item from a user's library")]
  19. public class GetItem : IReturn<BaseItemDto>
  20. {
  21. /// <summary>
  22. /// Gets or sets the user id.
  23. /// </summary>
  24. /// <value>The user id.</value>
  25. [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
  26. public Guid UserId { get; set; }
  27. /// <summary>
  28. /// Gets or sets the id.
  29. /// </summary>
  30. /// <value>The id.</value>
  31. [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
  32. public string Id { get; set; }
  33. }
  34. /// <summary>
  35. /// Class GetItem
  36. /// </summary>
  37. [Route("/Users/{UserId}/Items/Root", "GET")]
  38. [Api(Description = "Gets the root folder from a user's library")]
  39. public class GetRootFolder : IReturn<BaseItemDto>
  40. {
  41. /// <summary>
  42. /// Gets or sets the user id.
  43. /// </summary>
  44. /// <value>The user id.</value>
  45. [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
  46. public Guid UserId { get; set; }
  47. }
  48. /// <summary>
  49. /// Class GetIntros
  50. /// </summary>
  51. [Route("/Users/{UserId}/Items/{Id}/Intros", "GET")]
  52. [Api(("Gets intros to play before the main media item plays"))]
  53. public class GetIntros : IReturn<List<string>>
  54. {
  55. /// <summary>
  56. /// Gets or sets the user id.
  57. /// </summary>
  58. /// <value>The user id.</value>
  59. [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
  60. public Guid UserId { get; set; }
  61. /// <summary>
  62. /// Gets or sets the item id.
  63. /// </summary>
  64. /// <value>The item id.</value>
  65. [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
  66. public string Id { get; set; }
  67. }
  68. /// <summary>
  69. /// Class MarkFavoriteItem
  70. /// </summary>
  71. [Route("/Users/{UserId}/FavoriteItems/{Id}", "POST")]
  72. [Api(Description = "Marks an item as a favorite")]
  73. public class MarkFavoriteItem : IReturnVoid
  74. {
  75. /// <summary>
  76. /// Gets or sets the user id.
  77. /// </summary>
  78. /// <value>The user id.</value>
  79. [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
  80. public Guid UserId { get; set; }
  81. /// <summary>
  82. /// Gets or sets the id.
  83. /// </summary>
  84. /// <value>The id.</value>
  85. [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
  86. public string Id { get; set; }
  87. }
  88. /// <summary>
  89. /// Class UnmarkFavoriteItem
  90. /// </summary>
  91. [Route("/Users/{UserId}/FavoriteItems/{Id}", "DELETE")]
  92. [Api(Description = "Unmarks an item as a favorite")]
  93. public class UnmarkFavoriteItem : IReturnVoid
  94. {
  95. /// <summary>
  96. /// Gets or sets the user id.
  97. /// </summary>
  98. /// <value>The user id.</value>
  99. [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
  100. public Guid UserId { get; set; }
  101. /// <summary>
  102. /// Gets or sets the id.
  103. /// </summary>
  104. /// <value>The id.</value>
  105. [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
  106. public string Id { get; set; }
  107. }
  108. /// <summary>
  109. /// Class ClearUserItemRating
  110. /// </summary>
  111. [Route("/Users/{UserId}/Items/{Id}/Rating", "DELETE")]
  112. [Api(Description = "Deletes a user's saved personal rating for an item")]
  113. public class DeleteUserItemRating : IReturnVoid
  114. {
  115. /// <summary>
  116. /// Gets or sets the user id.
  117. /// </summary>
  118. /// <value>The user id.</value>
  119. [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
  120. public Guid UserId { get; set; }
  121. /// <summary>
  122. /// Gets or sets the id.
  123. /// </summary>
  124. /// <value>The id.</value>
  125. [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
  126. public string Id { get; set; }
  127. }
  128. /// <summary>
  129. /// Class UpdateUserItemRating
  130. /// </summary>
  131. [Route("/Users/{UserId}/Items/{Id}/Rating", "POST")]
  132. [Api(Description = "Updates a user's rating for an item")]
  133. public class UpdateUserItemRating : IReturnVoid
  134. {
  135. /// <summary>
  136. /// Gets or sets the user id.
  137. /// </summary>
  138. /// <value>The user id.</value>
  139. [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
  140. public Guid UserId { get; set; }
  141. /// <summary>
  142. /// Gets or sets the id.
  143. /// </summary>
  144. /// <value>The id.</value>
  145. [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
  146. public string Id { get; set; }
  147. /// <summary>
  148. /// Gets or sets a value indicating whether this <see cref="UpdateUserItemRating" /> is likes.
  149. /// </summary>
  150. /// <value><c>true</c> if likes; otherwise, <c>false</c>.</value>
  151. [ApiMember(Name = "Likes", Description = "Whether the user likes the item or not. true/false", IsRequired = true, DataType = "boolean", ParameterType = "query", Verb = "POST")]
  152. public bool Likes { get; set; }
  153. }
  154. /// <summary>
  155. /// Class MarkPlayedItem
  156. /// </summary>
  157. [Route("/Users/{UserId}/PlayedItems/{Id}", "POST")]
  158. [Api(Description = "Marks an item as played")]
  159. public class MarkPlayedItem : IReturnVoid
  160. {
  161. /// <summary>
  162. /// Gets or sets the user id.
  163. /// </summary>
  164. /// <value>The user id.</value>
  165. [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
  166. public Guid UserId { get; set; }
  167. /// <summary>
  168. /// Gets or sets the id.
  169. /// </summary>
  170. /// <value>The id.</value>
  171. [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
  172. public string Id { get; set; }
  173. }
  174. /// <summary>
  175. /// Class MarkUnplayedItem
  176. /// </summary>
  177. [Route("/Users/{UserId}/PlayedItems/{Id}", "DELETE")]
  178. [Api(Description = "Marks an item as unplayed")]
  179. public class MarkUnplayedItem : IReturnVoid
  180. {
  181. /// <summary>
  182. /// Gets or sets the user id.
  183. /// </summary>
  184. /// <value>The user id.</value>
  185. [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
  186. public Guid UserId { get; set; }
  187. /// <summary>
  188. /// Gets or sets the id.
  189. /// </summary>
  190. /// <value>The id.</value>
  191. [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
  192. public string Id { get; set; }
  193. }
  194. [Route("/Users/{UserId}/PlayingItems/{Id}", "POST")]
  195. [Api(Description = "Reports that a user has begun playing an item")]
  196. public class OnPlaybackStart : IReturnVoid
  197. {
  198. /// <summary>
  199. /// Gets or sets the user id.
  200. /// </summary>
  201. /// <value>The user id.</value>
  202. [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
  203. public Guid UserId { get; set; }
  204. /// <summary>
  205. /// Gets or sets the id.
  206. /// </summary>
  207. /// <value>The id.</value>
  208. [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
  209. public string Id { get; set; }
  210. }
  211. [Route("/Users/{UserId}/PlayingItems/{Id}/Progress", "POST")]
  212. [Api(Description = "Reports a user's playback progress")]
  213. public class OnPlaybackProgress : IReturnVoid
  214. {
  215. /// <summary>
  216. /// Gets or sets the user id.
  217. /// </summary>
  218. /// <value>The user id.</value>
  219. [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
  220. public Guid UserId { get; set; }
  221. /// <summary>
  222. /// Gets or sets the id.
  223. /// </summary>
  224. /// <value>The id.</value>
  225. [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
  226. public string Id { get; set; }
  227. /// <summary>
  228. /// Gets or sets the position ticks.
  229. /// </summary>
  230. /// <value>The position ticks.</value>
  231. [ApiMember(Name = "PositionTicks", Description = "Optional. The current position, in ticks. 1 tick = 10000 ms", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "POST")]
  232. public long? PositionTicks { get; set; }
  233. }
  234. [Route("/Users/{UserId}/PlayingItems/{Id}", "DELETE")]
  235. [Api(Description = "Reports that a user has stopped playing an item")]
  236. public class OnPlaybackStopped : IReturnVoid
  237. {
  238. /// <summary>
  239. /// Gets or sets the user id.
  240. /// </summary>
  241. /// <value>The user id.</value>
  242. [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
  243. public Guid UserId { get; set; }
  244. /// <summary>
  245. /// Gets or sets the id.
  246. /// </summary>
  247. /// <value>The id.</value>
  248. [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
  249. public string Id { get; set; }
  250. /// <summary>
  251. /// Gets or sets the position ticks.
  252. /// </summary>
  253. /// <value>The position ticks.</value>
  254. [ApiMember(Name = "PositionTicks", Description = "Optional. The position, in ticks, where playback stopped. 1 tick = 10000 ms", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "DELETE")]
  255. public long? PositionTicks { get; set; }
  256. }
  257. /// <summary>
  258. /// Class GetLocalTrailers
  259. /// </summary>
  260. [Route("/Users/{UserId}/Items/{Id}/LocalTrailers", "GET")]
  261. [Api(Description = "Gets local trailers for an item")]
  262. public class GetLocalTrailers : IReturn<List<BaseItemDto>>
  263. {
  264. /// <summary>
  265. /// Gets or sets the user id.
  266. /// </summary>
  267. /// <value>The user id.</value>
  268. [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
  269. public Guid UserId { get; set; }
  270. /// <summary>
  271. /// Gets or sets the id.
  272. /// </summary>
  273. /// <value>The id.</value>
  274. [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
  275. public string Id { get; set; }
  276. }
  277. /// <summary>
  278. /// Class GetSpecialFeatures
  279. /// </summary>
  280. [Route("/Users/{UserId}/Items/{Id}/SpecialFeatures", "GET")]
  281. [Api(Description = "Gets special features for a movie")]
  282. public class GetSpecialFeatures : IReturn<List<BaseItemDto>>
  283. {
  284. /// <summary>
  285. /// Gets or sets the user id.
  286. /// </summary>
  287. /// <value>The user id.</value>
  288. [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
  289. public Guid UserId { get; set; }
  290. /// <summary>
  291. /// Gets or sets the id.
  292. /// </summary>
  293. /// <value>The id.</value>
  294. [ApiMember(Name = "Id", Description = "Movie Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
  295. public string Id { get; set; }
  296. }
  297. /// <summary>
  298. /// Class UserLibraryService
  299. /// </summary>
  300. public class UserLibraryService : BaseApiService
  301. {
  302. /// <summary>
  303. /// The _user manager
  304. /// </summary>
  305. private readonly IUserManager _userManager;
  306. private readonly ILibraryManager _libraryManager;
  307. /// <summary>
  308. /// Initializes a new instance of the <see cref="UserLibraryService" /> class.
  309. /// </summary>
  310. /// <exception cref="System.ArgumentNullException">jsonSerializer</exception>
  311. public UserLibraryService(IUserManager userManager, ILibraryManager libraryManager)
  312. : base()
  313. {
  314. _userManager = userManager;
  315. _libraryManager = libraryManager;
  316. }
  317. /// <summary>
  318. /// Gets the specified request.
  319. /// </summary>
  320. /// <param name="request">The request.</param>
  321. /// <returns>System.Object.</returns>
  322. public object Get(GetSpecialFeatures request)
  323. {
  324. var user = _userManager.GetUserById(request.UserId);
  325. var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
  326. // Get everything
  327. var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList();
  328. var movie = (Movie)item;
  329. var dtoBuilder = new DtoBuilder(Logger, _libraryManager, _userManager);
  330. var items = movie.SpecialFeatures.Select(i => dtoBuilder.GetBaseItemDto(i, user, fields)).AsParallel().Select(t => t.Result).ToList();
  331. return ToOptimizedResult(items);
  332. }
  333. /// <summary>
  334. /// Gets the specified request.
  335. /// </summary>
  336. /// <param name="request">The request.</param>
  337. /// <returns>System.Object.</returns>
  338. public object Get(GetLocalTrailers request)
  339. {
  340. var user = _userManager.GetUserById(request.UserId);
  341. var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
  342. // Get everything
  343. var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList();
  344. var dtoBuilder = new DtoBuilder(Logger, _libraryManager, _userManager);
  345. var items = item.LocalTrailers.Select(i => dtoBuilder.GetBaseItemDto(i, user, fields)).AsParallel().Select(t => t.Result).ToList();
  346. return ToOptimizedResult(items);
  347. }
  348. /// <summary>
  349. /// Gets the specified request.
  350. /// </summary>
  351. /// <param name="request">The request.</param>
  352. /// <returns>System.Object.</returns>
  353. public object Get(GetItem request)
  354. {
  355. var user = _userManager.GetUserById(request.UserId);
  356. var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
  357. // Get everything
  358. var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList();
  359. var dtoBuilder = new DtoBuilder(Logger, _libraryManager, _userManager);
  360. var result = dtoBuilder.GetBaseItemDto(item, user, fields).Result;
  361. return ToOptimizedResult(result);
  362. }
  363. public object Get(GetRootFolder request)
  364. {
  365. var user = _userManager.GetUserById(request.UserId);
  366. var item = user.RootFolder;
  367. // Get everything
  368. var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList();
  369. var dtoBuilder = new DtoBuilder(Logger, _libraryManager, _userManager);
  370. var result = dtoBuilder.GetBaseItemDto(item, user, fields).Result;
  371. return ToOptimizedResult(result);
  372. }
  373. /// <summary>
  374. /// Gets the specified request.
  375. /// </summary>
  376. /// <param name="request">The request.</param>
  377. /// <returns>System.Object.</returns>
  378. public object Get(GetIntros request)
  379. {
  380. var user = _userManager.GetUserById(request.UserId);
  381. var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
  382. var result = _libraryManager.GetIntros(item, user);
  383. return ToOptimizedResult(result);
  384. }
  385. /// <summary>
  386. /// Posts the specified request.
  387. /// </summary>
  388. /// <param name="request">The request.</param>
  389. public void Post(MarkFavoriteItem request)
  390. {
  391. var user = _userManager.GetUserById(request.UserId);
  392. var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
  393. // Get the user data for this item
  394. var data = _userManager.GetUserData(user.Id, item.UserDataId).Result;
  395. // Set favorite status
  396. data.IsFavorite = true;
  397. var task = _userManager.SaveUserData(user.Id, item.UserDataId, data, CancellationToken.None);
  398. Task.WaitAll(task);
  399. }
  400. /// <summary>
  401. /// Deletes the specified request.
  402. /// </summary>
  403. /// <param name="request">The request.</param>
  404. public void Delete(UnmarkFavoriteItem request)
  405. {
  406. var user = _userManager.GetUserById(request.UserId);
  407. var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
  408. // Get the user data for this item
  409. var data = _userManager.GetUserData(user.Id, item.UserDataId).Result;
  410. // Set favorite status
  411. data.IsFavorite = false;
  412. var task = _userManager.SaveUserData(user.Id, item.UserDataId, data, CancellationToken.None);
  413. Task.WaitAll(task);
  414. }
  415. /// <summary>
  416. /// Deletes the specified request.
  417. /// </summary>
  418. /// <param name="request">The request.</param>
  419. public void Delete(DeleteUserItemRating request)
  420. {
  421. var user = _userManager.GetUserById(request.UserId);
  422. var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
  423. // Get the user data for this item
  424. var data = _userManager.GetUserData(user.Id, item.UserDataId).Result;
  425. data.Rating = null;
  426. var task = _userManager.SaveUserData(user.Id, item.UserDataId, data, CancellationToken.None);
  427. Task.WaitAll(task);
  428. }
  429. /// <summary>
  430. /// Posts the specified request.
  431. /// </summary>
  432. /// <param name="request">The request.</param>
  433. public void Post(UpdateUserItemRating request)
  434. {
  435. var user = _userManager.GetUserById(request.UserId);
  436. var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
  437. // Get the user data for this item
  438. var data = _userManager.GetUserData(user.Id, item.UserDataId).Result;
  439. data.Likes = request.Likes;
  440. var task = _userManager.SaveUserData(user.Id, item.UserDataId, data, CancellationToken.None);
  441. Task.WaitAll(task);
  442. }
  443. /// <summary>
  444. /// Posts the specified request.
  445. /// </summary>
  446. /// <param name="request">The request.</param>
  447. public void Post(MarkPlayedItem request)
  448. {
  449. var user = _userManager.GetUserById(request.UserId);
  450. var task = UpdatePlayedStatus(user, request.Id, true);
  451. Task.WaitAll(task);
  452. }
  453. /// <summary>
  454. /// Posts the specified request.
  455. /// </summary>
  456. /// <param name="request">The request.</param>
  457. public void Post(OnPlaybackStart request)
  458. {
  459. var user = _userManager.GetUserById(request.UserId);
  460. var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
  461. var auth = RequestFilterAttribute.GetAuthorization(RequestContext);
  462. if (auth != null)
  463. {
  464. _userManager.OnPlaybackStart(user, item, auth["Client"], auth["DeviceId"], auth["Device"] ?? string.Empty);
  465. }
  466. }
  467. /// <summary>
  468. /// Posts the specified request.
  469. /// </summary>
  470. /// <param name="request">The request.</param>
  471. public void Post(OnPlaybackProgress request)
  472. {
  473. var user = _userManager.GetUserById(request.UserId);
  474. var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
  475. var auth = RequestFilterAttribute.GetAuthorization(RequestContext);
  476. if (auth != null)
  477. {
  478. var task = _userManager.OnPlaybackProgress(user, item, request.PositionTicks, auth["Client"], auth["DeviceId"], auth["Device"] ?? string.Empty);
  479. Task.WaitAll(task);
  480. }
  481. }
  482. /// <summary>
  483. /// Posts the specified request.
  484. /// </summary>
  485. /// <param name="request">The request.</param>
  486. public void Delete(OnPlaybackStopped request)
  487. {
  488. var user = _userManager.GetUserById(request.UserId);
  489. var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
  490. var auth = RequestFilterAttribute.GetAuthorization(RequestContext);
  491. if (auth != null)
  492. {
  493. var task = _userManager.OnPlaybackStopped(user, item, request.PositionTicks, auth["Client"], auth["DeviceId"], auth["Device"] ?? string.Empty);
  494. Task.WaitAll(task);
  495. }
  496. }
  497. /// <summary>
  498. /// Deletes the specified request.
  499. /// </summary>
  500. /// <param name="request">The request.</param>
  501. public void Delete(MarkUnplayedItem request)
  502. {
  503. var user = _userManager.GetUserById(request.UserId);
  504. var task = UpdatePlayedStatus(user, request.Id, false);
  505. Task.WaitAll(task);
  506. }
  507. /// <summary>
  508. /// Updates the played status.
  509. /// </summary>
  510. /// <param name="user">The user.</param>
  511. /// <param name="itemId">The item id.</param>
  512. /// <param name="wasPlayed">if set to <c>true</c> [was played].</param>
  513. /// <returns>Task.</returns>
  514. private Task UpdatePlayedStatus(User user, string itemId, bool wasPlayed)
  515. {
  516. var item = DtoBuilder.GetItemByClientId(itemId, _userManager, _libraryManager, user.Id);
  517. return item.SetPlayedStatus(user, wasPlayed, _userManager);
  518. }
  519. }
  520. }