diff options
| author | Luke Pulverenti <luke.pulverenti@gmail.com> | 2016-11-03 02:37:52 -0400 |
|---|---|---|
| committer | Luke Pulverenti <luke.pulverenti@gmail.com> | 2016-11-03 02:37:52 -0400 |
| commit | 3eb4091808735858b01855d298226d239be464af (patch) | |
| tree | a17a94e2c677d60471a79617218c8ef9a7a7dee3 /Emby.Server.Implementations/Library/Resolvers/TV | |
| parent | 41bef184d1036b02baec00734f3edd8abbebf5fe (diff) | |
move additional classes to new server lib
Diffstat (limited to 'Emby.Server.Implementations/Library/Resolvers/TV')
3 files changed, 388 insertions, 0 deletions
diff --git a/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs b/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs new file mode 100644 index 0000000000..2a4cc49b76 --- /dev/null +++ b/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs @@ -0,0 +1,75 @@ +using System; +using MediaBrowser.Controller.Entities.TV; +using MediaBrowser.Controller.Library; +using System.Linq; +using MediaBrowser.Model.Entities; + +namespace Emby.Server.Implementations.Library.Resolvers.TV +{ + /// <summary> + /// Class EpisodeResolver + /// </summary> + public class EpisodeResolver : BaseVideoResolver<Episode> + { + public EpisodeResolver(ILibraryManager libraryManager) : base(libraryManager) + { + } + + /// <summary> + /// Resolves the specified args. + /// </summary> + /// <param name="args">The args.</param> + /// <returns>Episode.</returns> + protected override Episode Resolve(ItemResolveArgs args) + { + var parent = args.Parent; + + if (parent == null) + { + return null; + } + + var season = parent as Season; + // Just in case the user decided to nest episodes. + // Not officially supported but in some cases we can handle it. + if (season == null) + { + season = parent.GetParents().OfType<Season>().FirstOrDefault(); + } + + // If the parent is a Season or Series, then this is an Episode if the VideoResolver returns something + // Also handle flat tv folders + if (season != null || + string.Equals(args.GetCollectionType(), CollectionType.TvShows, StringComparison.OrdinalIgnoreCase) || + args.HasParent<Series>()) + { + var episode = ResolveVideo<Episode>(args, false); + + if (episode != null) + { + var series = parent as Series; + if (series == null) + { + series = parent.GetParents().OfType<Series>().FirstOrDefault(); + } + + if (series != null) + { + episode.SeriesId = series.Id; + episode.SeriesName = series.Name; + episode.SeriesSortName = series.SortName; + } + if (season != null) + { + episode.SeasonId = season.Id; + episode.SeasonName = season.Name; + } + } + + return episode; + } + + return null; + } + } +} diff --git a/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs b/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs new file mode 100644 index 0000000000..c065feda10 --- /dev/null +++ b/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs @@ -0,0 +1,62 @@ +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Entities.TV; +using MediaBrowser.Controller.Library; +using MediaBrowser.Naming.Common; +using MediaBrowser.Naming.TV; + +namespace Emby.Server.Implementations.Library.Resolvers.TV +{ + /// <summary> + /// Class SeasonResolver + /// </summary> + public class SeasonResolver : FolderResolver<Season> + { + /// <summary> + /// The _config + /// </summary> + private readonly IServerConfigurationManager _config; + + private readonly ILibraryManager _libraryManager; + + /// <summary> + /// Initializes a new instance of the <see cref="SeasonResolver"/> class. + /// </summary> + /// <param name="config">The config.</param> + public SeasonResolver(IServerConfigurationManager config, ILibraryManager libraryManager) + { + _config = config; + _libraryManager = libraryManager; + } + + /// <summary> + /// Resolves the specified args. + /// </summary> + /// <param name="args">The args.</param> + /// <returns>Season.</returns> + protected override Season Resolve(ItemResolveArgs args) + { + if (args.Parent is Series && args.IsDirectory) + { + var namingOptions = ((LibraryManager)_libraryManager).GetNamingOptions(); + var series = ((Series)args.Parent); + + var season = new Season + { + IndexNumber = new SeasonPathParser(namingOptions, new RegexProvider()).Parse(args.Path, true, true).SeasonNumber, + SeriesId = series.Id, + SeriesSortName = series.SortName, + SeriesName = series.Name + }; + + if (season.IndexNumber.HasValue && season.IndexNumber.Value == 0) + { + season.Name = _config.Configuration.SeasonZeroDisplayName; + } + + return season; + } + + return null; + } + } +} diff --git a/Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs b/Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs new file mode 100644 index 0000000000..44eb0e3e2c --- /dev/null +++ b/Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs @@ -0,0 +1,251 @@ +using MediaBrowser.Controller.Entities.TV; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Controller.Resolvers; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Logging; +using MediaBrowser.Naming.Common; +using MediaBrowser.Naming.TV; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Emby.Server.Implementations.Logging; +using MediaBrowser.Common.IO; +using MediaBrowser.Model.IO; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.IO; +using MediaBrowser.Model.Configuration; + +namespace Emby.Server.Implementations.Library.Resolvers.TV +{ + /// <summary> + /// Class SeriesResolver + /// </summary> + public class SeriesResolver : FolderResolver<Series> + { + private readonly IFileSystem _fileSystem; + private readonly ILogger _logger; + private readonly ILibraryManager _libraryManager; + + public SeriesResolver(IFileSystem fileSystem, ILogger logger, ILibraryManager libraryManager) + { + _fileSystem = fileSystem; + _logger = logger; + _libraryManager = libraryManager; + } + + /// <summary> + /// Gets the priority. + /// </summary> + /// <value>The priority.</value> + public override ResolverPriority Priority + { + get + { + return ResolverPriority.Second; + } + } + + /// <summary> + /// Resolves the specified args. + /// </summary> + /// <param name="args">The args.</param> + /// <returns>Series.</returns> + protected override Series Resolve(ItemResolveArgs args) + { + if (args.IsDirectory) + { + if (args.HasParent<Series>() || args.HasParent<Season>()) + { + return null; + } + + var collectionType = args.GetCollectionType(); + if (string.Equals(collectionType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase)) + { + //if (args.ContainsFileSystemEntryByName("tvshow.nfo")) + //{ + // return new Series + // { + // Path = args.Path, + // Name = Path.GetFileName(args.Path) + // }; + //} + + var configuredContentType = _libraryManager.GetConfiguredContentType(args.Path); + if (!string.Equals(configuredContentType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase)) + { + return new Series + { + Path = args.Path, + Name = Path.GetFileName(args.Path) + }; + } + } + else if (string.IsNullOrWhiteSpace(collectionType)) + { + if (args.ContainsFileSystemEntryByName("tvshow.nfo")) + { + if (args.Parent.IsRoot) + { + // For now, return null, but if we want to allow this in the future then add some additional checks to guard against a misplaced tvshow.nfo + return null; + } + + return new Series + { + Path = args.Path, + Name = Path.GetFileName(args.Path) + }; + } + + if (args.Parent.IsRoot) + { + return null; + } + + if (IsSeriesFolder(args.Path, args.FileSystemChildren, args.DirectoryService, _fileSystem, _logger, _libraryManager, args.GetLibraryOptions(), false)) + { + return new Series + { + Path = args.Path, + Name = Path.GetFileName(args.Path) + }; + } + } + } + + return null; + } + + public static bool IsSeriesFolder(string path, + IEnumerable<FileSystemMetadata> fileSystemChildren, + IDirectoryService directoryService, + IFileSystem fileSystem, + ILogger logger, + ILibraryManager libraryManager, + LibraryOptions libraryOptions, + bool isTvContentType) + { + foreach (var child in fileSystemChildren) + { + //if ((attributes & FileAttributes.Hidden) == FileAttributes.Hidden) + //{ + // //logger.Debug("Igoring series file or folder marked hidden: {0}", child.FullName); + // continue; + //} + + // Can't enforce this because files saved by Bitcasa are always marked System + //if ((attributes & FileAttributes.System) == FileAttributes.System) + //{ + // logger.Debug("Igoring series subfolder marked system: {0}", child.FullName); + // continue; + //} + + if (child.IsDirectory) + { + if (IsSeasonFolder(child.FullName, isTvContentType, libraryManager)) + { + //logger.Debug("{0} is a series because of season folder {1}.", path, child.FullName); + return true; + } + } + else + { + string fullName = child.FullName; + if (libraryManager.IsVideoFile(fullName, libraryOptions)) + { + if (isTvContentType) + { + return true; + } + + var namingOptions = ((LibraryManager)libraryManager).GetNamingOptions(); + + // In mixed folders we need to be conservative and avoid expressions that may result in false positives (e.g. movies with numbers in the title) + if (!isTvContentType) + { + namingOptions.EpisodeExpressions = namingOptions.EpisodeExpressions + .Where(i => i.IsNamed && !i.IsOptimistic) + .ToList(); + } + + var episodeResolver = new MediaBrowser.Naming.TV.EpisodeResolver(namingOptions, new PatternsLogger()); + var episodeInfo = episodeResolver.Resolve(fullName, false, false); + if (episodeInfo != null && episodeInfo.EpisodeNumber.HasValue) + { + return true; + } + } + } + } + + logger.Debug("{0} is not a series folder.", path); + return false; + } + + /// <summary> + /// Determines whether [is place holder] [the specified path]. + /// </summary> + /// <param name="path">The path.</param> + /// <returns><c>true</c> if [is place holder] [the specified path]; otherwise, <c>false</c>.</returns> + /// <exception cref="System.ArgumentNullException">path</exception> + private static bool IsVideoPlaceHolder(string path) + { + if (string.IsNullOrEmpty(path)) + { + throw new ArgumentNullException("path"); + } + + var extension = Path.GetExtension(path); + + return string.Equals(extension, ".disc", StringComparison.OrdinalIgnoreCase); + } + + /// <summary> + /// Determines whether [is season folder] [the specified path]. + /// </summary> + /// <param name="path">The path.</param> + /// <param name="isTvContentType">if set to <c>true</c> [is tv content type].</param> + /// <param name="libraryManager">The library manager.</param> + /// <returns><c>true</c> if [is season folder] [the specified path]; otherwise, <c>false</c>.</returns> + private static bool IsSeasonFolder(string path, bool isTvContentType, ILibraryManager libraryManager) + { + var namingOptions = ((LibraryManager)libraryManager).GetNamingOptions(); + + var seasonNumber = new SeasonPathParser(namingOptions, new RegexProvider()).Parse(path, isTvContentType, isTvContentType).SeasonNumber; + + return seasonNumber.HasValue; + } + + /// <summary> + /// Sets the initial item values. + /// </summary> + /// <param name="item">The item.</param> + /// <param name="args">The args.</param> + protected override void SetInitialItemValues(Series item, ItemResolveArgs args) + { + base.SetInitialItemValues(item, args); + + SetProviderIdFromPath(item, args.Path); + } + + /// <summary> + /// Sets the provider id from path. + /// </summary> + /// <param name="item">The item.</param> + /// <param name="path">The path.</param> + private void SetProviderIdFromPath(Series item, string path) + { + var justName = Path.GetFileName(path); + + var id = justName.GetAttributeValue("tvdbid"); + + if (!string.IsNullOrEmpty(id)) + { + item.SetProviderId(MetadataProviders.Tvdb, id); + } + } + } +} |
