ImageService.cs 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. using MediaBrowser.Common.Extensions;
  2. using MediaBrowser.Common.Net;
  3. using MediaBrowser.Controller;
  4. using MediaBrowser.Controller.Entities;
  5. using MediaBrowser.Controller.Library;
  6. using MediaBrowser.Model.Entities;
  7. using ServiceStack.ServiceHost;
  8. using System;
  9. using System.ComponentModel.Composition;
  10. using System.IO;
  11. using System.Linq;
  12. using System.Threading.Tasks;
  13. namespace MediaBrowser.Api.Images
  14. {
  15. /// <summary>
  16. /// Class GetItemImage
  17. /// </summary>
  18. [Route("/Items/{Id}/Images/{Type}", "GET")]
  19. [Route("/Items/{Id}/Images/{Type}/{Index}", "GET")]
  20. public class GetItemImage : ImageRequest
  21. {
  22. /// <summary>
  23. /// Gets or sets the id.
  24. /// </summary>
  25. /// <value>The id.</value>
  26. public string Id { get; set; }
  27. }
  28. /// <summary>
  29. /// Class GetPersonImage
  30. /// </summary>
  31. [Route("/Persons/{Name}/Images/{Type}", "GET")]
  32. [Route("/Persons/{Name}/Images/{Type}/{Index}", "GET")]
  33. public class GetPersonImage : ImageRequest
  34. {
  35. /// <summary>
  36. /// Gets or sets the name.
  37. /// </summary>
  38. /// <value>The name.</value>
  39. public string Name { get; set; }
  40. }
  41. /// <summary>
  42. /// Class GetStudioImage
  43. /// </summary>
  44. [Route("/Studios/{Name}/Images/{Type}", "GET")]
  45. [Route("/Studios/{Name}/Images/{Type}/{Index}", "GET")]
  46. public class GetStudioImage : ImageRequest
  47. {
  48. /// <summary>
  49. /// Gets or sets the name.
  50. /// </summary>
  51. /// <value>The name.</value>
  52. public string Name { get; set; }
  53. }
  54. /// <summary>
  55. /// Class GetGenreImage
  56. /// </summary>
  57. [Route("/Genres/{Name}/Images/{Type}", "GET")]
  58. [Route("/Genres/{Name}/Images/{Type}/{Index}", "GET")]
  59. public class GetGenreImage : ImageRequest
  60. {
  61. /// <summary>
  62. /// Gets or sets the name.
  63. /// </summary>
  64. /// <value>The name.</value>
  65. public string Name { get; set; }
  66. }
  67. /// <summary>
  68. /// Class GetYearImage
  69. /// </summary>
  70. [Route("/Years/{Year}/Images/{Type}", "GET")]
  71. [Route("/Years/{Year}/Images/{Type}/{Index}", "GET")]
  72. public class GetYearImage : ImageRequest
  73. {
  74. /// <summary>
  75. /// Gets or sets the year.
  76. /// </summary>
  77. /// <value>The year.</value>
  78. public int Year { get; set; }
  79. }
  80. /// <summary>
  81. /// Class GetUserImage
  82. /// </summary>
  83. [Route("/Users/{Id}/Images/{Type}", "GET")]
  84. [Route("/Users/{Id}/Images/{Type}/{Index}", "GET")]
  85. public class GetUserImage : ImageRequest
  86. {
  87. /// <summary>
  88. /// Gets or sets the id.
  89. /// </summary>
  90. /// <value>The id.</value>
  91. public Guid Id { get; set; }
  92. }
  93. /// <summary>
  94. /// Class DeleteUserImage
  95. /// </summary>
  96. [Route("/Users/{Id}/Images/{Type}", "DELETE")]
  97. [Route("/Users/{Id}/Images/{Type}/{Index}", "DELETE")]
  98. public class DeleteUserImage : DeleteImageRequest
  99. {
  100. /// <summary>
  101. /// Gets or sets the id.
  102. /// </summary>
  103. /// <value>The id.</value>
  104. public Guid Id { get; set; }
  105. }
  106. /// <summary>
  107. /// Class ImageService
  108. /// </summary>
  109. [Export(typeof(IRestfulService))]
  110. public class ImageService : BaseRestService
  111. {
  112. /// <summary>
  113. /// Gets the specified request.
  114. /// </summary>
  115. /// <param name="request">The request.</param>
  116. /// <returns>System.Object.</returns>
  117. public object Get(GetItemImage request)
  118. {
  119. var item = DtoBuilder.GetItemByClientId(request.Id);
  120. return GetImage(request, item);
  121. }
  122. /// <summary>
  123. /// Gets the specified request.
  124. /// </summary>
  125. /// <param name="request">The request.</param>
  126. /// <returns>System.Object.</returns>
  127. public object Get(GetUserImage request)
  128. {
  129. var kernel = (Kernel)Kernel;
  130. var item = kernel.Users.First(i => i.Id == request.Id);
  131. return GetImage(request, item);
  132. }
  133. /// <summary>
  134. /// Gets the specified request.
  135. /// </summary>
  136. /// <param name="request">The request.</param>
  137. /// <returns>System.Object.</returns>
  138. public object Get(GetYearImage request)
  139. {
  140. var kernel = (Kernel)Kernel;
  141. var item = kernel.LibraryManager.GetYear(request.Year).Result;
  142. return GetImage(request, item);
  143. }
  144. /// <summary>
  145. /// Gets the specified request.
  146. /// </summary>
  147. /// <param name="request">The request.</param>
  148. /// <returns>System.Object.</returns>
  149. public object Get(GetStudioImage request)
  150. {
  151. var kernel = (Kernel)Kernel;
  152. var item = kernel.LibraryManager.GetStudio(request.Name).Result;
  153. return GetImage(request, item);
  154. }
  155. /// <summary>
  156. /// Gets the specified request.
  157. /// </summary>
  158. /// <param name="request">The request.</param>
  159. /// <returns>System.Object.</returns>
  160. public object Get(GetPersonImage request)
  161. {
  162. var kernel = (Kernel)Kernel;
  163. var item = kernel.LibraryManager.GetPerson(request.Name).Result;
  164. return GetImage(request, item);
  165. }
  166. /// <summary>
  167. /// Gets the specified request.
  168. /// </summary>
  169. /// <param name="request">The request.</param>
  170. /// <returns>System.Object.</returns>
  171. public object Get(GetGenreImage request)
  172. {
  173. var kernel = (Kernel)Kernel;
  174. var item = kernel.LibraryManager.GetGenre(request.Name).Result;
  175. return GetImage(request, item);
  176. }
  177. /// <summary>
  178. /// Deletes the specified request.
  179. /// </summary>
  180. /// <param name="request">The request.</param>
  181. public void Delete(DeleteUserImage request)
  182. {
  183. var kernel = (Kernel)Kernel;
  184. var item = kernel.Users.First(i => i.Id == request.Id);
  185. var task = item.DeleteImage(request.Type);
  186. Task.WaitAll(task);
  187. }
  188. /// <summary>
  189. /// Gets the image.
  190. /// </summary>
  191. /// <param name="request">The request.</param>
  192. /// <param name="item">The item.</param>
  193. /// <returns>System.Object.</returns>
  194. /// <exception cref="ResourceNotFoundException"></exception>
  195. private object GetImage(ImageRequest request, BaseItem item)
  196. {
  197. var kernel = (Kernel)Kernel;
  198. var index = request.Index ?? 0;
  199. var imagePath = GetImagePath(kernel, request, item);
  200. if (string.IsNullOrEmpty(imagePath))
  201. {
  202. throw new ResourceNotFoundException();
  203. }
  204. // See if we can avoid a file system lookup by looking for the file in ResolveArgs
  205. var originalFileImageDateModified = kernel.ImageManager.GetImageDateModified(item, request.Type, index);
  206. var supportedImageEnhancers = kernel.ImageEnhancers.Where(i => i.Supports(item, request.Type)).ToList();
  207. // If the file does not exist GetLastWriteTimeUtc will return jan 1, 1601 as opposed to throwing an exception
  208. // http://msdn.microsoft.com/en-us/library/system.io.file.getlastwritetimeutc.aspx
  209. if (originalFileImageDateModified.Year == 1601 && !File.Exists(imagePath))
  210. {
  211. throw new ResourceNotFoundException(string.Format("File not found: {0}", imagePath));
  212. }
  213. var contentType = MimeTypes.GetMimeType(imagePath);
  214. var dateLastModified = (supportedImageEnhancers.Select(e => e.LastConfigurationChange(item, request.Type)).Concat(new[] { originalFileImageDateModified })).Max();
  215. var cacheGuid = kernel.ImageManager.GetImageCacheTag(imagePath, originalFileImageDateModified, supportedImageEnhancers, item, request.Type);
  216. TimeSpan? cacheDuration = null;
  217. if (!string.IsNullOrEmpty(request.Tag) && cacheGuid == new Guid(request.Tag))
  218. {
  219. cacheDuration = TimeSpan.FromDays(365);
  220. }
  221. return ToCachedResult(cacheGuid, dateLastModified, cacheDuration, () => new ImageWriter
  222. {
  223. Item = item,
  224. Request = request,
  225. CropWhiteSpace = request.Type == ImageType.Logo || request.Type == ImageType.Art,
  226. OriginalImageDateModified = originalFileImageDateModified,
  227. ContentType = contentType
  228. }, contentType);
  229. }
  230. /// <summary>
  231. /// Gets the image path.
  232. /// </summary>
  233. /// <param name="kernel">The kernel.</param>
  234. /// <param name="request">The request.</param>
  235. /// <param name="item">The item.</param>
  236. /// <returns>System.String.</returns>
  237. private string GetImagePath(Kernel kernel, ImageRequest request, BaseItem item)
  238. {
  239. var index = request.Index ?? 0;
  240. return kernel.ImageManager.GetImagePath(item, request.Type, index);
  241. }
  242. }
  243. }