diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj index bf96b22c14..f3c8cd45b6 100644 --- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj +++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj @@ -56,6 +56,7 @@ + @@ -78,10 +79,12 @@ + + @@ -94,6 +97,7 @@ + diff --git a/MediaBrowser.Providers/Movies/BoxSetProviderFromXml.cs b/MediaBrowser.Providers/Movies/BoxSetProviderFromXml.cs new file mode 100644 index 0000000000..d507f435a5 --- /dev/null +++ b/MediaBrowser.Providers/Movies/BoxSetProviderFromXml.cs @@ -0,0 +1,102 @@ +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Movies; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Logging; +using System; +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Providers.Movies +{ + /// + /// Class SeriesProviderFromXml + /// + public class BoxSetProviderFromXml : BaseMetadataProvider + { + public BoxSetProviderFromXml(ILogManager logManager, IServerConfigurationManager configurationManager) + : base(logManager, configurationManager) + { + } + + /// + /// Supportses the specified item. + /// + /// The item. + /// true if XXXX, false otherwise + public override bool Supports(BaseItem item) + { + return item is BoxSet && item.LocationType == LocationType.FileSystem; + } + + /// + /// Gets the priority. + /// + /// The priority. + public override MetadataProviderPriority Priority + { + get { return MetadataProviderPriority.First; } + } + + /// + /// 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) + { + var entry = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, "collection.xml")); + return entry != null ? entry.LastWriteTimeUtc : DateTime.MinValue; + } + + /// + /// 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 Task FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) + { + return Fetch(item, cancellationToken); + } + + /// + /// Fetches the specified item. + /// + /// The item. + /// The cancellation token. + /// true if XXXX, false otherwise + private async Task Fetch(BaseItem item, CancellationToken cancellationToken) + { + cancellationToken.ThrowIfCancellationRequested(); + + var metadataFile = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, "collection.xml")); + + if (metadataFile != null) + { + var path = metadataFile.FullName; + + await XmlParsingResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); + + try + { + new BaseItemXmlParser(Logger).Fetch((BoxSet)item, path, cancellationToken); + } + finally + { + XmlParsingResourcePool.Release(); + } + + SetLastRefreshed(item, DateTime.UtcNow); + + return true; + } + + return false; + } + } +} diff --git a/MediaBrowser.Providers/Movies/MovieDbProvider.cs b/MediaBrowser.Providers/Movies/MovieDbProvider.cs index 43eae7ca23..1ebae94186 100644 --- a/MediaBrowser.Providers/Movies/MovieDbProvider.cs +++ b/MediaBrowser.Providers/Movies/MovieDbProvider.cs @@ -228,6 +228,10 @@ namespace MediaBrowser.Providers.Movies /// true if [has alt meta] [the specified item]; otherwise, false. internal static bool HasAltMeta(BaseItem item) { + if (item is BoxSet) + { + return item.LocationType == LocationType.FileSystem && item.ResolveArgs.ContainsMetaFileByName("collection.xml"); + } return item.LocationType == LocationType.FileSystem && item.ResolveArgs.ContainsMetaFileByName(AltMetaFileName); } diff --git a/MediaBrowser.Providers/Movies/MovieProviderFromXml.cs b/MediaBrowser.Providers/Movies/MovieProviderFromXml.cs index 8c700c9449..5cf6805efc 100644 --- a/MediaBrowser.Providers/Movies/MovieProviderFromXml.cs +++ b/MediaBrowser.Providers/Movies/MovieProviderFromXml.cs @@ -37,7 +37,7 @@ namespace MediaBrowser.Providers.Movies return !trailer.IsLocalTrailer; } - return item is Movie || item is BoxSet || item is MusicVideo; + return item is Movie || item is MusicVideo; } /// @@ -101,28 +101,19 @@ namespace MediaBrowser.Providers.Movies } else { - var boxset = item as BoxSet; + var musicVideo = item as MusicVideo; - if (boxset != null) + if (musicVideo != null) { - new BaseItemXmlParser(Logger).Fetch(boxset, path, cancellationToken); + new BaseItemXmlParser(Logger).Fetch(musicVideo, path, cancellationToken); } else { - var musicVideo = item as MusicVideo; + var trailer = item as Trailer; - if (musicVideo != null) + if (trailer != null) { - new BaseItemXmlParser(Logger).Fetch(musicVideo, path, cancellationToken); - } - else - { - var trailer = item as Trailer; - - if (trailer != null) - { - new BaseItemXmlParser(Logger).Fetch(trailer, path, cancellationToken); - } + new BaseItemXmlParser(Logger).Fetch(trailer, path, cancellationToken); } } } diff --git a/MediaBrowser.Providers/Savers/BoxSetXmlSaver.cs b/MediaBrowser.Providers/Savers/BoxSetXmlSaver.cs new file mode 100644 index 0000000000..9fa38d4e51 --- /dev/null +++ b/MediaBrowser.Providers/Savers/BoxSetXmlSaver.cs @@ -0,0 +1,72 @@ +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Movies; +using MediaBrowser.Controller.Library; +using MediaBrowser.Model.Entities; +using System.IO; +using System.Text; +using System.Threading; + +namespace MediaBrowser.Providers.Savers +{ + public class BoxSetXmlSaver : IMetadataSaver + { + private readonly IServerConfigurationManager _config; + + public BoxSetXmlSaver(IServerConfigurationManager config) + { + _config = config; + } + + /// + /// Supportses the specified item. + /// + /// The item. + /// true if XXXX, false otherwise + public bool Supports(BaseItem item) + { + if (item.LocationType != LocationType.FileSystem) + { + return false; + } + + if (!_config.Configuration.SaveLocalMeta) + { + return false; + } + + return item is BoxSet; + } + + /// + /// Saves the specified item. + /// + /// The item. + /// The cancellation token. + /// Task. + public void Save(BaseItem item, CancellationToken cancellationToken) + { + var builder = new StringBuilder(); + + builder.Append(""); + + XmlSaverHelpers.AddCommonNodes(item, builder); + + builder.Append(""); + + var xmlFilePath = GetSavePath(item); + + XmlSaverHelpers.Save(builder, xmlFilePath, new string[] { }); + } + + /// + /// Gets the save path. + /// + /// The item. + /// System.String. + public string GetSavePath(BaseItem item) + { + return Path.Combine(item.Path, "collection.xml"); + } + } +} diff --git a/MediaBrowser.Providers/Savers/FolderXmlSaver.cs b/MediaBrowser.Providers/Savers/FolderXmlSaver.cs index 2c6117554b..19193d57c5 100644 --- a/MediaBrowser.Providers/Savers/FolderXmlSaver.cs +++ b/MediaBrowser.Providers/Savers/FolderXmlSaver.cs @@ -48,7 +48,7 @@ namespace MediaBrowser.Providers.Savers return false; } - return !(item is Series) && !(item is BoxSet) && !(item is MusicArtist) && !(item is MusicAlbum); + return !(item is Series) && !(item is BoxSet) && !(item is MusicArtist) && !(item is MusicAlbum) && !(item is Season); } /// diff --git a/MediaBrowser.Providers/Savers/SeasonXmlSaver.cs b/MediaBrowser.Providers/Savers/SeasonXmlSaver.cs new file mode 100644 index 0000000000..d0e19dcc5f --- /dev/null +++ b/MediaBrowser.Providers/Savers/SeasonXmlSaver.cs @@ -0,0 +1,72 @@ +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.TV; +using MediaBrowser.Controller.Library; +using MediaBrowser.Model.Entities; +using System.IO; +using System.Text; +using System.Threading; + +namespace MediaBrowser.Providers.Savers +{ + public class SeasonXmlSaver : IMetadataSaver + { + private readonly IServerConfigurationManager _config; + + public SeasonXmlSaver(IServerConfigurationManager config) + { + _config = config; + } + + /// + /// Supportses the specified item. + /// + /// The item. + /// true if XXXX, false otherwise + public bool Supports(BaseItem item) + { + if (item.LocationType != LocationType.FileSystem) + { + return false; + } + + if (!_config.Configuration.SaveLocalMeta) + { + return false; + } + + return item is Season; + } + + /// + /// Saves the specified item. + /// + /// The item. + /// The cancellation token. + /// Task. + public void Save(BaseItem item, CancellationToken cancellationToken) + { + var builder = new StringBuilder(); + + builder.Append(""); + + XmlSaverHelpers.AddCommonNodes(item, builder); + + builder.Append(""); + + var xmlFilePath = GetSavePath(item); + + XmlSaverHelpers.Save(builder, xmlFilePath, new string[] { }); + } + + /// + /// Gets the save path. + /// + /// The item. + /// System.String. + public string GetSavePath(BaseItem item) + { + return Path.Combine(item.Path, "season.xml"); + } + } +} diff --git a/MediaBrowser.Providers/TV/SeasonProviderFromXml.cs b/MediaBrowser.Providers/TV/SeasonProviderFromXml.cs new file mode 100644 index 0000000000..020c80baf6 --- /dev/null +++ b/MediaBrowser.Providers/TV/SeasonProviderFromXml.cs @@ -0,0 +1,102 @@ +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.TV; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Logging; +using System; +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Providers.TV +{ + /// + /// Class SeriesProviderFromXml + /// + public class SeasonProviderFromXml : BaseMetadataProvider + { + public SeasonProviderFromXml(ILogManager logManager, IServerConfigurationManager configurationManager) + : base(logManager, configurationManager) + { + } + + /// + /// Supportses the specified item. + /// + /// The item. + /// true if XXXX, false otherwise + public override bool Supports(BaseItem item) + { + return item is Season && item.LocationType == LocationType.FileSystem; + } + + /// + /// Gets the priority. + /// + /// The priority. + public override MetadataProviderPriority Priority + { + get { return MetadataProviderPriority.First; } + } + + /// + /// 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) + { + var entry = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, "season.xml")); + return entry != null ? entry.LastWriteTimeUtc : DateTime.MinValue; + } + + /// + /// 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 Task FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) + { + return Fetch(item, cancellationToken); + } + + /// + /// Fetches the specified item. + /// + /// The item. + /// The cancellation token. + /// true if XXXX, false otherwise + private async Task Fetch(BaseItem item, CancellationToken cancellationToken) + { + cancellationToken.ThrowIfCancellationRequested(); + + var metadataFile = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, "season.xml")); + + if (metadataFile != null) + { + var path = metadataFile.FullName; + + await XmlParsingResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); + + try + { + new BaseItemXmlParser(Logger).Fetch((Season)item, path, cancellationToken); + } + finally + { + XmlParsingResourcePool.Release(); + } + + SetLastRefreshed(item, DateTime.UtcNow); + + return true; + } + + return false; + } + } +} diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs index 2f810d2a1f..fc3906ebb4 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs @@ -29,7 +29,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies return null; } - if (filename.IndexOf("[boxset]", StringComparison.OrdinalIgnoreCase) != -1) + if (filename.IndexOf("[boxset]", StringComparison.OrdinalIgnoreCase) != -1 || args.ContainsFileSystemEntryByName("collection.xml")) { return new BoxSet(); }