create images list object

pull/702/head
Luke Pulverenti 10 years ago
parent 5e2a2a02ef
commit 76658f0797

@ -115,7 +115,7 @@ namespace MediaBrowser.Api.DefaultTheme
var itemsWithImages = allFavoriteItems.Where(i => !string.IsNullOrEmpty(i.PrimaryImagePath))
.ToList();
var itemsWithBackdrops = allFavoriteItems.Where(i => i.BackdropImagePaths.Count > 0)
var itemsWithBackdrops = allFavoriteItems.Where(i => i.GetImages(ImageType.Backdrop).Any())
.ToList();
var view = new FavoritesView();
@ -227,7 +227,7 @@ namespace MediaBrowser.Api.DefaultTheme
var gamesWithImages = items.OfType<Game>().Where(i => !string.IsNullOrEmpty(i.PrimaryImagePath)).ToList();
var itemsWithBackdrops = FilterItemsForBackdropDisplay(items.Where(i => i.BackdropImagePaths.Count > 0)).ToList();
var itemsWithBackdrops = FilterItemsForBackdropDisplay(items.Where(i => i.GetImages(ImageType.Backdrop).Any())).ToList();
var gamesWithBackdrops = itemsWithBackdrops.OfType<Game>().ToList();
@ -282,7 +282,7 @@ namespace MediaBrowser.Api.DefaultTheme
.OfType<Series>()
.ToList();
var seriesWithBackdrops = series.Where(i => i.BackdropImagePaths.Count > 0).ToList();
var seriesWithBackdrops = series.Where(i => i.GetImages(ImageType.Backdrop).Any()).ToList();
var view = new TvView();
@ -298,7 +298,7 @@ namespace MediaBrowser.Api.DefaultTheme
.ToList();
view.ShowsItems = series
.Where(i => i.BackdropImagePaths.Count > 0)
.Where(i => i.GetImages(ImageType.Backdrop).Any())
.Randomize("all")
.Select(i => GetItemStub(i, ImageType.Backdrop))
.Where(i => i != null)
@ -425,7 +425,7 @@ namespace MediaBrowser.Api.DefaultTheme
view.FamilyMoviePercentage /= movies.Count;
var moviesWithBackdrops = movies
.Where(i => i.BackdropImagePaths.Count > 0)
.Where(i => i.GetImages(ImageType.Backdrop).Any())
.ToList();
var fields = new List<ItemFields>();
@ -456,7 +456,7 @@ namespace MediaBrowser.Api.DefaultTheme
view.BoxSetItems = items
.OfType<BoxSet>()
.Where(i => i.BackdropImagePaths.Count > 0)
.Where(i => i.GetImages(ImageType.Backdrop).Any())
.Randomize()
.Select(i => GetItemStub(i, ImageType.Backdrop))
.Where(i => i != null)
@ -491,7 +491,7 @@ namespace MediaBrowser.Api.DefaultTheme
.ToList();
view.HDItems = hdMovies
.Where(i => i.BackdropImagePaths.Count > 0)
.Where(i => i.GetImages(ImageType.Backdrop).Any())
.Randomize("hd")
.Select(i => GetItemStub(i, ImageType.Backdrop))
.Where(i => i != null)
@ -499,7 +499,7 @@ namespace MediaBrowser.Api.DefaultTheme
.ToList();
view.FamilyMovies = familyMovies
.Where(i => i.BackdropImagePaths.Count > 0)
.Where(i => i.GetImages(ImageType.Backdrop).Any())
.Randomize("family")
.Select(i => GetItemStub(i, ImageType.Backdrop))
.Where(i => i != null)
@ -575,7 +575,7 @@ namespace MediaBrowser.Api.DefaultTheme
private IEnumerable<BaseItem> FilterItemsForBackdropDisplay(IEnumerable<BaseItem> items)
{
var tuples = items
.Select(i => new Tuple<BaseItem, double>(i, GetResolution(i, i.BackdropImagePaths[0])))
.Select(i => new Tuple<BaseItem, double>(i, GetResolution(i, ImageType.Backdrop, 0)))
.Where(i => i.Item2 > 0)
.ToList();
@ -591,13 +591,13 @@ namespace MediaBrowser.Api.DefaultTheme
return tuples.Select(i => i.Item1);
}
private double GetResolution(BaseItem item, string path)
private double GetResolution(BaseItem item, ImageType type, int index)
{
try
{
var date = item.GetImageDateModified(path);
var info = item.GetImageInfo(type, index);
var size = _imageProcessor.GetImageSize(path, date);
var size = _imageProcessor.GetImageSize(info.Path, info.DateModified);
return size.Width;
}
@ -618,9 +618,12 @@ namespace MediaBrowser.Api.DefaultTheme
try
{
var imagePath = item.GetImagePath(imageType, 0);
var tag = _imageProcessor.GetImageCacheTag(item, imageType);
stub.ImageTag = _imageProcessor.GetImageCacheTag(item, imageType, imagePath);
if (tag.HasValue)
{
stub.ImageTag = tag.Value;
}
}
catch (Exception ex)
{

@ -1,5 +1,6 @@
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
@ -334,12 +335,12 @@ namespace MediaBrowser.Api.Images
private readonly IItemRepository _itemRepo;
private readonly IDtoService _dtoService;
private readonly IImageProcessor _imageProcessor;
private readonly IFileSystem _fileSystem;
/// <summary>
/// Initializes a new instance of the <see cref="ImageService" /> class.
/// </summary>
public ImageService(IUserManager userManager, ILibraryManager libraryManager, IApplicationPaths appPaths, IProviderManager providerManager, IItemRepository itemRepo, IDtoService dtoService, IImageProcessor imageProcessor)
public ImageService(IUserManager userManager, ILibraryManager libraryManager, IApplicationPaths appPaths, IProviderManager providerManager, IItemRepository itemRepo, IDtoService dtoService, IImageProcessor imageProcessor, IFileSystem fileSystem)
{
_userManager = userManager;
_libraryManager = libraryManager;
@ -348,6 +349,7 @@ namespace MediaBrowser.Api.Images
_itemRepo = itemRepo;
_dtoService = dtoService;
_imageProcessor = imageProcessor;
_fileSystem = fileSystem;
}
/// <summary>
@ -395,9 +397,9 @@ namespace MediaBrowser.Api.Images
{
var list = new List<ImageInfo>();
foreach (var image in item.Images)
foreach (var image in item.ImageInfos.Where(i => !item.AllowsMultipleImages(i.Type)))
{
var info = GetImageInfo(image.Value, item, null, image.Key);
var info = GetImageInfo(item, image, null);
if (info != null)
{
@ -405,28 +407,16 @@ namespace MediaBrowser.Api.Images
}
}
var index = 0;
foreach (var image in item.BackdropImagePaths)
foreach (var imageType in item.ImageInfos.Select(i => i.Type).Distinct().Where(item.AllowsMultipleImages))
{
var info = GetImageInfo(image, item, index, ImageType.Backdrop);
if (info != null)
{
list.Add(info);
}
var index = 0;
index++;
}
// Prevent implicitly captured closure
var currentImageType = imageType;
index = 0;
var hasScreenshots = item as IHasScreenshots;
if (hasScreenshots != null)
{
foreach (var image in hasScreenshots.ScreenshotImagePaths)
foreach (var image in item.ImageInfos.Where(i => i.Type == currentImageType))
{
var info = GetImageInfo(image, item, index, ImageType.Screenshot);
var info = GetImageInfo(item, image, index);
if (info != null)
{
@ -441,7 +431,7 @@ namespace MediaBrowser.Api.Images
if (video != null)
{
index = 0;
var index = 0;
foreach (var chapter in _itemRepo.GetChapters(video.Id))
{
@ -449,7 +439,13 @@ namespace MediaBrowser.Api.Images
{
var image = chapter.ImagePath;
var info = GetImageInfo(image, item, index, ImageType.Chapter);
var info = GetImageInfo(item, new ItemImageInfo
{
Path = image,
Type = ImageType.Chapter,
DateModified = _fileSystem.GetLastWriteTimeUtc(image)
}, index);
if (info != null)
{
@ -464,20 +460,20 @@ namespace MediaBrowser.Api.Images
return list;
}
private ImageInfo GetImageInfo(string path, IHasImages item, int? imageIndex, ImageType type)
private ImageInfo GetImageInfo(IHasImages item, ItemImageInfo info, int? imageIndex)
{
try
{
var fileInfo = new FileInfo(path);
var fileInfo = new FileInfo(info.Path);
var size = _imageProcessor.GetImageSize(path);
var size = _imageProcessor.GetImageSize(info.Path);
return new ImageInfo
{
Path = path,
Path = info.Path,
ImageIndex = imageIndex,
ImageType = type,
ImageTag = _imageProcessor.GetImageCacheTag(item, type, path),
ImageType = info.Type,
ImageTag = _imageProcessor.GetImageCacheTag(item, info),
Size = fileInfo.Length,
Width = Convert.ToInt32(size.Width),
Height = Convert.ToInt32(size.Height)
@ -485,7 +481,7 @@ namespace MediaBrowser.Api.Images
}
catch (Exception ex)
{
Logger.ErrorException("Error getting image information for {0}", ex, path);
Logger.ErrorException("Error getting image information for {0}", ex, info.Path);
return null;
}
@ -584,7 +580,7 @@ namespace MediaBrowser.Api.Images
{
var item = _userManager.Users.First(i => i.Id == request.Id);
var task = item.DeleteImage(request.Type, request.Index);
var task = item.DeleteImage(request.Type, request.Index ?? 0);
Task.WaitAll(task);
}
@ -597,7 +593,7 @@ namespace MediaBrowser.Api.Images
{
var item = _libraryManager.GetItemById(request.Id);
var task = item.DeleteImage(request.Type, request.Index);
var task = item.DeleteImage(request.Type, request.Index ?? 0);
Task.WaitAll(task);
}
@ -613,7 +609,7 @@ namespace MediaBrowser.Api.Images
var item = GetItemByName(request.Name, type, _libraryManager);
var task = item.DeleteImage(request.Type, request.Index);
var task = item.DeleteImage(request.Type, request.Index ?? 0);
Task.WaitAll(task);
}
@ -671,15 +667,15 @@ namespace MediaBrowser.Api.Images
/// </exception>
public object GetImage(ImageRequest request, IHasImages item)
{
var imagePath = GetImagePath(request, item);
var imageInfo = GetImageInfo(request, item);
if (string.IsNullOrEmpty(imagePath))
if (imageInfo == null)
{
throw new ResourceNotFoundException(string.Format("{0} does not have an image of type {1}", item.Name, request.Type));
}
// See if we can avoid a file system lookup by looking for the file in ResolveArgs
var originalFileImageDateModified = item.GetImageDateModified(imagePath);
var originalFileImageDateModified = imageInfo.DateModified;
var supportedImageEnhancers = request.EnableImageEnhancers ? _imageProcessor.ImageEnhancers.Where(i =>
{
@ -696,16 +692,9 @@ namespace MediaBrowser.Api.Images
}).ToList() : new List<IImageEnhancer>();
// If the file does not exist GetLastWriteTimeUtc will return jan 1, 1601 as opposed to throwing an exception
// http://msdn.microsoft.com/en-us/library/system.io.file.getlastwritetimeutc.aspx
if (originalFileImageDateModified.Year == 1601 && !File.Exists(imagePath))
{
throw new ResourceNotFoundException(string.Format("File not found: {0}", imagePath));
}
var contentType = GetMimeType(request.Format, imagePath);
var contentType = GetMimeType(request.Format, imageInfo.Path);
var cacheGuid = _imageProcessor.GetImageCacheTag(item, request.Type, imagePath, originalFileImageDateModified, supportedImageEnhancers);
var cacheGuid = _imageProcessor.GetImageCacheTag(item, request.Type, imageInfo.Path, originalFileImageDateModified, supportedImageEnhancers);
TimeSpan? cacheDuration = null;
@ -724,7 +713,7 @@ namespace MediaBrowser.Api.Images
Request = currentRequest,
OriginalImageDateModified = originalFileImageDateModified,
Enhancers = supportedImageEnhancers,
OriginalImagePath = imagePath,
OriginalImagePath = imageInfo.Path,
ImageProcessor = _imageProcessor
}, contentType);
@ -758,11 +747,11 @@ namespace MediaBrowser.Api.Images
/// <param name="request">The request.</param>
/// <param name="item">The item.</param>
/// <returns>System.String.</returns>
private string GetImagePath(ImageRequest request, IHasImages item)
private ItemImageInfo GetImageInfo(ImageRequest request, IHasImages item)
{
var index = request.Index ?? 0;
return item.GetImagePath(request.Type, index);
return item.GetImageInfo(request.Type, index);
}
/// <summary>

@ -165,9 +165,11 @@ namespace MediaBrowser.Api
ProductionYear = item.ProductionYear
};
if (item.HasImage(ImageType.Primary))
var primaryImageTag = _imageProcessor.GetImageCacheTag(item, ImageType.Primary);
if (primaryImageTag.HasValue)
{
result.PrimaryImageTag = _imageProcessor.GetImageCacheTag(item, ImageType.Primary, item.GetImagePath(ImageType.Primary));
result.PrimaryImageTag = primaryImageTag.Value;
}
SetThumbImageInfo(result, item);
@ -241,8 +243,13 @@ namespace MediaBrowser.Api
if (itemWithImage != null)
{
hint.ThumbImageTag = _imageProcessor.GetImageCacheTag(itemWithImage, ImageType.Thumb, itemWithImage.GetImagePath(ImageType.Thumb));
hint.ThumbImageItemId = itemWithImage.Id.ToString("N");
var tag = _imageProcessor.GetImageCacheTag(itemWithImage, ImageType.Thumb);
if (tag.HasValue)
{
hint.ThumbImageTag = tag.Value;
hint.ThumbImageItemId = itemWithImage.Id.ToString("N");
}
}
}
@ -257,8 +264,13 @@ namespace MediaBrowser.Api
if (itemWithImage != null)
{
hint.BackdropImageTag = _imageProcessor.GetImageCacheTag(itemWithImage, ImageType.Backdrop, itemWithImage.GetImagePath(ImageType.Backdrop, 0));
hint.BackdropImageItemId = itemWithImage.Id.ToString("N");
var tag = _imageProcessor.GetImageCacheTag(itemWithImage, ImageType.Backdrop);
if (tag.HasValue)
{
hint.BackdropImageTag = tag.Value;
hint.BackdropImageItemId = itemWithImage.Id.ToString("N");
}
}
}

@ -1181,21 +1181,6 @@ namespace MediaBrowser.Api.UserLibrary
/// <returns><c>true</c> if the specified item has image; otherwise, <c>false</c>.</returns>
internal static bool HasImage(BaseItem item, ImageType imageType)
{
if (imageType == ImageType.Backdrop)
{
return item.BackdropImagePaths.Count > 0;
}
if (imageType == ImageType.Screenshot)
{
var hasScreenshots = item as IHasScreenshots;
if (hasScreenshots == null)
{
return false;
}
return hasScreenshots.ScreenshotImagePaths.Count > 0;
}
return item.HasImage(imageType);
}

@ -53,10 +53,9 @@ namespace MediaBrowser.Controller.Drawing
/// Gets the image cache tag.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="imageType">Type of the image.</param>
/// <param name="imagePath">The image path.</param>
/// <param name="image">The image.</param>
/// <returns>Guid.</returns>
Guid GetImageCacheTag(IHasImages item, ImageType imageType, string imagePath);
Guid GetImageCacheTag(IHasImages item, ItemImageInfo image);
/// <summary>
/// Gets the image cache tag.
@ -87,4 +86,24 @@ namespace MediaBrowser.Controller.Drawing
/// <returns>Task{System.String}.</returns>
Task<string> GetEnhancedImage(IHasImages item, ImageType imageType, int imageIndex);
}
public static class ImageProcessorExtensions
{
public static Guid? GetImageCacheTag(this IImageProcessor processor, IHasImages item, ImageType imageType)
{
return processor.GetImageCacheTag(item, imageType, 0);
}
public static Guid? GetImageCacheTag(this IImageProcessor processor, IHasImages item, ImageType imageType, int imageIndex)
{
var imageInfo = item.GetImageInfo(imageType, imageIndex);
if (imageInfo == null)
{
return null;
}
return processor.GetImageCacheTag(item, imageInfo);
}
}
}

@ -28,10 +28,9 @@ namespace MediaBrowser.Controller.Entities
Genres = new List<string>();
Studios = new List<string>();
People = new List<PersonInfo>();
BackdropImagePaths = new List<string>();
Images = new Dictionary<ImageType, string>();
ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
LockedFields = new List<MetadataFields>();
ImageInfos = new List<ItemImageInfo>();
}
/// <summary>
@ -48,6 +47,12 @@ namespace MediaBrowser.Controller.Entities
public const string ThemeVideosFolderName = "backdrops";
public const string XbmcTrailerFileSuffix = "-trailer";
public List<ItemImageInfo> ImageInfos { get; set; }
/// <summary>
/// Gets a value indicating whether this instance is in mixed folder.
/// </summary>
/// <value><c>true</c> if this instance is in mixed folder; otherwise, <c>false</c>.</value>
public bool IsInMixedFolder { get; set; }
private string _name;
@ -160,15 +165,8 @@ namespace MediaBrowser.Controller.Entities
public string PrimaryImagePath
{
get { return this.GetImagePath(ImageType.Primary); }
set { this.SetImagePath(ImageType.Primary, value); }
}
/// <summary>
/// Gets or sets the images.
/// </summary>
/// <value>The images.</value>
public Dictionary<ImageType, string> Images { get; set; }
/// <summary>
/// Gets or sets the date created.
/// </summary>
@ -349,12 +347,6 @@ namespace MediaBrowser.Controller.Entities
/// <value>The display type of the media.</value>
public string DisplayMediaType { get; set; }
/// <summary>
/// Gets or sets the backdrop image paths.
/// </summary>
/// <value>The backdrop image paths.</value>
public List<string> BackdropImagePaths { get; set; }
/// <summary>
/// Gets or sets the official rating.
/// </summary>
@ -1162,43 +1154,31 @@ namespace MediaBrowser.Controller.Entities
/// <exception cref="System.ArgumentException">Backdrops should be accessed using Item.Backdrops</exception>
public bool HasImage(ImageType type, int imageIndex)
{
if (type == ImageType.Backdrop)
{
return BackdropImagePaths.Count > imageIndex;
}
if (type == ImageType.Screenshot)
{
var hasScreenshots = this as IHasScreenshots;
return hasScreenshots != null && hasScreenshots.ScreenshotImagePaths.Count > imageIndex;
}
return !string.IsNullOrEmpty(this.GetImagePath(type));
return GetImageInfo(type, imageIndex) != null;
}
public void SetImagePath(ImageType type, int index, string path)
public void SetImagePath(ImageType type, int index, FileInfo file)
{
if (type == ImageType.Backdrop)
if (type == ImageType.Chapter)
{
throw new ArgumentException("Backdrops should be accessed using Item.Backdrops");
}
if (type == ImageType.Screenshot)
{
throw new ArgumentException("Screenshots should be accessed using Item.Screenshots");
throw new ArgumentException("Cannot set chapter images using SetImagePath");
}
var typeKey = type;
var image = GetImageInfo(type, index);
// If it's null remove the key from the dictionary
if (string.IsNullOrEmpty(path))
if (image == null)
{
if (Images.ContainsKey(typeKey))
ImageInfos.Add(new ItemImageInfo
{
Images.Remove(typeKey);
}
Path = file.FullName,
Type = type,
DateModified = FileSystem.GetLastWriteTimeUtc(file)
});
}
else
{
Images[typeKey] = path;
image.Path = file.FullName;
image.DateModified = FileSystem.GetLastWriteTimeUtc(file);
}
}
@ -1208,66 +1188,23 @@ namespace MediaBrowser.Controller.Entities
/// <param name="type">The type.</param>
/// <param name="index">The index.</param>
/// <returns>Task.</returns>
public Task DeleteImage(ImageType type, int? index)
public Task DeleteImage(ImageType type, int index)
{
if (type == ImageType.Backdrop)
{
if (!index.HasValue)
{
throw new ArgumentException("Please specify a backdrop image index to delete.");
}
var file = BackdropImagePaths[index.Value];
var info = GetImageInfo(type, index);
BackdropImagePaths.Remove(file);
// Delete the source file
DeleteImagePath(file);
}
else if (type == ImageType.Screenshot)
if (info == null)
{
if (!index.HasValue)
{
throw new ArgumentException("Please specify a screenshot image index to delete.");
}
var hasScreenshots = (IHasScreenshots)this;
var file = hasScreenshots.ScreenshotImagePaths[index.Value];
hasScreenshots.ScreenshotImagePaths.Remove(file);
// Delete the source file
DeleteImagePath(file);
}
else
{
// Delete the source file
DeleteImagePath(this.GetImagePath(type));
// Remove it from the item
this.SetImagePath(type, null);
// Nothing to do
return Task.FromResult(true);
}
// Refresh metadata
// Need to disable slow providers or the image might get re-downloaded
return RefreshMetadata(new MetadataRefreshOptions
{
ForceSave = true,
ImageRefreshMode = ImageRefreshMode.ValidationOnly,
MetadataRefreshMode = MetadataRefreshMode.None
}, CancellationToken.None);
}
// Remove it from the item
ImageInfos.Remove(info);
/// <summary>
/// Deletes the image path.
/// </summary>
/// <param name="path">The path.</param>
private void DeleteImagePath(string path)
{
var currentFile = new FileInfo(path);
// Delete the source file
var currentFile = new FileInfo(info.Path);
// This will fail if the file is hidden
// Deletion will fail if the file is hidden so remove the attribute first
if (currentFile.Exists)
{
if ((currentFile.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
@ -1277,6 +1214,8 @@ namespace MediaBrowser.Controller.Entities
currentFile.Delete();
}
return LibraryManager.UpdateItem(this, ItemUpdateType.ImageUpdate, CancellationToken.None);
}
/// <summary>
@ -1284,132 +1223,110 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
public bool ValidateImages()
{
var changed = false;
// Only validate paths from the same directory - need to copy to a list because we are going to potentially modify the collection below
var deletedKeys = Images
.Where(image => !File.Exists(image.Value))
.Select(i => i.Key)
var deletedImages = ImageInfos
.Where(image => !File.Exists(image.Path))
.ToList();
// Now remove them from the dictionary
foreach (var key in deletedKeys)
if (deletedImages.Count > 0)
{
Images.Remove(key);
changed = true;
ImageInfos = ImageInfos.Except(deletedImages).ToList();
}
if (ValidateBackdrops())
{
changed = true;
}
if (ValidateScreenshots())
{
changed = true;
}
return changed;
return deletedImages.Count > 0;
}
/// <summary>
/// Validates that backdrops within the item are still on the file system
/// Gets the image path.
/// </summary>
private bool ValidateBackdrops()
/// <param name="imageType">Type of the image.</param>
/// <param name="imageIndex">Index of the image.</param>
/// <returns>System.String.</returns>
/// <exception cref="System.InvalidOperationException">
/// </exception>
/// <exception cref="System.ArgumentNullException">item</exception>
public string GetImagePath(ImageType imageType, int imageIndex)
{
var changed = false;
// Only validate paths from the same directory - need to copy to a list because we are going to potentially modify the collection below
var deletedImages = BackdropImagePaths
.Where(path => !File.Exists(path))
.ToList();
// Now remove them from the dictionary
foreach (var path in deletedImages)
{
BackdropImagePaths.Remove(path);
var info = GetImageInfo(imageType, imageIndex);
changed = true;
}
return changed;
return info == null ? null : info.Path;
}
/// <summary>
/// Validates the screenshots.
/// Gets the image information.
/// </summary>
private bool ValidateScreenshots()
/// <param name="imageType">Type of the image.</param>
/// <param name="imageIndex">Index of the image.</param>
/// <returns>ItemImageInfo.</returns>
public ItemImageInfo GetImageInfo(ImageType imageType, int imageIndex)
{
var changed = false;
if (imageType == ImageType.Chapter)
{
var chapter = ItemRepository.GetChapter(Id, imageIndex);
var hasScreenshots = this as IHasScreenshots;
if (chapter == null)
{
return null;
}
if (hasScreenshots == null)
{
return changed;
}
var path = chapter.ImagePath;
// Only validate paths from the same directory - need to copy to a list because we are going to potentially modify the collection below
var deletedImages = hasScreenshots.ScreenshotImagePaths
.Where(path => !File.Exists(path))
.ToList();
if (string.IsNullOrWhiteSpace(path))
{
return null;
}
// Now remove them from the dictionary
foreach (var path in deletedImages)
{
hasScreenshots.ScreenshotImagePaths.Remove(path);
changed = true;
return new ItemImageInfo
{
Path = path,
DateModified = FileSystem.GetLastWriteTimeUtc(path),
Type = imageType
};
}
return changed;
return GetImages(imageType)
.ElementAtOrDefault(imageIndex);
}
/// <summary>
/// Gets the image path.
/// </summary>
/// <param name="imageType">Type of the image.</param>
/// <param name="imageIndex">Index of the image.</param>
/// <returns>System.String.</returns>
/// <exception cref="System.InvalidOperationException">
/// </exception>
/// <exception cref="System.ArgumentNullException">item</exception>
public string GetImagePath(ImageType imageType, int imageIndex)
public IEnumerable<ItemImageInfo> GetImages(ImageType imageType)
{
if (imageType == ImageType.Backdrop)
{
return BackdropImagePaths.Count > imageIndex ? BackdropImagePaths[imageIndex] : null;
}
if (imageType == ImageType.Screenshot)
{
var hasScreenshots = (IHasScreenshots)this;
return hasScreenshots.ScreenshotImagePaths.Count > imageIndex ? hasScreenshots.ScreenshotImagePaths[imageIndex] : null;
}
if (imageType == ImageType.Chapter)
{
return ItemRepository.GetChapter(Id, imageIndex).ImagePath;
throw new ArgumentException("No image info for chapter images");
}
string val;
Images.TryGetValue(imageType, out val);
return val;
return ImageInfos.Where(i => i.Type == imageType);
}
/// <summary>
/// Gets the image date modified.
/// Adds the images.
/// </summary>
/// <param name="imagePath">The image path.</param>
/// <returns>DateTime.</returns>
/// <exception cref="System.ArgumentNullException">item</exception>
public DateTime GetImageDateModified(string imagePath)
/// <param name="imageType">Type of the image.</param>
/// <param name="images">The images.</param>
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
/// <exception cref="System.ArgumentException">Cannot call AddImages with chapter images</exception>
public bool AddImages(ImageType imageType, IEnumerable<FileInfo> images)
{
if (string.IsNullOrEmpty(imagePath))
if (imageType == ImageType.Chapter)
{
throw new ArgumentNullException("imagePath");
throw new ArgumentException("Cannot call AddImages with chapter images");
}
// See if we can avoid a file system lookup by looking for the file in ResolveArgs
return FileSystem.GetLastWriteTimeUtc(imagePath);
var existingImagePaths = GetImages(imageType)
.Select(i => i.Path)
.ToList();
var newImages = images
.Where(i => !existingImagePaths.Contains(i.FullName, StringComparer.OrdinalIgnoreCase))
.ToList();
ImageInfos.AddRange(newImages.Select(i => new ItemImageInfo
{
Path = i.FullName,
Type = imageType,
DateModified = FileSystem.GetLastWriteTimeUtc(i)
}));
return newImages.Count > 0;
}
/// <summary>
@ -1421,25 +1338,39 @@ namespace MediaBrowser.Controller.Entities
return new[] { Path };
}
public bool AllowsMultipleImages(ImageType type)
{
return type == ImageType.Backdrop || type == ImageType.Screenshot || type == ImageType.Chapter;
}
public Task SwapImages(ImageType type, int index1, int index2)
{
if (type != ImageType.Screenshot && type != ImageType.Backdrop)
if (!AllowsMultipleImages(type))
{
throw new ArgumentException("The change index operation is only applicable to backdrops and screenshots");
}
var file1 = GetImagePath(type, index1);
var file2 = GetImagePath(type, index2);
var info1 = GetImageInfo(type, index1);
var info2 = GetImageInfo(type, index2);
FileSystem.SwapFiles(file1, file2);
// Directory watchers should repeat this, but do a quick refresh first
return RefreshMetadata(new MetadataRefreshOptions
if (info1 == null || info2 == null)
{
ForceSave = true,
MetadataRefreshMode = MetadataRefreshMode.None
// Nothing to do
return Task.FromResult(true);
}
var path1 = info1.Path;
var path2 = info2.Path;
FileSystem.SwapFiles(path1, path2);
info1.Path = path2;
info2.Path = path1;
info1.DateModified = FileSystem.GetLastWriteTimeUtc(info1.Path);
info2.DateModified = FileSystem.GetLastWriteTimeUtc(info2.Path);
}, CancellationToken.None);
return LibraryManager.UpdateItem(this, ItemUpdateType.ImageUpdate, CancellationToken.None);
}
public virtual bool IsPlayed(User user)

@ -30,17 +30,10 @@ namespace MediaBrowser.Controller.Entities
ThemeSongIds = new List<Guid>();
ThemeVideoIds = new List<Guid>();
Tags = new List<string>();
ScreenshotImagePaths = new List<string>();
}
public List<Guid> LocalTrailerIds { get; set; }
/// <summary>
/// Gets or sets the screenshot image paths.
/// </summary>
/// <value>The screenshot image paths.</value>
public List<string> ScreenshotImagePaths { get; set; }
/// <summary>
/// Gets or sets the tags.
/// </summary>

@ -1,4 +1,5 @@
using MediaBrowser.Model.Entities;
using System.IO;
using MediaBrowser.Model.Entities;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
@ -31,6 +32,13 @@ namespace MediaBrowser.Controller.Entities
/// <value>The type of the location.</value>
LocationType LocationType { get; }
/// <summary>
/// Gets the images.
/// </summary>
/// <param name="imageType">Type of the image.</param>
/// <returns>IEnumerable{ItemImageInfo}.</returns>
IEnumerable<ItemImageInfo> GetImages(ImageType imageType);
/// <summary>
/// Gets the image path.
/// </summary>
@ -40,19 +48,20 @@ namespace MediaBrowser.Controller.Entities
string GetImagePath(ImageType imageType, int imageIndex);
/// <summary>
/// Gets the image date modified.
/// Gets the image information.
/// </summary>
/// <param name="imagePath">The image path.</param>
/// <returns>DateTime.</returns>
DateTime GetImageDateModified(string imagePath);
/// <param name="imageType">Type of the image.</param>
/// <param name="imageIndex">Index of the image.</param>
/// <returns>ItemImageInfo.</returns>
ItemImageInfo GetImageInfo(ImageType imageType, int imageIndex);
/// <summary>
/// Sets the image.
/// </summary>
/// <param name="type">The type.</param>
/// <param name="index">The index.</param>
/// <param name="path">The path.</param>
void SetImagePath(ImageType type, int index, string path);
/// <param name="file">The file.</param>
void SetImagePath(ImageType type, int index, FileInfo file);
/// <summary>
/// Determines whether the specified type has image.
@ -62,6 +71,13 @@ namespace MediaBrowser.Controller.Entities
/// <returns><c>true</c> if the specified type has image; otherwise, <c>false</c>.</returns>
bool HasImage(ImageType type, int imageIndex);
/// <summary>
/// Allowses the multiple images.
/// </summary>
/// <param name="type">The type.</param>
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
bool AllowsMultipleImages(ImageType type);
/// <summary>
/// Swaps the images.
/// </summary>
@ -94,12 +110,6 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
bool ValidateImages();
/// <summary>
/// Gets or sets the backdrop image paths.
/// </summary>
/// <value>The backdrop image paths.</value>
List<string> BackdropImagePaths { get; set; }
/// <summary>
/// Gets a value indicating whether this instance is owned item.
/// </summary>
@ -111,6 +121,14 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
/// <value>The containing folder path.</value>
string ContainingFolderPath { get; }
/// <summary>
/// Adds the images.
/// </summary>
/// <param name="imageType">Type of the image.</param>
/// <param name="images">The images.</param>
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
bool AddImages(ImageType imageType, IEnumerable<FileInfo> images);
}
public static class HasImagesExtensions
@ -136,10 +154,10 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
/// <param name="item">The item.</param>
/// <param name="imageType">Type of the image.</param>
/// <param name="path">The path.</param>
public static void SetImagePath(this IHasImages item, ImageType imageType, string path)
/// <param name="file">The file.</param>
public static void SetImagePath(this IHasImages item, ImageType imageType, FileInfo file)
{
item.SetImagePath(imageType, 0, path);
item.SetImagePath(imageType, 0, file);
}
}
}

@ -1,5 +1,4 @@
using System.Collections.Generic;

namespace MediaBrowser.Controller.Entities
{
/// <summary>
@ -7,10 +6,5 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
public interface IHasScreenshots
{
/// <summary>
/// Gets or sets the screenshot image paths.
/// </summary>
/// <value>The screenshot image paths.</value>
List<string> ScreenshotImagePaths { get; set; }
}
}

@ -0,0 +1,14 @@
using MediaBrowser.Model.Entities;
using System;
namespace MediaBrowser.Controller.Entities
{
public class ItemImageInfo
{
public string Path { get; set; }
public ImageType Type { get; set; }
public DateTime DateModified { get; set; }
}
}

@ -104,6 +104,7 @@
<Compile Include="Entities\ILibraryItem.cs" />
<Compile Include="Entities\ImageSourceInfo.cs" />
<Compile Include="Entities\IMetadataContainer.cs" />
<Compile Include="Entities\ItemImageInfo.cs" />
<Compile Include="Entities\LinkedChild.cs" />
<Compile Include="Entities\MusicVideo.cs" />
<Compile Include="Entities\IHasAwards.cs" />

@ -60,7 +60,7 @@ namespace MediaBrowser.Controller.Providers
public void SetFormatFromMimeType(string mimeType)
{
}
}
}

@ -107,14 +107,9 @@ namespace MediaBrowser.Providers.Manager
}
}
if (type == ImageType.Backdrop && imageIndex == null)
if (!imageIndex.HasValue && item.AllowsMultipleImages(type))
{
imageIndex = item.BackdropImagePaths.Count;
}
else if (type == ImageType.Screenshot && imageIndex == null)
{
var hasScreenshots = (IHasScreenshots)item;
imageIndex = hasScreenshots.ScreenshotImagePaths.Count;
imageIndex = item.GetImages(type).Count();
}
var index = imageIndex ?? 0;
@ -275,43 +270,7 @@ namespace MediaBrowser.Providers.Manager
/// imageIndex</exception>
private void SetImagePath(BaseItem item, ImageType type, int? imageIndex, string path)
{
switch (type)
{
case ImageType.Screenshot:
if (!imageIndex.HasValue)
{
throw new ArgumentNullException("imageIndex");
}
var hasScreenshots = (IHasScreenshots)item;
if (hasScreenshots.ScreenshotImagePaths.Count > imageIndex.Value)
{
hasScreenshots.ScreenshotImagePaths[imageIndex.Value] = path;
}
else if (!hasScreenshots.ScreenshotImagePaths.Contains(path, StringComparer.OrdinalIgnoreCase))
{
hasScreenshots.ScreenshotImagePaths.Add(path);
}
break;
case ImageType.Backdrop:
if (!imageIndex.HasValue)
{
throw new ArgumentNullException("imageIndex");
}
if (item.BackdropImagePaths.Count > imageIndex.Value)
{
item.BackdropImagePaths[imageIndex.Value] = path;
}
else if (!item.BackdropImagePaths.Contains(path, StringComparer.OrdinalIgnoreCase))
{
item.BackdropImagePaths.Add(path);
}
break;
default:
item.SetImagePath(type, path);
break;
}
item.SetImagePath(type, imageIndex ?? 0, new FileInfo(path));
}
/// <summary>
@ -347,19 +306,10 @@ namespace MediaBrowser.Providers.Manager
filename = item is Episode ? Path.GetFileNameWithoutExtension(item.Path) : "folder";
break;
case ImageType.Backdrop:
if (!imageIndex.HasValue)
{
throw new ArgumentNullException("imageIndex");
}
filename = GetBackdropSaveFilename(item.BackdropImagePaths, "backdrop", "backdrop", imageIndex.Value);
filename = GetBackdropSaveFilename(item.GetImages(type), "backdrop", "backdrop", imageIndex);
break;
case ImageType.Screenshot:
if (!imageIndex.HasValue)
{
throw new ArgumentNullException("imageIndex");
}
var hasScreenshots = (IHasScreenshots)item;
filename = GetBackdropSaveFilename(hasScreenshots.ScreenshotImagePaths, "screenshot", "screenshot", imageIndex.Value);
filename = GetBackdropSaveFilename(item.GetImages(type), "screenshot", "screenshot", imageIndex);
break;
default:
filename = type.ToString().ToLower();
@ -404,16 +354,16 @@ namespace MediaBrowser.Providers.Manager
return path;
}
private string GetBackdropSaveFilename(IEnumerable<string> images, string zeroIndexFilename, string numberedIndexPrefix, int index)
private string GetBackdropSaveFilename(IEnumerable<ItemImageInfo> images, string zeroIndexFilename, string numberedIndexPrefix, int? index)
{
if (index == 0)
if (index.HasValue && index.Value == 0)
{
return zeroIndexFilename;
}
var filenames = images.Select(Path.GetFileNameWithoutExtension).ToList();
var filenames = images.Select(i => Path.GetFileNameWithoutExtension(i.Path)).ToList();
var current = index;
var current = 1;
while (filenames.Contains(numberedIndexPrefix + current.ToString(UsCulture), StringComparer.OrdinalIgnoreCase))
{
current++;
@ -484,7 +434,7 @@ namespace MediaBrowser.Providers.Manager
return new[] { GetSavePathForItemInMixedFolder(item, type, "fanart" + outputIndex.ToString(UsCulture), extension) };
}
var extraFanartFilename = GetBackdropSaveFilename(item.BackdropImagePaths, "fanart", "fanart", outputIndex);
var extraFanartFilename = GetBackdropSaveFilename(item.GetImages(ImageType.Backdrop), "fanart", "fanart", outputIndex);
return new[]
{

@ -178,23 +178,16 @@ namespace MediaBrowser.Providers.Manager
return false;
}
if (images.Contains(ImageType.Backdrop) && item.BackdropImagePaths.Count < backdropLimit)
if (images.Contains(ImageType.Backdrop) && item.GetImages(ImageType.Backdrop).Count() < backdropLimit)
{
return false;
}
if (images.Contains(ImageType.Screenshot))
if (images.Contains(ImageType.Screenshot) && item.GetImages(ImageType.Screenshot).Count() < backdropLimit)
{
var hasScreenshots = item as IHasScreenshots;
if (hasScreenshots != null)
{
if (hasScreenshots.ScreenshotImagePaths.Count < screenshotLimit)
{
return false;
}
}
}
return false;
}
return true;
}
@ -220,7 +213,7 @@ namespace MediaBrowser.Providers.Manager
}
_logger.Debug("Running {0} for {1}", provider.GetType().Name, item.Path ?? item.Name);
var images = await provider.GetAllImages(item, cancellationToken).ConfigureAwait(false);
var list = images.ToList();
@ -232,12 +225,12 @@ namespace MediaBrowser.Providers.Manager
}
}
await DownloadBackdrops(item, backdropLimit, provider, result, list, cancellationToken).ConfigureAwait(false);
await DownloadBackdrops(item, ImageType.Backdrop, backdropLimit, provider, result, list, cancellationToken).ConfigureAwait(false);
var hasScreenshots = item as IHasScreenshots;
if (hasScreenshots != null)
{
await DownloadScreenshots(hasScreenshots, screenshotLimit, provider, result, list, cancellationToken).ConfigureAwait(false);
await DownloadBackdrops(item, ImageType.Screenshot, screenshotLimit, provider, result, list, cancellationToken).ConfigureAwait(false);
}
}
catch (OperationCanceledException)
@ -280,50 +273,42 @@ namespace MediaBrowser.Providers.Manager
if (image != null)
{
var oldPath = item.GetImagePath(type);
var currentImage = item.GetImageInfo(type, 0);
item.SetImagePath(type, image.Path);
if (!string.Equals(oldPath, image.Path, StringComparison.OrdinalIgnoreCase))
if (currentImage == null || !string.Equals(currentImage.Path, image.Path, StringComparison.OrdinalIgnoreCase))
{
item.SetImagePath(type, new FileInfo(image.Path));
changed = true;
}
}
}
// The change reporting will only be accurate at the count level
// Improve this if/when needed
var backdrops = images.Where(i => i.Type == ImageType.Backdrop).ToList();
if (backdrops.Count > 0)
{
var oldCount = item.BackdropImagePaths.Count;
item.BackdropImagePaths = item.BackdropImagePaths
.Concat(backdrops.Select(i => i.Path))
.Distinct(StringComparer.OrdinalIgnoreCase)
var foundImages = images.Where(i => i.Type == ImageType.Backdrop)
.Select(i => new FileInfo(i.Path))
.ToList();
if (oldCount != item.BackdropImagePaths.Count)
if (foundImages.Count > 0)
{
changed = true;
if (item.AddImages(ImageType.Backdrop, foundImages))
{
changed = true;
}
}
}
var hasScreenshots = item as IHasScreenshots;
if (hasScreenshots != null)
{
var screenshots = images.Where(i => i.Type == ImageType.Screenshot).ToList();
var foundImages = images.Where(i => i.Type == ImageType.Screenshot)
.Select(i => new FileInfo(i.Path))
.ToList();
if (screenshots.Count > 0)
if (foundImages.Count > 0)
{
var oldCount = hasScreenshots.ScreenshotImagePaths.Count;
hasScreenshots.ScreenshotImagePaths = hasScreenshots.ScreenshotImagePaths
.Concat(screenshots.Select(i => i.Path))
.Distinct(StringComparer.OrdinalIgnoreCase)
.ToList();
if (oldCount != hasScreenshots.ScreenshotImagePaths.Count)
if (item.AddImages(ImageType.Screenshot, foundImages))
{
changed = true;
}
@ -360,46 +345,11 @@ namespace MediaBrowser.Providers.Manager
}
}
private async Task DownloadBackdrops(IHasImages item, int limit, IRemoteImageProvider provider, RefreshResult result, IEnumerable<RemoteImageInfo> images, CancellationToken cancellationToken)
private async Task DownloadBackdrops(IHasImages item, ImageType imageType, int limit, IRemoteImageProvider provider, RefreshResult result, IEnumerable<RemoteImageInfo> images, CancellationToken cancellationToken)
{
const ImageType imageType = ImageType.Backdrop;
foreach (var image in images.Where(i => i.Type == imageType))
{
if (item.BackdropImagePaths.Count >= limit)
{
break;
}
var url = image.Url;
try
{
var response = await provider.GetImageResponse(url, cancellationToken).ConfigureAwait(false);
await _providerManager.SaveImage((BaseItem)item, response.Content, response.ContentType, imageType, null, cancellationToken).ConfigureAwait(false);
result.UpdateType = result.UpdateType | ItemUpdateType.ImageUpdate;
break;
}
catch (HttpException ex)
{
// Sometimes providers send back bad url's. Just move onto the next image
if (ex.StatusCode.HasValue && ex.StatusCode.Value == HttpStatusCode.NotFound)
{
continue;
}
break;
}
}
}
private async Task DownloadScreenshots(IHasScreenshots item, int limit, IRemoteImageProvider provider, RefreshResult result, IEnumerable<RemoteImageInfo> images, CancellationToken cancellationToken)
{
const ImageType imageType = ImageType.Screenshot;
foreach (var image in images.Where(i => i.Type == imageType))
{
if (item.ScreenshotImagePaths.Count >= limit)
if (item.GetImages(imageType).Count() >= limit)
{
break;
}

@ -389,35 +389,33 @@ namespace MediaBrowser.Providers.Manager
public IEnumerable<MetadataPluginSummary> GetAllMetadataPlugins()
{
var list = new List<MetadataPluginSummary>();
list.Add(GetPluginSummary<Game>());
list.Add(GetPluginSummary<GameSystem>());
list.Add(GetPluginSummary<Movie>());
list.Add(GetPluginSummary<Trailer>());
list.Add(GetPluginSummary<BoxSet>());
list.Add(GetPluginSummary<Book>());
list.Add(GetPluginSummary<Series>());
list.Add(GetPluginSummary<Season>());
list.Add(GetPluginSummary<Episode>());
list.Add(GetPluginSummary<Person>());
list.Add(GetPluginSummary<MusicAlbum>());
list.Add(GetPluginSummary<MusicArtist>());
list.Add(GetPluginSummary<Audio>());
list.Add(GetPluginSummary<Genre>());
list.Add(GetPluginSummary<Studio>());
list.Add(GetPluginSummary<GameGenre>());
list.Add(GetPluginSummary<MusicGenre>());
list.Add(GetPluginSummary<AdultVideo>());
list.Add(GetPluginSummary<MusicVideo>());
list.Add(GetPluginSummary<Video>());
list.Add(GetPluginSummary<LiveTvChannel>());
list.Add(GetPluginSummary<LiveTvProgram>());
list.Add(GetPluginSummary<LiveTvVideoRecording>());
list.Add(GetPluginSummary<LiveTvAudioRecording>());
var list = new List<MetadataPluginSummary>
{
GetPluginSummary<Game>(),
GetPluginSummary<GameSystem>(),
GetPluginSummary<Movie>(),
GetPluginSummary<Trailer>(),
GetPluginSummary<BoxSet>(),
GetPluginSummary<Book>(),
GetPluginSummary<Series>(),
GetPluginSummary<Season>(),
GetPluginSummary<Episode>(),
GetPluginSummary<Person>(),
GetPluginSummary<MusicAlbum>(),
GetPluginSummary<MusicArtist>(),
GetPluginSummary<Audio>(),
GetPluginSummary<Genre>(),
GetPluginSummary<Studio>(),
GetPluginSummary<GameGenre>(),
GetPluginSummary<MusicGenre>(),
GetPluginSummary<AdultVideo>(),
GetPluginSummary<MusicVideo>(),
GetPluginSummary<Video>(),
GetPluginSummary<LiveTvChannel>(),
GetPluginSummary<LiveTvProgram>(),
GetPluginSummary<LiveTvVideoRecording>(),
GetPluginSummary<LiveTvAudioRecording>()
};
return list;
}

@ -66,17 +66,17 @@ namespace MediaBrowser.Providers.TV
if (!string.IsNullOrWhiteSpace(filename))
{
// Strip off everything but the filename. Some metadata tools like MetaBrowser v1.0 will have an 'episodes' prefix
// even though it's actually using the metadata folder.
filename = Path.GetFileName(filename);
//// Strip off everything but the filename. Some metadata tools like MetaBrowser v1.0 will have an 'episodes' prefix
//// even though it's actually using the metadata folder.
//filename = Path.GetFileName(filename);
var seasonFolder = Path.GetDirectoryName(item.Path);
filename = Path.Combine(seasonFolder, "metadata", filename);
//var seasonFolder = Path.GetDirectoryName(item.Path);
//filename = Path.Combine(seasonFolder, "metadata", filename);
if (File.Exists(filename))
{
item.SetImagePath(ImageType.Primary, 0, filename);
}
//if (File.Exists(filename))
//{
// item.SetImagePath(ImageType.Primary, 0, filename);
//}
}
break;
}

@ -619,27 +619,24 @@ namespace MediaBrowser.Server.Implementations.Drawing
/// Gets the image cache tag.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="imageType">Type of the image.</param>
/// <param name="imagePath">The image path.</param>
/// <param name="image">The image.</param>
/// <returns>Guid.</returns>
/// <exception cref="System.ArgumentNullException">item</exception>
public Guid GetImageCacheTag(IHasImages item, ImageType imageType, string imagePath)
public Guid GetImageCacheTag(IHasImages item, ItemImageInfo image)
{
if (item == null)
{
throw new ArgumentNullException("item");
}
if (string.IsNullOrEmpty(imagePath))
if (image == null)
{
throw new ArgumentNullException("imagePath");
throw new ArgumentNullException("image");
}
var dateModified = item.GetImageDateModified(imagePath);
var supportedEnhancers = GetSupportedEnhancers(item, imageType);
var supportedEnhancers = GetSupportedEnhancers(item, image.Type);
return GetImageCacheTag(item, imageType, imagePath, dateModified, supportedEnhancers.ToList());
return GetImageCacheTag(item, image.Type, image.Path, image.DateModified, supportedEnhancers.ToList());
}
/// <summary>
@ -693,9 +690,10 @@ namespace MediaBrowser.Server.Implementations.Drawing
{
var enhancers = GetSupportedEnhancers(item, imageType).ToList();
var imagePath = item.GetImagePath(imageType, imageIndex);
var imageInfo = item.GetImageInfo(imageType, imageIndex);
var imagePath = imageInfo.Path;
var dateModified = item.GetImageDateModified(imagePath);
var dateModified = imageInfo.DateModified;
var result = await GetEnhancedImage(imagePath, dateModified, item, imageType, imageIndex, enhancers);

@ -1,4 +1,5 @@
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Dto;
@ -34,8 +35,9 @@ namespace MediaBrowser.Server.Implementations.Dto
private readonly IImageProcessor _imageProcessor;
private readonly IServerConfigurationManager _config;
private readonly IFileSystem _fileSystem;
public DtoService(ILogger logger, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataRepository, IItemRepository itemRepo, IImageProcessor imageProcessor, IServerConfigurationManager config)
public DtoService(ILogger logger, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataRepository, IItemRepository itemRepo, IImageProcessor imageProcessor, IServerConfigurationManager config, IFileSystem fileSystem)
{
_logger = logger;
_libraryManager = libraryManager;
@ -44,6 +46,7 @@ namespace MediaBrowser.Server.Implementations.Dto
_itemRepo = itemRepo;
_imageProcessor = imageProcessor;
_config = config;
_fileSystem = fileSystem;
}
/// <summary>
@ -207,11 +210,11 @@ namespace MediaBrowser.Server.Implementations.Dto
Configuration = user.Configuration
};
var image = user.PrimaryImagePath;
var image = user.GetImageInfo(ImageType.Primary, 0);
if (!string.IsNullOrEmpty(image))
if (image != null)
{
dto.PrimaryImageTag = GetImageCacheTag(user, ImageType.Primary, image);
dto.PrimaryImageTag = GetImageCacheTag(user, image);
try
{
@ -288,12 +291,7 @@ namespace MediaBrowser.Server.Implementations.Dto
RunTimeTicks = item.RunTimeTicks
};
var imagePath = item.PrimaryImagePath;
if (!string.IsNullOrEmpty(imagePath))
{
info.PrimaryImageTag = GetImageCacheTag(item, ImageType.Primary, imagePath);
}
info.PrimaryImageTag = GetImageCacheTag(item, ImageType.Primary);
return info;
}
@ -380,11 +378,7 @@ namespace MediaBrowser.Server.Implementations.Dto
/// <returns>List{System.String}.</returns>
private List<Guid> GetBackdropImageTags(BaseItem item)
{
return item.BackdropImagePaths
.Select(p => GetImageCacheTag(item, ImageType.Backdrop, p))
.Where(i => i.HasValue)
.Select(i => i.Value)
.ToList();
return GetCacheTags(item, ImageType.Backdrop).ToList();
}
/// <summary>
@ -399,23 +393,40 @@ namespace MediaBrowser.Server.Implementations.Dto
{
return new List<Guid>();
}
return GetCacheTags(item, ImageType.Screenshot).ToList();
}
return hasScreenshots.ScreenshotImagePaths
.Select(p => GetImageCacheTag(item, ImageType.Screenshot, p))
private IEnumerable<Guid> GetCacheTags(BaseItem item, ImageType type)
{
return item.GetImages(type)
.Select(p => GetImageCacheTag(item, p))
.Where(i => i.HasValue)
.Select(i => i.Value)
.ToList();
}
private Guid? GetImageCacheTag(BaseItem item, ImageType type, string path)
private Guid? GetImageCacheTag(BaseItem item, ImageType type)
{
try
{
return _imageProcessor.GetImageCacheTag(item, type);
}
catch (IOException ex)
{
_logger.ErrorException("Error getting {0} image info", ex, type);
return null;
}
}
private Guid? GetImageCacheTag(BaseItem item, ItemImageInfo image)
{
try
{
return _imageProcessor.GetImageCacheTag(item, type, path);
return _imageProcessor.GetImageCacheTag(item, image);
}
catch (IOException ex)
{
_logger.ErrorException("Error getting {0} image info for {1}", ex, type, path);
_logger.ErrorException("Error getting {0} image info for {1}", ex, image.Type, image.Path);
return null;
}
}
@ -468,12 +479,7 @@ namespace MediaBrowser.Server.Implementations.Dto
if (dictionary.TryGetValue(person.Name, out entity))
{
var primaryImagePath = entity.PrimaryImagePath;
if (!string.IsNullOrEmpty(primaryImagePath))
{
baseItemPerson.PrimaryImageTag = GetImageCacheTag(entity, ImageType.Primary, primaryImagePath);
}
baseItemPerson.PrimaryImageTag = GetImageCacheTag(entity, ImageType.Primary);
}
dto.People[i] = baseItemPerson;
@ -520,12 +526,7 @@ namespace MediaBrowser.Server.Implementations.Dto
if (dictionary.TryGetValue(studio, out entity))
{
var primaryImagePath = entity.PrimaryImagePath;
if (!string.IsNullOrEmpty(primaryImagePath))
{
studioDto.PrimaryImageTag = GetImageCacheTag(entity, ImageType.Primary, primaryImagePath);
}
studioDto.PrimaryImageTag = GetImageCacheTag(entity, ImageType.Primary);
}
dto.Studios[i] = studioDto;
@ -544,7 +545,7 @@ namespace MediaBrowser.Server.Implementations.Dto
while (parent != null)
{
if (parent.BackdropImagePaths != null && parent.BackdropImagePaths.Count > 0)
if (parent.GetImages(ImageType.Backdrop).Any())
{
return parent;
}
@ -595,7 +596,12 @@ namespace MediaBrowser.Server.Implementations.Dto
if (!string.IsNullOrEmpty(chapterInfo.ImagePath))
{
dto.ImageTag = GetImageCacheTag(item, ImageType.Chapter, chapterInfo.ImagePath);
dto.ImageTag = GetImageCacheTag(item, new ItemImageInfo
{
Path = chapterInfo.ImagePath,
Type = ImageType.Chapter,
DateModified = _fileSystem.GetLastWriteTimeUtc(chapterInfo.ImagePath)
});
}
return dto;
@ -698,7 +704,7 @@ namespace MediaBrowser.Server.Implementations.Dto
if (fields.Contains(ItemFields.Keywords))
{
var hasTags = item as IHasKeywords;
var hasTags = item as IHasKeywords;
if (hasTags != null)
{
dto.Keywords = hasTags.Keywords;
@ -750,15 +756,15 @@ namespace MediaBrowser.Server.Implementations.Dto
dto.ImageTags = new Dictionary<ImageType, Guid>();
foreach (var image in item.Images)
// Prevent implicitly captured closure
var currentItem = item;
foreach (var image in currentItem.ImageInfos.Where(i => !currentItem.AllowsMultipleImages(i.Type)))
{
var type = image.Key;
var tag = GetImageCacheTag(item, type, image.Value);
var tag = GetImageCacheTag(item, image);
if (tag.HasValue)
{
dto.ImageTags[type] = tag.Value;
dto.ImageTags[image.Type] = tag.Value;
}
}
@ -804,7 +810,7 @@ namespace MediaBrowser.Server.Implementations.Dto
{
dto.CollectionType = collectionFolder.CollectionType;
}
if (fields.Contains(ItemFields.RemoteTrailers))
{
dto.RemoteTrailers = hasTrailers != null ?
@ -862,7 +868,7 @@ namespace MediaBrowser.Server.Implementations.Dto
{
dto.ParentLogoItemId = GetDtoId(parentWithLogo);
dto.ParentLogoImageTag = GetImageCacheTag(parentWithLogo, ImageType.Logo, parentWithLogo.GetImagePath(ImageType.Logo));
dto.ParentLogoImageTag = GetImageCacheTag(parentWithLogo, ImageType.Logo);
}
}
@ -875,7 +881,7 @@ namespace MediaBrowser.Server.Implementations.Dto
{
dto.ParentArtItemId = GetDtoId(parentWithImage);
dto.ParentArtImageTag = GetImageCacheTag(parentWithImage, ImageType.Art, parentWithImage.GetImagePath(ImageType.Art));
dto.ParentArtImageTag = GetImageCacheTag(parentWithImage, ImageType.Art);
}
}
@ -888,7 +894,7 @@ namespace MediaBrowser.Server.Implementations.Dto
{
dto.ParentThumbItemId = GetDtoId(parentWithImage);
dto.ParentThumbImageTag = GetImageCacheTag(parentWithImage, ImageType.Thumb, parentWithImage.GetImagePath(ImageType.Thumb));
dto.ParentThumbImageTag = GetImageCacheTag(parentWithImage, ImageType.Thumb);
}
}
@ -959,12 +965,7 @@ namespace MediaBrowser.Server.Implementations.Dto
{
dto.AlbumId = GetDtoId(albumParent);
var imagePath = albumParent.PrimaryImagePath;
if (!string.IsNullOrEmpty(imagePath))
{
dto.AlbumPrimaryImageTag = GetImageCacheTag(albumParent, ImageType.Primary, imagePath);
}
dto.AlbumPrimaryImageTag = GetImageCacheTag(albumParent, ImageType.Primary);
}
}
@ -1085,17 +1086,9 @@ namespace MediaBrowser.Server.Implementations.Dto
dto.AirTime = series.AirTime;
dto.SeriesStudio = series.Studios.FirstOrDefault();
if (series.HasImage(ImageType.Thumb))
{
dto.SeriesThumbImageTag = GetImageCacheTag(series, ImageType.Thumb, series.GetImagePath(ImageType.Thumb));
}
var imagePath = series.PrimaryImagePath;
dto.SeriesThumbImageTag = GetImageCacheTag(series, ImageType.Thumb);
if (!string.IsNullOrEmpty(imagePath))
{
dto.SeriesPrimaryImageTag = GetImageCacheTag(series, ImageType.Primary, imagePath);
}
dto.SeriesPrimaryImageTag = GetImageCacheTag(series, ImageType.Primary);
}
// Add SeasonInfo
@ -1110,12 +1103,7 @@ namespace MediaBrowser.Server.Implementations.Dto
dto.AirTime = series.AirTime;
dto.SeriesStudio = series.Studios.FirstOrDefault();
var imagePath = series.PrimaryImagePath;
if (!string.IsNullOrEmpty(imagePath))
{
dto.SeriesPrimaryImageTag = GetImageCacheTag(series, ImageType.Primary, imagePath);
}
dto.SeriesPrimaryImageTag = GetImageCacheTag(series, ImageType.Primary);
}
var game = item as Game;
@ -1303,15 +1291,17 @@ namespace MediaBrowser.Server.Implementations.Dto
/// <returns>Task.</returns>
public void AttachPrimaryImageAspectRatio(IItemDto dto, IHasImages item)
{
var path = item.PrimaryImagePath;
var imageInfo = item.GetImageInfo(ImageType.Primary, 0);
if (string.IsNullOrEmpty(path))
if (imageInfo == null)
{
return;
}
var path = imageInfo.Path;
// See if we can avoid a file system lookup by looking for the file in ResolveArgs
var dateModified = item.GetImageDateModified(path);
var dateModified = imageInfo.DateModified;
ImageSize size;

@ -401,16 +401,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv
private Guid? GetImageTag(IHasImages info)
{
var path = info.PrimaryImagePath;
if (string.IsNullOrEmpty(path))
{
return null;
}
try
{
return _imageProcessor.GetImageCacheTag(info, ImageType.Primary, path);
return _imageProcessor.GetImageCacheTag(info, ImageType.Primary);
}
catch (Exception ex)
{

@ -309,7 +309,7 @@ namespace MediaBrowser.ServerApplication
ImageProcessor = new ImageProcessor(Logger, ServerConfigurationManager.ApplicationPaths, FileSystemManager, JsonSerializer);
RegisterSingleInstance(ImageProcessor);
DtoService = new DtoService(Logger, LibraryManager, UserManager, UserDataManager, ItemRepository, ImageProcessor, ServerConfigurationManager);
DtoService = new DtoService(Logger, LibraryManager, UserManager, UserDataManager, ItemRepository, ImageProcessor, ServerConfigurationManager, FileSystemManager);
RegisterSingleInstance(DtoService);
var newsService = new Server.Implementations.News.NewsService(ApplicationPaths, JsonSerializer);

@ -258,8 +258,8 @@ namespace MediaBrowser.ServerApplication
previews.Add(new PreviewItem(item.GetImagePath(ImageType.Thumb), "Thumb"));
}
previews.AddRange(
item.BackdropImagePaths.Select(
image => new PreviewItem(image, "Backdrop")));
item.GetImages(ImageType.Backdrop).Select(
image => new PreviewItem(image.Path, "Backdrop")));
});
lstPreviews.ItemsSource = previews;
lstPreviews.Items.Refresh();

Loading…
Cancel
Save