diff options
| author | Luke Pulverenti <luke.pulverenti@gmail.com> | 2013-11-07 10:56:35 -0500 |
|---|---|---|
| committer | Luke Pulverenti <luke.pulverenti@gmail.com> | 2013-11-07 10:56:35 -0500 |
| commit | d609d0edec97655932e365309a847b525a5a7d3d (patch) | |
| tree | f2af7609a1b79c2053e448f82c5bf907d0210018 | |
| parent | a2cd03610fd8fedc55699f43bf4a169dc5072aa8 (diff) | |
fixes #616 - Support images in collection folders
5 files changed, 148 insertions, 135 deletions
diff --git a/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs b/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs index de7e8e98d..07bb7d5b2 100644 --- a/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs +++ b/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs @@ -24,6 +24,7 @@ namespace MediaBrowser.Controller.Providers /// </summary> /// <value>The logger.</value> protected ILogger Logger { get; set; } + protected ILogManager LogManager { get; set; } /// <summary> @@ -41,6 +42,7 @@ namespace MediaBrowser.Controller.Providers /// The true task result /// </summary> protected static readonly Task<bool> TrueTaskResult = Task.FromResult(true); + protected static readonly Task<bool> FalseTaskResult = Task.FromResult(false); protected static readonly SemaphoreSlim XmlParsingResourcePool = new SemaphoreSlim(5, 5); @@ -132,7 +134,8 @@ namespace MediaBrowser.Controller.Providers /// <param name="providerVersion">The provider version.</param> /// <param name="status">The status.</param> /// <exception cref="System.ArgumentNullException">item</exception> - public virtual void SetLastRefreshed(BaseItem item, DateTime value, string providerVersion, ProviderRefreshStatus status = ProviderRefreshStatus.Success) + public virtual void SetLastRefreshed(BaseItem item, DateTime value, string providerVersion, + ProviderRefreshStatus status = ProviderRefreshStatus.Success) { if (item == null) { @@ -172,7 +175,8 @@ namespace MediaBrowser.Controller.Providers /// <param name="item">The item.</param> /// <param name="value">The value.</param> /// <param name="status">The status.</param> - public void SetLastRefreshed(BaseItem item, DateTime value, ProviderRefreshStatus status = ProviderRefreshStatus.Success) + public void SetLastRefreshed(BaseItem item, DateTime value, + ProviderRefreshStatus status = ProviderRefreshStatus.Success) { SetLastRefreshed(item, value, ProviderVersion, status); } @@ -238,7 +242,8 @@ namespace MediaBrowser.Controller.Providers return true; } - if (RefreshOnFileSystemStampChange && item.LocationType == LocationType.FileSystem && HasFileSystemStampChanged(item, providerInfo)) + if (RefreshOnFileSystemStampChange && item.LocationType == LocationType.FileSystem && + HasFileSystemStampChanged(item, providerInfo)) { return true; } @@ -349,21 +354,23 @@ namespace MediaBrowser.Controller.Providers } private Dictionary<string, string> _fileStampExtensionsDictionary; + private Dictionary<string, string> FileStampExtensionsDictionary { get { return _fileStampExtensionsDictionary ?? (_fileStampExtensionsDictionary = - FilestampExtensions.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase)); + FilestampExtensions.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase)); } } + /// <summary> /// Gets the file system stamp. /// </summary> /// <param name="item">The item.</param> /// <returns>Guid.</returns> - private Guid GetFileSystemStamp(BaseItem item) + protected virtual Guid GetFileSystemStamp(BaseItem item) { // If there's no path or the item is a file, there's nothing to do if (item.LocationType != LocationType.FileSystem) @@ -404,6 +411,20 @@ namespace MediaBrowser.Controller.Providers private static readonly Dictionary<string, string> FoldersToMonitor = new[] { "extrafanart", "extrathumbs" } .ToDictionary(i => i, StringComparer.OrdinalIgnoreCase); + protected Guid GetFileSystemStamp(IEnumerable<FileSystemInfo> files) + { + var sb = new StringBuilder(); + + var extensions = FileStampExtensionsDictionary; + var numExtensions = FilestampExtensions.Length; + + // Record the name of each file + // Need to sort these because accoring to msdn docs, our i/o methods are not guaranteed in any order + AddFiles(sb, files, extensions, numExtensions); + + return sb.ToString().GetMD5(); + } + /// <summary> /// Adds the files. /// </summary> @@ -424,7 +445,7 @@ namespace MediaBrowser.Controller.Providers { sb.Append(file.Name); - var children = ((DirectoryInfo) file).EnumerateFiles("*", SearchOption.TopDirectoryOnly).ToList(); + var children = ((DirectoryInfo)file).EnumerateFiles("*", SearchOption.TopDirectoryOnly).ToList(); AddFiles(sb, children, extensions, numExtensions); } } diff --git a/MediaBrowser.Providers/CollectionFolderImageProvider.cs b/MediaBrowser.Providers/CollectionFolderImageProvider.cs new file mode 100644 index 000000000..45b1b36c2 --- /dev/null +++ b/MediaBrowser.Providers/CollectionFolderImageProvider.cs @@ -0,0 +1,55 @@ +using MediaBrowser.Common.IO; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Logging; +using System; +using System.IO; +using System.Linq; + +namespace MediaBrowser.Providers +{ + public class CollectionFolderImageProvider : ImageFromMediaLocationProvider + { + public CollectionFolderImageProvider(ILogManager logManager, IServerConfigurationManager configurationManager, IFileSystem fileSystem) + : base(logManager, configurationManager, fileSystem) + { + } + + public override bool Supports(BaseItem item) + { + return item is CollectionFolder && item.LocationType == LocationType.FileSystem; + } + + public override MetadataProviderPriority Priority + { + get { return MetadataProviderPriority.Second; } + } + + protected override FileSystemInfo GetImage(BaseItem item, ItemResolveArgs args, string filenameWithoutExtension) + { + return item.ResolveArgs.PhysicalLocations + .Select(i => GetImageFromLocation(i, filenameWithoutExtension)) + .FirstOrDefault(i => i != null); + } + + protected override Guid GetFileSystemStamp(BaseItem item) + { + var files = item.ResolveArgs.PhysicalLocations + .Select(i => new DirectoryInfo(i)) + .SelectMany(i => i.EnumerateFiles("*", SearchOption.TopDirectoryOnly)) + .Where(i => + { + var ext = i.Extension; + + return !string.IsNullOrEmpty(ext) && + BaseItem.SupportedImageExtensions.Contains(ext, StringComparer.OrdinalIgnoreCase); + }) + .ToList(); + + return GetFileSystemStamp(files); + } + } +} diff --git a/MediaBrowser.Providers/ImageFromMediaLocationProvider.cs b/MediaBrowser.Providers/ImageFromMediaLocationProvider.cs index 9943c7ab8..aa0dcc9d4 100644 --- a/MediaBrowser.Providers/ImageFromMediaLocationProvider.cs +++ b/MediaBrowser.Providers/ImageFromMediaLocationProvider.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Controller.Configuration; +using MediaBrowser.Common.IO; +using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; @@ -21,9 +22,12 @@ namespace MediaBrowser.Providers /// </summary> public class ImageFromMediaLocationProvider : BaseMetadataProvider { - public ImageFromMediaLocationProvider(ILogManager logManager, IServerConfigurationManager configurationManager) + protected readonly IFileSystem FileSystem; + + public ImageFromMediaLocationProvider(ILogManager logManager, IServerConfigurationManager configurationManager, IFileSystem fileSystem) : base(logManager, configurationManager) { + FileSystem = fileSystem; } public override ItemUpdateType ItemUpdateType @@ -543,5 +547,37 @@ namespace MediaBrowser.Providers item.ScreenshotImagePaths = screenshotFiles; } } + + protected FileSystemInfo GetImageFromLocation(string path, string filenameWithoutExtension) + { + try + { + var files = new DirectoryInfo(path) + .EnumerateFiles() + .Where(i => + { + var fileName = Path.GetFileNameWithoutExtension(i.FullName); + + if (!string.Equals(fileName, filenameWithoutExtension, StringComparison.OrdinalIgnoreCase)) + { + return false; + } + + var ext = i.Extension; + + return !string.IsNullOrEmpty(ext) && + BaseItem.SupportedImageExtensions.Contains(ext, StringComparer.OrdinalIgnoreCase); + }) + .ToList(); + + return BaseItem.SupportedImageExtensions + .Select(ext => files.FirstOrDefault(i => string.Equals(ext, i.Extension, StringComparison.OrdinalIgnoreCase))) + .FirstOrDefault(file => file != null); + } + catch (DirectoryNotFoundException) + { + return null; + } + } } } diff --git a/MediaBrowser.Providers/ImagesByNameProvider.cs b/MediaBrowser.Providers/ImagesByNameProvider.cs index 6be4ee108..590430823 100644 --- a/MediaBrowser.Providers/ImagesByNameProvider.cs +++ b/MediaBrowser.Providers/ImagesByNameProvider.cs @@ -1,16 +1,12 @@ -using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.IO; +using MediaBrowser.Common.IO; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.IO; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Logging; using System; using System.IO; using System.Linq; -using System.Threading; -using System.Threading.Tasks; namespace MediaBrowser.Providers { @@ -19,22 +15,11 @@ namespace MediaBrowser.Providers /// </summary> public class ImagesByNameProvider : ImageFromMediaLocationProvider { - private readonly IFileSystem _fileSystem; - public ImagesByNameProvider(ILogManager logManager, IServerConfigurationManager configurationManager, IFileSystem fileSystem) - : base(logManager, configurationManager) + : base(logManager, configurationManager, fileSystem) { - _fileSystem = fileSystem; } - public override ItemUpdateType ItemUpdateType - { - get - { - return ItemUpdateType.ImageUpdate; - } - } - /// <summary> /// Supportses the specified item. /// </summary> @@ -42,8 +27,8 @@ namespace MediaBrowser.Providers /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns> public override bool Supports(BaseItem item) { - //only run for these generic types since we are expensive in file i/o - return item is IndexFolder || item is BasePluginFolder || item is CollectionFolder; + // Only run for these generic types since we are expensive in file i/o + return item is BasePluginFolder || item is CollectionFolder; } /// <summary> @@ -59,102 +44,13 @@ namespace MediaBrowser.Providers } /// <summary> - /// Needses the refresh internal. - /// </summary> - /// <param name="item">The item.</param> - /// <param name="providerInfo">The provider info.</param> - /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns> - protected override bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo) - { - // Force a refresh if the IBN path changed - if (providerInfo.FileStamp != ConfigurationManager.ApplicationPaths.ItemsByNamePath.GetMD5()) - { - return true; - } - - return base.NeedsRefreshInternal(item, providerInfo); - } - - /// <summary> - /// Gets a value indicating whether [refresh on file system stamp change]. - /// </summary> - /// <value><c>true</c> if [refresh on file system stamp change]; otherwise, <c>false</c>.</value> - protected override bool RefreshOnFileSystemStampChange - { - get - { - return false; - } - } - - /// <summary> - /// Override this to return the date that should be compared to the last refresh date - /// to determine if this provider should be re-fetched. - /// </summary> - /// <param name="item">The item.</param> - /// <returns>DateTime.</returns> - protected override DateTime CompareDate(BaseItem item) - { - // If the IBN location exists return the last modified date of any file in it - var location = GetLocation(item); - - var directoryInfo = new DirectoryInfo(location); - - if (!directoryInfo.Exists) - { - return DateTime.MinValue; - } - - var files = directoryInfo.EnumerateFiles().ToList(); - - if (files.Count == 0) - { - return DateTime.MinValue; - } - - return files.Select(f => - { - var lastWriteTime = _fileSystem.GetLastWriteTimeUtc(f); - var creationTime = _fileSystem.GetCreationTimeUtc(f); - - return creationTime > lastWriteTime ? creationTime : lastWriteTime; - - }).Max(); - } - - /// <summary> - /// Fetches metadata and returns true or false indicating if any work that requires persistence was done - /// </summary> - /// <param name="item">The item.</param> - /// <param name="force">if set to <c>true</c> [force].</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task{System.Boolean}.</returns> - public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) - { - var result = await base.FetchAsync(item, force, cancellationToken).ConfigureAwait(false); - - BaseProviderInfo data; - - if (!item.ProviderData.TryGetValue(Id, out data)) - { - data = new BaseProviderInfo(); - item.ProviderData[Id] = data; - } - - data.FileStamp = ConfigurationManager.ApplicationPaths.ItemsByNamePath.GetMD5(); - SetLastRefreshed(item, DateTime.UtcNow); - - return result; - } - - /// <summary> /// Gets the location. /// </summary> /// <param name="item">The item.</param> /// <returns>System.String.</returns> protected string GetLocation(BaseItem item) { - var name = _fileSystem.GetValidFilename(item.Name); + var name = FileSystem.GetValidFilename(item.Name); return Path.Combine(ConfigurationManager.ApplicationPaths.GeneralPath, name); } @@ -170,30 +66,34 @@ namespace MediaBrowser.Providers { var location = GetLocation(item); - var directoryInfo = new DirectoryInfo(location); - - if (!directoryInfo.Exists) - { - return null; - } - - var files = directoryInfo.EnumerateFiles("*", SearchOption.TopDirectoryOnly).ToList(); + return GetImageFromLocation(location, filenameWithoutExtension); + } - var file = files.FirstOrDefault(i => string.Equals(i.Name, filenameWithoutExtension + ".png", StringComparison.OrdinalIgnoreCase)); + protected override Guid GetFileSystemStamp(BaseItem item) + { + var location = GetLocation(item); - if (file != null) + try { - return file; + var files = new DirectoryInfo(location) + .EnumerateFiles("*", SearchOption.TopDirectoryOnly) + .Where(i => + { + var ext = i.Extension; + + return !string.IsNullOrEmpty(ext) && + BaseItem.SupportedImageExtensions.Contains(ext, StringComparer.OrdinalIgnoreCase); + }) + .ToList(); + + return GetFileSystemStamp(files); } - - file = files.FirstOrDefault(i => string.Equals(i.Name, filenameWithoutExtension + ".jpg", StringComparison.OrdinalIgnoreCase)); - - if (file != null) + catch (DirectoryNotFoundException) { - return file; - } + // User doesn't have the folder. No need to log or blow up - return null; + return Guid.Empty; + } } } } diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj index 5aa8a0c84..ad5dd9b3f 100644 --- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj +++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj @@ -47,6 +47,7 @@ </Reference> </ItemGroup> <ItemGroup> + <Compile Include="CollectionFolderImageProvider.cs" /> <Compile Include="FanartBaseProvider.cs" /> <Compile Include="FolderProviderFromXml.cs" /> <Compile Include="Games\GameXmlParser.cs" /> |
