From eb45e67c81811451cb64cb24dd8b136b4147d6e8 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 5 May 2013 00:49:49 -0400 Subject: [PATCH] more on image uploading --- MediaBrowser.Api/Images/ImageService.cs | 405 +++++++++++++++++- .../BaseProgressiveStreamingService.cs | 2 +- MediaBrowser.Controller/Dto/DtoBuilder.cs | 16 + MediaBrowser.Controller/Entities/BaseItem.cs | 43 +- MediaBrowser.Controller/IO/FileSystem.cs | 2 +- .../Providers/IProviderManager.cs | 9 + MediaBrowser.Model/DTO/BaseItemDto.cs | 16 + MediaBrowser.Model/Dto/ImageInfo.cs | 52 +++ MediaBrowser.Model/MediaBrowser.Model.csproj | 1 + .../Providers/ProviderManager.cs | 13 + MediaBrowser.WebDashboard/ApiClient.js | 63 ++- MediaBrowser.WebDashboard/packages.config | 2 +- 12 files changed, 599 insertions(+), 25 deletions(-) create mode 100644 MediaBrowser.Model/Dto/ImageInfo.cs diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs index 0fa75af4d2..3de5f5dc3b 100644 --- a/MediaBrowser.Api/Images/ImageService.cs +++ b/MediaBrowser.Api/Images/ImageService.cs @@ -1,14 +1,20 @@ -using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Extensions; using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; using MediaBrowser.Controller; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using ServiceStack.ServiceHost; using ServiceStack.Text.Controller; using System; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading; @@ -19,6 +25,18 @@ namespace MediaBrowser.Api.Images /// /// Class GetItemImage /// + [Route("/Items/{Id}/Images", "GET")] + [Api(Description = "Gets information about an item's images")] + public class GetItemImageInfos : IReturn> + { + /// + /// Gets or sets the id. + /// + /// The id. + [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] + public string Id { get; set; } + } + [Route("/Items/{Id}/Images/{Type}", "GET")] [Route("/Items/{Id}/Images/{Type}/{Index}", "GET")] [Api(Description = "Gets an item image")] @@ -32,6 +50,58 @@ namespace MediaBrowser.Api.Images public string Id { get; set; } } + /// + /// Class UpdateItemImageIndex + /// + [Route("/Items/{Id}/Images/{Type}/{Index}/Index", "POST")] + [Api(Description = "Updates the index for an item image")] + public class UpdateItemImageIndex : IReturnVoid + { + /// + /// Gets or sets the id. + /// + /// The id. + [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] + public Guid Id { get; set; } + + /// + /// Gets or sets the type of the image. + /// + /// The type of the image. + [ApiMember(Name = "Type", Description = "Image Type", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] + public ImageType Type { get; set; } + + /// + /// Gets or sets the index. + /// + /// The index. + [ApiMember(Name = "Index", Description = "Image Index", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "POST")] + public int Index { get; set; } + + /// + /// Gets or sets the new index. + /// + /// The new index. + [ApiMember(Name = "NewIndex", Description = "The new image index", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")] + public int NewIndex { get; set; } + } + + /// + /// Class DeleteItemImage + /// + [Route("/Items/{Id}/Images/{Type}", "DELETE")] + [Route("/Items/{Id}/Images/{Type}/{Index}", "DELETE")] + [Api(Description = "Deletes an item image")] + public class DeleteItemImage : DeleteImageRequest, IReturnVoid + { + /// + /// Gets or sets the id. + /// + /// The id. + [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] + public Guid Id { get; set; } + } + /// /// Class GetPersonImage /// @@ -48,6 +118,9 @@ namespace MediaBrowser.Api.Images public string Name { get; set; } } + /// + /// Class GetArtistImage + /// [Route("/Artists/{Name}/Images/{Type}", "GET")] [Route("/Artists/{Name}/Images/{Type}/{Index}", "GET")] [Api(Description = "Gets an artist image")] @@ -141,6 +214,9 @@ namespace MediaBrowser.Api.Images public Guid Id { get; set; } } + /// + /// Class PostUserImage + /// [Route("/Users/{Id}/Images/{Type}", "POST")] [Route("/Users/{Id}/Images/{Type}/{Index}", "POST")] [Api(Description = "Posts a user image")] @@ -160,6 +236,9 @@ namespace MediaBrowser.Api.Images public Stream RequestStream { get; set; } } + /// + /// Class PostItemImage + /// [Route("/Items/{Id}/Images/{Type}", "POST")] [Route("/Items/{Id}/Images/{Type}/{Index}", "POST")] [Api(Description = "Posts an item image")] @@ -178,7 +257,7 @@ namespace MediaBrowser.Api.Images /// The request stream. public Stream RequestStream { get; set; } } - + /// /// Class ImageService /// @@ -194,17 +273,154 @@ namespace MediaBrowser.Api.Images /// private readonly ILibraryManager _libraryManager; + private readonly IApplicationPaths _appPaths; + + private readonly IProviderManager _providerManager; + /// /// Initializes a new instance of the class. /// /// The user manager. /// The library manager. - public ImageService(IUserManager userManager, ILibraryManager libraryManager) + /// The app paths. + /// The provider manager. + public ImageService(IUserManager userManager, ILibraryManager libraryManager, IApplicationPaths appPaths, IProviderManager providerManager) { _userManager = userManager; _libraryManager = libraryManager; + _appPaths = appPaths; + _providerManager = providerManager; } + /// + /// Gets the specified request. + /// + /// The request. + /// System.Object. + public object Get(GetItemImageInfos request) + { + var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager); + + var result = GetItemImageInfos(item).Result; + + return ToOptimizedResult(result); + } + + /// + /// Gets the item image infos. + /// + /// The item. + /// Task{List{ImageInfo}}. + public async Task> GetItemImageInfos(BaseItem item) + { + var list = new List(); + + foreach (var image in item.Images) + { + var path = image.Value; + + var fileInfo = new FileInfo(path); + + var dateModified = Kernel.Instance.ImageManager.GetImageDateModified(item, path); + + var size = await Kernel.Instance.ImageManager.GetImageSize(path, dateModified).ConfigureAwait(false); + + list.Add(new ImageInfo + { + Path = path, + ImageType = image.Key, + ImageTag = Kernel.Instance.ImageManager.GetImageCacheTag(item, image.Key, path), + Size = fileInfo.Length, + Width = Convert.ToInt32(size.Width), + Height = Convert.ToInt32(size.Height) + }); + } + + var index = 0; + + foreach (var image in item.BackdropImagePaths) + { + var fileInfo = new FileInfo(image); + + var dateModified = Kernel.Instance.ImageManager.GetImageDateModified(item, image); + + var size = await Kernel.Instance.ImageManager.GetImageSize(image, dateModified).ConfigureAwait(false); + + list.Add(new ImageInfo + { + Path = image, + ImageIndex = index, + ImageType = ImageType.Backdrop, + ImageTag = Kernel.Instance.ImageManager.GetImageCacheTag(item, ImageType.Backdrop, image), + Size = fileInfo.Length, + Width = Convert.ToInt32(size.Width), + Height = Convert.ToInt32(size.Height) + }); + + index++; + } + + index = 0; + + foreach (var image in item.ScreenshotImagePaths) + { + var fileInfo = new FileInfo(image); + + var dateModified = Kernel.Instance.ImageManager.GetImageDateModified(item, image); + + var size = await Kernel.Instance.ImageManager.GetImageSize(image, dateModified).ConfigureAwait(false); + + list.Add(new ImageInfo + { + Path = image, + ImageIndex = index, + ImageType = ImageType.Screenshot, + ImageTag = Kernel.Instance.ImageManager.GetImageCacheTag(item, ImageType.Screenshot, image), + Size = fileInfo.Length, + Width = Convert.ToInt32(size.Width), + Height = Convert.ToInt32(size.Height) + }); + + index++; + } + + var video = item as Video; + + if (video != null) + { + index = 0; + + foreach (var chapter in video.Chapters) + { + if (!string.IsNullOrEmpty(chapter.ImagePath)) + { + var image = chapter.ImagePath; + + var fileInfo = new FileInfo(image); + + var dateModified = Kernel.Instance.ImageManager.GetImageDateModified(item, image); + + var size = await Kernel.Instance.ImageManager.GetImageSize(image, dateModified).ConfigureAwait(false); + + list.Add(new ImageInfo + { + Path = image, + ImageIndex = index, + ImageType = ImageType.Chapter, + ImageTag = Kernel.Instance.ImageManager.GetImageCacheTag(item, ImageType.Chapter, image), + Size = fileInfo.Length, + Width = Convert.ToInt32(size.Width), + Height = Convert.ToInt32(size.Height) + }); + } + + index++; + } + } + + return list; + } + /// /// Gets the specified request. /// @@ -276,7 +492,7 @@ namespace MediaBrowser.Api.Images return GetImage(request, item); } - + /// /// Gets the specified request. /// @@ -333,18 +549,97 @@ namespace MediaBrowser.Api.Images { var item = _userManager.Users.First(i => i.Id == request.Id); - var task = item.DeleteImage(request.Type); + var task = item.DeleteImage(request.Type, request.Index); Task.WaitAll(task); } - + + /// + /// Deletes the specified request. + /// + /// The request. + public void Delete(DeleteItemImage request) + { + var item = _libraryManager.GetItemById(request.Id); + + var task = item.DeleteImage(request.Type, request.Index); + + Task.WaitAll(task); + } + + /// + /// Posts the specified request. + /// + /// The request. + public void Post(UpdateItemImageIndex request) + { + var item = _libraryManager.GetItemById(request.Id); + + var task = UpdateItemIndex(item, request.Type, request.Index, request.NewIndex); + + Task.WaitAll(task); + } + + /// + /// Updates the index of the item. + /// + /// The item. + /// The type. + /// Index of the current. + /// The new index. + /// Task. + /// The change index operation is only applicable to backdrops and screenshots + private Task UpdateItemIndex(BaseItem item, ImageType type, int currentIndex, int newIndex) + { + string file1; + string file2; + + if (type == ImageType.Screenshot) + { + file1 = item.ScreenshotImagePaths[currentIndex]; + file2 = item.ScreenshotImagePaths[newIndex]; + } + else if (type == ImageType.Backdrop) + { + file1 = item.BackdropImagePaths[currentIndex]; + file2 = item.BackdropImagePaths[newIndex]; + } + else + { + throw new ArgumentException("The change index operation is only applicable to backdrops and screenshots"); + } + + SwapFiles(file1, file2); + + // Directory watchers should repeat this, but do a quick refresh first + return item.RefreshMetadata(CancellationToken.None, forceSave: true, allowSlowProviders: false); + } + + /// + /// Swaps the files. + /// + /// The file1. + /// The file2. + private void SwapFiles(string file1, string file2) + { + var temp1 = Path.Combine(_appPaths.TempDirectory, Guid.NewGuid() + ".tmp"); + var temp2 = Path.Combine(_appPaths.TempDirectory, Guid.NewGuid() + ".tmp"); + + File.Copy(file1, temp1); + File.Copy(file2, temp2); + + File.Copy(temp1, file2, true); + File.Copy(temp2, file1, true); + } + /// /// Gets the image. /// /// The request. /// The item. /// System.Object. - /// + /// + /// private object GetImage(ImageRequest request, BaseItem item) { var kernel = Kernel.Instance; @@ -430,7 +725,13 @@ namespace MediaBrowser.Api.Images filename = "clearart"; break; case ImageType.Primary: - filename = "folder"; + filename = entity is Episode ? Path.GetFileNameWithoutExtension(entity.Path) : "folder"; + break; + case ImageType.Backdrop: + filename = GetBackdropFilenameToSave(entity); + break; + case ImageType.Screenshot: + filename = GetScreenshotFilenameToSave(entity); break; default: filename = imageType.ToString().ToLower(); @@ -440,9 +741,30 @@ namespace MediaBrowser.Api.Images var extension = mimeType.Split(';').First().Split('/').Last(); - var oldImagePath = entity.GetImage(imageType); + string oldImagePath; + switch (imageType) + { + case ImageType.Backdrop: + case ImageType.Screenshot: + oldImagePath = null; + break; + default: + oldImagePath = entity.GetImage(imageType); + break; + } + + // Don't save locally if there's no parent (special feature, trailer, etc) + var saveLocally = !(entity is Audio) && entity.Parent != null; + + if (imageType != ImageType.Primary) + { + if (entity is Episode) + { + saveLocally = false; + } + } - var imagePath = Path.Combine(entity.MetaLocation, filename + "." + extension); + var imagePath = _providerManager.GetSavePath(entity, filename + "." + extension, saveLocally); // Save to file system using (var fs = new FileStream(imagePath, FileMode.Create, FileAccess.Write, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, true)) @@ -450,8 +772,19 @@ namespace MediaBrowser.Api.Images await fs.WriteAsync(bytes, 0, bytes.Length).ConfigureAwait(false); } - // Set the image - entity.SetImage(imageType, imagePath); + if (imageType == ImageType.Screenshot) + { + entity.ScreenshotImagePaths.Add(imagePath); + } + else if (imageType == ImageType.Backdrop) + { + entity.BackdropImagePaths.Add(imagePath); + } + else + { + // Set the image + entity.SetImage(imageType, imagePath); + } // If the new and old paths are different, delete the old one if (!string.IsNullOrEmpty(oldImagePath) && !oldImagePath.Equals(imagePath, StringComparison.OrdinalIgnoreCase)) @@ -463,5 +796,53 @@ namespace MediaBrowser.Api.Images await entity.RefreshMetadata(CancellationToken.None, forceSave: true, allowSlowProviders: false).ConfigureAwait(false); } } + + /// + /// Gets the backdrop filename to save. + /// + /// The item. + /// System.String. + private string GetBackdropFilenameToSave(BaseItem item) + { + var paths = item.BackdropImagePaths.ToList(); + + if (!paths.Any(i => string.Equals(Path.GetFileNameWithoutExtension(i), "backdrop", StringComparison.OrdinalIgnoreCase))) + { + return "screenshot"; + } + + var index = 1; + + while (paths.Any(i => string.Equals(Path.GetFileNameWithoutExtension(i), "backdrop" + index, StringComparison.OrdinalIgnoreCase))) + { + index++; + } + + return "backdrop" + index; + } + + /// + /// Gets the screenshot filename to save. + /// + /// The item. + /// System.String. + private string GetScreenshotFilenameToSave(BaseItem item) + { + var paths = item.ScreenshotImagePaths.ToList(); + + if (!paths.Any(i => string.Equals(Path.GetFileNameWithoutExtension(i), "screenshot", StringComparison.OrdinalIgnoreCase))) + { + return "screenshot"; + } + + var index = 1; + + while (paths.Any(i => string.Equals(Path.GetFileNameWithoutExtension(i), "screenshot" + index, StringComparison.OrdinalIgnoreCase))) + { + index++; + } + + return "screenshot" + index; + } } } diff --git a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs index 4396fac66e..9bcce87c89 100644 --- a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs +++ b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs @@ -241,7 +241,7 @@ namespace MediaBrowser.Api.Playback.Progressive } } - return new ImageService(UserManager, LibraryManager) + return new ImageService(UserManager, LibraryManager, ApplicationPaths, null) { Logger = Logger, RequestContext = RequestContext, diff --git a/MediaBrowser.Controller/Dto/DtoBuilder.cs b/MediaBrowser.Controller/Dto/DtoBuilder.cs index 39b139f02b..803e198bf0 100644 --- a/MediaBrowser.Controller/Dto/DtoBuilder.cs +++ b/MediaBrowser.Controller/Dto/DtoBuilder.cs @@ -287,6 +287,7 @@ namespace MediaBrowser.Controller.Dto dto.AspectRatio = item.AspectRatio; dto.BackdropImageTags = GetBackdropImageTags(item); + dto.ScreenshotImageTags = GetScreenshotImageTags(item); if (fields.Contains(ItemFields.Genres)) { @@ -981,5 +982,20 @@ namespace MediaBrowser.Controller.Dto return item.BackdropImagePaths.Select(p => Kernel.Instance.ImageManager.GetImageCacheTag(item, ImageType.Backdrop, p)).ToList(); } + + /// + /// Gets the screenshot image tags. + /// + /// The item. + /// List{Guid}. + private List GetScreenshotImageTags(BaseItem item) + { + if (item.ScreenshotImagePaths == null) + { + return new List(); + } + + return item.ScreenshotImagePaths.Select(p => Kernel.Instance.ImageManager.GetImageCacheTag(item, ImageType.Screenshot, p)).ToList(); + } } } diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 48bfd8075c..a4cbd1b079 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -1475,22 +1475,49 @@ namespace MediaBrowser.Controller.Entities /// Deletes the image. /// /// The type. + /// The index. /// Task. - public async Task DeleteImage(ImageType type) + public Task DeleteImage(ImageType type, int? index) { - if (!HasImage(type)) + if (type == ImageType.Backdrop) { - return; + if (!index.HasValue) + { + throw new ArgumentException("Please specify a backdrop image index to delete."); + } + + var file = BackdropImagePaths[index.Value]; + + BackdropImagePaths.Remove(file); + + // Delete the source file + File.Delete(file); } + else if (type == ImageType.Screenshot) + { + if (!index.HasValue) + { + throw new ArgumentException("Please specify a screenshot image index to delete."); + } + + var file = ScreenshotImagePaths[index.Value]; - // Delete the source file - File.Delete(GetImage(type)); + ScreenshotImagePaths.Remove(file); + + // Delete the source file + File.Delete(file); + } + else + { + // Delete the source file + File.Delete(GetImage(type)); - // Remove it from the item - SetImage(type, null); + // Remove it from the item + SetImage(type, null); + } // Refresh metadata - await RefreshMetadata(CancellationToken.None).ConfigureAwait(false); + return RefreshMetadata(CancellationToken.None); } } } diff --git a/MediaBrowser.Controller/IO/FileSystem.cs b/MediaBrowser.Controller/IO/FileSystem.cs index cbe561fdf0..e5f80533aa 100644 --- a/MediaBrowser.Controller/IO/FileSystem.cs +++ b/MediaBrowser.Controller/IO/FileSystem.cs @@ -55,7 +55,7 @@ namespace MediaBrowser.Controller.IO try { - return info.LastAccessTimeUtc; + return info.LastWriteTimeUtc; } catch (Exception ex) { diff --git a/MediaBrowser.Controller/Providers/IProviderManager.cs b/MediaBrowser.Controller/Providers/IProviderManager.cs index fa10c85855..da46c0bce6 100644 --- a/MediaBrowser.Controller/Providers/IProviderManager.cs +++ b/MediaBrowser.Controller/Providers/IProviderManager.cs @@ -47,5 +47,14 @@ namespace MediaBrowser.Controller.Providers /// /// The providers. void AddMetadataProviders(IEnumerable providers); + + /// + /// Gets the save path. + /// + /// The item. + /// Name of the target file. + /// if set to true [save locally]. + /// System.String. + string GetSavePath(BaseItem item, string targetFileName, bool saveLocally); } } \ No newline at end of file diff --git a/MediaBrowser.Model/DTO/BaseItemDto.cs b/MediaBrowser.Model/DTO/BaseItemDto.cs index f33892c47e..2e54f33110 100644 --- a/MediaBrowser.Model/DTO/BaseItemDto.cs +++ b/MediaBrowser.Model/DTO/BaseItemDto.cs @@ -338,6 +338,12 @@ namespace MediaBrowser.Model.Dto /// The backdrop image tags. public List BackdropImageTags { get; set; } + /// + /// Gets or sets the screenshot image tags. + /// + /// The screenshot image tags. + public List ScreenshotImageTags { get; set; } + /// /// Gets or sets the parent logo image tag. /// @@ -440,6 +446,16 @@ namespace MediaBrowser.Model.Dto get { return BackdropImageTags == null ? 0 : BackdropImageTags.Count; } } + /// + /// Gets the screenshot count. + /// + /// The screenshot count. + [IgnoreDataMember] + public int ScreenshotCount + { + get { return ScreenshotImageTags == null ? 0 : ScreenshotImageTags.Count; } + } + /// /// Gets a value indicating whether this instance has banner. /// diff --git a/MediaBrowser.Model/Dto/ImageInfo.cs b/MediaBrowser.Model/Dto/ImageInfo.cs new file mode 100644 index 0000000000..0850ee0a4e --- /dev/null +++ b/MediaBrowser.Model/Dto/ImageInfo.cs @@ -0,0 +1,52 @@ +using MediaBrowser.Model.Entities; +using System; + +namespace MediaBrowser.Model.Dto +{ + /// + /// Class ImageInfo + /// + public class ImageInfo + { + /// + /// Gets or sets the type of the image. + /// + /// The type of the image. + public ImageType ImageType { get; set; } + + /// + /// Gets or sets the index of the image. + /// + /// The index of the image. + public int? ImageIndex { get; set; } + + /// + /// The image tag + /// + public Guid ImageTag; + + /// + /// Gets or sets the path. + /// + /// The path. + public string Path { get; set; } + + /// + /// Gets or sets the height. + /// + /// The height. + public int Height { get; set; } + + /// + /// Gets or sets the width. + /// + /// The width. + public int Width { get; set; } + + /// + /// Gets or sets the size. + /// + /// The size. + public long Size { get; set; } + } +} diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index 512ddd7ded..707e6ea4d4 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -45,6 +45,7 @@ + diff --git a/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs b/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs index fe93cd3779..569fb8e022 100644 --- a/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs +++ b/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs @@ -397,6 +397,19 @@ namespace MediaBrowser.Server.Implementations.Providers return localPath; } + /// + /// Gets the save path. + /// + /// The item. + /// Name of the target file. + /// if set to true [save locally]. + /// System.String. + public string GetSavePath(BaseItem item, string targetFileName, bool saveLocally) + { + return (saveLocally && item.MetaLocation != null) ? + Path.Combine(item.MetaLocation, targetFileName) : + _remoteImageCache.GetResourcePath(item.GetType().FullName + item.Path.ToLower(), targetFileName); + } /// /// Saves to library filesystem. diff --git a/MediaBrowser.WebDashboard/ApiClient.js b/MediaBrowser.WebDashboard/ApiClient.js index 2e11a72fca..ae97e86f11 100644 --- a/MediaBrowser.WebDashboard/ApiClient.js +++ b/MediaBrowser.WebDashboard/ApiClient.js @@ -758,7 +758,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) { * @param {String} userId * @param {String} imageType The type of image to delete, based on the server-side ImageType enum. */ - self.deleteUserImage = function (userId, imageType) { + self.deleteUserImage = function (userId, imageType, imageIndex) { if (!userId) { throw new Error("null userId"); @@ -770,12 +770,71 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) { var url = self.getUrl("Users/" + userId + "/Images/" + imageType); + if (imageIndex != null) { + url += "/" + imageIndex; + } + return self.ajax({ type: "DELETE", url: url }); }; + self.deleteItemImage = function (itemId, imageType, imageIndex) { + + if (!itemId) { + throw new Error("null itemId"); + } + + if (!imageType) { + throw new Error("null imageType"); + } + + var url = self.getUrl("Items/" + itemId + "/Images/" + imageType); + + if (imageIndex != null) { + url += "/" + imageIndex; + } + + return self.ajax({ + type: "DELETE", + url: url + }); + }; + + self.updateItemImageIndex = function (itemId, imageType, imageIndex, newIndex) { + + if (!itemId) { + throw new Error("null itemId"); + } + + if (!imageType) { + throw new Error("null imageType"); + } + + var url = self.getUrl("Items/" + itemId + "/Images/" + imageType + "/" + imageIndex + "/Index", { newIndex: newIndex }); + + return self.ajax({ + type: "POST", + url: url + }); + }; + + self.getItemImageInfos = function (itemId) { + + if (!itemId) { + throw new Error("null itemId"); + } + + var url = self.getUrl("Items/" + itemId + "/Images"); + + return self.ajax({ + type: "GET", + url: url, + dataType: "json" + }); + }; + /** * Uploads a user image * @param {String} userId @@ -839,7 +898,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) { return deferred.promise(); }; - self.uploadImage = function (itemId, imageType, file) { + self.uploadItemImage = function (itemId, imageType, file) { if (!itemId) { throw new Error("null itemId"); diff --git a/MediaBrowser.WebDashboard/packages.config b/MediaBrowser.WebDashboard/packages.config index 23ebca2930..34667ce4cc 100644 --- a/MediaBrowser.WebDashboard/packages.config +++ b/MediaBrowser.WebDashboard/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file