using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Model.Entities; using System; using System.ComponentModel.Composition; using System.IO; using System.Threading; using System.Threading.Tasks; namespace MediaBrowser.Controller.Providers.TV { /// /// Class EpisodeImageFromMediaLocationProvider /// [Export(typeof(BaseMetadataProvider))] public class EpisodeImageFromMediaLocationProvider : BaseMetadataProvider { /// /// Supportses the specified item. /// /// The item. /// true if XXXX, false otherwise public override bool Supports(BaseItem item) { return item is Episode && item.LocationType == LocationType.FileSystem; } /// /// Gets the priority. /// /// The priority. public override MetadataProviderPriority Priority { get { return MetadataProviderPriority.First; } } /// /// Returns true or false indicating if the provider should refresh when the contents of it's directory changes /// /// true if [refresh on file system stamp change]; otherwise, false. protected override bool RefreshOnFileSystemStampChange { get { return true; } } /// /// Fetches metadata and returns true or false indicating if any work that requires persistence was done /// /// The item. /// if set to true [force]. /// The cancellation token. /// Task{System.Boolean}. protected override Task FetchAsyncInternal(BaseItem item, bool force, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var episode = (Episode)item; var episodeFileName = Path.GetFileName(episode.Path); var parent = item.ResolveArgs.Parent; ValidateImage(episode, item.MetaLocation); cancellationToken.ThrowIfCancellationRequested(); SetPrimaryImagePath(episode, parent, item.MetaLocation, episodeFileName); SetLastRefreshed(item, DateTime.UtcNow); return TrueTaskResult; } /// /// Validates the primary image path still exists /// /// The episode. /// The metadata folder path. /// true if XXXX, false otherwise private void ValidateImage(Episode episode, string metadataFolderPath) { var path = episode.PrimaryImagePath; if (string.IsNullOrEmpty(path)) { return; } // Only validate images in the season/metadata folder if (!string.Equals(Path.GetDirectoryName(path), metadataFolderPath, StringComparison.OrdinalIgnoreCase)) { return; } if (!episode.Parent.ResolveArgs.GetMetaFileByPath(path).HasValue) { episode.PrimaryImagePath = null; } } /// /// Sets the primary image path. /// /// The item. /// The parent. /// The metadata folder. /// Name of the episode file. private void SetPrimaryImagePath(Episode item, Folder parent, string metadataFolder, string episodeFileName) { // Look for the image file in the metadata folder, and if found, set PrimaryImagePath var imageFiles = new[] { Path.Combine(metadataFolder, Path.ChangeExtension(episodeFileName, ".jpg")), Path.Combine(metadataFolder, Path.ChangeExtension(episodeFileName, ".png")) }; var file = parent.ResolveArgs.GetMetaFileByPath(imageFiles[0]) ?? parent.ResolveArgs.GetMetaFileByPath(imageFiles[1]); if (file.HasValue) { item.PrimaryImagePath = file.Value.Path; } } } }