diff --git a/MediaBrowser.Controller/FFMpeg/FFProbe.cs b/MediaBrowser.Controller/FFMpeg/FFProbe.cs
index 83f70af3a..fac1d4667 100644
--- a/MediaBrowser.Controller/FFMpeg/FFProbe.cs
+++ b/MediaBrowser.Controller/FFMpeg/FFProbe.cs
@@ -13,12 +13,15 @@ namespace MediaBrowser.Controller.FFMpeg
///
public static class FFProbe
{
+ ///
+ /// Runs FFProbe against an Audio file, caches the result and returns the output
+ ///
public static FFProbeResult Run(Audio item)
{
// Use try catch to avoid having to use File.Exists
try
{
- return GetCachedResult(GetFFProbeAudioCachePath(item));
+ return GetCachedResult(GetFFProbeCachePath(item));
}
catch (FileNotFoundException)
{
@@ -31,16 +34,22 @@ namespace MediaBrowser.Controller.FFMpeg
FFProbeResult result = Run(item.Path);
// Fire and forget
- CacheResult(result, GetFFProbeAudioCachePath(item));
+ CacheResult(result, GetFFProbeCachePath(item));
return result;
}
+ ///
+ /// Gets the cached result of an FFProbe operation
+ ///
private static FFProbeResult GetCachedResult(string path)
{
return ProtobufSerializer.DeserializeFromFile(path);
}
+ ///
+ /// Caches the result of an FFProbe operation
+ ///
private static async void CacheResult(FFProbeResult result, string outputCachePath)
{
await Task.Run(() =>
@@ -56,12 +65,15 @@ namespace MediaBrowser.Controller.FFMpeg
}).ConfigureAwait(false);
}
+ ///
+ /// Runs FFProbe against a Video file, caches the result and returns the output
+ ///
public static FFProbeResult Run(Video item)
{
// Use try catch to avoid having to use File.Exists
try
{
- return GetCachedResult(GetFFProbeVideoCachePath(item));
+ return GetCachedResult(GetFFProbeCachePath(item));
}
catch (FileNotFoundException)
{
@@ -74,7 +86,7 @@ namespace MediaBrowser.Controller.FFMpeg
FFProbeResult result = Run(item.Path);
// Fire and forget
- CacheResult(result, GetFFProbeVideoCachePath(item));
+ CacheResult(result, GetFFProbeCachePath(item));
return result;
}
@@ -131,14 +143,14 @@ namespace MediaBrowser.Controller.FFMpeg
}
}
- private static string GetFFProbeAudioCachePath(BaseEntity item)
+ private static string GetFFProbeCachePath(Audio item)
{
string outputDirectory = Path.Combine(Kernel.Instance.ApplicationPaths.FFProbeAudioCacheDirectory, item.Id.ToString().Substring(0, 1));
return Path.Combine(outputDirectory, item.Id + "-" + item.DateModified.Ticks + ".pb");
}
- private static string GetFFProbeVideoCachePath(BaseEntity item)
+ private static string GetFFProbeCachePath(Video item)
{
string outputDirectory = Path.Combine(Kernel.Instance.ApplicationPaths.FFProbeVideoCacheDirectory, item.Id.ToString().Substring(0, 1));
diff --git a/MediaBrowser.Controller/IO/FileData.cs b/MediaBrowser.Controller/IO/FileData.cs
index eca166ead..21d090a27 100644
--- a/MediaBrowser.Controller/IO/FileData.cs
+++ b/MediaBrowser.Controller/IO/FileData.cs
@@ -1,32 +1,61 @@
using System;
+using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
-using System.Runtime.ConstrainedExecution;
-using Microsoft.Win32.SafeHandles;
-using System.Collections.Generic;
-using System.Linq;
-
namespace MediaBrowser.Controller.IO
{
+ ///
+ /// Provides low level File access that is much faster than the File/Directory api's
+ ///
public static class FileData
{
public const int MAX_PATH = 260;
public const int MAX_ALTERNATE = 14;
- public static WIN32_FIND_DATA GetFileData(string fileName)
+ ///
+ /// Gets information about a path
+ ///
+ public static WIN32_FIND_DATA GetFileData(string path)
{
WIN32_FIND_DATA data;
- IntPtr handle = FindFirstFile(fileName, out data);
+ IntPtr handle = FindFirstFile(path, out data);
if (handle == IntPtr.Zero)
throw new IOException("FindFirstFile failed");
FindClose(handle);
- data.Path = fileName;
+ data.Path = path;
return data;
}
+ ///
+ /// Gets all file system entries within a foler
+ ///
public static IEnumerable GetFileSystemEntries(string path, string searchPattern)
+ {
+ return GetFileSystemEntries(path, searchPattern, true, true);
+ }
+
+ ///
+ /// Gets all files within a folder
+ ///
+ public static IEnumerable GetFiles(string path, string searchPattern)
+ {
+ return GetFileSystemEntries(path, searchPattern, true, false);
+ }
+
+ ///
+ /// Gets all sub-directories within a folder
+ ///
+ public static IEnumerable GetDirectories(string path, string searchPattern)
+ {
+ return GetFileSystemEntries(path, searchPattern, false, true);
+ }
+
+ ///
+ /// Gets all file system entries within a foler
+ ///
+ public static IEnumerable GetFileSystemEntries(string path, string searchPattern, bool includeFiles, bool includeDirectories)
{
string lpFileName = Path.Combine(path, searchPattern);
@@ -43,14 +72,14 @@ namespace MediaBrowser.Controller.IO
yield break;
}
- if (IsValid(lpFindFileData.cFileName))
+ if (IncludeInOutput(lpFindFileData.cFileName, lpFindFileData.dwFileAttributes, includeFiles, includeDirectories))
{
yield return lpFindFileData;
}
while (FindNextFile(handle, out lpFindFileData) != IntPtr.Zero)
{
- if (IsValid(lpFindFileData.cFileName))
+ if (IncludeInOutput(lpFindFileData.cFileName, lpFindFileData.dwFileAttributes, includeFiles, includeDirectories))
{
lpFindFileData.Path = Path.Combine(path, lpFindFileData.cFileName);
yield return lpFindFileData;
@@ -60,7 +89,7 @@ namespace MediaBrowser.Controller.IO
FindClose(handle);
}
- private static bool IsValid(string cFileName)
+ private static bool IncludeInOutput(string cFileName, FileAttributes attributes, bool includeFiles, bool includeDirectories)
{
if (cFileName.Equals(".", StringComparison.OrdinalIgnoreCase))
{
@@ -71,6 +100,16 @@ namespace MediaBrowser.Controller.IO
return false;
}
+ if (!includeFiles && !attributes.HasFlag(FileAttributes.Directory))
+ {
+ return false;
+ }
+
+ if (!includeDirectories && attributes.HasFlag(FileAttributes.Directory))
+ {
+ return false;
+ }
+
return true;
}
diff --git a/MediaBrowser.Controller/Kernel.cs b/MediaBrowser.Controller/Kernel.cs
index b7e0258e0..44833fe8e 100644
--- a/MediaBrowser.Controller/Kernel.cs
+++ b/MediaBrowser.Controller/Kernel.cs
@@ -9,7 +9,6 @@ using System.Text;
using System.Threading.Tasks;
using MediaBrowser.Common.Kernel;
using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Events;
using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
diff --git a/MediaBrowser.Controller/Library/ItemController.cs b/MediaBrowser.Controller/Library/ItemController.cs
index df7cf8810..fdc2276d0 100644
--- a/MediaBrowser.Controller/Library/ItemController.cs
+++ b/MediaBrowser.Controller/Library/ItemController.cs
@@ -4,7 +4,6 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
-using MediaBrowser.Controller.Events;
using MediaBrowser.Controller.IO;
using MediaBrowser.Model.Entities;
diff --git a/MediaBrowser.Controller/Events/ItemResolveEventArgs.cs b/MediaBrowser.Controller/Library/ItemResolveEventArgs.cs
similarity index 94%
rename from MediaBrowser.Controller/Events/ItemResolveEventArgs.cs
rename to MediaBrowser.Controller/Library/ItemResolveEventArgs.cs
index 7251e3ec9..0daca3b44 100644
--- a/MediaBrowser.Controller/Events/ItemResolveEventArgs.cs
+++ b/MediaBrowser.Controller/Library/ItemResolveEventArgs.cs
@@ -3,7 +3,7 @@ using System.IO;
using MediaBrowser.Controller.IO;
using MediaBrowser.Model.Entities;
-namespace MediaBrowser.Controller.Events
+namespace MediaBrowser.Controller.Library
{
///
/// This is an EventArgs object used when resolving a Path into a BaseItem
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index 652a9d736..610a4cc01 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -55,7 +55,7 @@
-
+
diff --git a/MediaBrowser.Controller/Providers/AudioInfoProvider.cs b/MediaBrowser.Controller/Providers/AudioInfoProvider.cs
index d45c5ee68..4166cb152 100644
--- a/MediaBrowser.Controller/Providers/AudioInfoProvider.cs
+++ b/MediaBrowser.Controller/Providers/AudioInfoProvider.cs
@@ -5,8 +5,8 @@ using System.IO;
using System.Linq;
using System.Threading.Tasks;
using MediaBrowser.Common.Logging;
-using MediaBrowser.Controller.Events;
using MediaBrowser.Controller.FFMpeg;
+using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Controller.Providers
diff --git a/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs b/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs
index 5c536913e..45cd59883 100644
--- a/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs
+++ b/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs
@@ -1,6 +1,6 @@
using System;
using System.Threading.Tasks;
-using MediaBrowser.Controller.Events;
+using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Controller.Providers
diff --git a/MediaBrowser.Controller/Providers/FolderProviderFromXml.cs b/MediaBrowser.Controller/Providers/FolderProviderFromXml.cs
index d0bd20a47..cdf02e90b 100644
--- a/MediaBrowser.Controller/Providers/FolderProviderFromXml.cs
+++ b/MediaBrowser.Controller/Providers/FolderProviderFromXml.cs
@@ -1,12 +1,15 @@
using System.ComponentModel.Composition;
using System.IO;
using System.Threading.Tasks;
-using MediaBrowser.Controller.Events;
+using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Xml;
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Controller.Providers
{
+ ///
+ /// Provides metadata for Folders and all subclasses by parsing folder.xml
+ ///
[Export(typeof(BaseMetadataProvider))]
public class FolderProviderFromXml : BaseMetadataProvider
{
@@ -22,15 +25,15 @@ namespace MediaBrowser.Controller.Providers
public async override Task FetchAsync(BaseEntity item, ItemResolveEventArgs args)
{
- await Task.Run(() => { Fetch(item, args); }).ConfigureAwait(false);
+ if (args.ContainsFile("folder.xml"))
+ {
+ await Task.Run(() => { Fetch(item, args); }).ConfigureAwait(false);
+ }
}
private void Fetch(BaseEntity item, ItemResolveEventArgs args)
{
- if (args.ContainsFile("folder.xml"))
- {
- new BaseItemXmlParser().Fetch(item as Folder, Path.Combine(args.Path, "folder.xml"));
- }
+ new BaseItemXmlParser().Fetch(item as Folder, Path.Combine(args.Path, "folder.xml"));
}
}
}
diff --git a/MediaBrowser.Controller/Providers/ImageFromMediaLocationProvider.cs b/MediaBrowser.Controller/Providers/ImageFromMediaLocationProvider.cs
index 59b58474f..242a139ef 100644
--- a/MediaBrowser.Controller/Providers/ImageFromMediaLocationProvider.cs
+++ b/MediaBrowser.Controller/Providers/ImageFromMediaLocationProvider.cs
@@ -3,11 +3,14 @@ using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.IO;
using System.Threading.Tasks;
-using MediaBrowser.Controller.Events;
+using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Controller.Providers
{
+ ///
+ /// Provides images for all types by looking for standard images - folder, backdrop, logo, etc.
+ ///
[Export(typeof(BaseMetadataProvider))]
public class ImageFromMediaLocationProvider : BaseMetadataProvider
{
diff --git a/MediaBrowser.Controller/Providers/LocalTrailerProvider.cs b/MediaBrowser.Controller/Providers/LocalTrailerProvider.cs
index 536294c7b..ac258ee61 100644
--- a/MediaBrowser.Controller/Providers/LocalTrailerProvider.cs
+++ b/MediaBrowser.Controller/Providers/LocalTrailerProvider.cs
@@ -2,12 +2,15 @@
using System.ComponentModel.Composition;
using System.IO;
using System.Threading.Tasks;
-using MediaBrowser.Controller.Events;
using MediaBrowser.Controller.IO;
+using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Controller.Providers
{
+ ///
+ /// Provides local trailers by checking the trailers subfolder
+ ///
[Export(typeof(BaseMetadataProvider))]
public class LocalTrailerProvider : BaseMetadataProvider
{
diff --git a/MediaBrowser.Controller/Providers/VideoInfoProvider.cs b/MediaBrowser.Controller/Providers/VideoInfoProvider.cs
index 2f8175b7e..9b5a8933d 100644
--- a/MediaBrowser.Controller/Providers/VideoInfoProvider.cs
+++ b/MediaBrowser.Controller/Providers/VideoInfoProvider.cs
@@ -4,10 +4,9 @@ using System.ComponentModel.Composition;
using System.Linq;
using System.Threading.Tasks;
using MediaBrowser.Common.Logging;
-using MediaBrowser.Controller.Events;
using MediaBrowser.Controller.FFMpeg;
+using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Entities;
-using System.IO;
namespace MediaBrowser.Controller.Providers
{
@@ -38,12 +37,6 @@ namespace MediaBrowser.Controller.Providers
return;
}
- // For now
- if (Path.GetExtension(video.Path).EndsWith("iso", StringComparison.OrdinalIgnoreCase))
- {
- return;
- }
-
if (CanSkip(video))
{
return;
diff --git a/MediaBrowser.Controller/Resolvers/AudioResolver.cs b/MediaBrowser.Controller/Resolvers/AudioResolver.cs
index 26b4da310..7b52ccfc4 100644
--- a/MediaBrowser.Controller/Resolvers/AudioResolver.cs
+++ b/MediaBrowser.Controller/Resolvers/AudioResolver.cs
@@ -1,6 +1,6 @@
using System.ComponentModel.Composition;
using System.IO;
-using MediaBrowser.Controller.Events;
+using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Controller.Resolvers
diff --git a/MediaBrowser.Controller/Resolvers/BaseItemResolver.cs b/MediaBrowser.Controller/Resolvers/BaseItemResolver.cs
index 948e0cfb5..643580b31 100644
--- a/MediaBrowser.Controller/Resolvers/BaseItemResolver.cs
+++ b/MediaBrowser.Controller/Resolvers/BaseItemResolver.cs
@@ -1,7 +1,7 @@
using System;
using System.IO;
-using MediaBrowser.Controller.Events;
using MediaBrowser.Controller.IO;
+using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Controller.Resolvers
diff --git a/MediaBrowser.Controller/Resolvers/FolderResolver.cs b/MediaBrowser.Controller/Resolvers/FolderResolver.cs
index 62fe2f6fb..6857c3574 100644
--- a/MediaBrowser.Controller/Resolvers/FolderResolver.cs
+++ b/MediaBrowser.Controller/Resolvers/FolderResolver.cs
@@ -1,5 +1,5 @@
using System.ComponentModel.Composition;
-using MediaBrowser.Controller.Events;
+using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Controller.Resolvers
diff --git a/MediaBrowser.Controller/Resolvers/VideoResolver.cs b/MediaBrowser.Controller/Resolvers/VideoResolver.cs
index ee2fc62f3..1157401af 100644
--- a/MediaBrowser.Controller/Resolvers/VideoResolver.cs
+++ b/MediaBrowser.Controller/Resolvers/VideoResolver.cs
@@ -1,6 +1,6 @@
using System.ComponentModel.Composition;
using System.IO;
-using MediaBrowser.Controller.Events;
+using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Controller.Resolvers
diff --git a/MediaBrowser.Controller/Resolvers/VirtualFolderResolver.cs b/MediaBrowser.Controller/Resolvers/VirtualFolderResolver.cs
index 19bf66f29..e7940ef14 100644
--- a/MediaBrowser.Controller/Resolvers/VirtualFolderResolver.cs
+++ b/MediaBrowser.Controller/Resolvers/VirtualFolderResolver.cs
@@ -1,6 +1,6 @@
using System.ComponentModel.Composition;
using System.IO;
-using MediaBrowser.Controller.Events;
+using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Controller.Resolvers
diff --git a/MediaBrowser.Movies/MediaBrowser.Movies.csproj b/MediaBrowser.Movies/MediaBrowser.Movies.csproj
index 588a23e90..5eefa6b81 100644
--- a/MediaBrowser.Movies/MediaBrowser.Movies.csproj
+++ b/MediaBrowser.Movies/MediaBrowser.Movies.csproj
@@ -43,6 +43,7 @@
+
diff --git a/MediaBrowser.Movies/Providers/MovieProviderFromXml.cs b/MediaBrowser.Movies/Providers/MovieProviderFromXml.cs
index 689e786d1..0498deb9a 100644
--- a/MediaBrowser.Movies/Providers/MovieProviderFromXml.cs
+++ b/MediaBrowser.Movies/Providers/MovieProviderFromXml.cs
@@ -1,7 +1,7 @@
using System.ComponentModel.Composition;
using System.IO;
using System.Threading.Tasks;
-using MediaBrowser.Controller.Events;
+using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Controller.Xml;
using MediaBrowser.Model.Entities;
diff --git a/MediaBrowser.Movies/Providers/MovieSpecialFeaturesProvider.cs b/MediaBrowser.Movies/Providers/MovieSpecialFeaturesProvider.cs
new file mode 100644
index 000000000..a70c56747
--- /dev/null
+++ b/MediaBrowser.Movies/Providers/MovieSpecialFeaturesProvider.cs
@@ -0,0 +1,47 @@
+using System.Collections.Generic;
+using System.ComponentModel.Composition;
+using System.IO;
+using System.Threading.Tasks;
+using MediaBrowser.Controller;
+using MediaBrowser.Controller.IO;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Providers;
+using MediaBrowser.Model.Entities;
+using MediaBrowser.Movies.Entities;
+
+namespace MediaBrowser.Movies.Providers
+{
+ [Export(typeof(BaseMetadataProvider))]
+ public class MovieSpecialFeaturesProvider : BaseMetadataProvider
+ {
+ public override bool Supports(BaseEntity item)
+ {
+ return item is Movie;
+ }
+
+ public override MetadataProviderPriority Priority
+ {
+ get { return MetadataProviderPriority.First; }
+ }
+
+ public async override Task FetchAsync(BaseEntity item, ItemResolveEventArgs args)
+ {
+ if (args.ContainsFolder("specials"))
+ {
+ List