diff options
Diffstat (limited to 'MediaBrowser.Api/Images/ImageService.cs')
| -rw-r--r-- | MediaBrowser.Api/Images/ImageService.cs | 187 |
1 files changed, 126 insertions, 61 deletions
diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs index 2aa680061..f2586b043 100644 --- a/MediaBrowser.Api/Images/ImageService.cs +++ b/MediaBrowser.Api/Images/ImageService.cs @@ -18,14 +18,14 @@ using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; +using MimeTypes = MediaBrowser.Model.Net.MimeTypes; namespace MediaBrowser.Api.Images { /// <summary> /// Class GetItemImage /// </summary> - [Route("/Items/{Id}/Images", "GET")] - [Api(Description = "Gets information about an item's images")] + [Route("/Items/{Id}/Images", "GET", Summary = "Gets information about an item's images")] [Authenticated] public class GetItemImageInfos : IReturn<List<ImageInfo>> { @@ -39,9 +39,10 @@ namespace MediaBrowser.Api.Images [Route("/Items/{Id}/Images/{Type}", "GET")] [Route("/Items/{Id}/Images/{Type}/{Index}", "GET")] + [Route("/Items/{Id}/Images/{Type}", "HEAD")] + [Route("/Items/{Id}/Images/{Type}/{Index}", "HEAD")] [Route("/Items/{Id}/Images/{Type}/{Index}/{Tag}/{Format}/{MaxWidth}/{MaxHeight}/{PercentPlayed}", "GET")] [Route("/Items/{Id}/Images/{Type}/{Index}/{Tag}/{Format}/{MaxWidth}/{MaxHeight}/{PercentPlayed}", "HEAD")] - [Api(Description = "Gets an item image")] public class GetItemImage : ImageRequest { /// <summary> @@ -55,8 +56,7 @@ namespace MediaBrowser.Api.Images /// <summary> /// Class UpdateItemImageIndex /// </summary> - [Route("/Items/{Id}/Images/{Type}/{Index}/Index", "POST")] - [Api(Description = "Updates the index for an item image")] + [Route("/Items/{Id}/Images/{Type}/{Index}/Index", "POST", Summary = "Updates the index for an item image")] [Authenticated] public class UpdateItemImageIndex : IReturnVoid { @@ -106,7 +106,20 @@ namespace MediaBrowser.Api.Images [Route("/Studios/{Name}/Images/{Type}/{Index}", "GET")] [Route("/Years/{Year}/Images/{Type}", "GET")] [Route("/Years/{Year}/Images/{Type}/{Index}", "GET")] - [Api(Description = "Gets an item by name image")] + [Route("/Artists/{Name}/Images/{Type}", "HEAD")] + [Route("/Artists/{Name}/Images/{Type}/{Index}", "HEAD")] + [Route("/Genres/{Name}/Images/{Type}", "HEAD")] + [Route("/Genres/{Name}/Images/{Type}/{Index}", "HEAD")] + [Route("/GameGenres/{Name}/Images/{Type}", "HEAD")] + [Route("/GameGenres/{Name}/Images/{Type}/{Index}", "HEAD")] + [Route("/MusicGenres/{Name}/Images/{Type}", "HEAD")] + [Route("/MusicGenres/{Name}/Images/{Type}/{Index}", "HEAD")] + [Route("/Persons/{Name}/Images/{Type}", "HEAD")] + [Route("/Persons/{Name}/Images/{Type}/{Index}", "HEAD")] + [Route("/Studios/{Name}/Images/{Type}", "HEAD")] + [Route("/Studios/{Name}/Images/{Type}/{Index}", "HEAD")] + [Route("/Years/{Year}/Images/{Type}", "HEAD")] + [Route("/Years/{Year}/Images/{Type}/{Index}", "HEAD")] public class GetItemByNameImage : ImageRequest { /// <summary> @@ -122,7 +135,8 @@ namespace MediaBrowser.Api.Images /// </summary> [Route("/Users/{Id}/Images/{Type}", "GET")] [Route("/Users/{Id}/Images/{Type}/{Index}", "GET")] - [Api(Description = "Gets a user image")] + [Route("/Users/{Id}/Images/{Type}", "HEAD")] + [Route("/Users/{Id}/Images/{Type}/{Index}", "HEAD")] public class GetUserImage : ImageRequest { /// <summary> @@ -138,7 +152,6 @@ namespace MediaBrowser.Api.Images /// </summary> [Route("/Items/{Id}/Images/{Type}", "DELETE")] [Route("/Items/{Id}/Images/{Type}/{Index}", "DELETE")] - [Api(Description = "Deletes an item image")] [Authenticated] public class DeleteItemImage : DeleteImageRequest, IReturnVoid { @@ -155,7 +168,6 @@ namespace MediaBrowser.Api.Images /// </summary> [Route("/Users/{Id}/Images/{Type}", "DELETE")] [Route("/Users/{Id}/Images/{Type}/{Index}", "DELETE")] - [Api(Description = "Deletes a user image")] [Authenticated] public class DeleteUserImage : DeleteImageRequest, IReturnVoid { @@ -172,7 +184,6 @@ namespace MediaBrowser.Api.Images /// </summary> [Route("/Users/{Id}/Images/{Type}", "POST")] [Route("/Users/{Id}/Images/{Type}/{Index}", "POST")] - [Api(Description = "Posts a user image")] [Authenticated] public class PostUserImage : DeleteImageRequest, IRequiresRequestStream, IReturnVoid { @@ -294,36 +305,6 @@ namespace MediaBrowser.Api.Images } } - var video = item as Video; - - if (video != null) - { - var index = 0; - - foreach (var chapter in _itemRepo.GetChapters(video.Id)) - { - if (!string.IsNullOrEmpty(chapter.ImagePath)) - { - var image = chapter.ImagePath; - - var info = GetImageInfo(item, new ItemImageInfo - { - Path = image, - Type = ImageType.Chapter, - DateModified = _fileSystem.GetLastWriteTimeUtc(image) - - }, index); - - if (info != null) - { - list.Add(info); - } - } - - index++; - } - } - return list; } @@ -333,8 +314,20 @@ namespace MediaBrowser.Api.Images { var fileInfo = new FileInfo(info.Path); - var size = _imageProcessor.GetImageSize(info.Path); + int? width = null; + int? height = null; + + try + { + var size = _imageProcessor.GetImageSize(info.Path, info.DateModified); + + width = Convert.ToInt32(size.Width); + height = Convert.ToInt32(size.Height); + } + catch + { + } return new ImageInfo { Path = info.Path, @@ -342,8 +335,8 @@ namespace MediaBrowser.Api.Images ImageType = info.Type, ImageTag = _imageProcessor.GetImageCacheTag(item, info), Size = fileInfo.Length, - Width = Convert.ToInt32(size.Width), - Height = Convert.ToInt32(size.Height) + Width = width, + Height = height }; } catch (Exception ex) @@ -389,11 +382,18 @@ namespace MediaBrowser.Api.Images /// <returns>System.Object.</returns> public object Get(GetUserImage request) { - var item = _userManager.Users.First(i => i.Id == request.Id); + var item = _userManager.GetUserById(request.Id); return GetImage(request, item, false); } + public object Head(GetUserImage request) + { + var item = _userManager.GetUserById(request.Id); + + return GetImage(request, item, true); + } + public object Get(GetItemByNameImage request) { var pathInfo = PathInfo.Parse(Request.PathInfo); @@ -404,6 +404,16 @@ namespace MediaBrowser.Api.Images return GetImage(request, item, false); } + public object Head(GetItemByNameImage request) + { + var pathInfo = PathInfo.Parse(Request.PathInfo); + var type = pathInfo.GetArgumentValue<string>(0); + + var item = GetItemByName(request.Name, type, _libraryManager); + + return GetImage(request, item, true); + } + /// <summary> /// Posts the specified request. /// </summary> @@ -415,7 +425,7 @@ namespace MediaBrowser.Api.Images request.Type = (ImageType)Enum.Parse(typeof(ImageType), pathInfo.GetArgumentValue<string>(3), true); - var item = _userManager.Users.First(i => i.Id == id); + var item = _userManager.GetUserById(id); var task = PostImage(item, request.RequestStream, request.Type, Request.ContentType); @@ -446,7 +456,7 @@ namespace MediaBrowser.Api.Images /// <param name="request">The request.</param> public void Delete(DeleteUserImage request) { - var item = _userManager.Users.First(i => i.Id == request.Id); + var item = _userManager.GetUserById(request.Id); var task = item.DeleteImage(request.Type, request.Index ?? 0); @@ -525,7 +535,8 @@ namespace MediaBrowser.Api.Images }).ToList() : new List<IImageEnhancer>(); - var contentType = GetMimeType(request.Format, imageInfo.Path); + var format = GetOutputFormat(request, imageInfo, supportedImageEnhancers); + var contentType = GetMimeType(format, imageInfo.Path); var cacheGuid = new Guid(_imageProcessor.GetImageCacheTag(item, imageInfo, supportedImageEnhancers)); @@ -545,6 +556,7 @@ namespace MediaBrowser.Api.Images return GetImageResult(item, request, imageInfo, + format, supportedImageEnhancers, contentType, cacheDuration, @@ -556,6 +568,7 @@ namespace MediaBrowser.Api.Images private async Task<object> GetImageResult(IHasImages item, ImageRequest request, ItemImageInfo image, + ImageFormat format, List<IImageEnhancer> enhancers, string contentType, TimeSpan? cacheDuration, @@ -581,11 +594,11 @@ namespace MediaBrowser.Api.Images MaxWidth = request.MaxWidth, Quality = request.Quality, Width = request.Width, - OutputFormat = request.Format, AddPlayedIndicator = request.AddPlayedIndicator, PercentPlayed = request.PercentPlayed ?? 0, UnplayedCount = request.UnplayedCount, - BackgroundColor = request.BackgroundColor + BackgroundColor = request.BackgroundColor, + OutputFormat = format }; var file = await _imageProcessor.ProcessImage(options).ConfigureAwait(false); @@ -600,30 +613,82 @@ namespace MediaBrowser.Api.Images }); } - private string GetMimeType(ImageOutputFormat format, string path) + private ImageFormat GetOutputFormat(ImageRequest request, ItemImageInfo image, List<IImageEnhancer> enhancers) + { + if (!string.IsNullOrWhiteSpace(request.Format)) + { + ImageFormat format; + if (Enum.TryParse(request.Format, true, out format)) + { + return format; + } + } + + var serverFormats = _imageProcessor.GetSupportedImageOutputFormats(); + + var clientFormats = GetClientSupportedFormats(); + + if (serverFormats.Contains(ImageFormat.Webp) && + clientFormats.Contains(ImageFormat.Webp)) + { + return ImageFormat.Webp; + } + + if (enhancers.Count > 0) + { + return ImageFormat.Png; + } + + if (string.Equals(Path.GetExtension(image.Path), ".jpg", StringComparison.OrdinalIgnoreCase) || + string.Equals(Path.GetExtension(image.Path), ".jpeg", StringComparison.OrdinalIgnoreCase)) + { + return ImageFormat.Jpg; + } + + // We can't predict if there will be transparency or not, so play it safe + return ImageFormat.Png; + } + + private ImageFormat[] GetClientSupportedFormats() + { + if ((Request.AcceptTypes ?? new string[] { }).Contains("image/webp", StringComparer.OrdinalIgnoreCase)) + { + var userAgent = Request.UserAgent ?? string.Empty; + + // Not displaying properly on iOS + if (userAgent.IndexOf("cfnetwork", StringComparison.OrdinalIgnoreCase) == -1) + { + return new[] { ImageFormat.Webp, ImageFormat.Jpg, ImageFormat.Png }; + } + } + + return new[] { ImageFormat.Jpg, ImageFormat.Png }; + } + + private string GetMimeType(ImageFormat format, string path) { - if (format == ImageOutputFormat.Bmp) + if (format == ImageFormat.Bmp) { - return Common.Net.MimeTypes.GetMimeType("i.bmp"); + return MimeTypes.GetMimeType("i.bmp"); } - if (format == ImageOutputFormat.Gif) + if (format == ImageFormat.Gif) { - return Common.Net.MimeTypes.GetMimeType("i.gif"); + return MimeTypes.GetMimeType("i.gif"); } - if (format == ImageOutputFormat.Jpg) + if (format == ImageFormat.Jpg) { - return Common.Net.MimeTypes.GetMimeType("i.jpg"); + return MimeTypes.GetMimeType("i.jpg"); } - if (format == ImageOutputFormat.Png) + if (format == ImageFormat.Png) { - return Common.Net.MimeTypes.GetMimeType("i.png"); + return MimeTypes.GetMimeType("i.png"); } - if (format == ImageOutputFormat.Webp) + if (format == ImageFormat.Webp) { - return Common.Net.MimeTypes.GetMimeType("i.webp"); + return MimeTypes.GetMimeType("i.webp"); } - return Common.Net.MimeTypes.GetMimeType(path); + return MimeTypes.GetMimeType(path); } /// <summary> |
