moved resolvers to implementations, trimmed nuget package a bit

pull/702/head
LukePulverenti 11 years ago
parent 627b8370a8
commit ac3a94f5a1

@ -3,7 +3,6 @@ using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Localization;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using System;

@ -2,7 +2,6 @@
using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Localization;
using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Controller.Sorting;
using MediaBrowser.Model.Entities;
using System;

@ -115,7 +115,7 @@ namespace MediaBrowser.Controller.Entities.TV
/// Add files from the metadata folder to ResolveArgs
/// </summary>
/// <param name="args">The args.</param>
internal static void AddMetadataFiles(ItemResolveArgs args)
public static void AddMetadataFiles(ItemResolveArgs args)
{
var folder = args.GetFileSystemEntryByName("metadata");

@ -0,0 +1,97 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.IO;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace MediaBrowser.Controller.Library
{
/// <summary>
/// Class EntityResolutionHelper
/// </summary>
public static class EntityResolutionHelper
{
/// <summary>
/// Any extension in this list is considered a video file - can be added to at runtime for extensibility
/// </summary>
public static List<string> VideoFileExtensions = new List<string>
{
".mkv",
".m2t",
".m2ts",
".img",
".iso",
".ts",
".rmvb",
".mov",
".avi",
".mpg",
".mpeg",
".wmv",
".mp4",
".divx",
".dvr-ms",
".wtv",
".ogm",
".ogv",
".asf",
".m4v",
".flv",
".f4v",
".3gp",
".webm"
};
/// <summary>
/// Determines whether [is video file] [the specified path].
/// </summary>
/// <param name="path">The path.</param>
/// <returns><c>true</c> if [is video file] [the specified path]; otherwise, <c>false</c>.</returns>
public static bool IsVideoFile(string path)
{
var extension = Path.GetExtension(path) ?? string.Empty;
return VideoFileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase);
}
/// <summary>
/// Ensures DateCreated and DateModified have values
/// </summary>
/// <param name="item">The item.</param>
/// <param name="args">The args.</param>
public static void EnsureDates(BaseItem item, ItemResolveArgs args)
{
if (!Path.IsPathRooted(item.Path))
{
return;
}
// See if a different path came out of the resolver than what went in
if (!args.Path.Equals(item.Path, StringComparison.OrdinalIgnoreCase))
{
var childData = args.IsDirectory ? args.GetFileSystemEntryByPath(item.Path) : null;
if (childData.HasValue)
{
item.DateCreated = childData.Value.CreationTimeUtc;
item.DateModified = childData.Value.LastWriteTimeUtc;
}
else
{
var fileData = FileSystem.GetFileData(item.Path);
if (fileData.HasValue)
{
item.DateCreated = fileData.Value.CreationTimeUtc;
item.DateModified = fileData.Value.LastWriteTimeUtc;
}
}
}
else
{
item.DateCreated = args.FileInfo.CreationTimeUtc;
item.DateModified = args.FileInfo.LastWriteTimeUtc;
}
}
}
}

@ -0,0 +1,22 @@
using MediaBrowser.Controller.Entities;
namespace MediaBrowser.Controller.Library
{
/// <summary>
/// Interface IItemResolver
/// </summary>
public interface IItemResolver
{
/// <summary>
/// Resolves the path.
/// </summary>
/// <param name="args">The args.</param>
/// <returns>BaseItem.</returns>
BaseItem ResolvePath(ItemResolveArgs args);
/// <summary>
/// Gets the priority.
/// </summary>
/// <value>The priority.</value>
ResolverPriority Priority { get; }
}
}

@ -1,6 +1,5 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Model.Entities;
using System;
using System.Collections.Generic;
@ -158,7 +157,7 @@ namespace MediaBrowser.Controller.Library
/// <param name="pluginFolders">The plugin folders.</param>
/// <param name="resolvers">The resolvers.</param>
/// <param name="introProviders">The intro providers.</param>
void AddParts(IEnumerable<IResolutionIgnoreRule> rules, IEnumerable<IVirtualFolderCreator> pluginFolders,
IEnumerable<IBaseItemResolver> resolvers, IEnumerable<IIntroProvider> introProviders);
void AddParts(IEnumerable<IResolverIgnoreRule> rules, IEnumerable<IVirtualFolderCreator> pluginFolders,
IEnumerable<IItemResolver> resolvers, IEnumerable<IIntroProvider> introProviders);
}
}

@ -1,11 +1,9 @@
using MediaBrowser.Controller.Library;
namespace MediaBrowser.Controller.Resolvers
namespace MediaBrowser.Controller.Library
{
/// <summary>
/// Provides a base "rule" that anyone can use to have paths ignored by the resolver
/// </summary>
public interface IResolutionIgnoreRule
public interface IResolverIgnoreRule
{
bool ShouldIgnore(ItemResolveArgs args);
}

@ -0,0 +1,26 @@

namespace MediaBrowser.Controller.Library
{
/// <summary>
/// Enum ResolverPriority
/// </summary>
public enum ResolverPriority
{
/// <summary>
/// The first
/// </summary>
First = 1,
/// <summary>
/// The second
/// </summary>
Second = 2,
/// <summary>
/// The third
/// </summary>
Third = 3,
/// <summary>
/// The last
/// </summary>
Last = 4
}
}

@ -4,7 +4,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace MediaBrowser.Controller.Resolvers.TV
namespace MediaBrowser.Controller.Library
{
/// <summary>
/// Class TVUtils

@ -110,6 +110,7 @@
<Compile Include="IServerApplicationPaths.cs" />
<Compile Include="Library\ChildrenChangedEventArgs.cs" />
<Compile Include="Library\DtoBuilder.cs" />
<Compile Include="Library\IItemResolver.cs" />
<Compile Include="Library\ILibraryManager.cs" />
<Compile Include="Library\IUserManager.cs" />
<Compile Include="Library\Profiler.cs" />
@ -163,18 +164,10 @@
<Compile Include="Providers\TV\SeriesProviderFromXml.cs" />
<Compile Include="Providers\TV\SeriesXmlParser.cs" />
<Compile Include="Providers\MediaInfo\FFMpegVideoImageProvider.cs" />
<Compile Include="Resolvers\Audio\MusicAlbumResolver.cs" />
<Compile Include="Resolvers\Audio\MusicArtistResolver.cs" />
<Compile Include="Resolvers\IResolutionIgnoreRule.cs" />
<Compile Include="Resolvers\CoreResolutionIgnoreRule.cs" />
<Compile Include="Resolvers\EntityResolutionHelper.cs" />
<Compile Include="Resolvers\LocalTrailerResolver.cs" />
<Compile Include="Resolvers\Movies\BoxSetResolver.cs" />
<Compile Include="Resolvers\Movies\MovieResolver.cs" />
<Compile Include="Resolvers\TV\EpisodeResolver.cs" />
<Compile Include="Resolvers\TV\SeasonResolver.cs" />
<Compile Include="Resolvers\TV\SeriesResolver.cs" />
<Compile Include="Resolvers\TV\TVUtils.cs" />
<Compile Include="Library\IResolverIgnoreRule.cs" />
<Compile Include="Library\EntityResolutionHelper.cs" />
<Compile Include="Library\ResolverPriority.cs" />
<Compile Include="Library\TVUtils.cs" />
<Compile Include="ScheduledTasks\PeopleValidationTask.cs" />
<Compile Include="ScheduledTasks\RefreshMediaLibraryTask.cs" />
<Compile Include="Library\ItemResolveArgs.cs" />
@ -187,10 +180,6 @@
<Compile Include="Providers\FolderProviderFromXml.cs" />
<Compile Include="Providers\ImageFromMediaLocationProvider.cs" />
<Compile Include="Providers\MediaInfo\FFProbeVideoInfoProvider.cs" />
<Compile Include="Resolvers\Audio\AudioResolver.cs" />
<Compile Include="Resolvers\BaseItemResolver.cs" />
<Compile Include="Resolvers\FolderResolver.cs" />
<Compile Include="Resolvers\VideoResolver.cs" />
<Compile Include="Sorting\BaseItemComparer.cs" />
<Compile Include="Sorting\SortOrder.cs" />
<Compile Include="Updates\InstallationManager.cs" />

@ -2,7 +2,7 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Extensions;
using MediaBrowser.Controller.Resolvers.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Net;

@ -1,7 +1,7 @@
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Resolvers.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Net;

@ -3,7 +3,7 @@ using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Extensions;
using MediaBrowser.Controller.Resolvers.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Net;

@ -1,5 +1,5 @@
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Resolvers.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using System;

@ -1,39 +0,0 @@
using MediaBrowser.Controller.Library;
namespace MediaBrowser.Controller.Resolvers.Audio
{
/// <summary>
/// Class AudioResolver
/// </summary>
public class AudioResolver : BaseItemResolver<Entities.Audio.Audio>
{
/// <summary>
/// Gets the priority.
/// </summary>
/// <value>The priority.</value>
public override ResolverPriority Priority
{
get { return ResolverPriority.Last; }
}
/// <summary>
/// Resolves the specified args.
/// </summary>
/// <param name="args">The args.</param>
/// <returns>Entities.Audio.Audio.</returns>
protected override Entities.Audio.Audio Resolve(ItemResolveArgs args)
{
// Return audio if the path is a file and has a matching extension
if (!args.IsDirectory)
{
if (EntityResolutionHelper.IsAudioFile(args))
{
return new Entities.Audio.Audio();
}
}
return null;
}
}
}

@ -1,37 +0,0 @@
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
namespace MediaBrowser.Controller.Resolvers.Audio
{
/// <summary>
/// Class MusicAlbumResolver
/// </summary>
public class MusicAlbumResolver : BaseItemResolver<MusicAlbum>
{
/// <summary>
/// Gets the priority.
/// </summary>
/// <value>The priority.</value>
public override ResolverPriority Priority
{
get { return ResolverPriority.Third; } // we need to be ahead of the generic folder resolver but behind the movie one
}
/// <summary>
/// Resolves the specified args.
/// </summary>
/// <param name="args">The args.</param>
/// <returns>MusicAlbum.</returns>
protected override MusicAlbum Resolve(ItemResolveArgs args)
{
if (!args.IsDirectory) return null;
//Avoid mis-identifying top folders
if (args.Parent == null) return null;
if (args.Parent.IsRoot) return null;
return EntityResolutionHelper.IsMusicAlbum(args) ? new MusicAlbum() : null;
}
}
}

@ -1,165 +0,0 @@
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using System.IO;
using System.Text.RegularExpressions;
namespace MediaBrowser.Controller.Resolvers
{
/// <summary>
/// Class BaseItemResolver
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class BaseItemResolver<T> : IBaseItemResolver
where T : BaseItem, new()
{
/// <summary>
/// Resolves the specified args.
/// </summary>
/// <param name="args">The args.</param>
/// <returns>`0.</returns>
protected virtual T Resolve(ItemResolveArgs args)
{
return null;
}
/// <summary>
/// Gets the priority.
/// </summary>
/// <value>The priority.</value>
public virtual ResolverPriority Priority
{
get
{
return ResolverPriority.First;
}
}
/// <summary>
/// Sets initial values on the newly resolved item
/// </summary>
/// <param name="item">The item.</param>
/// <param name="args">The args.</param>
protected virtual void SetInitialItemValues(T item, ItemResolveArgs args)
{
// If the subclass didn't specify this
if (string.IsNullOrEmpty(item.Path))
{
item.Path = args.Path;
}
// If the subclass didn't specify this
if (args.Parent != null)
{
item.Parent = args.Parent;
}
item.Id = item.Path.GetMBId(item.GetType());
item.DisplayMediaType = item.GetType().Name;
}
/// <summary>
/// Resolves the path.
/// </summary>
/// <param name="args">The args.</param>
/// <returns>BaseItem.</returns>
public BaseItem ResolvePath(ItemResolveArgs args)
{
T item = Resolve(args);
if (item != null)
{
// Set the args on the item
item.ResolveArgs = args;
// Set initial values on the newly resolved item
SetInitialItemValues(item, args);
// Make sure the item has a name
EnsureName(item);
// Make sure DateCreated and DateModified have values
EntityResolutionHelper.EnsureDates(item, args);
}
return item;
}
/// <summary>
/// Ensures the name.
/// </summary>
/// <param name="item">The item.</param>
private void EnsureName(T item)
{
// If the subclass didn't supply a name, add it here
if (string.IsNullOrEmpty(item.Name) && !string.IsNullOrEmpty(item.Path))
{
//we use our resolve args name here to get the name of the containg folder, not actual video file
item.Name = GetMBName(item.ResolveArgs.FileInfo.cFileName, item.ResolveArgs.FileInfo.IsDirectory);
}
}
/// <summary>
/// The MB name regex
/// </summary>
private static readonly Regex MBNameRegex = new Regex("(\\[.*\\])", RegexOptions.Compiled);
/// <summary>
/// Strip out attribute items and return just the name we will use for items
/// </summary>
/// <param name="path">Assumed to be a file or directory path</param>
/// <param name="isDirectory">if set to <c>true</c> [is directory].</param>
/// <returns>The cleaned name</returns>
private static string GetMBName(string path, bool isDirectory)
{
//first just get the file or directory name
var fn = isDirectory ? Path.GetFileName(path) : Path.GetFileNameWithoutExtension(path);
//now - strip out anything inside brackets
fn = MBNameRegex.Replace(fn, string.Empty);
return fn;
}
}
/// <summary>
/// Weed this to keep a list of resolvers, since Resolvers are built with generics
/// </summary>
public interface IBaseItemResolver
{
/// <summary>
/// Resolves the path.
/// </summary>
/// <param name="args">The args.</param>
/// <returns>BaseItem.</returns>
BaseItem ResolvePath(ItemResolveArgs args);
/// <summary>
/// Gets the priority.
/// </summary>
/// <value>The priority.</value>
ResolverPriority Priority { get; }
}
/// <summary>
/// Enum ResolverPriority
/// </summary>
public enum ResolverPriority
{
/// <summary>
/// The first
/// </summary>
First = 1,
/// <summary>
/// The second
/// </summary>
Second = 2,
/// <summary>
/// The third
/// </summary>
Third = 3,
/// <summary>
/// The last
/// </summary>
Last = 4
}
}

@ -1,210 +0,0 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Library;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace MediaBrowser.Controller.Resolvers
{
/// <summary>
/// Class EntityResolutionHelper
/// </summary>
public static class EntityResolutionHelper
{
/// <summary>
/// Any extension in this list is considered a metadata file - can be added to at runtime for extensibility
/// </summary>
public static List<string> MetaExtensions = new List<string>
{
".xml",
".jpg",
".png",
".json",
".data"
};
/// <summary>
/// Any extension in this list is considered a video file - can be added to at runtime for extensibility
/// </summary>
public static List<string> VideoFileExtensions = new List<string>
{
".mkv",
".m2t",
".m2ts",
".img",
".iso",
".ts",
".rmvb",
".mov",
".avi",
".mpg",
".mpeg",
".wmv",
".mp4",
".divx",
".dvr-ms",
".wtv",
".ogm",
".ogv",
".asf",
".m4v",
".flv",
".f4v",
".3gp",
".webm"
};
/// <summary>
/// Determines whether [is video file] [the specified path].
/// </summary>
/// <param name="path">The path.</param>
/// <returns><c>true</c> if [is video file] [the specified path]; otherwise, <c>false</c>.</returns>
public static bool IsVideoFile(string path)
{
var extension = Path.GetExtension(path) ?? string.Empty;
return VideoFileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase);
}
/// <summary>
/// The audio file extensions
/// </summary>
public static readonly string[] AudioFileExtensions = new[] {
".mp3",
".flac",
".wma",
".aac",
".acc",
".m4a",
".m4b",
".wav",
".ape",
".ogg",
".oga"
};
/// <summary>
/// Determines whether [is audio file] [the specified args].
/// </summary>
/// <param name="args">The args.</param>
/// <returns><c>true</c> if [is audio file] [the specified args]; otherwise, <c>false</c>.</returns>
public static bool IsAudioFile(ItemResolveArgs args)
{
return AudioFileExtensions.Contains(Path.GetExtension(args.Path), StringComparer.OrdinalIgnoreCase);
}
/// <summary>
/// Determines whether [is audio file] [the specified file].
/// </summary>
/// <param name="file">The file.</param>
/// <returns><c>true</c> if [is audio file] [the specified file]; otherwise, <c>false</c>.</returns>
public static bool IsAudioFile(WIN32_FIND_DATA file)
{
return AudioFileExtensions.Contains(Path.GetExtension(file.Path), StringComparer.OrdinalIgnoreCase);
}
/// <summary>
/// Determine if the supplied file data points to a music album
/// </summary>
/// <param name="data">The data.</param>
/// <returns><c>true</c> if [is music album] [the specified data]; otherwise, <c>false</c>.</returns>
public static bool IsMusicAlbum(WIN32_FIND_DATA data)
{
return ContainsMusic(FileSystem.GetFiles(data.Path));
}
/// <summary>
/// Determine if the supplied reslove args should be considered a music album
/// </summary>
/// <param name="args">The args.</param>
/// <returns><c>true</c> if [is music album] [the specified args]; otherwise, <c>false</c>.</returns>
public static bool IsMusicAlbum(ItemResolveArgs args)
{
// Args points to an album if parent is an Artist folder or it directly contains music
if (args.IsDirectory)
{
//if (args.Parent is MusicArtist) return true; //saves us from testing children twice
if (ContainsMusic(args.FileSystemChildren)) return true;
}
return false;
}
/// <summary>
/// Determine if the supplied list contains what we should consider music
/// </summary>
/// <param name="list">The list.</param>
/// <returns><c>true</c> if the specified list contains music; otherwise, <c>false</c>.</returns>
public static bool ContainsMusic(IEnumerable<WIN32_FIND_DATA> list)
{
// If list contains at least 2 audio files or at least one and no video files consider it to contain music
var foundAudio = 0;
var foundVideo = 0;
foreach (var file in list)
{
if (IsAudioFile(file)) foundAudio++;
if (foundAudio >= 2)
{
return true;
}
if (IsVideoFile(file.Path)) foundVideo++;
}
// or a single audio file and no video files
if (foundAudio > 0 && foundVideo == 0) return true;
return false;
}
/// <summary>
/// Determines whether a path should be ignored based on its contents - called after the contents have been read
/// </summary>
/// <param name="args">The args.</param>
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
public static bool ShouldResolvePathContents(ItemResolveArgs args)
{
// Ignore any folders containing a file called .ignore
return !args.ContainsFileSystemEntryByName(".ignore");
}
/// <summary>
/// Ensures DateCreated and DateModified have values
/// </summary>
/// <param name="item">The item.</param>
/// <param name="args">The args.</param>
public static void EnsureDates(BaseItem item, ItemResolveArgs args)
{
if (!Path.IsPathRooted(item.Path))
{
return;
}
// See if a different path came out of the resolver than what went in
if (!args.Path.Equals(item.Path, StringComparison.OrdinalIgnoreCase))
{
var childData = args.IsDirectory ? args.GetFileSystemEntryByPath(item.Path) : null;
if (childData.HasValue)
{
item.DateCreated = childData.Value.CreationTimeUtc;
item.DateModified = childData.Value.LastWriteTimeUtc;
}
else
{
var fileData = FileSystem.GetFileData(item.Path);
if (fileData.HasValue)
{
item.DateCreated = fileData.Value.CreationTimeUtc;
item.DateModified = fileData.Value.LastWriteTimeUtc;
}
}
}
else
{
item.DateCreated = args.FileInfo.CreationTimeUtc;
item.DateModified = args.FileInfo.LastWriteTimeUtc;
}
}
}
}

@ -3,12 +3,12 @@ using System;
using System.Collections.Generic;
using System.Linq;
namespace MediaBrowser.Controller.Resolvers
namespace MediaBrowser.Server.Implementations.Library
{
/// <summary>
/// Provides the core resolver ignore rules
/// </summary>
public class CoreResolutionIgnoreRule : IResolutionIgnoreRule
public class CoreResolutionIgnoreRule : IResolverIgnoreRule
{
/// <summary>
/// Any folder named in this list will be ignored - can be added to at runtime for extensibility

@ -6,10 +6,10 @@ using MediaBrowser.Controller;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Controller.ScheduledTasks;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Server.Implementations.Library.Resolvers;
using MoreLinq;
using System;
using System.Collections.Concurrent;
@ -37,7 +37,7 @@ namespace MediaBrowser.Server.Implementations.Library
/// Gets the list of entity resolution ignore rules
/// </summary>
/// <value>The entity resolution ignore rules.</value>
private IEnumerable<IResolutionIgnoreRule> EntityResolutionIgnoreRules { get; set; }
private IEnumerable<IResolverIgnoreRule> EntityResolutionIgnoreRules { get; set; }
/// <summary>
/// Gets the list of BasePluginFolders added by plugins
@ -49,7 +49,7 @@ namespace MediaBrowser.Server.Implementations.Library
/// Gets the list of currently registered entity resolvers
/// </summary>
/// <value>The entity resolvers enumerable.</value>
private IEnumerable<IBaseItemResolver> EntityResolvers { get; set; }
private IEnumerable<IItemResolver> EntityResolvers { get; set; }
#region LibraryChanged Event
/// <summary>
@ -113,7 +113,7 @@ namespace MediaBrowser.Server.Implementations.Library
/// <param name="pluginFolders">The plugin folders.</param>
/// <param name="resolvers">The resolvers.</param>
/// <param name="introProviders">The intro providers.</param>
public void AddParts(IEnumerable<IResolutionIgnoreRule> rules, IEnumerable<IVirtualFolderCreator> pluginFolders, IEnumerable<IBaseItemResolver> resolvers, IEnumerable<IIntroProvider> introProviders)
public void AddParts(IEnumerable<IResolverIgnoreRule> rules, IEnumerable<IVirtualFolderCreator> pluginFolders, IEnumerable<IItemResolver> resolvers, IEnumerable<IIntroProvider> introProviders)
{
EntityResolutionIgnoreRules = rules;
PluginFolderCreators = pluginFolders;
@ -189,7 +189,14 @@ namespace MediaBrowser.Server.Implementations.Library
/// <returns>BaseItem.</returns>
public BaseItem ResolveItem(ItemResolveArgs args)
{
return EntityResolvers.Select(r => r.ResolvePath(args)).FirstOrDefault(i => i != null);
var item = EntityResolvers.Select(r => r.ResolvePath(args)).FirstOrDefault(i => i != null);
if (item != null)
{
ResolverHelper.SetInitialItemValues(item, args);
}
return item;
}
/// <summary>
@ -237,7 +244,7 @@ namespace MediaBrowser.Server.Implementations.Library
}
// Check to see if we should resolve based on our contents
if (args.IsDirectory && !EntityResolutionHelper.ShouldResolvePathContents(args))
if (args.IsDirectory && !ShouldResolvePathContents(args))
{
return null;
}
@ -245,6 +252,17 @@ namespace MediaBrowser.Server.Implementations.Library
return ResolveItem(args);
}
/// <summary>
/// Determines whether a path should be ignored based on its contents - called after the contents have been read
/// </summary>
/// <param name="args">The args.</param>
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
private static bool ShouldResolvePathContents(ItemResolveArgs args)
{
// Ignore any folders containing a file called .ignore
return !args.ContainsFileSystemEntryByName(".ignore");
}
/// <summary>
/// Resolves a set of files into a list of BaseItem
/// </summary>

@ -0,0 +1,82 @@
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using System.IO;
using System.Text.RegularExpressions;
namespace MediaBrowser.Server.Implementations.Library
{
/// <summary>
/// Class ResolverHelper
/// </summary>
public static class ResolverHelper
{
/// <summary>
/// Sets the initial item values.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="args">The args.</param>
public static void SetInitialItemValues(BaseItem item, ItemResolveArgs args)
{
item.ResolveArgs = args;
// If the resolver didn't specify this
if (string.IsNullOrEmpty(item.Path))
{
item.Path = args.Path;
}
// If the resolver didn't specify this
if (args.Parent != null)
{
item.Parent = args.Parent;
}
item.Id = item.Path.GetMBId(item.GetType());
item.DisplayMediaType = item.GetType().Name;
// Make sure the item has a name
EnsureName(item);
// Make sure DateCreated and DateModified have values
EntityResolutionHelper.EnsureDates(item, args);
}
/// <summary>
/// Ensures the name.
/// </summary>
/// <param name="item">The item.</param>
private static void EnsureName(BaseItem item)
{
// If the subclass didn't supply a name, add it here
if (string.IsNullOrEmpty(item.Name) && !string.IsNullOrEmpty(item.Path))
{
//we use our resolve args name here to get the name of the containg folder, not actual video file
item.Name = GetMBName(item.ResolveArgs.FileInfo.cFileName, item.ResolveArgs.FileInfo.IsDirectory);
}
}
/// <summary>
/// The MB name regex
/// </summary>
private static readonly Regex MBNameRegex = new Regex("(\\[.*\\])", RegexOptions.Compiled);
/// <summary>
/// Strip out attribute items and return just the name we will use for items
/// </summary>
/// <param name="path">Assumed to be a file or directory path</param>
/// <param name="isDirectory">if set to <c>true</c> [is directory].</param>
/// <returns>The cleaned name</returns>
private static string GetMBName(string path, bool isDirectory)
{
//first just get the file or directory name
var fn = isDirectory ? Path.GetFileName(path) : Path.GetFileNameWithoutExtension(path);
//now - strip out anything inside brackets
fn = MBNameRegex.Replace(fn, string.Empty);
return fn;
}
}
}

@ -0,0 +1,80 @@
using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Library;
using System;
using System.IO;
using System.Linq;
namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio
{
/// <summary>
/// Class AudioResolver
/// </summary>
public class AudioResolver : ItemResolver<Controller.Entities.Audio.Audio>
{
/// <summary>
/// Gets the priority.
/// </summary>
/// <value>The priority.</value>
public override ResolverPriority Priority
{
get { return ResolverPriority.Last; }
}
/// <summary>
/// Resolves the specified args.
/// </summary>
/// <param name="args">The args.</param>
/// <returns>Entities.Audio.Audio.</returns>
protected override Controller.Entities.Audio.Audio Resolve(ItemResolveArgs args)
{
// Return audio if the path is a file and has a matching extension
if (!args.IsDirectory)
{
if (IsAudioFile(args))
{
return new Controller.Entities.Audio.Audio();
}
}
return null;
}
/// <summary>
/// The audio file extensions
/// </summary>
public static readonly string[] AudioFileExtensions = new[] {
".mp3",
".flac",
".wma",
".aac",
".acc",
".m4a",
".m4b",
".wav",
".ape",
".ogg",
".oga"
};
/// <summary>
/// Determines whether [is audio file] [the specified args].
/// </summary>
/// <param name="args">The args.</param>
/// <returns><c>true</c> if [is audio file] [the specified args]; otherwise, <c>false</c>.</returns>
public static bool IsAudioFile(ItemResolveArgs args)
{
return AudioFileExtensions.Contains(Path.GetExtension(args.Path), StringComparer.OrdinalIgnoreCase);
}
/// <summary>
/// Determines whether [is audio file] [the specified file].
/// </summary>
/// <param name="file">The file.</param>
/// <returns><c>true</c> if [is audio file] [the specified file]; otherwise, <c>false</c>.</returns>
public static bool IsAudioFile(WIN32_FIND_DATA file)
{
return AudioFileExtensions.Contains(Path.GetExtension(file.Path), StringComparer.OrdinalIgnoreCase);
}
}
}

@ -0,0 +1,92 @@
using System.Collections.Generic;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Library;
namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio
{
/// <summary>
/// Class MusicAlbumResolver
/// </summary>
public class MusicAlbumResolver : ItemResolver<MusicAlbum>
{
/// <summary>
/// Gets the priority.
/// </summary>
/// <value>The priority.</value>
public override ResolverPriority Priority
{
get { return ResolverPriority.Third; } // we need to be ahead of the generic folder resolver but behind the movie one
}
/// <summary>
/// Resolves the specified args.
/// </summary>
/// <param name="args">The args.</param>
/// <returns>MusicAlbum.</returns>
protected override MusicAlbum Resolve(ItemResolveArgs args)
{
if (!args.IsDirectory) return null;
//Avoid mis-identifying top folders
if (args.Parent == null) return null;
if (args.Parent.IsRoot) return null;
return IsMusicAlbum(args) ? new MusicAlbum() : null;
}
/// <summary>
/// Determine if the supplied file data points to a music album
/// </summary>
/// <param name="data">The data.</param>
/// <returns><c>true</c> if [is music album] [the specified data]; otherwise, <c>false</c>.</returns>
public static bool IsMusicAlbum(WIN32_FIND_DATA data)
{
return ContainsMusic(FileSystem.GetFiles(data.Path));
}
/// <summary>
/// Determine if the supplied reslove args should be considered a music album
/// </summary>
/// <param name="args">The args.</param>
/// <returns><c>true</c> if [is music album] [the specified args]; otherwise, <c>false</c>.</returns>
public static bool IsMusicAlbum(ItemResolveArgs args)
{
// Args points to an album if parent is an Artist folder or it directly contains music
if (args.IsDirectory)
{
//if (args.Parent is MusicArtist) return true; //saves us from testing children twice
if (ContainsMusic(args.FileSystemChildren)) return true;
}
return false;
}
/// <summary>
/// Determine if the supplied list contains what we should consider music
/// </summary>
/// <param name="list">The list.</param>
/// <returns><c>true</c> if the specified list contains music; otherwise, <c>false</c>.</returns>
public static bool ContainsMusic(IEnumerable<WIN32_FIND_DATA> list)
{
// If list contains at least 2 audio files or at least one and no video files consider it to contain music
var foundAudio = 0;
var foundVideo = 0;
foreach (var file in list)
{
if (AudioResolver.IsAudioFile(file)) foundAudio++;
if (foundAudio >= 2)
{
return true;
}
if (EntityResolutionHelper.IsVideoFile(file.Path)) foundVideo++;
}
// or a single audio file and no video files
if (foundAudio > 0 && foundVideo == 0) return true;
return false;
}
}
}

@ -2,12 +2,12 @@
using MediaBrowser.Controller.Library;
using System.Linq;
namespace MediaBrowser.Controller.Resolvers.Audio
namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio
{
/// <summary>
/// Class MusicArtistResolver
/// </summary>
public class MusicArtistResolver : BaseItemResolver<MusicArtist>
public class MusicArtistResolver : ItemResolver<MusicArtist>
{
/// <summary>
/// Gets the priority.
@ -32,7 +32,7 @@ namespace MediaBrowser.Controller.Resolvers.Audio
if (args.Parent.IsRoot) return null;
// If we contain an album assume we are an artist folder
return args.FileSystemChildren.Any(EntityResolutionHelper.IsMusicAlbum) ? new MusicArtist() : null;
return args.FileSystemChildren.Any(MusicAlbumResolver.IsMusicAlbum) ? new MusicArtist() : null;
}
}

@ -0,0 +1,61 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
namespace MediaBrowser.Server.Implementations.Library.Resolvers
{
/// <summary>
/// Class ItemResolver
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class ItemResolver<T> : IItemResolver
where T : BaseItem, new()
{
/// <summary>
/// Resolves the specified args.
/// </summary>
/// <param name="args">The args.</param>
/// <returns>`0.</returns>
protected virtual T Resolve(ItemResolveArgs args)
{
return null;
}
/// <summary>
/// Gets the priority.
/// </summary>
/// <value>The priority.</value>
public virtual ResolverPriority Priority
{
get
{
return ResolverPriority.First;
}
}
/// <summary>
/// Sets initial values on the newly resolved item
/// </summary>
/// <param name="item">The item.</param>
/// <param name="args">The args.</param>
protected virtual void SetInitialItemValues(T item, ItemResolveArgs args)
{
}
/// <summary>
/// Resolves the path.
/// </summary>
/// <param name="args">The args.</param>
/// <returns>BaseItem.</returns>
BaseItem IItemResolver.ResolvePath(ItemResolveArgs args)
{
var item = Resolve(args);
if (item != null)
{
SetInitialItemValues(item, args);
}
return item;
}
}
}

@ -1,12 +1,12 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
namespace MediaBrowser.Controller.Resolvers
namespace MediaBrowser.Server.Implementations.Library.Resolvers
{
/// <summary>
/// Class FolderResolver
/// </summary>
public class FolderResolver : BaseFolderResolver<Folder>
public class FolderResolver : FolderResolver<Folder>
{
/// <summary>
/// Gets the priority.
@ -47,10 +47,10 @@ namespace MediaBrowser.Controller.Resolvers
}
/// <summary>
/// Class BaseFolderResolver
/// Class FolderResolver
/// </summary>
/// <typeparam name="TItemType">The type of the T item type.</typeparam>
public abstract class BaseFolderResolver<TItemType> : BaseItemResolver<TItemType>
public abstract class FolderResolver<TItemType> : ItemResolver<TItemType>
where TItemType : Folder, new()
{
/// <summary>

@ -3,12 +3,12 @@ using MediaBrowser.Controller.Library;
using System;
using System.IO;
namespace MediaBrowser.Controller.Resolvers
namespace MediaBrowser.Server.Implementations.Library.Resolvers
{
/// <summary>
/// Class LocalTrailerResolver
/// </summary>
public class LocalTrailerResolver : BaseVideoResolver<Trailer>
public class LocalTrailerResolver : VideoResolver<Trailer>
{
/// <summary>
/// Resolves the specified args.

@ -3,12 +3,12 @@ using MediaBrowser.Controller.Library;
using System;
using System.IO;
namespace MediaBrowser.Controller.Resolvers.Movies
namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
{
/// <summary>
/// Class BoxSetResolver
/// </summary>
public class BoxSetResolver : BaseFolderResolver<BoxSet>
public class BoxSetResolver : FolderResolver<BoxSet>
{
/// <summary>
/// Resolves the specified args.

@ -8,12 +8,12 @@ using System;
using System.Collections.Generic;
using System.IO;
namespace MediaBrowser.Controller.Resolvers.Movies
namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
{
/// <summary>
/// Class MovieResolver
/// </summary>
public class MovieResolver : BaseVideoResolver<Movie>
public class MovieResolver : VideoResolver<Movie>
{
/// <summary>
/// Gets the priority.
@ -87,7 +87,7 @@ namespace MediaBrowser.Controller.Resolvers.Movies
private void SetProviderIdFromPath(Movie item)
{
//we need to only look at the name of this actual item (not parents)
var justName = item.Path.Substring(item.Path.LastIndexOf(Path.DirectorySeparatorChar));
var justName = Path.GetFileName(item.Path);
var id = justName.GetAttributeValue("tmdbid");

@ -3,12 +3,12 @@ using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Entities;
using System;
namespace MediaBrowser.Controller.Resolvers.TV
namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
{
/// <summary>
/// Class EpisodeResolver
/// </summary>
public class EpisodeResolver : BaseVideoResolver<Episode>
public class EpisodeResolver : VideoResolver<Episode>
{
/// <summary>
/// Resolves the specified args.

@ -2,12 +2,12 @@
using MediaBrowser.Controller.Library;
using System;
namespace MediaBrowser.Controller.Resolvers.TV
namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
{
/// <summary>
/// Class SeasonResolver
/// </summary>
public class SeasonResolver : BaseFolderResolver<Season>
public class SeasonResolver : FolderResolver<Season>
{
/// <summary>
/// Resolves the specified args.

@ -5,12 +5,12 @@ using MediaBrowser.Model.Entities;
using System;
using System.IO;
namespace MediaBrowser.Controller.Resolvers.TV
namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
{
/// <summary>
/// Class SeriesResolver
/// </summary>
public class SeriesResolver : BaseFolderResolver<Series>
public class SeriesResolver : FolderResolver<Series>
{
/// <summary>
/// Gets the priority.
@ -76,16 +76,16 @@ namespace MediaBrowser.Controller.Resolvers.TV
Season.AddMetadataFiles(args);
SetProviderIdFromPath(item);
SetProviderIdFromPath(item, args.Path);
}
/// <summary>
/// Sets the provider id from path.
/// </summary>
/// <param name="item">The item.</param>
private void SetProviderIdFromPath(Series item)
private void SetProviderIdFromPath(Series item, string path)
{
var justName = item.Path.Substring(item.Path.LastIndexOf(Path.DirectorySeparatorChar));
var justName = Path.GetFileName(path);
var id = justName.GetAttributeValue("tvdbid");

@ -4,12 +4,12 @@ using MediaBrowser.Model.Entities;
using System;
using System.IO;
namespace MediaBrowser.Controller.Resolvers
namespace MediaBrowser.Server.Implementations.Library.Resolvers
{
/// <summary>
/// Resolves a Path into a Video
/// </summary>
public class VideoResolver : BaseVideoResolver<Video>
public class VideoResolver : VideoResolver<Video>
{
/// <summary>
/// Gets the priority.
@ -25,7 +25,7 @@ namespace MediaBrowser.Controller.Resolvers
/// Resolves a Path into a Video or Video subclass
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class BaseVideoResolver<T> : BaseItemResolver<T>
public abstract class VideoResolver<T> : ItemResolver<T>
where T : Video, new()
{
/// <summary>

@ -58,7 +58,21 @@
<Link>Properties\SharedVersion.cs</Link>
</Compile>
<Compile Include="BdInfo\BdInfoExaminer.cs" />
<Compile Include="Library\CoreResolutionIgnoreRule.cs" />
<Compile Include="Library\LibraryManager.cs" />
<Compile Include="Library\ResolverHelper.cs" />
<Compile Include="Library\Resolvers\Audio\AudioResolver.cs" />
<Compile Include="Library\Resolvers\Audio\MusicAlbumResolver.cs" />
<Compile Include="Library\Resolvers\Audio\MusicArtistResolver.cs" />
<Compile Include="Library\Resolvers\BaseItemResolver.cs" />
<Compile Include="Library\Resolvers\FolderResolver.cs" />
<Compile Include="Library\Resolvers\LocalTrailerResolver.cs" />
<Compile Include="Library\Resolvers\Movies\BoxSetResolver.cs" />
<Compile Include="Library\Resolvers\Movies\MovieResolver.cs" />
<Compile Include="Library\Resolvers\TV\EpisodeResolver.cs" />
<Compile Include="Library\Resolvers\TV\SeasonResolver.cs" />
<Compile Include="Library\Resolvers\TV\SeriesResolver.cs" />
<Compile Include="Library\Resolvers\VideoResolver.cs" />
<Compile Include="Library\UserManager.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Reflection\TypeMapper.cs" />

@ -15,7 +15,6 @@ using MediaBrowser.Common.Updates;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Controller.Updates;
using MediaBrowser.IsoMounter;
using MediaBrowser.Model.IO;
@ -27,6 +26,7 @@ using MediaBrowser.Model.Updates;
using MediaBrowser.Server.Implementations;
using MediaBrowser.Server.Implementations.BdInfo;
using MediaBrowser.Server.Implementations.Library;
using MediaBrowser.Server.Implementations.Library.Resolvers;
using MediaBrowser.ServerApplication.Implementations;
using MediaBrowser.WebDashboard.Api;
using System;
@ -147,7 +147,7 @@ namespace MediaBrowser.ServerApplication
{
base.FindParts();
Resolve<ILibraryManager>().AddParts(GetExports<IResolutionIgnoreRule>(), GetExports<IVirtualFolderCreator>(), GetExports<IBaseItemResolver>(), GetExports<IIntroProvider>());
Resolve<ILibraryManager>().AddParts(GetExports<IResolverIgnoreRule>(), GetExports<IVirtualFolderCreator>(), GetExports<IItemResolver>(), GetExports<IIntroProvider>());
Kernel.InstallationManager = (InstallationManager)CreateInstance(typeof(InstallationManager));

Loading…
Cancel
Save