From 9e0c1340fc3ad4b41e3c349b98ea71b708ade95a Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 2 Feb 2014 08:36:31 -0500 Subject: [PATCH] convert games to new providers --- MediaBrowser.Api/ConfigurationService.cs | 110 ++++++++++++ MediaBrowser.Api/MediaBrowser.Api.csproj | 1 + .../BaseProgressiveStreamingService.cs | 2 +- MediaBrowser.Api/SystemService.cs | 88 +-------- MediaBrowser.Controller/Entities/BaseItem.cs | 85 --------- .../Entities/IHasImages.cs | 7 - .../Entities/IHasScreenshots.cs | 7 - .../Library/ILibraryManager.cs | 12 +- .../Library/IMetadataSaver.cs | 14 +- .../MediaBrowser.Controller.csproj | 1 + .../Providers/ICustomMetadataProvider.cs | 15 ++ .../Providers/IHasMetadata.cs | 6 + .../Providers/IMetadataService.cs | 13 +- .../Providers/IProviderManager.cs | 19 +- MediaBrowser.Controller/Providers/ItemId.cs | 18 ++ .../MediaBrowser.Model.Portable.csproj | 12 +- .../MediaBrowser.Model.net35.csproj | 12 +- .../Configuration/AutoOrganize.cs | 36 ++++ .../Configuration/ImageDownloadOptions.cs | 81 --------- .../Configuration/MetadataOptions.cs | 89 ++++++++++ .../Configuration/MetadataPlugin.cs | 60 +++++++ .../Configuration/ServerConfiguration.cs | 99 ++--------- MediaBrowser.Model/MediaBrowser.Model.csproj | 4 +- MediaBrowser.Providers/BaseXmlProvider.cs | 8 +- .../BoxSets/BoxSetMetadataService.cs | 12 +- .../BoxSets/BoxSetXmlProvider.cs | 8 +- .../GameGenres/GameGenreImageProvider.cs | 2 +- .../GameGenres/GameGenreMetadataService.cs | 11 +- .../Games/GameMetadataService.cs | 59 ++++++ .../Games/GameProviderFromXml.cs | 93 ---------- .../Games/GameSystemMetadataService.cs | 59 ++++++ .../Games/GameSystemProviderFromXml.cs | 92 ---------- .../Games/GameSystemXmlParser.cs | 63 +++++++ .../Games/GameSystemXmlProvider.cs | 59 ++++++ MediaBrowser.Providers/Games/GameXmlParser.cs | 10 +- .../Games/GameXmlProvider.cs | 74 ++++++++ .../Genres/GenreImageProvider.cs | 2 +- .../Genres/GenreMetadataService.cs | 11 +- .../LiveTv/ChannelMetadataService.cs | 11 +- .../LiveTv/ChannelXmlProvider.cs | 8 +- .../LiveTv/ProgramMetadataService.cs | 11 +- .../Manager/ConcreteMetadataService.cs | 21 --- MediaBrowser.Providers/Manager/ImageSaver.cs | 9 - .../Manager/ItemImageProvider.cs | 91 ++++------ .../Manager/MetadataService.cs | 84 ++++++--- .../Manager/ProviderManager.cs | 168 +++++++++++++++++- .../MediaBrowser.Providers.csproj | 8 +- .../Movies/FanArtMovieProvider.cs | 20 ++- .../Movies/MovieDbImagesProvider.cs | 28 +-- .../Movies/MovieDbProvider.cs | 2 +- .../Movies/MovieProviderFromXml.cs | 8 +- .../Music/AlbumMetadataService.cs | 10 +- .../Music/AlbumXmlProvider.cs | 8 +- .../Music/ArtistMetadataService.cs | 10 +- .../Music/ArtistXmlProvider.cs | 8 +- .../MusicGenres/MusicGenreImageProvider.cs | 2 +- .../MusicGenres/MusicGenreMetadataService.cs | 10 +- .../People/PersonMetadataService.cs | 11 +- .../People/PersonXmlProvider.cs | 8 +- .../Savers/AlbumXmlSaver.cs | 20 ++- .../Savers/ArtistXmlSaver.cs | 17 +- .../Savers/BoxSetXmlSaver.cs | 17 +- .../Savers/ChannelXmlSaver.cs | 22 ++- .../Savers/EpisodeXmlSaver.cs | 18 +- .../Savers/FolderXmlSaver.cs | 24 ++- .../Savers/GameSystemXmlSaver.cs | 27 ++- MediaBrowser.Providers/Savers/GameXmlSaver.cs | 23 ++- .../Savers/MovieXmlSaver.cs | 37 ++-- .../Savers/PersonXmlSaver.cs | 23 ++- .../Savers/SeasonXmlSaver.cs | 18 +- .../Savers/SeriesXmlSaver.cs | 22 ++- .../Studios/StudioMetadataService.cs | 11 +- .../Studios/StudiosImageProvider.cs | 2 +- .../TV/FanArtSeasonProvider.cs | 5 +- MediaBrowser.Providers/TV/FanArtTVProvider.cs | 17 +- .../TV/TvdbSeasonProvider.cs | 19 +- .../TV/TvdbSeriesImageProvider.cs | 18 +- .../Users/UserMetadataService.cs | 12 +- .../Library/LibraryManager.cs | 58 +----- .../ApplicationHost.cs | 8 +- Nuget/MediaBrowser.Common.Internal.nuspec | 4 +- Nuget/MediaBrowser.Common.nuspec | 2 +- Nuget/MediaBrowser.Server.Core.nuspec | 4 +- 83 files changed, 1353 insertions(+), 965 deletions(-) create mode 100644 MediaBrowser.Api/ConfigurationService.cs create mode 100644 MediaBrowser.Controller/Providers/ICustomMetadataProvider.cs create mode 100644 MediaBrowser.Model/Configuration/AutoOrganize.cs delete mode 100644 MediaBrowser.Model/Configuration/ImageDownloadOptions.cs create mode 100644 MediaBrowser.Model/Configuration/MetadataOptions.cs create mode 100644 MediaBrowser.Model/Configuration/MetadataPlugin.cs create mode 100644 MediaBrowser.Providers/Games/GameMetadataService.cs delete mode 100644 MediaBrowser.Providers/Games/GameProviderFromXml.cs create mode 100644 MediaBrowser.Providers/Games/GameSystemMetadataService.cs delete mode 100644 MediaBrowser.Providers/Games/GameSystemProviderFromXml.cs create mode 100644 MediaBrowser.Providers/Games/GameSystemXmlParser.cs create mode 100644 MediaBrowser.Providers/Games/GameSystemXmlProvider.cs create mode 100644 MediaBrowser.Providers/Games/GameXmlProvider.cs delete mode 100644 MediaBrowser.Providers/Manager/ConcreteMetadataService.cs diff --git a/MediaBrowser.Api/ConfigurationService.cs b/MediaBrowser.Api/ConfigurationService.cs new file mode 100644 index 0000000000..206d0c265f --- /dev/null +++ b/MediaBrowser.Api/ConfigurationService.cs @@ -0,0 +1,110 @@ +using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.IO; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Configuration; +using MediaBrowser.Model.Serialization; +using ServiceStack; +using System.Collections.Generic; +using System.Linq; + +namespace MediaBrowser.Api +{ + /// + /// Class GetConfiguration + /// + [Route("/System/Configuration", "GET")] + [Api(("Gets application configuration"))] + public class GetConfiguration : IReturn + { + + } + + /// + /// Class UpdateConfiguration + /// + [Route("/System/Configuration", "POST")] + [Api(("Updates application configuration"))] + public class UpdateConfiguration : ServerConfiguration, IReturnVoid + { + } + + [Route("/System/Configuration/MetadataOptions/Default", "GET")] + [Api(("Gets a default MetadataOptions object"))] + public class GetDefaultMetadataOptions : IReturn + { + + } + + [Route("/System/Configuration/MetadataPlugins", "GET")] + [Api(("Gets all available metadata plugins"))] + public class GetMetadataPlugins : IReturn> + { + + } + + public class ConfigurationService : BaseApiService + { + /// + /// The _json serializer + /// + private readonly IJsonSerializer _jsonSerializer; + + /// + /// The _configuration manager + /// + private readonly IServerConfigurationManager _configurationManager; + + private readonly IFileSystem _fileSystem; + private readonly IProviderManager _providerManager; + + public ConfigurationService(IJsonSerializer jsonSerializer, IServerConfigurationManager configurationManager, IFileSystem fileSystem, IProviderManager providerManager) + { + _jsonSerializer = jsonSerializer; + _configurationManager = configurationManager; + _fileSystem = fileSystem; + _providerManager = providerManager; + } + + /// + /// Gets the specified request. + /// + /// The request. + /// System.Object. + public object Get(GetConfiguration request) + { + var configPath = _configurationManager.ApplicationPaths.SystemConfigurationFilePath; + + var dateModified = _fileSystem.GetLastWriteTimeUtc(configPath); + + var cacheKey = (configPath + dateModified.Ticks).GetMD5(); + + return ToOptimizedResultUsingCache(cacheKey, dateModified, null, () => _configurationManager.Configuration); + } + + /// + /// Posts the specified configuraiton. + /// + /// The request. + public void Post(UpdateConfiguration request) + { + // Silly, but we need to serialize and deserialize or the XmlSerializer will write the xml with an element name of UpdateConfiguration + + var json = _jsonSerializer.SerializeToString(request); + + var config = _jsonSerializer.DeserializeFromString(json); + + _configurationManager.ReplaceConfiguration(config); + } + + public object Get(GetDefaultMetadataOptions request) + { + return ToOptimizedResult(new MetadataOptions()); + } + + public object Get(GetMetadataPlugins request) + { + return ToOptimizedResult(_providerManager.GetAllMetadataPlugins().ToList()); + } + } +} diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj index f4b68810b8..e105b41ce5 100644 --- a/MediaBrowser.Api/MediaBrowser.Api.csproj +++ b/MediaBrowser.Api/MediaBrowser.Api.csproj @@ -72,6 +72,7 @@ + diff --git a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs index 9c5acb7a02..c975d7e31a 100644 --- a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs +++ b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs @@ -161,7 +161,7 @@ namespace MediaBrowser.Api.Playback.Progressive if (!string.IsNullOrEmpty(contentFeatures)) { - responseHeaders["ContentFeatures.DLNA.ORG"] = (contentFeatures + orgOp + orgCi + dlnaflags).Trim(';'); + responseHeaders["contentFeatures.dlna.org"] = (contentFeatures + orgOp + orgCi + dlnaflags).Trim(';'); } foreach (var item in responseHeaders) diff --git a/MediaBrowser.Api/SystemService.cs b/MediaBrowser.Api/SystemService.cs index 23d64e89b5..9f5f3716ec 100644 --- a/MediaBrowser.Api/SystemService.cs +++ b/MediaBrowser.Api/SystemService.cs @@ -1,14 +1,6 @@ -using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.IO; -using MediaBrowser.Controller; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.IO; -using MediaBrowser.Model.Configuration; -using MediaBrowser.Model.Serialization; +using MediaBrowser.Controller; using MediaBrowser.Model.System; using ServiceStack; -using System; -using System.IO; using System.Threading.Tasks; namespace MediaBrowser.Api @@ -38,71 +30,25 @@ namespace MediaBrowser.Api { } - /// - /// Class GetConfiguration - /// - [Route("/System/Configuration", "GET")] - [Api(("Gets application configuration"))] - public class GetConfiguration : IReturn - { - - } - - /// - /// Class UpdateConfiguration - /// - [Route("/System/Configuration", "POST")] - [Api(("Updates application configuration"))] - public class UpdateConfiguration : ServerConfiguration, IReturnVoid - { - } - /// /// Class SystemInfoService /// public class SystemService : BaseApiService { - /// - /// The _json serializer - /// - private readonly IJsonSerializer _jsonSerializer; - /// /// The _app host /// private readonly IServerApplicationHost _appHost; - /// - /// The _configuration manager - /// - private readonly IServerConfigurationManager _configurationManager; - - private readonly IFileSystem _fileSystem; - /// /// Initializes a new instance of the class. /// - /// The json serializer. /// The app host. - /// The configuration manager. /// jsonSerializer - public SystemService(IJsonSerializer jsonSerializer, IServerApplicationHost appHost, IServerConfigurationManager configurationManager, IFileSystem fileSystem) - : base() + public SystemService(IServerApplicationHost appHost) { - if (jsonSerializer == null) - { - throw new ArgumentNullException("jsonSerializer"); - } - if (appHost == null) - { - throw new ArgumentNullException("appHost"); - } - _appHost = appHost; - _configurationManager = configurationManager; - _fileSystem = fileSystem; - _jsonSerializer = jsonSerializer; } /// @@ -117,22 +63,6 @@ namespace MediaBrowser.Api return ToOptimizedResult(result); } - /// - /// Gets the specified request. - /// - /// The request. - /// System.Object. - public object Get(GetConfiguration request) - { - var configPath = _configurationManager.ApplicationPaths.SystemConfigurationFilePath; - - var dateModified = _fileSystem.GetLastWriteTimeUtc(configPath); - - var cacheKey = (configPath + dateModified.Ticks).GetMD5(); - - return ToOptimizedResultUsingCache(cacheKey, dateModified, null, () => _configurationManager.Configuration); - } - /// /// Posts the specified request. /// @@ -159,19 +89,5 @@ namespace MediaBrowser.Api }); } - /// - /// Posts the specified configuraiton. - /// - /// The request. - public void Post(UpdateConfiguration request) - { - // Silly, but we need to serialize and deserialize or the XmlSerializer will write the xml with an element name of UpdateConfiguration - - var json = _jsonSerializer.SerializeToString(request); - - var config = _jsonSerializer.DeserializeFromString(json); - - _configurationManager.ReplaceConfiguration(config); - } } } diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index f12532204f..d9579d79f8 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -34,7 +34,6 @@ namespace MediaBrowser.Controller.Entities Images = new Dictionary(); ProviderIds = new Dictionary(StringComparer.OrdinalIgnoreCase); LockedFields = new List(); - ImageSources = new List(); } /// @@ -474,12 +473,6 @@ namespace MediaBrowser.Controller.Entities /// The backdrop image paths. public List BackdropImagePaths { get; set; } - /// - /// Gets or sets the backdrop image sources. - /// - /// The backdrop image sources. - public List ImageSources { get; set; } - /// /// Gets or sets the official rating. /// @@ -1458,8 +1451,6 @@ namespace MediaBrowser.Controller.Entities BackdropImagePaths.Remove(file); - RemoveImageSourceForPath(file); - // Delete the source file DeleteImagePath(file); } @@ -1567,88 +1558,12 @@ namespace MediaBrowser.Controller.Entities { BackdropImagePaths.Remove(path); - RemoveImageSourceForPath(path); - changed = true; } return changed; } - /// - /// Adds the image source. - /// - /// The path. - /// The URL. - public void AddImageSource(string path, string url) - { - RemoveImageSourceForPath(path); - - var pathMd5 = path.ToLower().GetMD5(); - - ImageSources.Add(new ImageSourceInfo - { - ImagePathMD5 = pathMd5, - ImageUrlMD5 = url.ToLower().GetMD5() - }); - } - - /// - /// Gets the image source info. - /// - /// The path. - /// ImageSourceInfo. - public ImageSourceInfo GetImageSourceInfo(string path) - { - if (ImageSources.Count == 0) - { - return null; - } - - var pathMd5 = path.ToLower().GetMD5(); - - return ImageSources.FirstOrDefault(i => i.ImagePathMD5 == pathMd5); - } - - /// - /// Removes the image source for path. - /// - /// The path. - public void RemoveImageSourceForPath(string path) - { - if (ImageSources.Count == 0) - { - return; - } - - var pathMd5 = path.ToLower().GetMD5(); - - // Remove existing - foreach (var entry in ImageSources - .Where(i => i.ImagePathMD5 == pathMd5) - .ToList()) - { - ImageSources.Remove(entry); - } - } - - /// - /// Determines whether [contains image with source URL] [the specified URL]. - /// - /// The URL. - /// true if [contains image with source URL] [the specified URL]; otherwise, false. - public bool ContainsImageWithSourceUrl(string url) - { - if (ImageSources.Count == 0) - { - return false; - } - - var md5 = url.ToLower().GetMD5(); - - return ImageSources.Any(i => i.ImageUrlMD5 == md5); - } - /// /// Validates the screenshots. /// diff --git a/MediaBrowser.Controller/Entities/IHasImages.cs b/MediaBrowser.Controller/Entities/IHasImages.cs index 18e6afcd18..1aa299c2af 100644 --- a/MediaBrowser.Controller/Entities/IHasImages.cs +++ b/MediaBrowser.Controller/Entities/IHasImages.cs @@ -99,13 +99,6 @@ namespace MediaBrowser.Controller.Entities /// /// The backdrop image paths. List BackdropImagePaths { get; set; } - - /// - /// Determines whether [contains image with source URL] [the specified URL]. - /// - /// The URL. - /// true if [contains image with source URL] [the specified URL]; otherwise, false. - bool ContainsImageWithSourceUrl(string url); } public static class HasImagesExtensions diff --git a/MediaBrowser.Controller/Entities/IHasScreenshots.cs b/MediaBrowser.Controller/Entities/IHasScreenshots.cs index 70d154a958..341d6403f2 100644 --- a/MediaBrowser.Controller/Entities/IHasScreenshots.cs +++ b/MediaBrowser.Controller/Entities/IHasScreenshots.cs @@ -12,12 +12,5 @@ namespace MediaBrowser.Controller.Entities /// /// The screenshot image paths. List ScreenshotImagePaths { get; set; } - - /// - /// Determines whether [contains image with source URL] [the specified URL]. - /// - /// The URL. - /// true if [contains image with source URL] [the specified URL]; otherwise, false. - bool ContainsImageWithSourceUrl(string url); } } diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index c3a87fc317..d8ba019db3 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -165,7 +165,6 @@ namespace MediaBrowser.Controller.Library /// The prescan tasks. /// The postscan tasks. /// The people prescan tasks. - /// The savers. void AddParts(IEnumerable rules, IEnumerable pluginFolders, IEnumerable resolvers, @@ -173,8 +172,7 @@ namespace MediaBrowser.Controller.Library IEnumerable itemComparers, IEnumerable prescanTasks, IEnumerable postscanTasks, - IEnumerable peoplePrescanTasks, - IEnumerable savers); + IEnumerable peoplePrescanTasks); /// /// Sorts the specified items. @@ -300,14 +298,6 @@ namespace MediaBrowser.Controller.Library /// System.String. string FindCollectionType(BaseItem item); - /// - /// Saves the metadata. - /// - /// The item. - /// Type of the update. - /// Task. - Task SaveMetadata(BaseItem item, ItemUpdateType updateType); - /// /// Gets all artists. /// diff --git a/MediaBrowser.Controller/Library/IMetadataSaver.cs b/MediaBrowser.Controller/Library/IMetadataSaver.cs index 15671af4da..0c75e7edcf 100644 --- a/MediaBrowser.Controller/Library/IMetadataSaver.cs +++ b/MediaBrowser.Controller/Library/IMetadataSaver.cs @@ -1,4 +1,4 @@ -using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Providers; using System.Threading; namespace MediaBrowser.Controller.Library @@ -8,20 +8,26 @@ namespace MediaBrowser.Controller.Library /// public interface IMetadataSaver { + /// + /// Gets the name. + /// + /// The name. + string Name { get; } + /// /// Determines whether [is enabled for] [the specified item]. /// /// The item. /// Type of the update. /// true if [is enabled for] [the specified item]; otherwise, false. - bool IsEnabledFor(BaseItem item, ItemUpdateType updateType); + bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType); /// /// Gets the save path. /// /// The item. /// System.String. - string GetSavePath(BaseItem item); + string GetSavePath(IHasMetadata item); /// /// Saves the specified item. @@ -29,6 +35,6 @@ namespace MediaBrowser.Controller.Library /// The item. /// The cancellation token. /// Task. - void Save(BaseItem item, CancellationToken cancellationToken); + void Save(IHasMetadata item, CancellationToken cancellationToken); } } diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index b05f14a13d..6b42285240 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -143,6 +143,7 @@ + diff --git a/MediaBrowser.Controller/Providers/ICustomMetadataProvider.cs b/MediaBrowser.Controller/Providers/ICustomMetadataProvider.cs new file mode 100644 index 0000000000..a53222b5a1 --- /dev/null +++ b/MediaBrowser.Controller/Providers/ICustomMetadataProvider.cs @@ -0,0 +1,15 @@ +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Controller.Providers +{ + public interface ICustomMetadataProvider : IMetadataProvider + { + } + + public interface ICustomMetadataProvider : IMetadataProvider, ICustomMetadataProvider + where TItemType : IHasMetadata + { + Task FetchAsync(TItemType item, CancellationToken cancellationToken); + } +} diff --git a/MediaBrowser.Controller/Providers/IHasMetadata.cs b/MediaBrowser.Controller/Providers/IHasMetadata.cs index 4ee54f69ed..1e2a76b792 100644 --- a/MediaBrowser.Controller/Providers/IHasMetadata.cs +++ b/MediaBrowser.Controller/Providers/IHasMetadata.cs @@ -27,5 +27,11 @@ namespace MediaBrowser.Controller.Providers /// /// The date last saved. DateTime DateLastSaved { get; set; } + + /// + /// Determines whether [is save local metadata enabled]. + /// + /// true if [is save local metadata enabled]; otherwise, false. + bool IsSaveLocalMetadataEnabled(); } } diff --git a/MediaBrowser.Controller/Providers/IMetadataService.cs b/MediaBrowser.Controller/Providers/IMetadataService.cs index e9ce320ab4..c4314c15fd 100644 --- a/MediaBrowser.Controller/Providers/IMetadataService.cs +++ b/MediaBrowser.Controller/Providers/IMetadataService.cs @@ -1,17 +1,10 @@ -using System.Collections.Generic; -using System.Threading; +using System.Threading; using System.Threading.Tasks; namespace MediaBrowser.Controller.Providers { public interface IMetadataService { - /// - /// Adds the parts. - /// - /// The providers. - void AddParts(IEnumerable providers); - /// /// Determines whether this instance can refresh the specified item. /// @@ -23,10 +16,10 @@ namespace MediaBrowser.Controller.Providers /// Refreshes the metadata. /// /// The item. - /// The options. + /// The options. /// The cancellation token. /// Task. - Task RefreshMetadata(IHasMetadata item, MetadataRefreshOptions options, CancellationToken cancellationToken); + Task RefreshMetadata(IHasMetadata item, MetadataRefreshOptions refreshOptions, CancellationToken cancellationToken); /// /// Gets the order. diff --git a/MediaBrowser.Controller/Providers/IProviderManager.cs b/MediaBrowser.Controller/Providers/IProviderManager.cs index 0159f778ff..0e4f70c065 100644 --- a/MediaBrowser.Controller/Providers/IProviderManager.cs +++ b/MediaBrowser.Controller/Providers/IProviderManager.cs @@ -1,5 +1,6 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; +using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Providers; using System.Collections.Generic; @@ -64,7 +65,9 @@ namespace MediaBrowser.Controller.Providers /// The image providers. /// The metadata services. /// The metadata providers. - void AddParts(IEnumerable providers, IEnumerable imageProviders, IEnumerable metadataServices, IEnumerable metadataProviders); + /// The savers. + void AddParts(IEnumerable providers, IEnumerable imageProviders, IEnumerable metadataServices, IEnumerable metadataProviders, + IEnumerable savers); /// /// Gets the available remote images. @@ -82,5 +85,19 @@ namespace MediaBrowser.Controller.Providers /// The item. /// IEnumerable{ImageProviderInfo}. IEnumerable GetImageProviderInfo(IHasImages item); + + /// + /// Gets all metadata plugins. + /// + /// IEnumerable{MetadataPlugin}. + IEnumerable GetAllMetadataPlugins(); + + /// + /// Saves the metadata. + /// + /// The item. + /// Type of the update. + /// Task. + Task SaveMetadata(IHasMetadata item, ItemUpdateType updateType); } } \ No newline at end of file diff --git a/MediaBrowser.Controller/Providers/ItemId.cs b/MediaBrowser.Controller/Providers/ItemId.cs index 3abb64bfb2..3dbaa78fa3 100644 --- a/MediaBrowser.Controller/Providers/ItemId.cs +++ b/MediaBrowser.Controller/Providers/ItemId.cs @@ -51,4 +51,22 @@ namespace MediaBrowser.Controller.Providers /// The artist music brainz identifier. public string ArtistMusicBrainzId { get; set; } } + + public class GameId : ItemId + { + /// + /// Gets or sets the game system. + /// + /// The game system. + public string GameSystem { get; set; } + } + + public class GameSystemId : ItemId + { + /// + /// Gets or sets the path. + /// + /// The path. + public string Path { get; set; } + } } diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj index 04f95c4ffd..d95c27efdc 100644 --- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj +++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj @@ -74,15 +74,21 @@ ApiClient\ServerEventArgs.cs + + Configuration\AutoOrganize.cs + Configuration\BaseApplicationConfiguration.cs - - Configuration\ImageDownloadOptions.cs - Configuration\ManualLoginCategory.cs + + Configuration\MetadataOptions.cs + + + Configuration\MetadataPlugin.cs + Configuration\ServerConfiguration.cs diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj index bd411cce1c..93d52e9c05 100644 --- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj +++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj @@ -61,15 +61,21 @@ ApiClient\ServerEventArgs.cs + + Configuration\AutoOrganize.cs + Configuration\BaseApplicationConfiguration.cs - - Configuration\ImageDownloadOptions.cs - Configuration\ManualLoginCategory.cs + + Configuration\MetadataOptions.cs + + + Configuration\MetadataPlugin.cs + Configuration\ServerConfiguration.cs diff --git a/MediaBrowser.Model/Configuration/AutoOrganize.cs b/MediaBrowser.Model/Configuration/AutoOrganize.cs new file mode 100644 index 0000000000..a30aa36d8b --- /dev/null +++ b/MediaBrowser.Model/Configuration/AutoOrganize.cs @@ -0,0 +1,36 @@ + +namespace MediaBrowser.Model.Configuration +{ + public class TvFileOrganizationOptions + { + public bool IsEnabled { get; set; } + public int MinFileSizeMb { get; set; } + public string[] LeftOverFileExtensionsToDelete { get; set; } + public string[] WatchLocations { get; set; } + + public string SeasonFolderPattern { get; set; } + + public string SeasonZeroFolderName { get; set; } + + public string EpisodeNamePattern { get; set; } + public string MultiEpisodeNamePattern { get; set; } + + public bool OverwriteExistingEpisodes { get; set; } + + public bool DeleteEmptyFolders { get; set; } + + public TvFileOrganizationOptions() + { + MinFileSizeMb = 50; + + LeftOverFileExtensionsToDelete = new string[] { }; + + WatchLocations = new string[] { }; + + EpisodeNamePattern = "%sn - %sx%0e - %en.%ext"; + MultiEpisodeNamePattern = "%sn - %sx%0e-x%0ed - %en.%ext"; + SeasonFolderPattern = "Season %s"; + SeasonZeroFolderName = "Season 0"; + } + } +} diff --git a/MediaBrowser.Model/Configuration/ImageDownloadOptions.cs b/MediaBrowser.Model/Configuration/ImageDownloadOptions.cs deleted file mode 100644 index 6031121100..0000000000 --- a/MediaBrowser.Model/Configuration/ImageDownloadOptions.cs +++ /dev/null @@ -1,81 +0,0 @@ - -namespace MediaBrowser.Model.Configuration -{ - /// - /// Class ImageDownloadOptions - /// - public class ImageDownloadOptions - { - /// - /// Download Art Image - /// - /// true if art; otherwise, false. - public bool Art { get; set; } - - /// - /// Download Logo Image - /// - /// true if logo; otherwise, false. - public bool Logo { get; set; } - - /// - /// Download Primary Image - /// - /// true if primary; otherwise, false. - public bool Primary { get; set; } - - /// - /// Download Backdrop Images - /// - /// true if backdrops; otherwise, false. - public bool Backdrops { get; set; } - - /// - /// Download Disc Image - /// - /// true if disc; otherwise, false. - public bool Disc { get; set; } - - /// - /// Download Thumb Image - /// - /// true if thumb; otherwise, false. - public bool Thumb { get; set; } - - /// - /// Download Banner Image - /// - /// true if banner; otherwise, false. - public bool Banner { get; set; } - - /// - /// Initializes a new instance of the class. - /// - public ImageDownloadOptions() - { - Art = true; - Logo = true; - Primary = true; - Backdrops = true; - Disc = true; - Thumb = true; - Banner = true; - } - } - - /// - /// Class MetadataOptions. - /// - public class MetadataOptions - { - public int MaxBackdrops { get; set; } - - public int MinBackdropWidth { get; set; } - - public MetadataOptions() - { - MaxBackdrops = 3; - MinBackdropWidth = 1280; - } - } -} diff --git a/MediaBrowser.Model/Configuration/MetadataOptions.cs b/MediaBrowser.Model/Configuration/MetadataOptions.cs new file mode 100644 index 0000000000..f914a2d21b --- /dev/null +++ b/MediaBrowser.Model/Configuration/MetadataOptions.cs @@ -0,0 +1,89 @@ +using MediaBrowser.Model.Entities; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace MediaBrowser.Model.Configuration +{ + /// + /// Class MetadataOptions. + /// + public class MetadataOptions + { + public string ItemType { get; set; } + + public ImageOption[] ImageOptions { get; set; } + + public string[] DisabledMetadataSavers { get; set; } + + public MetadataOptions() + : this(3, 1280) + { + } + + public MetadataOptions(int backdropLimit, int minBackdropWidth) + { + var imageOptions = new List + { + new ImageOption + { + Limit = backdropLimit, + MinWidth = minBackdropWidth, + Type = ImageType.Backdrop + } + }; + + ImageOptions = imageOptions.ToArray(); + DisabledMetadataSavers = new string[] { }; + } + + public int GetLimit(ImageType type) + { + var option = ImageOptions.FirstOrDefault(i => i.Type == type); + + return option == null ? 1 : option.Limit; + } + + public int GetMinWidth(ImageType type) + { + var option = ImageOptions.FirstOrDefault(i => i.Type == type); + + return option == null ? 0 : option.MinWidth; + } + + public bool IsEnabled(ImageType type) + { + return GetLimit(type) > 0; + } + + public bool IsMetadataSaverEnabled(string name) + { + return !DisabledMetadataSavers.Contains(name, StringComparer.OrdinalIgnoreCase); + } + } + + public class ImageOption + { + /// + /// Gets or sets the type. + /// + /// The type. + public ImageType Type { get; set; } + /// + /// Gets or sets the limit. + /// + /// The limit. + public int Limit { get; set; } + + /// + /// Gets or sets the minimum width. + /// + /// The minimum width. + public int MinWidth { get; set; } + + public ImageOption() + { + Limit = 1; + } + } +} diff --git a/MediaBrowser.Model/Configuration/MetadataPlugin.cs b/MediaBrowser.Model/Configuration/MetadataPlugin.cs new file mode 100644 index 0000000000..b019cf71a1 --- /dev/null +++ b/MediaBrowser.Model/Configuration/MetadataPlugin.cs @@ -0,0 +1,60 @@ +using MediaBrowser.Model.Entities; +using System.Collections.Generic; + +namespace MediaBrowser.Model.Configuration +{ + public class MetadataPlugin + { + /// + /// Gets or sets the name. + /// + /// The name. + public string Name { get; set; } + + /// + /// Gets or sets the type. + /// + /// The type. + public MetadataPluginType Type { get; set; } + } + + public class MetadataPluginSummary + { + /// + /// Gets or sets the type of the item. + /// + /// The type of the item. + public string ItemType { get; set; } + + /// + /// Gets or sets the plugins. + /// + /// The plugins. + public List Plugins { get; set; } + + /// + /// Gets or sets the supported image types. + /// + /// The supported image types. + public List SupportedImageTypes { get; set; } + + public MetadataPluginSummary() + { + SupportedImageTypes = new List(); + Plugins = new List(); + } + } + + /// + /// Enum MetadataPluginType + /// + public enum MetadataPluginType + { + LocalImageProvider, + ImageFetcher, + ImageSaver, + LocalMetadataProvider, + MetadataFetcher, + MetadataSaver + } +} diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 716be54d25..f874bdbb25 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using MediaBrowser.Model.Weather; using System; @@ -87,31 +88,6 @@ namespace MediaBrowser.Model.Configuration /// The metadata country code. public string MetadataCountryCode { get; set; } - /// - /// Options for specific art to download for movies. - /// - public ImageDownloadOptions DownloadMovieImages { get; set; } - - /// - /// Options for specific art to download for Series. - /// - public ImageDownloadOptions DownloadSeriesImages { get; set; } - - /// - /// Options for specific art to download for Seasons. - /// - public ImageDownloadOptions DownloadSeasonImages { get; set; } - - /// - /// Options for specific art to download for MusicArtists. - /// - public ImageDownloadOptions DownloadMusicArtistImages { get; set; } - - /// - /// Options for specific art to download for MusicAlbums. - /// - public ImageDownloadOptions DownloadMusicAlbumImages { get; set; } - /// /// Characters to be replaced with a ' ' in strings to create a sort name /// @@ -215,11 +191,7 @@ namespace MediaBrowser.Model.Configuration public bool EnableEpisodeChapterImageExtraction { get; set; } public bool EnableOtherVideoChapterImageExtraction { get; set; } - public MetadataOptions MovieOptions { get; set; } - public MetadataOptions TvOptions { get; set; } - public MetadataOptions MusicOptions { get; set; } - public MetadataOptions GameOptions { get; set; } - public MetadataOptions BookOptions { get; set; } + public MetadataOptions[] MetadataOptions { get; set; } public bool EnableDebugEncodingLogging { get; set; } public string TranscodingTempPath { get; set; } @@ -267,14 +239,6 @@ namespace MediaBrowser.Model.Configuration MetadataRefreshDays = 30; PreferredMetadataLanguage = "en"; MetadataCountryCode = "US"; - DownloadMovieImages = new ImageDownloadOptions(); - DownloadSeriesImages = new ImageDownloadOptions(); - DownloadSeasonImages = new ImageDownloadOptions - { - Backdrops = false - }; - DownloadMusicArtistImages = new ImageDownloadOptions(); - DownloadMusicAlbumImages = new ImageDownloadOptions(); SortReplaceCharacters = new[] { ".", "+", "%" }; SortRemoveCharacters = new[] { ",", "&", "-", "{", "}", "'" }; @@ -282,26 +246,26 @@ namespace MediaBrowser.Model.Configuration SeasonZeroDisplayName = "Specials"; - MovieOptions = new MetadataOptions(); - TvOptions = new MetadataOptions(); + LiveTvOptions = new LiveTvOptions(); - MusicOptions = new MetadataOptions() - { - MaxBackdrops = 1 - }; + TvFileOrganizationOptions = new TvFileOrganizationOptions(); - GameOptions = new MetadataOptions(); + EnableRealtimeMonitor = true; - BookOptions = new MetadataOptions + var options = new List { - MaxBackdrops = 1 + new MetadataOptions(1, 1280) {ItemType = "Book"}, + new MetadataOptions(1, 1280) {ItemType = "MusicAlbum"}, + new MetadataOptions(1, 1280) {ItemType = "MusicArtist"}, + new MetadataOptions(0, 1280) {ItemType = "Season"} }; - LiveTvOptions = new LiveTvOptions(); - - TvFileOrganizationOptions = new TvFileOrganizationOptions(); + MetadataOptions = options.ToArray(); + } - EnableRealtimeMonitor = true; + public MetadataOptions GetMetadataOptions(string type) + { + return MetadataOptions.FirstOrDefault(i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase)); } } @@ -324,39 +288,6 @@ namespace MediaBrowser.Model.Configuration public int? GuideDays { get; set; } } - public class TvFileOrganizationOptions - { - public bool IsEnabled { get; set; } - public int MinFileSizeMb { get; set; } - public string[] LeftOverFileExtensionsToDelete { get; set; } - public string[] WatchLocations { get; set; } - - public string SeasonFolderPattern { get; set; } - - public string SeasonZeroFolderName { get; set; } - - public string EpisodeNamePattern { get; set; } - public string MultiEpisodeNamePattern { get; set; } - - public bool OverwriteExistingEpisodes { get; set; } - - public bool DeleteEmptyFolders { get; set; } - - public TvFileOrganizationOptions() - { - MinFileSizeMb = 50; - - LeftOverFileExtensionsToDelete = new string[] {}; - - WatchLocations = new string[] { }; - - EpisodeNamePattern = "%sn - %sx%0e - %en.%ext"; - MultiEpisodeNamePattern = "%sn - %sx%0e-x%0ed - %en.%ext"; - SeasonFolderPattern = "Season %s"; - SeasonZeroFolderName = "Season 0"; - } - } - public class PathSubstitution { public string From { get; set; } diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index 1e9b579716..136a78381c 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -58,8 +58,11 @@ + + + @@ -124,7 +127,6 @@ - diff --git a/MediaBrowser.Providers/BaseXmlProvider.cs b/MediaBrowser.Providers/BaseXmlProvider.cs index eab5bb574e..68b0034807 100644 --- a/MediaBrowser.Providers/BaseXmlProvider.cs +++ b/MediaBrowser.Providers/BaseXmlProvider.cs @@ -17,18 +17,18 @@ namespace MediaBrowser.Providers FileSystem = fileSystem; } - protected abstract string GetXmlPath(string path); + protected abstract FileInfo GetXmlFile(string path); public bool HasChanged(IHasMetadata item, DateTime date) { - var path = GetXmlPath(item.Path); + var file = GetXmlFile(item.Path); - return FileSystem.GetLastWriteTimeUtc(path) > date; + return FileSystem.GetLastWriteTimeUtc(file) > date; } public bool HasLocalMetadata(IHasMetadata item) { - return File.Exists(GetXmlPath(item.Path)); + return GetXmlFile(item.Path).Exists; } } } diff --git a/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs b/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs index 53ab3614d3..2d0fed02d1 100644 --- a/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs +++ b/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs @@ -1,9 +1,12 @@ -using MediaBrowser.Controller.Configuration; +using MediaBrowser.Common.IO; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Localization; using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Providers.Manager; @@ -15,13 +18,13 @@ using System.Threading.Tasks; namespace MediaBrowser.Providers.BoxSets { - public class BoxSetMetadataService : ConcreteMetadataService + public class BoxSetMetadataService : MetadataService { private readonly ILibraryManager _libraryManager; private readonly ILocalizationManager _iLocalizationManager; - public BoxSetMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, ILibraryManager libraryManager, ILocalizationManager iLocalizationManager) - : base(serverConfigurationManager, logger, providerManager, providerRepo) + public BoxSetMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, ILibraryManager libraryManager, ILocalizationManager iLocalizationManager) + : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem) { _libraryManager = libraryManager; _iLocalizationManager = iLocalizationManager; @@ -34,6 +37,7 @@ namespace MediaBrowser.Providers.BoxSets /// The target. /// The locked fields. /// if set to true [replace data]. + /// if set to true [merge metadata settings]. protected override void MergeData(BoxSet source, BoxSet target, List lockedFields, bool replaceData, bool mergeMetadataSettings) { ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings); diff --git a/MediaBrowser.Providers/BoxSets/BoxSetXmlProvider.cs b/MediaBrowser.Providers/BoxSets/BoxSetXmlProvider.cs index 8b8c8bffd8..391dd456eb 100644 --- a/MediaBrowser.Providers/BoxSets/BoxSetXmlProvider.cs +++ b/MediaBrowser.Providers/BoxSets/BoxSetXmlProvider.cs @@ -23,7 +23,7 @@ namespace MediaBrowser.Providers.BoxSets public async Task> GetMetadata(string path, CancellationToken cancellationToken) { - path = GetXmlPath(path); + path = GetXmlFile(path).FullName; var result = new MetadataResult(); @@ -51,12 +51,12 @@ namespace MediaBrowser.Providers.BoxSets public string Name { - get { return "Media Browser Xml"; } + get { return "Media Browser xml"; } } - protected override string GetXmlPath(string path) + protected override FileInfo GetXmlFile(string path) { - return Path.Combine(path, "collection.xml"); + return new FileInfo(Path.Combine(path, "collection.xml")); } } } diff --git a/MediaBrowser.Providers/GameGenres/GameGenreImageProvider.cs b/MediaBrowser.Providers/GameGenres/GameGenreImageProvider.cs index 0dbf114505..85aa9f7166 100644 --- a/MediaBrowser.Providers/GameGenres/GameGenreImageProvider.cs +++ b/MediaBrowser.Providers/GameGenres/GameGenreImageProvider.cs @@ -37,7 +37,7 @@ namespace MediaBrowser.Providers.GameGenres public static string ProviderName { - get { return "Media Browser"; } + get { return "Media Browser Images"; } } public bool Supports(IHasImages item) diff --git a/MediaBrowser.Providers/GameGenres/GameGenreMetadataService.cs b/MediaBrowser.Providers/GameGenres/GameGenreMetadataService.cs index 1eefb07988..68602b1592 100644 --- a/MediaBrowser.Providers/GameGenres/GameGenreMetadataService.cs +++ b/MediaBrowser.Providers/GameGenres/GameGenreMetadataService.cs @@ -1,7 +1,10 @@ -using MediaBrowser.Controller.Configuration; +using MediaBrowser.Common.IO; +using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Providers.Manager; @@ -11,12 +14,12 @@ using System.Threading.Tasks; namespace MediaBrowser.Providers.GameGenres { - public class GameGenreMetadataService : ConcreteMetadataService + public class GameGenreMetadataService : MetadataService { private readonly ILibraryManager _libraryManager; - public GameGenreMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, ILibraryManager libraryManager) - : base(serverConfigurationManager, logger, providerManager, providerRepo) + public GameGenreMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, ILibraryManager libraryManager) + : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem) { _libraryManager = libraryManager; } diff --git a/MediaBrowser.Providers/Games/GameMetadataService.cs b/MediaBrowser.Providers/Games/GameMetadataService.cs new file mode 100644 index 0000000000..afa123bf7e --- /dev/null +++ b/MediaBrowser.Providers/Games/GameMetadataService.cs @@ -0,0 +1,59 @@ +using MediaBrowser.Common.IO; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Configuration; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Logging; +using MediaBrowser.Providers.Manager; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Providers.Games +{ + public class GameMetadataService : MetadataService + { + private readonly ILibraryManager _libraryManager; + + public GameMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, ILibraryManager libraryManager) + : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem) + { + _libraryManager = libraryManager; + } + + /// + /// Merges the specified source. + /// + /// The source. + /// The target. + /// The locked fields. + /// if set to true [replace data]. + /// if set to true [merge metadata settings]. + protected override void MergeData(Game source, Game target, List lockedFields, bool replaceData, bool mergeMetadataSettings) + { + ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings); + + if (replaceData || string.IsNullOrEmpty(target.GameSystem)) + { + target.GameSystem = source.GameSystem; + } + } + + protected override Task SaveItem(Game item, ItemUpdateType reason, CancellationToken cancellationToken) + { + return _libraryManager.UpdateItem(item, reason, cancellationToken); + } + + protected override GameId GetId(Game item) + { + var id = base.GetId(item); + + id.GameSystem = item.GameSystem; + + return id; + } + } +} diff --git a/MediaBrowser.Providers/Games/GameProviderFromXml.cs b/MediaBrowser.Providers/Games/GameProviderFromXml.cs deleted file mode 100644 index ab1f96a8e4..0000000000 --- a/MediaBrowser.Providers/Games/GameProviderFromXml.cs +++ /dev/null @@ -1,93 +0,0 @@ -using MediaBrowser.Common.IO; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Logging; -using MediaBrowser.Providers.Savers; -using System; -using System.IO; -using System.Threading; -using System.Threading.Tasks; - -namespace MediaBrowser.Providers.Games -{ - public class GameProviderFromXml : BaseMetadataProvider - { - private readonly IFileSystem _fileSystem; - - /// - /// - /// - /// - /// - public GameProviderFromXml(ILogManager logManager, IServerConfigurationManager configurationManager, IFileSystem fileSystem) - : base(logManager, configurationManager) - { - _fileSystem = fileSystem; - } - - /// - /// - /// - /// - /// - public override bool Supports(BaseItem item) - { - return item is Game; - } - - protected override bool NeedsRefreshBasedOnCompareDate(BaseItem item, BaseProviderInfo providerInfo) - { - var savePath = GameXmlSaver.GetGameSavePath(item); - - var xml = item.ResolveArgs.GetMetaFileByPath(savePath) ?? new FileInfo(savePath); - - if (!xml.Exists) - { - return false; - } - - return _fileSystem.GetLastWriteTimeUtc(xml) > item.DateLastSaved; - } - - /// - /// - /// - /// - /// - /// - /// - public override async Task FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) - { - var game = (Game)item; - cancellationToken.ThrowIfCancellationRequested(); - - var metaFile = GameXmlSaver.GetGameSavePath(game); - - if (File.Exists(metaFile)) - { - await XmlParsingResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); - - try - { - new GameXmlParser(Logger).Fetch(game, metaFile, cancellationToken); - } - finally - { - XmlParsingResourcePool.Release(); - } - } - - SetLastRefreshed(game, DateTime.UtcNow, providerInfo); - return true; - } - - /// - /// - /// - public override MetadataProviderPriority Priority - { - get { return MetadataProviderPriority.Second; } - } - } -} \ No newline at end of file diff --git a/MediaBrowser.Providers/Games/GameSystemMetadataService.cs b/MediaBrowser.Providers/Games/GameSystemMetadataService.cs new file mode 100644 index 0000000000..9e5532a27e --- /dev/null +++ b/MediaBrowser.Providers/Games/GameSystemMetadataService.cs @@ -0,0 +1,59 @@ +using MediaBrowser.Common.IO; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Configuration; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Logging; +using MediaBrowser.Providers.Manager; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Providers.Games +{ + public class GameSystemMetadataService : MetadataService + { + private readonly ILibraryManager _libraryManager; + + public GameSystemMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, ILibraryManager libraryManager) + : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem) + { + _libraryManager = libraryManager; + } + + /// + /// Merges the specified source. + /// + /// The source. + /// The target. + /// The locked fields. + /// if set to true [replace data]. + /// if set to true [merge metadata settings]. + protected override void MergeData(GameSystem source, GameSystem target, List lockedFields, bool replaceData, bool mergeMetadataSettings) + { + ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings); + + if (replaceData || string.IsNullOrEmpty(target.GameSystemName)) + { + target.GameSystemName = source.GameSystemName; + } + } + + protected override Task SaveItem(GameSystem item, ItemUpdateType reason, CancellationToken cancellationToken) + { + return _libraryManager.UpdateItem(item, reason, cancellationToken); + } + + protected override GameSystemId GetId(GameSystem item) + { + var id = base.GetId(item); + + id.Path = item.Path; + + return id; + } + } +} diff --git a/MediaBrowser.Providers/Games/GameSystemProviderFromXml.cs b/MediaBrowser.Providers/Games/GameSystemProviderFromXml.cs deleted file mode 100644 index 58143ce3db..0000000000 --- a/MediaBrowser.Providers/Games/GameSystemProviderFromXml.cs +++ /dev/null @@ -1,92 +0,0 @@ -using MediaBrowser.Common.IO; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Entities; -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.Games -{ - public class GameSystemProviderFromXml : BaseMetadataProvider - { - private readonly IFileSystem _fileSystem; - - public GameSystemProviderFromXml(ILogManager logManager, IServerConfigurationManager configurationManager, IFileSystem fileSystem) - : base(logManager, configurationManager) - { - _fileSystem = fileSystem; - } - - /// - /// Supportses the specified item. - /// - /// The item. - /// true if XXXX, false otherwise - public override bool Supports(BaseItem item) - { - return item is GameSystem && item.LocationType == LocationType.FileSystem; - } - - /// - /// Gets the priority. - /// - /// The priority. - public override MetadataProviderPriority Priority - { - get { return MetadataProviderPriority.Second; } - } - - private const string XmlFileName = "gamesystem.xml"; - protected override bool NeedsRefreshBasedOnCompareDate(BaseItem item, BaseProviderInfo providerInfo) - { - var xml = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, XmlFileName)); - - if (xml == null) - { - return false; - } - - return _fileSystem.GetLastWriteTimeUtc(xml) > item.DateLastSaved; - } - - /// - /// 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, BaseProviderInfo providerInfo, CancellationToken cancellationToken) - { - cancellationToken.ThrowIfCancellationRequested(); - - var metadataFile = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, XmlFileName)); - - if (metadataFile != null) - { - var path = metadataFile.FullName; - - await XmlParsingResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); - - try - { - new BaseItemXmlParser(Logger).Fetch((GameSystem)item, path, cancellationToken); - } - finally - { - XmlParsingResourcePool.Release(); - } - - SetLastRefreshed(item, DateTime.UtcNow, providerInfo); - - return true; - } - - return false; - } - } -} diff --git a/MediaBrowser.Providers/Games/GameSystemXmlParser.cs b/MediaBrowser.Providers/Games/GameSystemXmlParser.cs new file mode 100644 index 0000000000..ba69c1fb25 --- /dev/null +++ b/MediaBrowser.Providers/Games/GameSystemXmlParser.cs @@ -0,0 +1,63 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Logging; +using System.Threading; +using System.Threading.Tasks; +using System.Xml; + +namespace MediaBrowser.Providers.Games +{ + public class GameSystemXmlParser : BaseItemXmlParser + { + public GameSystemXmlParser(ILogger logger) + : base(logger) + { + } + + public Task FetchAsync(GameSystem item, string metadataFile, CancellationToken cancellationToken) + { + Fetch(item, metadataFile, cancellationToken); + + cancellationToken.ThrowIfCancellationRequested(); + + return Task.FromResult(true); + } + + /// + /// Fetches the data from XML node. + /// + /// The reader. + /// The item. + protected override void FetchDataFromXmlNode(XmlReader reader, GameSystem item) + { + switch (reader.Name) + { + case "GameSystem": + { + var val = reader.ReadElementContentAsString(); + if (!string.IsNullOrWhiteSpace(val)) + { + item.GameSystemName = val; + } + break; + } + + case "GamesDbId": + { + var val = reader.ReadElementContentAsString(); + if (!string.IsNullOrWhiteSpace(val)) + { + item.SetProviderId(MetadataProviders.Gamesdb, val); + } + break; + } + + + default: + base.FetchDataFromXmlNode(reader, item); + break; + } + } + } +} diff --git a/MediaBrowser.Providers/Games/GameSystemXmlProvider.cs b/MediaBrowser.Providers/Games/GameSystemXmlProvider.cs new file mode 100644 index 0000000000..f2001f5861 --- /dev/null +++ b/MediaBrowser.Providers/Games/GameSystemXmlProvider.cs @@ -0,0 +1,59 @@ +using MediaBrowser.Common.IO; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Logging; +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Providers.Games +{ + public class GameSystemXmlProvider : BaseXmlProvider, ILocalMetadataProvider + { + private readonly ILogger _logger; + + public GameSystemXmlProvider(IFileSystem fileSystem, ILogger logger) + : base(fileSystem) + { + _logger = logger; + } + + public async Task> GetMetadata(string path, CancellationToken cancellationToken) + { + path = GetXmlFile(path).FullName; + + var result = new MetadataResult(); + + await XmlParsingResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); + + try + { + var item = new GameSystem(); + + new GameSystemXmlParser(_logger).Fetch(item, path, cancellationToken); + result.HasMetadata = true; + result.Item = item; + } + catch (FileNotFoundException) + { + result.HasMetadata = false; + } + finally + { + XmlParsingResourcePool.Release(); + } + + return result; + } + + public string Name + { + get { return "Media Browser xml"; } + } + + protected override FileInfo GetXmlFile(string path) + { + return new FileInfo(Path.Combine(path, "gamesystem.xml")); + } + } +} diff --git a/MediaBrowser.Providers/Games/GameXmlParser.cs b/MediaBrowser.Providers/Games/GameXmlParser.cs index 53cc123884..a5e6adbefd 100644 --- a/MediaBrowser.Providers/Games/GameXmlParser.cs +++ b/MediaBrowser.Providers/Games/GameXmlParser.cs @@ -14,7 +14,6 @@ namespace MediaBrowser.Providers.Games /// public class GameXmlParser : BaseItemXmlParser { - private Task _chaptersTask = null; private readonly CultureInfo _usCulture = new CultureInfo("en-US"); public GameXmlParser(ILogger logger) @@ -22,18 +21,13 @@ namespace MediaBrowser.Providers.Games { } - public async Task FetchAsync(Game item, string metadataFile, CancellationToken cancellationToken) + public Task FetchAsync(Game item, string metadataFile, CancellationToken cancellationToken) { - _chaptersTask = null; - Fetch(item, metadataFile, cancellationToken); cancellationToken.ThrowIfCancellationRequested(); - if (_chaptersTask != null) - { - await _chaptersTask.ConfigureAwait(false); - } + return Task.FromResult(true); } /// diff --git a/MediaBrowser.Providers/Games/GameXmlProvider.cs b/MediaBrowser.Providers/Games/GameXmlProvider.cs new file mode 100644 index 0000000000..fb64c2a61b --- /dev/null +++ b/MediaBrowser.Providers/Games/GameXmlProvider.cs @@ -0,0 +1,74 @@ +using MediaBrowser.Common.IO; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Logging; +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Providers.Games +{ + public class GameXmlProvider : BaseXmlProvider, ILocalMetadataProvider + { + private readonly ILogger _logger; + + public GameXmlProvider(IFileSystem fileSystem, ILogger logger) + : base(fileSystem) + { + _logger = logger; + } + + public async Task> GetMetadata(string path, CancellationToken cancellationToken) + { + path = GetXmlFile(path).FullName; + + var result = new MetadataResult(); + + await XmlParsingResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); + + try + { + var item = new Game(); + + new GameXmlParser(_logger).Fetch(item, path, cancellationToken); + result.HasMetadata = true; + result.Item = item; + } + catch (FileNotFoundException) + { + result.HasMetadata = false; + } + finally + { + XmlParsingResourcePool.Release(); + } + + return result; + } + + public string Name + { + get { return "Media Browser xml"; } + } + + protected override FileInfo GetXmlFile(string path) + { + var fileInfo = FileSystem.GetFileSystemInfo(path); + + var directoryInfo = fileInfo as DirectoryInfo; + + if (directoryInfo == null) + { + directoryInfo = new DirectoryInfo(Path.GetDirectoryName(path)); + } + + var directoryPath = directoryInfo.FullName; + + var specificFile = Path.Combine(directoryPath, Path.GetFileNameWithoutExtension(path) + ".xml"); + + var file = new FileInfo(specificFile); + + return file.Exists ? file : new FileInfo(Path.Combine(directoryPath, "game.xml")); + } + } +} diff --git a/MediaBrowser.Providers/Genres/GenreImageProvider.cs b/MediaBrowser.Providers/Genres/GenreImageProvider.cs index 189cc8cde6..007eeab7bc 100644 --- a/MediaBrowser.Providers/Genres/GenreImageProvider.cs +++ b/MediaBrowser.Providers/Genres/GenreImageProvider.cs @@ -38,7 +38,7 @@ namespace MediaBrowser.Providers.Genres public static string ProviderName { - get { return "Media Browser"; } + get { return "Media Browser Images"; } } public bool Supports(IHasImages item) diff --git a/MediaBrowser.Providers/Genres/GenreMetadataService.cs b/MediaBrowser.Providers/Genres/GenreMetadataService.cs index fa4a4c955f..e2437fed16 100644 --- a/MediaBrowser.Providers/Genres/GenreMetadataService.cs +++ b/MediaBrowser.Providers/Genres/GenreMetadataService.cs @@ -1,7 +1,10 @@ -using MediaBrowser.Controller.Configuration; +using MediaBrowser.Common.IO; +using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Providers.Manager; @@ -11,12 +14,12 @@ using System.Threading.Tasks; namespace MediaBrowser.Providers.Genres { - public class GenreMetadataService : ConcreteMetadataService + public class GenreMetadataService : MetadataService { private readonly ILibraryManager _libraryManager; - public GenreMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, ILibraryManager libraryManager) - : base(serverConfigurationManager, logger, providerManager, providerRepo) + public GenreMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, ILibraryManager libraryManager) + : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem) { _libraryManager = libraryManager; } diff --git a/MediaBrowser.Providers/LiveTv/ChannelMetadataService.cs b/MediaBrowser.Providers/LiveTv/ChannelMetadataService.cs index 5c476c89dd..b0c916a613 100644 --- a/MediaBrowser.Providers/LiveTv/ChannelMetadataService.cs +++ b/MediaBrowser.Providers/LiveTv/ChannelMetadataService.cs @@ -1,7 +1,10 @@ -using MediaBrowser.Controller.Configuration; +using MediaBrowser.Common.IO; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Providers.Manager; @@ -11,12 +14,12 @@ using System.Threading.Tasks; namespace MediaBrowser.Providers.LiveTv { - public class ChannelMetadataService : ConcreteMetadataService + public class ChannelMetadataService : MetadataService { private readonly ILibraryManager _libraryManager; - public ChannelMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, ILibraryManager libraryManager) - : base(serverConfigurationManager, logger, providerManager, providerRepo) + public ChannelMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, ILibraryManager libraryManager) + : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem) { _libraryManager = libraryManager; } diff --git a/MediaBrowser.Providers/LiveTv/ChannelXmlProvider.cs b/MediaBrowser.Providers/LiveTv/ChannelXmlProvider.cs index 544685f661..096e68a8aa 100644 --- a/MediaBrowser.Providers/LiveTv/ChannelXmlProvider.cs +++ b/MediaBrowser.Providers/LiveTv/ChannelXmlProvider.cs @@ -20,7 +20,7 @@ namespace MediaBrowser.Providers.LiveTv public async Task> GetMetadata(string path, CancellationToken cancellationToken) { - path = GetXmlPath(path); + path = GetXmlFile(path).FullName; var result = new MetadataResult(); @@ -48,12 +48,12 @@ namespace MediaBrowser.Providers.LiveTv public string Name { - get { return "Media Browser Xml"; } + get { return "Media Browser xml"; } } - protected override string GetXmlPath(string path) + protected override FileInfo GetXmlFile(string path) { - return Path.Combine(path, "channel.xml"); + return new FileInfo(Path.Combine(path, "channel.xml")); } } } diff --git a/MediaBrowser.Providers/LiveTv/ProgramMetadataService.cs b/MediaBrowser.Providers/LiveTv/ProgramMetadataService.cs index 0a22daf2f1..02d5c1a796 100644 --- a/MediaBrowser.Providers/LiveTv/ProgramMetadataService.cs +++ b/MediaBrowser.Providers/LiveTv/ProgramMetadataService.cs @@ -1,7 +1,10 @@ -using MediaBrowser.Controller.Configuration; +using MediaBrowser.Common.IO; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Providers.Manager; @@ -11,12 +14,12 @@ using System.Threading.Tasks; namespace MediaBrowser.Providers.LiveTv { - public class ProgramMetadataService : ConcreteMetadataService + public class ProgramMetadataService : MetadataService { private readonly ILibraryManager _libraryManager; - public ProgramMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, ILibraryManager libraryManager) - : base(serverConfigurationManager, logger, providerManager, providerRepo) + public ProgramMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, ILibraryManager libraryManager) + : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem) { _libraryManager = libraryManager; } diff --git a/MediaBrowser.Providers/Manager/ConcreteMetadataService.cs b/MediaBrowser.Providers/Manager/ConcreteMetadataService.cs deleted file mode 100644 index f3644581e3..0000000000 --- a/MediaBrowser.Providers/Manager/ConcreteMetadataService.cs +++ /dev/null @@ -1,21 +0,0 @@ -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Logging; - -namespace MediaBrowser.Providers.Manager -{ - public abstract class ConcreteMetadataService : MetadataService - where TItemType : IHasMetadata, new() - where TIdType : ItemId, new() - { - protected ConcreteMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo) - : base(serverConfigurationManager, logger, providerManager, providerRepo) - { - } - - protected override TItemType CreateNew() - { - return new TItemType(); - } - } -} diff --git a/MediaBrowser.Providers/Manager/ImageSaver.cs b/MediaBrowser.Providers/Manager/ImageSaver.cs index 2decba1610..2e0bf9a050 100644 --- a/MediaBrowser.Providers/Manager/ImageSaver.cs +++ b/MediaBrowser.Providers/Manager/ImageSaver.cs @@ -309,15 +309,6 @@ namespace MediaBrowser.Providers.Manager { item.BackdropImagePaths.Add(path); } - - if (string.IsNullOrEmpty(sourceUrl)) - { - item.RemoveImageSourceForPath(path); - } - else - { - item.AddImageSource(path, sourceUrl); - } break; default: item.SetImagePath(type, path); diff --git a/MediaBrowser.Providers/Manager/ItemImageProvider.cs b/MediaBrowser.Providers/Manager/ItemImageProvider.cs index 7f0dc8b89d..ee6f7cf698 100644 --- a/MediaBrowser.Providers/Manager/ItemImageProvider.cs +++ b/MediaBrowser.Providers/Manager/ItemImageProvider.cs @@ -1,16 +1,17 @@ -using System.IO; -using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.Extensions; using MediaBrowser.Common.IO; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Net; using MediaBrowser.Model.Providers; using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Net; using System.Threading; @@ -25,11 +26,12 @@ namespace MediaBrowser.Providers.Manager private readonly IServerConfigurationManager _config; private readonly IFileSystem _fileSystem; - public ItemImageProvider(ILogger logger, IProviderManager providerManager, IServerConfigurationManager config) + public ItemImageProvider(ILogger logger, IProviderManager providerManager, IServerConfigurationManager config, IFileSystem fileSystem) { _logger = logger; _providerManager = providerManager; _config = config; + _fileSystem = fileSystem; } public bool ValidateImages(IHasImages item, IEnumerable providers) @@ -49,7 +51,7 @@ namespace MediaBrowser.Providers.Manager return hasChanges; } - public async Task RefreshImages(IHasImages item, IEnumerable imageProviders, ImageRefreshOptions options, CancellationToken cancellationToken) + public async Task RefreshImages(IHasImages item, IEnumerable imageProviders, ImageRefreshOptions refreshOptions, MetadataOptions savedOptions, CancellationToken cancellationToken) { var result = new RefreshResult { UpdateType = ItemUpdateType.Unspecified }; @@ -57,16 +59,20 @@ namespace MediaBrowser.Providers.Manager var providerIds = new List(); + // In order to avoid duplicates, only download these if there are none already + var backdropLimit = item.HasImage(ImageType.Backdrop) ? 0 : savedOptions.GetLimit(ImageType.Backdrop); + var screenshotLimit = item.HasImage(ImageType.Screenshot) ? 0 : savedOptions.GetLimit(ImageType.Screenshot); + foreach (var provider in providers.OfType()) { - await RefreshFromProvider(item, provider, options, result, cancellationToken).ConfigureAwait(false); + await RefreshFromProvider(item, provider, refreshOptions, savedOptions, backdropLimit, screenshotLimit, result, cancellationToken).ConfigureAwait(false); providerIds.Add(provider.GetType().FullName.GetMD5()); } foreach (var provider in providers.OfType()) { - await RefreshFromProvider(item, provider, result, cancellationToken).ConfigureAwait(false); + await RefreshFromProvider(item, provider, savedOptions, result, cancellationToken).ConfigureAwait(false); providerIds.Add(provider.GetType().FullName.GetMD5()); } @@ -81,10 +87,11 @@ namespace MediaBrowser.Providers.Manager /// /// The item. /// The provider. + /// The saved options. /// The result. /// The cancellation token. /// Task. - private async Task RefreshFromProvider(IHasImages item, IDynamicImageProvider provider, RefreshResult result, CancellationToken cancellationToken) + private async Task RefreshFromProvider(IHasImages item, IDynamicImageProvider provider, MetadataOptions savedOptions, RefreshResult result, CancellationToken cancellationToken) { _logger.Debug("Running {0} for {1}", provider.GetType().Name, item.Path ?? item.Name); @@ -94,7 +101,7 @@ namespace MediaBrowser.Providers.Manager foreach (var imageType in images) { - if (!item.HasImage(imageType)) + if (!item.HasImage(imageType) && savedOptions.IsEnabled(imageType)) { var response = await provider.GetImage(item, imageType, cancellationToken).ConfigureAwait(false); @@ -152,17 +159,20 @@ namespace MediaBrowser.Providers.Manager /// /// Determines if an item already contains the given images /// - /// - /// - /// - private bool ContainsImages(IHasImages item, List images) + /// The item. + /// The images. + /// The saved options. + /// The backdrop limit. + /// The screenshot limit. + /// true if the specified item contains images; otherwise, false. + private bool ContainsImages(IHasImages item, List images, MetadataOptions savedOptions, int backdropLimit, int screenshotLimit) { - if (_singularImages.Any(i => images.Contains(i) && !item.HasImage(i))) + if (_singularImages.Any(i => images.Contains(i) && !item.HasImage(i) && savedOptions.GetLimit(i) > 0)) { return false; } - if (images.Contains(ImageType.Backdrop) && item.BackdropImagePaths.Count < GetMaxBackdropCount(item)) + if (images.Contains(ImageType.Backdrop) && item.BackdropImagePaths.Count < backdropLimit) { return false; } @@ -172,7 +182,7 @@ namespace MediaBrowser.Providers.Manager var hasScreenshots = item as IHasScreenshots; if (hasScreenshots != null) { - if (hasScreenshots.ScreenshotImagePaths.Count < GetMaxBackdropCount(item)) + if (hasScreenshots.ScreenshotImagePaths.Count < screenshotLimit) { return false; } @@ -187,16 +197,18 @@ namespace MediaBrowser.Providers.Manager /// /// The item. /// The provider. - /// The options. + /// The refresh options. + /// The saved options. + /// The backdrop limit. + /// The screenshot limit. /// The result. /// The cancellation token. /// Task. - private async Task RefreshFromProvider(IHasImages item, IRemoteImageProvider provider, ImageRefreshOptions options, RefreshResult result, CancellationToken cancellationToken) + private async Task RefreshFromProvider(IHasImages item, IRemoteImageProvider provider, ImageRefreshOptions refreshOptions, MetadataOptions savedOptions, int backdropLimit, int screenshotLimit, RefreshResult result, CancellationToken cancellationToken) { try { - // TODO: Also factor in IsConfiguredToDownloadImage - if (ContainsImages(item, provider.GetSupportedImages(item).ToList())) + if (ContainsImages(item, provider.GetSupportedImages(item).ToList(), savedOptions, backdropLimit, screenshotLimit)) { return; } @@ -208,18 +220,18 @@ namespace MediaBrowser.Providers.Manager foreach (var type in _singularImages) { - if (IsConfiguredToDownloadImage(item, type) && !item.HasImage(type)) + if (savedOptions.IsEnabled(type) && !item.HasImage(type)) { await DownloadImage(item, provider, result, list, type, cancellationToken).ConfigureAwait(false); } } - await DownloadBackdrops(item, provider, result, list, cancellationToken).ConfigureAwait(false); + await DownloadBackdrops(item, backdropLimit, provider, result, list, cancellationToken).ConfigureAwait(false); var hasScreenshots = item as IHasScreenshots; if (hasScreenshots != null) { - await DownloadScreenshots(hasScreenshots, provider, result, list, cancellationToken).ConfigureAwait(false); + await DownloadScreenshots(hasScreenshots, screenshotLimit, provider, result, list, cancellationToken).ConfigureAwait(false); } } catch (OperationCanceledException) @@ -342,25 +354,19 @@ namespace MediaBrowser.Providers.Manager } } - private async Task DownloadBackdrops(IHasImages item, IRemoteImageProvider provider, RefreshResult result, IEnumerable images, CancellationToken cancellationToken) + private async Task DownloadBackdrops(IHasImages item, int limit, IRemoteImageProvider provider, RefreshResult result, IEnumerable images, CancellationToken cancellationToken) { const ImageType imageType = ImageType.Backdrop; - var maxCount = GetMaxBackdropCount(item); foreach (var image in images.Where(i => i.Type == imageType)) { - if (item.BackdropImagePaths.Count >= maxCount) + if (item.BackdropImagePaths.Count >= limit) { break; } var url = image.Url; - if (item.ContainsImageWithSourceUrl(url)) - { - continue; - } - try { var response = await provider.GetImageResponse(url, cancellationToken).ConfigureAwait(false); @@ -381,25 +387,19 @@ namespace MediaBrowser.Providers.Manager } } - private async Task DownloadScreenshots(IHasScreenshots item, IRemoteImageProvider provider, RefreshResult result, IEnumerable images, CancellationToken cancellationToken) + private async Task DownloadScreenshots(IHasScreenshots item, int limit, IRemoteImageProvider provider, RefreshResult result, IEnumerable images, CancellationToken cancellationToken) { const ImageType imageType = ImageType.Screenshot; - var maxCount = GetMaxScreenshotCount(item); foreach (var image in images.Where(i => i.Type == imageType)) { - if (item.ScreenshotImagePaths.Count >= maxCount) + if (item.ScreenshotImagePaths.Count >= limit) { break; } var url = image.Url; - if (item.ContainsImageWithSourceUrl(url)) - { - continue; - } - try { var response = await provider.GetImageResponse(url, cancellationToken).ConfigureAwait(false); @@ -419,20 +419,5 @@ namespace MediaBrowser.Providers.Manager } } } - - private bool IsConfiguredToDownloadImage(IHasImages item, ImageType type) - { - return true; - } - - private int GetMaxBackdropCount(IHasImages item) - { - return 1; - } - - private int GetMaxScreenshotCount(IHasScreenshots item) - { - return 1; - } } } diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index 69f9708914..f6e27238e7 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -1,7 +1,9 @@ using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.IO; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using System; @@ -13,32 +15,22 @@ using System.Threading.Tasks; namespace MediaBrowser.Providers.Manager { public abstract class MetadataService : IMetadataService - where TItemType : IHasMetadata + where TItemType : IHasMetadata, new() where TIdType : ItemId, new() { protected readonly IServerConfigurationManager ServerConfigurationManager; protected readonly ILogger Logger; protected readonly IProviderManager ProviderManager; - private readonly IProviderRepository _providerRepo; + protected readonly IProviderRepository ProviderRepo; + protected readonly IFileSystem FileSystem; - private IMetadataProvider[] _providers = { }; - - protected MetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo) + protected MetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem) { ServerConfigurationManager = serverConfigurationManager; Logger = logger; ProviderManager = providerManager; - _providerRepo = providerRepo; - } - - /// - /// Adds the parts. - /// - /// The providers. - public void AddParts(IEnumerable providers) - { - _providers = providers.OfType>() - .ToArray(); + ProviderRepo = providerRepo; + FileSystem = fileSystem; } /// @@ -48,7 +40,7 @@ namespace MediaBrowser.Providers.Manager /// Task. protected Task SaveProviderResult(MetadataStatus result) { - return _providerRepo.SaveMetadataStatus(result, CancellationToken.None); + return ProviderRepo.SaveMetadataStatus(result, CancellationToken.None); } /// @@ -58,20 +50,22 @@ namespace MediaBrowser.Providers.Manager /// ProviderResult. protected MetadataStatus GetLastResult(Guid itemId) { - return _providerRepo.GetMetadataStatus(itemId) ?? new MetadataStatus { ItemId = itemId }; + return ProviderRepo.GetMetadataStatus(itemId) ?? new MetadataStatus { ItemId = itemId }; } - public async Task RefreshMetadata(IHasMetadata item, MetadataRefreshOptions options, CancellationToken cancellationToken) + public async Task RefreshMetadata(IHasMetadata item, MetadataRefreshOptions refreshOptions, CancellationToken cancellationToken) { var itemOfType = (TItemType)item; + var config = GetMetadataOptions(itemOfType); + var updateType = ItemUpdateType.Unspecified; var lastResult = GetLastResult(item.Id); var refreshResult = lastResult; refreshResult.LastErrorMessage = string.Empty; refreshResult.LastStatus = ProviderRefreshStatus.Success; - var itemImageProvider = new ItemImageProvider(Logger, ProviderManager, ServerConfigurationManager); + var itemImageProvider = new ItemImageProvider(Logger, ProviderManager, ServerConfigurationManager, FileSystem); var localImagesFailed = false; var allImageProviders = ((ProviderManager)ProviderManager).GetImageProviders(item).ToList(); @@ -93,13 +87,13 @@ namespace MediaBrowser.Providers.Manager } // Next run metadata providers - if (options.MetadataRefreshMode != MetadataRefreshMode.None) + if (refreshOptions.MetadataRefreshMode != MetadataRefreshMode.None) { - var providers = GetProviders(item, lastResult.DateLastMetadataRefresh.HasValue, options).ToList(); + var providers = GetProviders(item, lastResult.DateLastMetadataRefresh.HasValue, refreshOptions).ToList(); if (providers.Count > 0) { - var result = await RefreshWithProviders(itemOfType, options, providers, cancellationToken).ConfigureAwait(false); + var result = await RefreshWithProviders(itemOfType, refreshOptions, providers, cancellationToken).ConfigureAwait(false); updateType = updateType | result.UpdateType; refreshResult.AddStatus(result.Status, result.ErrorMessage); @@ -109,13 +103,13 @@ namespace MediaBrowser.Providers.Manager } // Next run remote image providers, but only if local image providers didn't throw an exception - if (!localImagesFailed && options.ImageRefreshMode != ImageRefreshMode.ValidationOnly) + if (!localImagesFailed && refreshOptions.ImageRefreshMode != ImageRefreshMode.ValidationOnly) { - var providers = GetNonLocalImageProviders(item, allImageProviders, lastResult.DateLastImagesRefresh.HasValue, options).ToList(); + var providers = GetNonLocalImageProviders(item, allImageProviders, lastResult.DateLastImagesRefresh.HasValue, refreshOptions).ToList(); if (providers.Count > 0) { - var result = await itemImageProvider.RefreshImages(itemOfType, providers, options, cancellationToken).ConfigureAwait(false); + var result = await itemImageProvider.RefreshImages(itemOfType, providers, refreshOptions, config, cancellationToken).ConfigureAwait(false); updateType = updateType | result.UpdateType; refreshResult.AddStatus(result.Status, result.ErrorMessage); @@ -128,7 +122,7 @@ namespace MediaBrowser.Providers.Manager var providersHadChanges = updateType > ItemUpdateType.Unspecified; - if (options.ForceSave || providersHadChanges) + if (refreshOptions.ForceSave || providersHadChanges) { if (string.IsNullOrEmpty(item.Name)) { @@ -145,6 +139,15 @@ namespace MediaBrowser.Providers.Manager } } + private readonly MetadataOptions _defaultOptions = new MetadataOptions(); + protected MetadataOptions GetMetadataOptions(TItemType item) + { + var type = item.GetType().Name; + return ServerConfigurationManager.Configuration.MetadataOptions + .FirstOrDefault(i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase)) ?? + _defaultOptions; + } + /// /// Afters the metadata refresh. /// @@ -292,10 +295,35 @@ namespace MediaBrowser.Providers.Manager MergeData(temp, item, item.LockedFields, true, true); } + foreach (var provider in providers.OfType>()) + { + Logger.Debug("Running {0} for {1}", provider.GetType().Name, item.Path ?? item.Name); + + try + { + await provider.FetchAsync(item, cancellationToken).ConfigureAwait(false); + + refreshResult.UpdateType = refreshResult.UpdateType | ItemUpdateType.MetadataDownload; + } + catch (OperationCanceledException) + { + throw; + } + catch (Exception ex) + { + refreshResult.Status = ProviderRefreshStatus.CompletedWithErrors; + refreshResult.ErrorMessage = ex.Message; + Logger.ErrorException("Error in {0}", ex, provider.Name); + } + } + return refreshResult; } - protected abstract TItemType CreateNew(); + protected virtual TItemType CreateNew() + { + return new TItemType(); + } private async Task ExecuteRemoteProviders(TItemType item, TItemType temp, IEnumerable> providers, RefreshResult refreshResult, CancellationToken cancellationToken) { diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index 77a9298eeb..b4f228a1d9 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -2,14 +2,17 @@ using MediaBrowser.Common.Net; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.IO; +using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Controller.Entities.Movies; +using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Providers; using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; @@ -58,6 +61,7 @@ namespace MediaBrowser.Providers.Manager private IMetadataService[] _metadataServices = { }; private IMetadataProvider[] _metadataProviders = { }; + private IEnumerable _savers; /// /// Initializes a new instance of the class. @@ -85,7 +89,8 @@ namespace MediaBrowser.Providers.Manager /// The image providers. /// The metadata services. /// The metadata providers. - public void AddParts(IEnumerable providers, IEnumerable imageProviders, IEnumerable metadataServices, IEnumerable metadataProviders) + /// The metadata savers. + public void AddParts(IEnumerable providers, IEnumerable imageProviders, IEnumerable metadataServices, IEnumerable metadataProviders, IEnumerable metadataSavers) { MetadataProviders = providers.OrderBy(e => e.Priority).ToArray(); @@ -93,6 +98,7 @@ namespace MediaBrowser.Providers.Manager _metadataServices = metadataServices.OrderBy(i => i.Order).ToArray(); _metadataProviders = metadataProviders.ToArray(); + _savers = metadataSavers.ToArray(); } public Task RefreshMetadata(IHasMetadata item, MetadataRefreshOptions options, CancellationToken cancellationToken) @@ -479,9 +485,15 @@ namespace MediaBrowser.Providers.Manager public IEnumerable> GetMetadataProviders(IHasMetadata item) where T : IHasMetadata + { + return GetMetadataProvidersInternal(item, false); + } + + private IEnumerable> GetMetadataProvidersInternal(IHasMetadata item, bool includeDisabled) + where T : IHasMetadata { return _metadataProviders.OfType>() - .Where(i => CanRefresh(i, item)) + .Where(i => CanRefresh(i, item, includeDisabled)) .OrderBy(i => GetOrder(item, i)); } @@ -495,10 +507,11 @@ namespace MediaBrowser.Providers.Manager /// /// The provider. /// The item. + /// if set to true [include disabled]. /// true if this instance can refresh the specified provider; otherwise, false. - protected bool CanRefresh(IMetadataProvider provider, IHasMetadata item) + private bool CanRefresh(IMetadataProvider provider, IHasMetadata item, bool includeDisabled) { - if (!ConfigurationManager.Configuration.EnableInternetProviders && provider is IRemoteMetadataProvider) + if (!includeDisabled && !ConfigurationManager.Configuration.EnableInternetProviders && provider is IRemoteMetadataProvider) { return false; } @@ -546,5 +559,148 @@ namespace MediaBrowser.Providers.Manager return hasOrder.Order; } + + public IEnumerable GetAllMetadataPlugins() + { + var list = new List(); + + list.Add(GetPluginSummary()); + list.Add(GetPluginSummary()); + list.Add(GetPluginSummary()); + list.Add(GetPluginSummary()); + list.Add(GetPluginSummary()); + list.Add(GetPluginSummary()); + list.Add(GetPluginSummary()); + list.Add(GetPluginSummary()); + list.Add(GetPluginSummary()); + list.Add(GetPluginSummary()); + list.Add(GetPluginSummary()); + list.Add(GetPluginSummary()); + list.Add(GetPluginSummary /// The item. /// System.String. - public string GetSavePath(BaseItem item) + public string GetSavePath(IHasMetadata item) { return Path.Combine(item.Path, "album.xml"); } diff --git a/MediaBrowser.Providers/Savers/ArtistXmlSaver.cs b/MediaBrowser.Providers/Savers/ArtistXmlSaver.cs index 6b801f1e26..efaa967512 100644 --- a/MediaBrowser.Providers/Savers/ArtistXmlSaver.cs +++ b/MediaBrowser.Providers/Savers/ArtistXmlSaver.cs @@ -2,6 +2,7 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Providers; using MediaBrowser.Providers.Music; using System; using System.Collections.Generic; @@ -20,13 +21,21 @@ namespace MediaBrowser.Providers.Savers _config = config; } + public string Name + { + get + { + return "Media Browser xml"; + } + } + /// /// Determines whether [is enabled for] [the specified item]. /// /// The item. /// Type of the update. /// true if [is enabled for] [the specified item]; otherwise, false. - public bool IsEnabledFor(BaseItem item, ItemUpdateType updateType) + public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType) { var wasMetadataEdited = (updateType & ItemUpdateType.MetadataEdit) == ItemUpdateType.MetadataEdit; var wasMetadataDownloaded = (updateType & ItemUpdateType.MetadataDownload) == ItemUpdateType.MetadataDownload; @@ -59,13 +68,13 @@ namespace MediaBrowser.Providers.Savers /// The item. /// The cancellation token. /// Task. - public void Save(BaseItem item, CancellationToken cancellationToken) + public void Save(IHasMetadata item, CancellationToken cancellationToken) { var builder = new StringBuilder(); builder.Append(""); - XmlSaverHelpers.AddCommonNodes(item, builder); + XmlSaverHelpers.AddCommonNodes((MusicArtist)item, builder); builder.Append(""); @@ -79,7 +88,7 @@ namespace MediaBrowser.Providers.Savers /// /// The item. /// System.String. - public string GetSavePath(BaseItem item) + public string GetSavePath(IHasMetadata item) { return Path.Combine(item.Path, "artist.xml"); } diff --git a/MediaBrowser.Providers/Savers/BoxSetXmlSaver.cs b/MediaBrowser.Providers/Savers/BoxSetXmlSaver.cs index 5d5624c556..078b1feba5 100644 --- a/MediaBrowser.Providers/Savers/BoxSetXmlSaver.cs +++ b/MediaBrowser.Providers/Savers/BoxSetXmlSaver.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.IO; using System.Text; using System.Threading; +using MediaBrowser.Controller.Providers; namespace MediaBrowser.Providers.Savers { @@ -18,13 +19,21 @@ namespace MediaBrowser.Providers.Savers _config = config; } + public string Name + { + get + { + return "Media Browser xml"; + } + } + /// /// Determines whether [is enabled for] [the specified item]. /// /// The item. /// Type of the update. /// true if [is enabled for] [the specified item]; otherwise, false. - public bool IsEnabledFor(BaseItem item, ItemUpdateType updateType) + public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType) { var wasMetadataEdited = (updateType & ItemUpdateType.MetadataEdit) == ItemUpdateType.MetadataEdit; var wasMetadataDownloaded = (updateType & ItemUpdateType.MetadataDownload) == ItemUpdateType.MetadataDownload; @@ -44,13 +53,13 @@ namespace MediaBrowser.Providers.Savers /// The item. /// The cancellation token. /// Task. - public void Save(BaseItem item, CancellationToken cancellationToken) + public void Save(IHasMetadata item, CancellationToken cancellationToken) { var builder = new StringBuilder(); builder.Append(""); - XmlSaverHelpers.AddCommonNodes(item, builder); + XmlSaverHelpers.AddCommonNodes((BoxSet)item, builder); builder.Append(""); @@ -64,7 +73,7 @@ namespace MediaBrowser.Providers.Savers /// /// The item. /// System.String. - public string GetSavePath(BaseItem item) + public string GetSavePath(IHasMetadata item) { return Path.Combine(item.Path, "collection.xml"); } diff --git a/MediaBrowser.Providers/Savers/ChannelXmlSaver.cs b/MediaBrowser.Providers/Savers/ChannelXmlSaver.cs index ad7f1287f8..ed9a9bd6dd 100644 --- a/MediaBrowser.Providers/Savers/ChannelXmlSaver.cs +++ b/MediaBrowser.Providers/Savers/ChannelXmlSaver.cs @@ -1,8 +1,6 @@ -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; -using MediaBrowser.Providers.LiveTv; -using System; +using MediaBrowser.Controller.Providers; using System.Collections.Generic; using System.IO; using System.Text; @@ -21,7 +19,7 @@ namespace MediaBrowser.Providers.Savers /// The item. /// Type of the update. /// true if [is enabled for] [the specified item]; otherwise, false. - public bool IsEnabledFor(BaseItem item, ItemUpdateType updateType) + public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType) { var wasMetadataEdited = (updateType & ItemUpdateType.MetadataEdit) == ItemUpdateType.MetadataEdit; var wasMetadataDownloaded = (updateType & ItemUpdateType.MetadataDownload) == ItemUpdateType.MetadataDownload; @@ -35,19 +33,27 @@ namespace MediaBrowser.Providers.Savers return false; } + public string Name + { + get + { + return "Media Browser xml"; + } + } + /// /// Saves the specified item. /// /// The item. /// The cancellation token. /// Task. - public void Save(BaseItem item, CancellationToken cancellationToken) + public void Save(IHasMetadata item, CancellationToken cancellationToken) { var builder = new StringBuilder(); builder.Append(""); - XmlSaverHelpers.AddCommonNodes(item, builder); + XmlSaverHelpers.AddCommonNodes((LiveTvChannel)item, builder); builder.Append(""); @@ -63,7 +69,7 @@ namespace MediaBrowser.Providers.Savers /// /// The item. /// System.String. - public string GetSavePath(BaseItem item) + public string GetSavePath(IHasMetadata item) { return Path.Combine(item.Path, "channel.xml"); } diff --git a/MediaBrowser.Providers/Savers/EpisodeXmlSaver.cs b/MediaBrowser.Providers/Savers/EpisodeXmlSaver.cs index b7cfe8aeec..a0e3097185 100644 --- a/MediaBrowser.Providers/Savers/EpisodeXmlSaver.cs +++ b/MediaBrowser.Providers/Savers/EpisodeXmlSaver.cs @@ -1,8 +1,8 @@ using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Persistence; +using MediaBrowser.Controller.Providers; using System.Collections.Generic; using System.Globalization; using System.IO; @@ -23,7 +23,7 @@ namespace MediaBrowser.Providers.Savers /// The item. /// Type of the update. /// true if [is enabled for] [the specified item]; otherwise, false. - public bool IsEnabledFor(BaseItem item, ItemUpdateType updateType) + public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType) { var wasMetadataEdited = (updateType & ItemUpdateType.MetadataEdit) == ItemUpdateType.MetadataEdit; var wasMetadataDownloaded = (updateType & ItemUpdateType.MetadataDownload) == ItemUpdateType.MetadataDownload; @@ -37,6 +37,14 @@ namespace MediaBrowser.Providers.Savers return false; } + public string Name + { + get + { + return "Media Browser xml"; + } + } + private readonly CultureInfo _usCulture = new CultureInfo("en-US"); public EpisodeXmlSaver(IServerConfigurationManager config, IItemRepository itemRepository) @@ -51,7 +59,7 @@ namespace MediaBrowser.Providers.Savers /// The item. /// The cancellation token. /// Task. - public void Save(BaseItem item, CancellationToken cancellationToken) + public void Save(IHasMetadata item, CancellationToken cancellationToken) { var episode = (Episode)item; @@ -112,7 +120,7 @@ namespace MediaBrowser.Providers.Savers builder.Append("" + SecurityElement.Escape(episode.PremiereDate.Value.ToLocalTime().ToString("yyyy-MM-dd")) + ""); } - XmlSaverHelpers.AddCommonNodes(item, builder); + XmlSaverHelpers.AddCommonNodes(episode, builder); XmlSaverHelpers.AddMediaInfo(episode, builder, _itemRepository); builder.Append(""); @@ -140,7 +148,7 @@ namespace MediaBrowser.Providers.Savers /// /// The item. /// System.String. - public string GetSavePath(BaseItem item) + public string GetSavePath(IHasMetadata item) { var filename = Path.ChangeExtension(Path.GetFileName(item.Path), ".xml"); diff --git a/MediaBrowser.Providers/Savers/FolderXmlSaver.cs b/MediaBrowser.Providers/Savers/FolderXmlSaver.cs index 7ad13905d6..6d384e410d 100644 --- a/MediaBrowser.Providers/Savers/FolderXmlSaver.cs +++ b/MediaBrowser.Providers/Savers/FolderXmlSaver.cs @@ -4,6 +4,7 @@ using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Providers; using System.Collections.Generic; using System.IO; using System.Text; @@ -20,15 +21,25 @@ namespace MediaBrowser.Providers.Savers _config = config; } + public string Name + { + get + { + return "Media Browser xml"; + } + } + /// /// Determines whether [is enabled for] [the specified item]. /// /// The item. /// Type of the update. /// true if [is enabled for] [the specified item]; otherwise, false. - public bool IsEnabledFor(BaseItem item, ItemUpdateType updateType) + public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType) { - if (!item.IsFolder) + var folder = item as Folder; + + if (folder == null) { return false; } @@ -40,7 +51,8 @@ namespace MediaBrowser.Providers.Savers if (item.IsSaveLocalMetadataEnabled() && (wasMetadataEdited || wasMetadataDownloaded)) { if (!(item is Series) && !(item is BoxSet) && !(item is MusicArtist) && !(item is MusicAlbum) && - !(item is Season)) + !(item is Season) && + !(item is GameSystem)) { return true; } @@ -64,13 +76,13 @@ namespace MediaBrowser.Providers.Savers /// The item. /// The cancellation token. /// Task. - public void Save(BaseItem item, CancellationToken cancellationToken) + public void Save(IHasMetadata item, CancellationToken cancellationToken) { var builder = new StringBuilder(); builder.Append(""); - XmlSaverHelpers.AddCommonNodes(item, builder); + XmlSaverHelpers.AddCommonNodes((Folder)item, builder); builder.Append(""); @@ -84,7 +96,7 @@ namespace MediaBrowser.Providers.Savers /// /// The item. /// System.String. - public string GetSavePath(BaseItem item) + public string GetSavePath(IHasMetadata item) { return Path.Combine(item.Path, "folder.xml"); } diff --git a/MediaBrowser.Providers/Savers/GameSystemXmlSaver.cs b/MediaBrowser.Providers/Savers/GameSystemXmlSaver.cs index 7089b8e1b0..d0d2ffcd0e 100644 --- a/MediaBrowser.Providers/Savers/GameSystemXmlSaver.cs +++ b/MediaBrowser.Providers/Savers/GameSystemXmlSaver.cs @@ -1,10 +1,10 @@ using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; -using MediaBrowser.Providers.Games; -using System; +using MediaBrowser.Controller.Providers; using System.Collections.Generic; using System.IO; +using System.Security; using System.Text; using System.Threading; @@ -19,13 +19,21 @@ namespace MediaBrowser.Providers.Savers _config = config; } + public string Name + { + get + { + return "Media Browser xml"; + } + } + /// /// Determines whether [is enabled for] [the specified item]. /// /// The item. /// Type of the update. /// true if [is enabled for] [the specified item]; otherwise, false. - public bool IsEnabledFor(BaseItem item, ItemUpdateType updateType) + public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType) { var wasMetadataEdited = (updateType & ItemUpdateType.MetadataEdit) == ItemUpdateType.MetadataEdit; var wasMetadataDownloaded = (updateType & ItemUpdateType.MetadataDownload) == ItemUpdateType.MetadataDownload; @@ -45,13 +53,20 @@ namespace MediaBrowser.Providers.Savers /// The item. /// The cancellation token. /// Task. - public void Save(BaseItem item, CancellationToken cancellationToken) + public void Save(IHasMetadata item, CancellationToken cancellationToken) { + var gameSystem = (GameSystem)item; + var builder = new StringBuilder(); builder.Append(""); - XmlSaverHelpers.AddCommonNodes(item, builder); + if (!string.IsNullOrEmpty(gameSystem.GameSystemName)) + { + builder.Append("" + SecurityElement.Escape(gameSystem.GameSystemName) + ""); + } + + XmlSaverHelpers.AddCommonNodes(gameSystem, builder); builder.Append(""); @@ -65,7 +80,7 @@ namespace MediaBrowser.Providers.Savers /// /// The item. /// System.String. - public string GetSavePath(BaseItem item) + public string GetSavePath(IHasMetadata item) { return Path.Combine(item.Path, "gamesystem.xml"); } diff --git a/MediaBrowser.Providers/Savers/GameXmlSaver.cs b/MediaBrowser.Providers/Savers/GameXmlSaver.cs index 5dd7617e09..4e3f948a3c 100644 --- a/MediaBrowser.Providers/Savers/GameXmlSaver.cs +++ b/MediaBrowser.Providers/Savers/GameXmlSaver.cs @@ -1,9 +1,8 @@ using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; -using MediaBrowser.Providers.Movies; -using System; using System.Collections.Generic; using System.Globalization; using System.IO; @@ -25,13 +24,21 @@ namespace MediaBrowser.Providers.Savers _config = config; } + public string Name + { + get + { + return "Media Browser xml"; + } + } + /// /// Determines whether [is enabled for] [the specified item]. /// /// The item. /// Type of the update. /// true if [is enabled for] [the specified item]; otherwise, false. - public bool IsEnabledFor(BaseItem item, ItemUpdateType updateType) + public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType) { var wasMetadataEdited = (updateType & ItemUpdateType.MetadataEdit) == ItemUpdateType.MetadataEdit; var wasMetadataDownloaded = (updateType & ItemUpdateType.MetadataDownload) == ItemUpdateType.MetadataDownload; @@ -53,7 +60,7 @@ namespace MediaBrowser.Providers.Savers /// The item. /// The cancellation token. /// Task. - public void Save(BaseItem item, CancellationToken cancellationToken) + public void Save(IHasMetadata item, CancellationToken cancellationToken) { var builder = new StringBuilder(); @@ -85,7 +92,7 @@ namespace MediaBrowser.Providers.Savers builder.Append("" + SecurityElement.Escape(val) + ""); } - XmlSaverHelpers.AddCommonNodes(item, builder); + XmlSaverHelpers.AddCommonNodes(game, builder); builder.Append(""); @@ -100,12 +107,12 @@ namespace MediaBrowser.Providers.Savers }); } - public string GetSavePath(BaseItem item) + public string GetSavePath(IHasMetadata item) { - return GetGameSavePath(item); + return GetGameSavePath((Game)item); } - public static string GetGameSavePath(BaseItem item) + public static string GetGameSavePath(Game item) { if (item.IsInMixedFolder) { diff --git a/MediaBrowser.Providers/Savers/MovieXmlSaver.cs b/MediaBrowser.Providers/Savers/MovieXmlSaver.cs index 3fc4579e38..f65c8f5df1 100644 --- a/MediaBrowser.Providers/Savers/MovieXmlSaver.cs +++ b/MediaBrowser.Providers/Savers/MovieXmlSaver.cs @@ -10,6 +10,7 @@ using System.IO; using System.Security; using System.Text; using System.Threading; +using MediaBrowser.Controller.Providers; namespace MediaBrowser.Providers.Savers { @@ -27,13 +28,21 @@ namespace MediaBrowser.Providers.Savers _itemRepository = itemRepository; } + public string Name + { + get + { + return "Media Browser xml"; + } + } + /// /// Determines whether [is enabled for] [the specified item]. /// /// The item. /// Type of the update. /// true if [is enabled for] [the specified item]; otherwise, false. - public bool IsEnabledFor(BaseItem item, ItemUpdateType updateType) + public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType) { var wasMetadataEdited = (updateType & ItemUpdateType.MetadataEdit) == ItemUpdateType.MetadataEdit; var wasMetadataDownloaded = (updateType & ItemUpdateType.MetadataDownload) == ItemUpdateType.MetadataDownload; @@ -48,9 +57,9 @@ namespace MediaBrowser.Providers.Savers { return !trailer.IsLocalTrailer; } - + var video = item as Video; // Check parent for null to avoid running this against things like video backdrops - return item is Video && !(item is Episode) && item.Parent != null; + return video != null && !(item is Episode) && video.Parent != null; } return false; @@ -64,22 +73,24 @@ namespace MediaBrowser.Providers.Savers /// The item. /// The cancellation token. /// Task. - public void Save(BaseItem item, CancellationToken cancellationToken) + public void Save(IHasMetadata item, CancellationToken cancellationToken) { + var video = (Video)item; + var builder = new StringBuilder(); builder.Append(""); - XmlSaverHelpers.AddCommonNodes(item, builder); + XmlSaverHelpers.AddCommonNodes(video, builder); - if (item.CommunityRating.HasValue) + if (video.CommunityRating.HasValue) { - builder.Append("<IMDBrating>" + SecurityElement.Escape(item.CommunityRating.Value.ToString(UsCulture)) + "</IMDBrating>"); + builder.Append("<IMDBrating>" + SecurityElement.Escape(video.CommunityRating.Value.ToString(UsCulture)) + "</IMDBrating>"); } - if (!string.IsNullOrEmpty(item.Overview)) + if (!string.IsNullOrEmpty(video.Overview)) { - builder.Append("<Description><![CDATA[" + item.Overview + "]]></Description>"); + builder.Append("<Description><![CDATA[" + video.Overview + "]]></Description>"); } var musicVideo = item as MusicVideo; @@ -106,8 +117,6 @@ namespace MediaBrowser.Providers.Savers } } - var video = (Video)item; - XmlSaverHelpers.AddMediaInfo(video, builder, _itemRepository); builder.Append(""); @@ -124,12 +133,12 @@ namespace MediaBrowser.Providers.Savers }); } - public string GetSavePath(BaseItem item) + public string GetSavePath(IHasMetadata item) { - return GetMovieSavePath(item); + return GetMovieSavePath((Video)item); } - public static string GetMovieSavePath(BaseItem item) + public static string GetMovieSavePath(Video item) { if (item.IsInMixedFolder) { diff --git a/MediaBrowser.Providers/Savers/PersonXmlSaver.cs b/MediaBrowser.Providers/Savers/PersonXmlSaver.cs index a6d7575eae..676f2dae05 100644 --- a/MediaBrowser.Providers/Savers/PersonXmlSaver.cs +++ b/MediaBrowser.Providers/Savers/PersonXmlSaver.cs @@ -1,7 +1,6 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; -using MediaBrowser.Providers.Movies; -using System; +using MediaBrowser.Controller.Providers; using System.Collections.Generic; using System.IO; using System.Security; @@ -15,13 +14,21 @@ namespace MediaBrowser.Providers.Savers /// public class PersonXmlSaver : IMetadataSaver { + public string Name + { + get + { + return "Media Browser xml"; + } + } + /// /// Determines whether [is enabled for] [the specified item]. /// /// The item. /// Type of the update. /// true if [is enabled for] [the specified item]; otherwise, false. - public bool IsEnabledFor(BaseItem item, ItemUpdateType updateType) + public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType) { var wasMetadataEdited = (updateType & ItemUpdateType.MetadataEdit) == ItemUpdateType.MetadataEdit; var wasMetadataDownloaded = (updateType & ItemUpdateType.MetadataDownload) == ItemUpdateType.MetadataDownload; @@ -41,15 +48,15 @@ namespace MediaBrowser.Providers.Savers /// The item. /// The cancellation token. /// Task. - public void Save(BaseItem item, CancellationToken cancellationToken) + public void Save(IHasMetadata item, CancellationToken cancellationToken) { + var person = (Person)item; + var builder = new StringBuilder(); builder.Append(""); - XmlSaverHelpers.AddCommonNodes(item, builder); - - var person = (Person)item; + XmlSaverHelpers.AddCommonNodes(person, builder); if (!string.IsNullOrEmpty(person.PlaceOfBirth)) { @@ -71,7 +78,7 @@ namespace MediaBrowser.Providers.Savers /// /// The item. /// System.String. - public string GetSavePath(BaseItem item) + public string GetSavePath(IHasMetadata item) { return Path.Combine(item.Path, "person.xml"); } diff --git a/MediaBrowser.Providers/Savers/SeasonXmlSaver.cs b/MediaBrowser.Providers/Savers/SeasonXmlSaver.cs index 0a9f2e4f62..52f310f0f7 100644 --- a/MediaBrowser.Providers/Savers/SeasonXmlSaver.cs +++ b/MediaBrowser.Providers/Savers/SeasonXmlSaver.cs @@ -1,7 +1,7 @@ using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Providers; using System.Collections.Generic; using System.IO; using System.Text; @@ -18,13 +18,21 @@ namespace MediaBrowser.Providers.Savers _config = config; } + public string Name + { + get + { + return "Media Browser xml"; + } + } + /// /// Determines whether [is enabled for] [the specified item]. /// /// The item. /// Type of the update. /// true if [is enabled for] [the specified item]; otherwise, false. - public bool IsEnabledFor(BaseItem item, ItemUpdateType updateType) + public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType) { var wasMetadataEdited = (updateType & ItemUpdateType.MetadataEdit) == ItemUpdateType.MetadataEdit; var wasMetadataDownloaded = (updateType & ItemUpdateType.MetadataDownload) == ItemUpdateType.MetadataDownload; @@ -44,13 +52,13 @@ namespace MediaBrowser.Providers.Savers /// The item. /// The cancellation token. /// Task. - public void Save(BaseItem item, CancellationToken cancellationToken) + public void Save(IHasMetadata item, CancellationToken cancellationToken) { var builder = new StringBuilder(); builder.Append(""); - XmlSaverHelpers.AddCommonNodes(item, builder); + XmlSaverHelpers.AddCommonNodes((Season)item, builder); builder.Append(""); @@ -64,7 +72,7 @@ namespace MediaBrowser.Providers.Savers /// /// The item. /// System.String. - public string GetSavePath(BaseItem item) + public string GetSavePath(IHasMetadata item) { return Path.Combine(item.Path, "season.xml"); } diff --git a/MediaBrowser.Providers/Savers/SeriesXmlSaver.cs b/MediaBrowser.Providers/Savers/SeriesXmlSaver.cs index 29ca12f7fd..d472c2da25 100644 --- a/MediaBrowser.Providers/Savers/SeriesXmlSaver.cs +++ b/MediaBrowser.Providers/Savers/SeriesXmlSaver.cs @@ -1,7 +1,7 @@ using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; using System.Collections.Generic; using System.IO; @@ -20,13 +20,21 @@ namespace MediaBrowser.Providers.Savers _config = config; } + public string Name + { + get + { + return "Media Browser xml"; + } + } + /// /// Determines whether [is enabled for] [the specified item]. /// /// The item. /// Type of the update. /// true if [is enabled for] [the specified item]; otherwise, false. - public bool IsEnabledFor(BaseItem item, ItemUpdateType updateType) + public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType) { var wasMetadataEdited = (updateType & ItemUpdateType.MetadataEdit) == ItemUpdateType.MetadataEdit; var wasMetadataDownloaded = (updateType & ItemUpdateType.MetadataDownload) == ItemUpdateType.MetadataDownload; @@ -46,7 +54,7 @@ namespace MediaBrowser.Providers.Savers /// The item. /// The cancellation token. /// Task. - public void Save(BaseItem item, CancellationToken cancellationToken) + public void Save(IHasMetadata item, CancellationToken cancellationToken) { var series = (Series)item; @@ -73,7 +81,7 @@ namespace MediaBrowser.Providers.Savers if (series.Studios.Count > 0) { - builder.Append("" + SecurityElement.Escape(item.Studios[0]) + ""); + builder.Append("" + SecurityElement.Escape(series.Studios[0]) + ""); } if (!string.IsNullOrEmpty(series.AirTime)) @@ -97,8 +105,8 @@ namespace MediaBrowser.Providers.Savers { builder.Append("" + SecurityElement.Escape(series.PremiereDate.Value.ToLocalTime().ToString("yyyy-MM-dd")) + ""); } - - XmlSaverHelpers.AddCommonNodes(item, builder); + + XmlSaverHelpers.AddCommonNodes(series, builder); builder.Append(""); @@ -124,7 +132,7 @@ namespace MediaBrowser.Providers.Savers /// /// The item. /// System.String. - public string GetSavePath(BaseItem item) + public string GetSavePath(IHasMetadata item) { return Path.Combine(item.Path, "series.xml"); } diff --git a/MediaBrowser.Providers/Studios/StudioMetadataService.cs b/MediaBrowser.Providers/Studios/StudioMetadataService.cs index 78ef1b51c7..a42a882af5 100644 --- a/MediaBrowser.Providers/Studios/StudioMetadataService.cs +++ b/MediaBrowser.Providers/Studios/StudioMetadataService.cs @@ -1,7 +1,10 @@ -using MediaBrowser.Controller.Configuration; +using MediaBrowser.Common.IO; +using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Providers.Manager; @@ -11,12 +14,12 @@ using System.Threading.Tasks; namespace MediaBrowser.Providers.Studios { - public class StudioMetadataService : ConcreteMetadataService + public class StudioMetadataService : MetadataService { private readonly ILibraryManager _libraryManager; - public StudioMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, ILibraryManager libraryManager) - : base(serverConfigurationManager, logger, providerManager, providerRepo) + public StudioMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, ILibraryManager libraryManager) + : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem) { _libraryManager = libraryManager; } diff --git a/MediaBrowser.Providers/Studios/StudiosImageProvider.cs b/MediaBrowser.Providers/Studios/StudiosImageProvider.cs index eacec5b694..006ab827d2 100644 --- a/MediaBrowser.Providers/Studios/StudiosImageProvider.cs +++ b/MediaBrowser.Providers/Studios/StudiosImageProvider.cs @@ -37,7 +37,7 @@ namespace MediaBrowser.Providers.Studios public static string ProviderName { - get { return "Media Browser"; } + get { return "Media Browser Images"; } } public bool Supports(IHasImages item) diff --git a/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs b/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs index 6ab612784a..50db33b3da 100644 --- a/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs +++ b/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs @@ -4,6 +4,7 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Providers; @@ -121,7 +122,9 @@ namespace MediaBrowser.Providers.TV /// Task. private async Task FetchImages(Season season, List images, CancellationToken cancellationToken) { - if (ConfigurationManager.Configuration.DownloadSeasonImages.Thumb && !season.HasImage(ImageType.Thumb) && !season.LockedFields.Contains(MetadataFields.Images)) + var options = ConfigurationManager.Configuration.GetMetadataOptions("Season") ?? new MetadataOptions(); + + if (options.IsEnabled(ImageType.Thumb) && !season.HasImage(ImageType.Thumb) && !season.LockedFields.Contains(MetadataFields.Images)) { await SaveImage(season, images, ImageType.Thumb, cancellationToken).ConfigureAwait(false); } diff --git a/MediaBrowser.Providers/TV/FanArtTVProvider.cs b/MediaBrowser.Providers/TV/FanArtTVProvider.cs index 1f7109c610..3f2199fc41 100644 --- a/MediaBrowser.Providers/TV/FanArtTVProvider.cs +++ b/MediaBrowser.Providers/TV/FanArtTVProvider.cs @@ -6,6 +6,7 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Providers; @@ -197,39 +198,41 @@ namespace MediaBrowser.Providers.TV /// Task. private async Task FetchFromXml(BaseItem item, List images, CancellationToken cancellationToken) { + var options = ConfigurationManager.Configuration.GetMetadataOptions("Series") ?? new MetadataOptions(); + if (!item.LockedFields.Contains(MetadataFields.Images)) { cancellationToken.ThrowIfCancellationRequested(); - if (ConfigurationManager.Configuration.DownloadSeriesImages.Primary && !item.HasImage(ImageType.Primary)) + if (options.IsEnabled(ImageType.Primary) && !item.HasImage(ImageType.Primary)) { await SaveImage(item, images, ImageType.Primary, cancellationToken).ConfigureAwait(false); } cancellationToken.ThrowIfCancellationRequested(); - if (ConfigurationManager.Configuration.DownloadSeriesImages.Logo && !item.HasImage(ImageType.Logo)) + if (options.IsEnabled(ImageType.Logo) && !item.HasImage(ImageType.Logo)) { await SaveImage(item, images, ImageType.Logo, cancellationToken).ConfigureAwait(false); } cancellationToken.ThrowIfCancellationRequested(); - if (ConfigurationManager.Configuration.DownloadSeriesImages.Art && !item.HasImage(ImageType.Art)) + if (options.IsEnabled(ImageType.Art) && !item.HasImage(ImageType.Art)) { await SaveImage(item, images, ImageType.Art, cancellationToken).ConfigureAwait(false); } cancellationToken.ThrowIfCancellationRequested(); - if (ConfigurationManager.Configuration.DownloadSeriesImages.Thumb && !item.HasImage(ImageType.Thumb)) + if (options.IsEnabled(ImageType.Thumb) && !item.HasImage(ImageType.Thumb)) { await SaveImage(item, images, ImageType.Thumb, cancellationToken).ConfigureAwait(false); } cancellationToken.ThrowIfCancellationRequested(); - if (ConfigurationManager.Configuration.DownloadSeriesImages.Banner && !item.HasImage(ImageType.Banner)) + if (options.IsEnabled(ImageType.Banner) && !item.HasImage(ImageType.Banner)) { await SaveImage(item, images, ImageType.Banner, cancellationToken).ConfigureAwait(false); } @@ -239,8 +242,8 @@ namespace MediaBrowser.Providers.TV { cancellationToken.ThrowIfCancellationRequested(); - var backdropLimit = ConfigurationManager.Configuration.TvOptions.MaxBackdrops; - if (ConfigurationManager.Configuration.DownloadSeriesImages.Backdrops && + var backdropLimit = options.GetLimit(ImageType.Backdrop); + if (options.IsEnabled(ImageType.Backdrop) && item.BackdropImagePaths.Count < backdropLimit) { foreach (var image in images.Where(i => i.Type == ImageType.Backdrop)) diff --git a/MediaBrowser.Providers/TV/TvdbSeasonProvider.cs b/MediaBrowser.Providers/TV/TvdbSeasonProvider.cs index 17ed6b5a24..d7281ac218 100644 --- a/MediaBrowser.Providers/TV/TvdbSeasonProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbSeasonProvider.cs @@ -5,6 +5,7 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Net; @@ -149,16 +150,17 @@ namespace MediaBrowser.Providers.TV var images = await _providerManager.GetAvailableRemoteImages(item, cancellationToken, ManualTvdbSeasonImageProvider.ProviderName).ConfigureAwait(false); - const int backdropLimit = 1; - - await DownloadImages(item, images.ToList(), backdropLimit, cancellationToken).ConfigureAwait(false); + await DownloadImages(item, images.ToList(), cancellationToken).ConfigureAwait(false); SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } - private async Task DownloadImages(BaseItem item, List images, int backdropLimit, CancellationToken cancellationToken) + private async Task DownloadImages(BaseItem item, List images, CancellationToken cancellationToken) { + var options = ConfigurationManager.Configuration.GetMetadataOptions("Season") ?? new MetadataOptions(); + var backdropLimit = options.GetLimit(ImageType.Backdrop); + if (!item.LockedFields.Contains(MetadataFields.Images)) { if (!item.HasImage(ImageType.Primary)) @@ -166,23 +168,18 @@ namespace MediaBrowser.Providers.TV await SaveImage(item, images, ImageType.Primary, cancellationToken).ConfigureAwait(false); } - if (ConfigurationManager.Configuration.DownloadSeasonImages.Banner && !item.HasImage(ImageType.Banner)) + if (options.IsEnabled(ImageType.Banner) && !item.HasImage(ImageType.Banner)) { await SaveImage(item, images, ImageType.Banner, cancellationToken).ConfigureAwait(false); } } - if (ConfigurationManager.Configuration.DownloadSeasonImages.Backdrops && item.BackdropImagePaths.Count < backdropLimit && !item.LockedFields.Contains(MetadataFields.Backdrops)) + if (options.IsEnabled(ImageType.Backdrop) && item.BackdropImagePaths.Count < backdropLimit && !item.LockedFields.Contains(MetadataFields.Backdrops)) { foreach (var backdrop in images.Where(i => i.Type == ImageType.Backdrop)) { var url = backdrop.Url; - if (item.ContainsImageWithSourceUrl(url)) - { - continue; - } - await _providerManager.SaveImage(item, url, TvdbSeriesProvider.Current.TvDbResourcePool, ImageType.Backdrop, null, cancellationToken).ConfigureAwait(false); if (item.BackdropImagePaths.Count >= backdropLimit) break; diff --git a/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs b/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs index 21a72dd578..73db2680e8 100644 --- a/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs @@ -5,6 +5,7 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Providers; @@ -137,7 +138,9 @@ namespace MediaBrowser.Providers.TV protected override bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo) { - if (item.HasImage(ImageType.Primary) && item.HasImage(ImageType.Banner) && item.BackdropImagePaths.Count >= ConfigurationManager.Configuration.TvOptions.MaxBackdrops) + var options = ConfigurationManager.Configuration.GetMetadataOptions("Series") ?? new MetadataOptions(); + + if (item.HasImage(ImageType.Primary) && item.HasImage(ImageType.Banner) && item.BackdropImagePaths.Count >= options.GetLimit(ImageType.Backdrop)) { return false; } @@ -167,6 +170,8 @@ namespace MediaBrowser.Providers.TV private async Task DownloadImages(BaseItem item, List images, int backdropLimit, CancellationToken cancellationToken) { + var options = ConfigurationManager.Configuration.GetMetadataOptions("Series") ?? new MetadataOptions(); + if (!item.LockedFields.Contains(MetadataFields.Images)) { if (!item.HasImage(ImageType.Primary)) @@ -180,7 +185,7 @@ namespace MediaBrowser.Providers.TV } } - if (ConfigurationManager.Configuration.DownloadSeriesImages.Banner && !item.HasImage(ImageType.Banner)) + if (options.IsEnabled(ImageType.Banner) && !item.HasImage(ImageType.Banner)) { var image = images.FirstOrDefault(i => i.Type == ImageType.Banner); @@ -192,19 +197,14 @@ namespace MediaBrowser.Providers.TV } } - if (ConfigurationManager.Configuration.DownloadSeriesImages.Backdrops && item.BackdropImagePaths.Count < backdropLimit && !item.LockedFields.Contains(MetadataFields.Backdrops)) + if (options.IsEnabled(ImageType.Backdrop) && item.BackdropImagePaths.Count < backdropLimit && !item.LockedFields.Contains(MetadataFields.Backdrops)) { foreach (var backdrop in images.Where(i => i.Type == ImageType.Backdrop && (!i.Width.HasValue || - i.Width.Value >= ConfigurationManager.Configuration.TvOptions.MinBackdropWidth))) + i.Width.Value >= options.GetMinWidth(ImageType.Backdrop)))) { var url = backdrop.Url; - if (item.ContainsImageWithSourceUrl(url)) - { - continue; - } - await _providerManager.SaveImage(item, url, TvdbSeriesProvider.Current.TvDbResourcePool, ImageType.Backdrop, null, cancellationToken).ConfigureAwait(false); if (item.BackdropImagePaths.Count >= backdropLimit) break; diff --git a/MediaBrowser.Providers/Users/UserMetadataService.cs b/MediaBrowser.Providers/Users/UserMetadataService.cs index 3a7abd79b2..01c27c7541 100644 --- a/MediaBrowser.Providers/Users/UserMetadataService.cs +++ b/MediaBrowser.Providers/Users/UserMetadataService.cs @@ -1,7 +1,10 @@ -using MediaBrowser.Controller.Configuration; +using MediaBrowser.Common.IO; +using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Providers.Manager; @@ -11,12 +14,12 @@ using System.Threading.Tasks; namespace MediaBrowser.Providers.Users { - public class UserMetadataService : ConcreteMetadataService + public class UserMetadataService : MetadataService { private readonly IUserManager _userManager; - public UserMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, ILibraryManager libraryManager, IUserManager userManager) - : base(serverConfigurationManager, logger, providerManager, providerRepo) + public UserMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserManager userManager) + : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem) { _userManager = userManager; } @@ -28,6 +31,7 @@ namespace MediaBrowser.Providers.Users /// The target. /// The locked fields. /// if set to true [replace data]. + /// if set to true [merge metadata settings]. protected override void MergeData(User source, User target, List lockedFields, bool replaceData, bool mergeMetadataSettings) { ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings); diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 17b5ea4244..789cc1100b 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -9,6 +9,7 @@ using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.IO; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Persistence; +using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Resolvers; using MediaBrowser.Controller.Sorting; using MediaBrowser.Model.Configuration; @@ -135,9 +136,8 @@ namespace MediaBrowser.Server.Implementations.Library /// The by reference items. private ConcurrentDictionary ByReferenceItems { get; set; } - private IEnumerable _savers; - private readonly Func _libraryMonitorFactory; + private readonly Func _providerManagerFactory; /// /// The _library items cache @@ -180,7 +180,7 @@ namespace MediaBrowser.Server.Implementations.Library /// The user manager. /// The configuration manager. /// The user data repository. - public LibraryManager(ILogger logger, ITaskManager taskManager, IUserManager userManager, IServerConfigurationManager configurationManager, IUserDataManager userDataRepository, Func libraryMonitorFactory, IFileSystem fileSystem) + public LibraryManager(ILogger logger, ITaskManager taskManager, IUserManager userManager, IServerConfigurationManager configurationManager, IUserDataManager userDataRepository, Func libraryMonitorFactory, IFileSystem fileSystem, Func providerManagerFactory) { _logger = logger; _taskManager = taskManager; @@ -189,6 +189,7 @@ namespace MediaBrowser.Server.Implementations.Library _userDataRepository = userDataRepository; _libraryMonitorFactory = libraryMonitorFactory; _fileSystem = fileSystem; + _providerManagerFactory = providerManagerFactory; ByReferenceItems = new ConcurrentDictionary(); ConfigurationManager.ConfigurationUpdated += ConfigurationUpdated; @@ -215,8 +216,7 @@ namespace MediaBrowser.Server.Implementations.Library IEnumerable itemComparers, IEnumerable prescanTasks, IEnumerable postscanTasks, - IEnumerable peoplePrescanTasks, - IEnumerable savers) + IEnumerable peoplePrescanTasks) { EntityResolutionIgnoreRules = rules.ToArray(); PluginFolderCreators = pluginFolders.ToArray(); @@ -226,7 +226,6 @@ namespace MediaBrowser.Server.Implementations.Library PrescanTasks = prescanTasks; PostscanTasks = postscanTasks; PeoplePrescanTasks = peoplePrescanTasks; - _savers = savers; } /// @@ -1375,9 +1374,9 @@ namespace MediaBrowser.Server.Implementations.Library { if (item.LocationType == LocationType.FileSystem) { - await SaveMetadata(item, updateReason).ConfigureAwait(false); + await _providerManagerFactory().SaveMetadata(item, updateReason).ConfigureAwait(false); } - + item.DateLastSaved = DateTime.UtcNow; await ItemRepository.SaveItem(item, cancellationToken).ConfigureAwait(false); @@ -1440,49 +1439,6 @@ namespace MediaBrowser.Server.Implementations.Library return ItemRepository.RetrieveItem(id); } - private readonly ConcurrentDictionary _fileLocks = new ConcurrentDictionary(); - - /// - /// Saves the metadata. - /// - /// The item. - /// Type of the update. - /// Task. - public async Task SaveMetadata(BaseItem item, ItemUpdateType updateType) - { - var locationType = item.LocationType; - if (locationType == LocationType.Remote || locationType == LocationType.Virtual) - { - throw new ArgumentException("Only file-system based items can save metadata."); - } - - foreach (var saver in _savers.Where(i => i.IsEnabledFor(item, updateType))) - { - var path = saver.GetSavePath(item); - - var semaphore = _fileLocks.GetOrAdd(path, key => new SemaphoreSlim(1, 1)); - - var libraryMonitor = _libraryMonitorFactory(); - - await semaphore.WaitAsync().ConfigureAwait(false); - - try - { - libraryMonitor.ReportFileSystemChangeBeginning(path); - saver.Save(item, CancellationToken.None); - } - catch (Exception ex) - { - _logger.ErrorException("Error in metadata saver", ex); - } - finally - { - libraryMonitor.ReportFileSystemChangeComplete(path, false); - semaphore.Release(); - } - } - } - /// /// Finds the type of the collection. /// diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs index 4fa345829b..88a928795a 100644 --- a/MediaBrowser.ServerApplication/ApplicationHost.cs +++ b/MediaBrowser.ServerApplication/ApplicationHost.cs @@ -282,7 +282,7 @@ namespace MediaBrowser.ServerApplication UserManager = new UserManager(Logger, ServerConfigurationManager, UserRepository); RegisterSingleInstance(UserManager); - LibraryManager = new LibraryManager(Logger, TaskManager, UserManager, ServerConfigurationManager, UserDataManager, () => LibraryMonitor, FileSystemManager); + LibraryManager = new LibraryManager(Logger, TaskManager, UserManager, ServerConfigurationManager, UserDataManager, () => LibraryMonitor, FileSystemManager, () => ProviderManager); RegisterSingleInstance(LibraryManager); LibraryMonitor = new LibraryMonitor(LogManager, TaskManager, LibraryManager, ServerConfigurationManager, FileSystemManager); @@ -499,10 +499,10 @@ namespace MediaBrowser.ServerApplication GetExports(), GetExports(), GetExports(), - GetExports(), - GetExports()); + GetExports()); - ProviderManager.AddParts(GetExports(), GetExports(), GetExports(), GetExports()); + ProviderManager.AddParts(GetExports(), GetExports(), GetExports(), GetExports(), + GetExports()); ImageProcessor.AddParts(GetExports()); diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index 607b286edb..daf905a8a9 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common.Internal - 3.0.310 + 3.0.317 MediaBrowser.Common.Internal Luke ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption. Copyright © Media Browser 2013 - + diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index 3222e429bb..4a3c258802 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common - 3.0.310 + 3.0.317 MediaBrowser.Common Media Browser Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index abfd72ff36..08f0a11888 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Server.Core - 3.0.310 + 3.0.317 Media Browser.Server.Core Media Browser Team ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains core components required to build plugins for Media Browser Server. Copyright © Media Browser 2013 - +