aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Controller/Entities/BaseItem.cs
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Controller/Entities/BaseItem.cs')
-rw-r--r--MediaBrowser.Controller/Entities/BaseItem.cs315
1 files changed, 123 insertions, 192 deletions
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index 1962921e7..35691a080 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -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,16 +165,9 @@ 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>
/// <value>The date created.</value>
@@ -350,12 +348,6 @@ namespace MediaBrowser.Controller.Entities
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>
/// <value>The official rating.</value>
@@ -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)