UserLibraryService.cs 19 KB

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