diff --git a/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs b/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs
index de7e8e98d9..07bb7d5b20 100644
--- a/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs
+++ b/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs
@@ -24,6 +24,7 @@ namespace MediaBrowser.Controller.Providers
///
/// The logger.
protected ILogger Logger { get; set; }
+
protected ILogManager LogManager { get; set; }
///
@@ -41,6 +42,7 @@ namespace MediaBrowser.Controller.Providers
/// The true task result
///
protected static readonly Task TrueTaskResult = Task.FromResult(true);
+
protected static readonly Task FalseTaskResult = Task.FromResult(false);
protected static readonly SemaphoreSlim XmlParsingResourcePool = new SemaphoreSlim(5, 5);
@@ -132,7 +134,8 @@ namespace MediaBrowser.Controller.Providers
/// The provider version.
/// The status.
/// item
- 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
/// The item.
/// The value.
/// The status.
- 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 _fileStampExtensionsDictionary;
+
private Dictionary FileStampExtensionsDictionary
{
get
{
return _fileStampExtensionsDictionary ??
(_fileStampExtensionsDictionary =
- FilestampExtensions.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase));
+ FilestampExtensions.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase));
}
}
+
///
/// Gets the file system stamp.
///
/// The item.
/// Guid.
- 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 FoldersToMonitor = new[] { "extrafanart", "extrathumbs" }
.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
+ protected Guid GetFileSystemStamp(IEnumerable 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();
+ }
+
///
/// Adds the files.
///
@@ -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 0000000000..45b1b36c26
--- /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 9943c7ab8a..aa0dcc9d47 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
///
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 6be4ee108b..5904308234 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
///
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;
- }
- }
-
///
/// Supportses the specified item.
///
@@ -42,8 +27,8 @@ namespace MediaBrowser.Providers
/// true if XXXX, false otherwise
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;
}
///
@@ -58,95 +43,6 @@ namespace MediaBrowser.Providers
}
}
- ///
- /// Needses the refresh internal.
- ///
- /// The item.
- /// The provider info.
- /// true if XXXX, false otherwise
- 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);
- }
-
- ///
- /// Gets a value indicating whether [refresh on file system stamp change].
- ///
- /// true if [refresh on file system stamp change]; otherwise, false.
- protected override bool RefreshOnFileSystemStampChange
- {
- get
- {
- return false;
- }
- }
-
- ///
- /// Override this to return the date that should be compared to the last refresh date
- /// to determine if this provider should be re-fetched.
- ///
- /// The item.
- /// DateTime.
- 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();
- }
-
- ///
- /// 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}.
- public override async Task 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;
- }
-
///
/// Gets the location.
///
@@ -154,7 +50,7 @@ namespace MediaBrowser.Providers
/// System.String.
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 5aa8a0c846..ad5dd9b3fd 100644
--- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj
+++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj
@@ -47,6 +47,7 @@
+