diff options
Diffstat (limited to 'MediaBrowser.Controller/Providers')
29 files changed, 255 insertions, 595 deletions
diff --git a/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs b/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs index a5823c60e..aaf3fe6bf 100644 --- a/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs +++ b/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Model.Logging; @@ -12,7 +11,7 @@ namespace MediaBrowser.Controller.Providers /// <summary> /// Class BaseMetadataProvider /// </summary> - public abstract class BaseMetadataProvider : IDisposable + public abstract class BaseMetadataProvider { /// <summary> /// Gets the logger. @@ -27,16 +26,6 @@ namespace MediaBrowser.Controller.Providers /// <value>The configuration manager.</value> protected IServerConfigurationManager ConfigurationManager { get; private set; } - // Cache these since they will be used a lot - /// <summary> - /// The false task result - /// </summary> - protected static readonly Task<bool> FalseTaskResult = Task.FromResult(false); - /// <summary> - /// The true task result - /// </summary> - protected static readonly Task<bool> TrueTaskResult = Task.FromResult(true); - /// <summary> /// The _id /// </summary> @@ -135,7 +124,7 @@ namespace MediaBrowser.Controller.Providers /// <param name="providerVersion">The provider version.</param> /// <param name="status">The status.</param> /// <exception cref="System.ArgumentNullException">item</exception> - protected virtual void SetLastRefreshed(BaseItem item, DateTime value, string providerVersion, ProviderRefreshStatus status = ProviderRefreshStatus.Success) + public virtual void SetLastRefreshed(BaseItem item, DateTime value, string providerVersion, ProviderRefreshStatus status = ProviderRefreshStatus.Success) { if (item == null) { @@ -162,7 +151,7 @@ namespace MediaBrowser.Controller.Providers /// <param name="item">The item.</param> /// <param name="value">The value.</param> /// <param name="status">The status.</param> - protected virtual void SetLastRefreshed(BaseItem item, DateTime value, ProviderRefreshStatus status = ProviderRefreshStatus.Success) + public void SetLastRefreshed(BaseItem item, DateTime value, ProviderRefreshStatus status = ProviderRefreshStatus.Success) { SetLastRefreshed(item, value, ProviderVersion, status); } @@ -254,76 +243,7 @@ namespace MediaBrowser.Controller.Providers /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{System.Boolean}.</returns> /// <exception cref="System.ArgumentNullException"></exception> - public async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) - { - if (item == null) - { - throw new ArgumentNullException(); - } - - cancellationToken.ThrowIfCancellationRequested(); - - Logger.Info("Running for {0}", item.Path ?? item.Name ?? "--Unknown--"); - - // This provides the ability to cancel just this one provider - var innerCancellationTokenSource = new CancellationTokenSource(); - - Kernel.Instance.ProviderManager.OnProviderRefreshBeginning(this, item, innerCancellationTokenSource); - - try - { - var task = FetchAsyncInternal(item, force, CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, innerCancellationTokenSource.Token).Token); - - await task.ConfigureAwait(false); - - if (task.IsFaulted) - { - // Log the AggregateException - if (task.Exception != null) - { - Logger.ErrorException("AggregateException:", task.Exception); - } - - return false; - } - - return task.Result; - } - catch (OperationCanceledException ex) - { - Logger.Info("{0} cancelled for {1}", GetType().Name, item.Name); - - // If the outer cancellation token is the one that caused the cancellation, throw it - if (cancellationToken.IsCancellationRequested && ex.CancellationToken == cancellationToken) - { - throw; - } - - return false; - } - catch (Exception ex) - { - Logger.ErrorException("failed refreshing {0}", ex, item.Name); - - SetLastRefreshed(item, DateTime.UtcNow, ProviderRefreshStatus.Failure); - return true; - } - finally - { - innerCancellationTokenSource.Dispose(); - - Kernel.Instance.ProviderManager.OnProviderRefreshCompleted(this, item); - } - } - - /// <summary> - /// Fetches metadata and returns true or false indicating if any work that requires persistence was done - /// </summary> - /// <param name="item">The item.</param> - /// <param name="force">if set to <c>true</c> [force].</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task{System.Boolean}.</returns> - protected abstract Task<bool> FetchAsyncInternal(BaseItem item, bool force, CancellationToken cancellationToken); + public abstract Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken); /// <summary> /// Gets the priority. @@ -332,23 +252,6 @@ namespace MediaBrowser.Controller.Providers public abstract MetadataProviderPriority Priority { get; } /// <summary> - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// </summary> - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// <summary> - /// Releases unmanaged and - optionally - managed resources. - /// </summary> - /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> - protected virtual void Dispose(bool dispose) - { - } - - /// <summary> /// Returns true or false indicating if the provider should refresh when the contents of it's directory changes /// </summary> /// <value><c>true</c> if [refresh on file system stamp change]; otherwise, <c>false</c>.</value> @@ -386,34 +289,4 @@ namespace MediaBrowser.Controller.Providers return item.FileSystemStamp; } } - - /// <summary> - /// Determines when a provider should execute, relative to others - /// </summary> - public enum MetadataProviderPriority - { - // Run this provider at the beginning - /// <summary> - /// The first - /// </summary> - First = 1, - - // Run this provider after all first priority providers - /// <summary> - /// The second - /// </summary> - Second = 2, - - // Run this provider after all second priority providers - /// <summary> - /// The third - /// </summary> - Third = 3, - - // Run this provider last - /// <summary> - /// The last - /// </summary> - Last = 4 - } } diff --git a/MediaBrowser.Controller/Providers/FolderProviderFromXml.cs b/MediaBrowser.Controller/Providers/FolderProviderFromXml.cs index 45a47a58d..d2c2d5b15 100644 --- a/MediaBrowser.Controller/Providers/FolderProviderFromXml.cs +++ b/MediaBrowser.Controller/Providers/FolderProviderFromXml.cs @@ -56,7 +56,7 @@ namespace MediaBrowser.Controller.Providers /// <param name="force">if set to <c>true</c> [force].</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{System.Boolean}.</returns> - protected override Task<bool> FetchAsyncInternal(BaseItem item, bool force, CancellationToken cancellationToken) + public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) { return Task.Run(() => Fetch(item, cancellationToken)); } diff --git a/MediaBrowser.Controller/Providers/IProviderManager.cs b/MediaBrowser.Controller/Providers/IProviderManager.cs new file mode 100644 index 000000000..902ed21bc --- /dev/null +++ b/MediaBrowser.Controller/Providers/IProviderManager.cs @@ -0,0 +1,51 @@ +using System.Collections.Generic; +using MediaBrowser.Controller.Entities; +using System; +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Controller.Providers +{ + public interface IProviderManager : IDisposable + { + /// <summary> + /// Downloads the and save image. + /// </summary> + /// <param name="item">The item.</param> + /// <param name="source">The source.</param> + /// <param name="targetName">Name of the target.</param> + /// <param name="resourcePool">The resource pool.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task{System.String}.</returns> + /// <exception cref="System.ArgumentNullException">item</exception> + Task<string> DownloadAndSaveImage(BaseItem item, string source, string targetName, SemaphoreSlim resourcePool, CancellationToken cancellationToken); + + /// <summary> + /// Saves to library filesystem. + /// </summary> + /// <param name="item">The item.</param> + /// <param name="path">The path.</param> + /// <param name="dataToSave">The data to save.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task.</returns> + /// <exception cref="System.ArgumentNullException"></exception> + Task SaveToLibraryFilesystem(BaseItem item, string path, Stream dataToSave, CancellationToken cancellationToken); + + /// <summary> + /// Executes the metadata providers. + /// </summary> + /// <param name="item">The item.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <param name="force">if set to <c>true</c> [force].</param> + /// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param> + /// <returns>Task{System.Boolean}.</returns> + Task<bool> ExecuteMetadataProviders(BaseItem item, CancellationToken cancellationToken, bool force = false, bool allowSlowProviders = true); + + /// <summary> + /// Adds the metadata providers. + /// </summary> + /// <param name="providers">The providers.</param> + void AddMetadataProviders(IEnumerable<BaseMetadataProvider> providers); + } +}
\ No newline at end of file diff --git a/MediaBrowser.Controller/Providers/ImageFromMediaLocationProvider.cs b/MediaBrowser.Controller/Providers/ImageFromMediaLocationProvider.cs index 4b337aadc..70de38743 100644 --- a/MediaBrowser.Controller/Providers/ImageFromMediaLocationProvider.cs +++ b/MediaBrowser.Controller/Providers/ImageFromMediaLocationProvider.cs @@ -53,13 +53,18 @@ namespace MediaBrowser.Controller.Providers } /// <summary> + /// The true task result + /// </summary> + protected static readonly Task<bool> TrueTaskResult = Task.FromResult(true); + + /// <summary> /// Fetches metadata and returns true or false indicating if any work that requires persistence was done /// </summary> /// <param name="item">The item.</param> /// <param name="force">if set to <c>true</c> [force].</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{System.Boolean}.</returns> - protected override Task<bool> FetchAsyncInternal(BaseItem item, bool force, CancellationToken cancellationToken) + public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); diff --git a/MediaBrowser.Controller/Providers/MediaInfo/BaseFFProbeProvider.cs b/MediaBrowser.Controller/Providers/MediaInfo/BaseFFProbeProvider.cs index 9fe2a6c01..253d4dfed 100644 --- a/MediaBrowser.Controller/Providers/MediaInfo/BaseFFProbeProvider.cs +++ b/MediaBrowser.Controller/Providers/MediaInfo/BaseFFProbeProvider.cs @@ -17,7 +17,7 @@ namespace MediaBrowser.Controller.Providers.MediaInfo /// Provides a base class for extracting media information through ffprobe /// </summary> /// <typeparam name="T"></typeparam> - public abstract class BaseFFProbeProvider<T> : BaseFFMpegProvider<T> + public abstract class BaseFFProbeProvider<T> : BaseFFMpegProvider<T>, IDisposable where T : BaseItem { protected BaseFFProbeProvider(ILogManager logManager, IServerConfigurationManager configurationManager) : base(logManager, configurationManager) @@ -69,7 +69,7 @@ namespace MediaBrowser.Controller.Providers.MediaInfo /// <param name="force">if set to <c>true</c> [force].</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{System.Boolean}.</returns> - protected override async Task<bool> FetchAsyncInternal(BaseItem item, bool force, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) { var myItem = (T)item; @@ -351,14 +351,17 @@ namespace MediaBrowser.Controller.Providers.MediaInfo /// Releases unmanaged and - optionally - managed resources. /// </summary> /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> - protected override void Dispose(bool dispose) + protected virtual void Dispose(bool dispose) { if (dispose) { FFProbeCache.Dispose(); } + } - base.Dispose(dispose); + public void Dispose() + { + Dispose(true); } } } diff --git a/MediaBrowser.Controller/Providers/MediaInfo/FFMpegAudioImageProvider.cs b/MediaBrowser.Controller/Providers/MediaInfo/FFMpegAudioImageProvider.cs index aedd03537..e752a863d 100644 --- a/MediaBrowser.Controller/Providers/MediaInfo/FFMpegAudioImageProvider.cs +++ b/MediaBrowser.Controller/Providers/MediaInfo/FFMpegAudioImageProvider.cs @@ -20,13 +20,18 @@ namespace MediaBrowser.Controller.Providers.MediaInfo } /// <summary> + /// The true task result + /// </summary> + protected static readonly Task<bool> TrueTaskResult = Task.FromResult(true); + + /// <summary> /// Fetches metadata and returns true or false indicating if any work that requires persistence was done /// </summary> /// <param name="item">The item.</param> /// <param name="force">if set to <c>true</c> [force].</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{System.Boolean}.</returns> - protected override Task<bool> FetchAsyncInternal(BaseItem item, bool force, CancellationToken cancellationToken) + public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) { var audio = (Audio)item; diff --git a/MediaBrowser.Controller/Providers/MediaInfo/FFMpegVideoImageProvider.cs b/MediaBrowser.Controller/Providers/MediaInfo/FFMpegVideoImageProvider.cs index a44acb8f6..5a8157ebf 100644 --- a/MediaBrowser.Controller/Providers/MediaInfo/FFMpegVideoImageProvider.cs +++ b/MediaBrowser.Controller/Providers/MediaInfo/FFMpegVideoImageProvider.cs @@ -60,13 +60,18 @@ namespace MediaBrowser.Controller.Providers.MediaInfo } /// <summary> + /// The true task result + /// </summary> + protected static readonly Task<bool> TrueTaskResult = Task.FromResult(true); + + /// <summary> /// Fetches metadata and returns true or false indicating if any work that requires persistence was done /// </summary> /// <param name="item">The item.</param> /// <param name="force">if set to <c>true</c> [force].</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{System.Boolean}.</returns> - protected override Task<bool> FetchAsyncInternal(BaseItem item, bool force, CancellationToken cancellationToken) + public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(item.PrimaryImagePath)) { diff --git a/MediaBrowser.Controller/Providers/MetadataProviderPriority.cs b/MediaBrowser.Controller/Providers/MetadataProviderPriority.cs new file mode 100644 index 000000000..9ddc0a33f --- /dev/null +++ b/MediaBrowser.Controller/Providers/MetadataProviderPriority.cs @@ -0,0 +1,33 @@ + +namespace MediaBrowser.Controller.Providers +{ + /// <summary> + /// Determines when a provider should execute, relative to others + /// </summary> + public enum MetadataProviderPriority + { + // Run this provider at the beginning + /// <summary> + /// The first + /// </summary> + First = 1, + + // Run this provider after all first priority providers + /// <summary> + /// The second + /// </summary> + Second = 2, + + // Run this provider after all second priority providers + /// <summary> + /// The third + /// </summary> + Third = 3, + + // Run this provider last + /// <summary> + /// The last + /// </summary> + Last = 4 + } +} diff --git a/MediaBrowser.Controller/Providers/Movies/FanArtMovieProvider.cs b/MediaBrowser.Controller/Providers/Movies/FanArtMovieProvider.cs index 9c71642e9..af613f023 100644 --- a/MediaBrowser.Controller/Providers/Movies/FanArtMovieProvider.cs +++ b/MediaBrowser.Controller/Providers/Movies/FanArtMovieProvider.cs @@ -17,7 +17,7 @@ namespace MediaBrowser.Controller.Providers.Movies /// <summary> /// Class FanArtMovieProvider /// </summary> - class FanArtMovieProvider : FanartBaseProvider + class FanArtMovieProvider : FanartBaseProvider, IDisposable { /// <summary> /// The fan art @@ -32,6 +32,8 @@ namespace MediaBrowser.Controller.Providers.Movies /// <value>The HTTP client.</value> protected IHttpClient HttpClient { get; private set; } + private readonly IProviderManager _providerManager; + /// <summary> /// Initializes a new instance of the <see cref="FanArtMovieProvider" /> class. /// </summary> @@ -39,7 +41,7 @@ namespace MediaBrowser.Controller.Providers.Movies /// <param name="logManager">The log manager.</param> /// <param name="configurationManager">The configuration manager.</param> /// <exception cref="System.ArgumentNullException">httpClient</exception> - public FanArtMovieProvider(IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager) + public FanArtMovieProvider(IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager) : base(logManager, configurationManager) { if (httpClient == null) @@ -47,19 +49,19 @@ namespace MediaBrowser.Controller.Providers.Movies throw new ArgumentNullException("httpClient"); } HttpClient = httpClient; + _providerManager = providerManager; } /// <summary> /// Releases unmanaged and - optionally - managed resources. /// </summary> /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> - protected override void Dispose(bool dispose) + protected virtual void Dispose(bool dispose) { if (dispose) { FanArtResourcePool.Dispose(); } - base.Dispose(dispose); } /// <summary> @@ -103,7 +105,7 @@ namespace MediaBrowser.Controller.Providers.Movies /// <param name="force">if set to <c>true</c> [force].</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{System.Boolean}.</returns> - protected override async Task<bool> FetchAsyncInternal(BaseItem item, bool force, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -147,7 +149,7 @@ namespace MediaBrowser.Controller.Providers.Movies Logger.Debug("FanArtProvider getting ClearLogo for " + movie.Name); try { - movie.SetImage(ImageType.Logo, await Kernel.Instance.ProviderManager.DownloadAndSaveImage(movie, path, LOGO_FILE, FanArtResourcePool, cancellationToken).ConfigureAwait(false)); + movie.SetImage(ImageType.Logo, await _providerManager.DownloadAndSaveImage(movie, path, LOGO_FILE, FanArtResourcePool, cancellationToken).ConfigureAwait(false)); } catch (HttpException) { @@ -173,7 +175,7 @@ namespace MediaBrowser.Controller.Providers.Movies Logger.Debug("FanArtProvider getting ClearArt for " + movie.Name); try { - movie.SetImage(ImageType.Art, await Kernel.Instance.ProviderManager.DownloadAndSaveImage(movie, path, ART_FILE, FanArtResourcePool, cancellationToken).ConfigureAwait(false)); + movie.SetImage(ImageType.Art, await _providerManager.DownloadAndSaveImage(movie, path, ART_FILE, FanArtResourcePool, cancellationToken).ConfigureAwait(false)); } catch (HttpException) { @@ -196,7 +198,7 @@ namespace MediaBrowser.Controller.Providers.Movies Logger.Debug("FanArtProvider getting DiscArt for " + movie.Name); try { - movie.SetImage(ImageType.Disc, await Kernel.Instance.ProviderManager.DownloadAndSaveImage(movie, path, DISC_FILE, FanArtResourcePool, cancellationToken).ConfigureAwait(false)); + movie.SetImage(ImageType.Disc, await _providerManager.DownloadAndSaveImage(movie, path, DISC_FILE, FanArtResourcePool, cancellationToken).ConfigureAwait(false)); } catch (HttpException) { @@ -220,7 +222,7 @@ namespace MediaBrowser.Controller.Providers.Movies Logger.Debug("FanArtProvider getting Banner for " + movie.Name); try { - movie.SetImage(ImageType.Banner, await Kernel.Instance.ProviderManager.DownloadAndSaveImage(movie, path, BANNER_FILE, FanArtResourcePool, cancellationToken).ConfigureAwait(false)); + movie.SetImage(ImageType.Banner, await _providerManager.DownloadAndSaveImage(movie, path, BANNER_FILE, FanArtResourcePool, cancellationToken).ConfigureAwait(false)); } catch (HttpException) { @@ -244,7 +246,7 @@ namespace MediaBrowser.Controller.Providers.Movies Logger.Debug("FanArtProvider getting Banner for " + movie.Name); try { - movie.SetImage(ImageType.Thumb, await Kernel.Instance.ProviderManager.DownloadAndSaveImage(movie, path, THUMB_FILE, FanArtResourcePool, cancellationToken).ConfigureAwait(false)); + movie.SetImage(ImageType.Thumb, await _providerManager.DownloadAndSaveImage(movie, path, THUMB_FILE, FanArtResourcePool, cancellationToken).ConfigureAwait(false)); } catch (HttpException) { @@ -260,5 +262,10 @@ namespace MediaBrowser.Controller.Providers.Movies SetLastRefreshed(movie, DateTime.UtcNow); return true; } + + public void Dispose() + { + Dispose(true); + } } } diff --git a/MediaBrowser.Controller/Providers/Movies/MovieDbProvider.cs b/MediaBrowser.Controller/Providers/Movies/MovieDbProvider.cs index 8d004a574..3eea0979c 100644 --- a/MediaBrowser.Controller/Providers/Movies/MovieDbProvider.cs +++ b/MediaBrowser.Controller/Providers/Movies/MovieDbProvider.cs @@ -30,8 +30,10 @@ namespace MediaBrowser.Controller.Providers.Movies /// <summary> /// Class MovieDbProvider /// </summary> - public class MovieDbProvider : BaseMetadataProvider + public class MovieDbProvider : BaseMetadataProvider, IDisposable { + protected readonly IProviderManager ProviderManager; + /// <summary> /// The movie db /// </summary> @@ -58,11 +60,12 @@ namespace MediaBrowser.Controller.Providers.Movies /// <param name="configurationManager">The configuration manager.</param> /// <param name="jsonSerializer">The json serializer.</param> /// <param name="httpClient">The HTTP client.</param> - public MovieDbProvider(ILogManager logManager, IServerConfigurationManager configurationManager, IJsonSerializer jsonSerializer, IHttpClient httpClient) + public MovieDbProvider(ILogManager logManager, IServerConfigurationManager configurationManager, IJsonSerializer jsonSerializer, IHttpClient httpClient, IProviderManager providerManager) : base(logManager, configurationManager) { JsonSerializer = jsonSerializer; HttpClient = httpClient; + ProviderManager = providerManager; Current = this; } @@ -70,13 +73,12 @@ namespace MediaBrowser.Controller.Providers.Movies /// Releases unmanaged and - optionally - managed resources. /// </summary> /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> - protected override void Dispose(bool dispose) + protected virtual void Dispose(bool dispose) { if (dispose) { MovieDbResourcePool.Dispose(); } - base.Dispose(dispose); } /// <summary> @@ -209,16 +211,17 @@ namespace MediaBrowser.Controller.Providers.Movies /// </summary> /// <param name="item">The item.</param> /// <param name="value">The value.</param> + /// <param name="providerVersion">The provider version.</param> /// <param name="status">The status.</param> - protected override void SetLastRefreshed(BaseItem item, DateTime value, ProviderRefreshStatus status = ProviderRefreshStatus.Success) + public override void SetLastRefreshed(BaseItem item, DateTime value, string providerVersion, ProviderRefreshStatus status = ProviderRefreshStatus.Success) { - base.SetLastRefreshed(item, value, status); + base.SetLastRefreshed(item, value, providerVersion, status); if (ConfigurationManager.Configuration.SaveLocalMeta) { //in addition to ours, we need to set the last refreshed time for the local data provider //so it won't see the new files we download and process them all over again - if (JsonProvider == null) JsonProvider = new MovieProviderFromJson(LogManager, ConfigurationManager, JsonSerializer, HttpClient); + if (JsonProvider == null) JsonProvider = new MovieProviderFromJson(LogManager, ConfigurationManager, JsonSerializer, HttpClient, ProviderManager); var data = item.ProviderData.GetValueOrDefault(JsonProvider.Id, new BaseProviderInfo { ProviderId = JsonProvider.Id }); data.LastRefreshed = value; item.ProviderData[JsonProvider.Id] = data; @@ -291,7 +294,7 @@ namespace MediaBrowser.Controller.Providers.Movies /// <param name="force">if set to <c>true</c> [force].</param> /// <param name="cancellationToken">The cancellation token</param> /// <returns>Task{System.Boolean}.</returns> - protected override async Task<bool> FetchAsyncInternal(BaseItem item, bool force, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) { if (HasAltMeta(item)) { @@ -724,7 +727,7 @@ namespace MediaBrowser.Controller.Providers.Movies cancellationToken.ThrowIfCancellationRequested(); - await Kernel.Instance.FileSystemManager.SaveToLibraryFilesystem(item, Path.Combine(item.MetaLocation, LOCAL_META_FILE_NAME), ms, cancellationToken).ConfigureAwait(false); + await ProviderManager.SaveToLibraryFilesystem(item, Path.Combine(item.MetaLocation, LOCAL_META_FILE_NAME), ms, cancellationToken).ConfigureAwait(false); } } @@ -1018,7 +1021,7 @@ namespace MediaBrowser.Controller.Providers.Movies { try { - item.PrimaryImagePath = await Kernel.Instance.ProviderManager.DownloadAndSaveImage(item, tmdbImageUrl + poster.file_path, "folder" + Path.GetExtension(poster.file_path), MovieDbResourcePool, cancellationToken).ConfigureAwait(false); + item.PrimaryImagePath = await ProviderManager.DownloadAndSaveImage(item, tmdbImageUrl + poster.file_path, "folder" + Path.GetExtension(poster.file_path), MovieDbResourcePool, cancellationToken).ConfigureAwait(false); } catch (HttpException) { @@ -1050,7 +1053,7 @@ namespace MediaBrowser.Controller.Providers.Movies { try { - item.BackdropImagePaths.Add(await Kernel.Instance.ProviderManager.DownloadAndSaveImage(item, tmdbImageUrl + images.backdrops[i].file_path, bdName + Path.GetExtension(images.backdrops[i].file_path), MovieDbResourcePool, cancellationToken).ConfigureAwait(false)); + item.BackdropImagePaths.Add(await ProviderManager.DownloadAndSaveImage(item, tmdbImageUrl + images.backdrops[i].file_path, bdName + Path.GetExtension(images.backdrops[i].file_path), MovieDbResourcePool, cancellationToken).ConfigureAwait(false)); } catch (HttpException) { @@ -1661,5 +1664,10 @@ namespace MediaBrowser.Controller.Providers.Movies public TmdbImageSettings images { get; set; } } #endregion + + public void Dispose() + { + Dispose(true); + } } } diff --git a/MediaBrowser.Controller/Providers/Movies/MovieProviderFromJson.cs b/MediaBrowser.Controller/Providers/Movies/MovieProviderFromJson.cs index 2a7a09625..b81e0c51d 100644 --- a/MediaBrowser.Controller/Providers/Movies/MovieProviderFromJson.cs +++ b/MediaBrowser.Controller/Providers/Movies/MovieProviderFromJson.cs @@ -15,8 +15,8 @@ namespace MediaBrowser.Controller.Providers.Movies /// </summary> public class MovieProviderFromJson : MovieDbProvider { - public MovieProviderFromJson(ILogManager logManager, IServerConfigurationManager configurationManager, IJsonSerializer jsonSerializer, IHttpClient httpClient) : - base(logManager, configurationManager, jsonSerializer, httpClient) + public MovieProviderFromJson(ILogManager logManager, IServerConfigurationManager configurationManager, IJsonSerializer jsonSerializer, IHttpClient httpClient, IProviderManager providerManager) + : base(logManager, configurationManager, jsonSerializer, httpClient, providerManager) { } @@ -79,7 +79,7 @@ namespace MediaBrowser.Controller.Providers.Movies /// <param name="force">if set to <c>true</c> [force].</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{System.Boolean}.</returns> - protected override Task<bool> FetchAsyncInternal(BaseItem item, bool force, CancellationToken cancellationToken) + public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) { // Since we don't have anything truly async, and since deserializing can be expensive, create a task to force parallelism return Task.Run(() => diff --git a/MediaBrowser.Controller/Providers/Movies/MovieProviderFromXml.cs b/MediaBrowser.Controller/Providers/Movies/MovieProviderFromXml.cs index 3e5a6fe8d..279533636 100644 --- a/MediaBrowser.Controller/Providers/Movies/MovieProviderFromXml.cs +++ b/MediaBrowser.Controller/Providers/Movies/MovieProviderFromXml.cs @@ -56,7 +56,7 @@ namespace MediaBrowser.Controller.Providers.Movies /// <param name="force">if set to <c>true</c> [force].</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{System.Boolean}.</returns> - protected override Task<bool> FetchAsyncInternal(BaseItem item, bool force, CancellationToken cancellationToken) + public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) { return Task.Run(() => Fetch(item, cancellationToken)); } diff --git a/MediaBrowser.Controller/Providers/Movies/PersonProviderFromJson.cs b/MediaBrowser.Controller/Providers/Movies/PersonProviderFromJson.cs index 278d67261..e89f1a044 100644 --- a/MediaBrowser.Controller/Providers/Movies/PersonProviderFromJson.cs +++ b/MediaBrowser.Controller/Providers/Movies/PersonProviderFromJson.cs @@ -15,8 +15,8 @@ namespace MediaBrowser.Controller.Providers.Movies /// </summary> class PersonProviderFromJson : TmdbPersonProvider { - public PersonProviderFromJson(IHttpClient httpClient, IJsonSerializer jsonSerializer, ILogManager logManager, IServerConfigurationManager configurationManager) : - base(httpClient, jsonSerializer, logManager, configurationManager) + public PersonProviderFromJson(IHttpClient httpClient, IJsonSerializer jsonSerializer, ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager) + : base(httpClient, jsonSerializer, logManager, configurationManager, providerManager) { } @@ -90,7 +90,7 @@ namespace MediaBrowser.Controller.Providers.Movies /// <param name="force">if set to <c>true</c> [force].</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{System.Boolean}.</returns> - protected override Task<bool> FetchAsyncInternal(BaseItem item, bool force, CancellationToken cancellationToken) + public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) { return Task.Run(() => { diff --git a/MediaBrowser.Controller/Providers/Movies/TmdbPersonProvider.cs b/MediaBrowser.Controller/Providers/Movies/TmdbPersonProvider.cs index 5c977a928..f721a04eb 100644 --- a/MediaBrowser.Controller/Providers/Movies/TmdbPersonProvider.cs +++ b/MediaBrowser.Controller/Providers/Movies/TmdbPersonProvider.cs @@ -26,7 +26,9 @@ namespace MediaBrowser.Controller.Providers.Movies /// </summary> protected const string MetaFileName = "MBPerson.json"; - public TmdbPersonProvider(IHttpClient httpClient, IJsonSerializer jsonSerializer, ILogManager logManager, IServerConfigurationManager configurationManager) + protected readonly IProviderManager ProviderManager; + + public TmdbPersonProvider(IHttpClient httpClient, IJsonSerializer jsonSerializer, ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager) : base(logManager, configurationManager) { if (jsonSerializer == null) @@ -39,6 +41,7 @@ namespace MediaBrowser.Controller.Providers.Movies } HttpClient = httpClient; JsonSerializer = jsonSerializer; + ProviderManager = providerManager; } /// <summary> @@ -83,7 +86,7 @@ namespace MediaBrowser.Controller.Providers.Movies /// <param name="force">if set to <c>true</c> [force].</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{System.Boolean}.</returns> - protected override async Task<bool> FetchAsyncInternal(BaseItem item, bool force, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -209,7 +212,7 @@ namespace MediaBrowser.Controller.Providers.Movies JsonSerializer.SerializeToStream(searchResult, memoryStream); - await Kernel.Instance.FileSystemManager.SaveToLibraryFilesystem(person, Path.Combine(person.MetaLocation, MetaFileName), memoryStream, cancellationToken); + await ProviderManager.SaveToLibraryFilesystem(person, Path.Combine(person.MetaLocation, MetaFileName), memoryStream, cancellationToken); Logger.Debug("TmdbPersonProvider downloaded and saved information for {0}", person.Name); } @@ -288,7 +291,7 @@ namespace MediaBrowser.Controller.Providers.Movies } if (profile != null) { - var tmdbSettings = await Kernel.Instance.MetadataProviders.OfType<MovieDbProvider>().First().TmdbSettings.ConfigureAwait(false); + var tmdbSettings = await MovieDbProvider.Current.TmdbSettings.ConfigureAwait(false); var img = await DownloadAndSaveImage(person, tmdbSettings.images.base_url + ConfigurationManager.Configuration.TmdbFetchedProfileSize + profile.File_Path, "folder" + Path.GetExtension(profile.File_Path), cancellationToken).ConfigureAwait(false); @@ -319,7 +322,7 @@ namespace MediaBrowser.Controller.Providers.Movies { using (var sourceStream = await HttpClient.GetMemoryStream(source, MovieDbProvider.Current.MovieDbResourcePool, cancellationToken).ConfigureAwait(false)) { - await Kernel.Instance.FileSystemManager.SaveToLibraryFilesystem(item, localPath, sourceStream, cancellationToken).ConfigureAwait(false); + await ProviderManager.SaveToLibraryFilesystem(item, localPath, sourceStream, cancellationToken).ConfigureAwait(false); Logger.Debug("TmdbPersonProvider downloaded and saved image for {0}", item.Name); } diff --git a/MediaBrowser.Controller/Providers/Music/FanArtAlbumProvider.cs b/MediaBrowser.Controller/Providers/Music/FanArtAlbumProvider.cs index 2d7284c80..331bd00da 100644 --- a/MediaBrowser.Controller/Providers/Music/FanArtAlbumProvider.cs +++ b/MediaBrowser.Controller/Providers/Music/FanArtAlbumProvider.cs @@ -15,8 +15,12 @@ namespace MediaBrowser.Controller.Providers.Music { public class FanArtAlbumProvider : FanartBaseProvider { - public FanArtAlbumProvider(ILogManager logManager, IServerConfigurationManager configurationManager) : base(logManager, configurationManager) + private readonly IProviderManager _providerManager; + + public FanArtAlbumProvider(ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager) + : base(logManager, configurationManager) { + _providerManager = providerManager; } public override bool Supports(BaseItem item) @@ -37,7 +41,7 @@ namespace MediaBrowser.Controller.Providers.Music DateTime.Today.Subtract(providerInfo.LastRefreshed).TotalDays > ConfigurationManager.Configuration.MetadataRefreshDays; } - protected override async Task<bool> FetchAsyncInternal(BaseItem item, bool force, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) { var mbid = item.GetProviderId(MetadataProviders.Musicbrainz); if (mbid == null) @@ -67,7 +71,7 @@ namespace MediaBrowser.Controller.Providers.Music return false; } - item.SetImage(ImageType.Primary, await Kernel.Instance.ProviderManager.DownloadAndSaveImage(item, cover, "folder.jpg", FanArtResourcePool, cancellationToken).ConfigureAwait(false)); + item.SetImage(ImageType.Primary, await _providerManager.DownloadAndSaveImage(item, cover, "folder.jpg", FanArtResourcePool, cancellationToken).ConfigureAwait(false)); return true; } } diff --git a/MediaBrowser.Controller/Providers/Music/FanArtArtistProvider.cs b/MediaBrowser.Controller/Providers/Music/FanArtArtistProvider.cs index 3834bff91..4846c8fdc 100644 --- a/MediaBrowser.Controller/Providers/Music/FanArtArtistProvider.cs +++ b/MediaBrowser.Controller/Providers/Music/FanArtArtistProvider.cs @@ -28,7 +28,9 @@ namespace MediaBrowser.Controller.Providers.Music /// <value>The HTTP client.</value> protected IHttpClient HttpClient { get; private set; } - public FanArtArtistProvider(IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager) + private readonly IProviderManager _providerManager; + + public FanArtArtistProvider(IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager) : base(logManager, configurationManager) { if (httpClient == null) @@ -36,6 +38,7 @@ namespace MediaBrowser.Controller.Providers.Music throw new ArgumentNullException("httpClient"); } HttpClient = httpClient; + _providerManager = providerManager; } /// <summary> @@ -80,7 +83,7 @@ namespace MediaBrowser.Controller.Providers.Music /// <param name="force">if set to <c>true</c> [force].</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{System.Boolean}.</returns> - protected override async Task<bool> FetchAsyncInternal(BaseItem item, bool force, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -118,7 +121,7 @@ namespace MediaBrowser.Controller.Providers.Music Logger.Debug("FanArtProvider getting ClearLogo for " + artist.Name); try { - artist.SetImage(ImageType.Logo, await Kernel.Instance.ProviderManager.DownloadAndSaveImage(artist, path, LOGO_FILE, FanArtResourcePool, cancellationToken).ConfigureAwait(false)); + artist.SetImage(ImageType.Logo, await _providerManager.DownloadAndSaveImage(artist, path, LOGO_FILE, FanArtResourcePool, cancellationToken).ConfigureAwait(false)); } catch (HttpException) { @@ -146,7 +149,7 @@ namespace MediaBrowser.Controller.Providers.Music Logger.Debug("FanArtProvider getting Backdrop for " + artist.Name); try { - artist.BackdropImagePaths.Add(await Kernel.Instance.ProviderManager.DownloadAndSaveImage(artist, path, ("Backdrop"+(numBackdrops > 0 ? numBackdrops.ToString() : "")+".jpg"), FanArtResourcePool, cancellationToken).ConfigureAwait(false)); + artist.BackdropImagePaths.Add(await _providerManager.DownloadAndSaveImage(artist, path, ("Backdrop" + (numBackdrops > 0 ? numBackdrops.ToString() : "") + ".jpg"), FanArtResourcePool, cancellationToken).ConfigureAwait(false)); numBackdrops++; if (numBackdrops >= ConfigurationManager.Configuration.MaxBackdrops) break; } @@ -203,7 +206,7 @@ namespace MediaBrowser.Controller.Providers.Music Logger.Debug("FanArtProvider getting ClearArt for " + artist.Name); try { - artist.SetImage(ImageType.Art, await Kernel.Instance.ProviderManager.DownloadAndSaveImage(artist, path, ART_FILE, FanArtResourcePool, cancellationToken).ConfigureAwait(false)); + artist.SetImage(ImageType.Art, await _providerManager.DownloadAndSaveImage(artist, path, ART_FILE, FanArtResourcePool, cancellationToken).ConfigureAwait(false)); } catch (HttpException) { @@ -226,7 +229,7 @@ namespace MediaBrowser.Controller.Providers.Music Logger.Debug("FanArtProvider getting Banner for " + artist.Name); try { - artist.SetImage(ImageType.Banner, await Kernel.Instance.ProviderManager.DownloadAndSaveImage(artist, path, BANNER_FILE, FanArtResourcePool, cancellationToken).ConfigureAwait(false)); + artist.SetImage(ImageType.Banner, await _providerManager.DownloadAndSaveImage(artist, path, BANNER_FILE, FanArtResourcePool, cancellationToken).ConfigureAwait(false)); } catch (HttpException) { @@ -250,7 +253,7 @@ namespace MediaBrowser.Controller.Providers.Music Logger.Debug("FanArtProvider getting Primary image for " + artist.Name); try { - artist.SetImage(ImageType.Primary, await Kernel.Instance.ProviderManager.DownloadAndSaveImage(artist, path, PRIMARY_FILE, FanArtResourcePool, cancellationToken).ConfigureAwait(false)); + artist.SetImage(ImageType.Primary, await _providerManager.DownloadAndSaveImage(artist, path, PRIMARY_FILE, FanArtResourcePool, cancellationToken).ConfigureAwait(false)); } catch (HttpException) { diff --git a/MediaBrowser.Controller/Providers/Music/LastfmAlbumProvider.cs b/MediaBrowser.Controller/Providers/Music/LastfmAlbumProvider.cs index 70de42f4d..7f2952c66 100644 --- a/MediaBrowser.Controller/Providers/Music/LastfmAlbumProvider.cs +++ b/MediaBrowser.Controller/Providers/Music/LastfmAlbumProvider.cs @@ -16,9 +16,12 @@ namespace MediaBrowser.Controller.Providers.Music { private static readonly Task<string> BlankId = Task.FromResult("0000"); - public LastfmAlbumProvider(IJsonSerializer jsonSerializer, IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager) + private readonly IProviderManager _providerManager; + + public LastfmAlbumProvider(IJsonSerializer jsonSerializer, IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager) : base(jsonSerializer, httpClient, logManager, configurationManager) { + _providerManager = providerManager; LocalMetaFileName = LastfmHelper.LocalAlbumMetaFileName; } @@ -62,7 +65,7 @@ namespace MediaBrowser.Controller.Providers.Music cancellationToken.ThrowIfCancellationRequested(); - await Kernel.Instance.FileSystemManager.SaveToLibraryFilesystem(item, Path.Combine(item.MetaLocation, LocalMetaFileName), ms, cancellationToken).ConfigureAwait(false); + await _providerManager.SaveToLibraryFilesystem(item, Path.Combine(item.MetaLocation, LocalMetaFileName), ms, cancellationToken).ConfigureAwait(false); } } diff --git a/MediaBrowser.Controller/Providers/Music/LastfmArtistProvider.cs b/MediaBrowser.Controller/Providers/Music/LastfmArtistProvider.cs index 29cb35cdc..016650071 100644 --- a/MediaBrowser.Controller/Providers/Music/LastfmArtistProvider.cs +++ b/MediaBrowser.Controller/Providers/Music/LastfmArtistProvider.cs @@ -19,10 +19,12 @@ namespace MediaBrowser.Controller.Providers.Music { public class LastfmArtistProvider : LastfmBaseProvider { - - public LastfmArtistProvider(IJsonSerializer jsonSerializer, IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager) + private readonly IProviderManager _providerManager; + + public LastfmArtistProvider(IJsonSerializer jsonSerializer, IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager) : base(jsonSerializer, httpClient, logManager, configurationManager) { + _providerManager = providerManager; LocalMetaFileName = LastfmHelper.LocalArtistMetaFileName; } @@ -91,7 +93,7 @@ namespace MediaBrowser.Controller.Providers.Music cancellationToken.ThrowIfCancellationRequested(); - await Kernel.Instance.FileSystemManager.SaveToLibraryFilesystem(item, Path.Combine(item.MetaLocation, LocalMetaFileName), ms, cancellationToken).ConfigureAwait(false); + await _providerManager.SaveToLibraryFilesystem(item, Path.Combine(item.MetaLocation, LocalMetaFileName), ms, cancellationToken).ConfigureAwait(false); } } diff --git a/MediaBrowser.Controller/Providers/Music/LastfmBaseProvider.cs b/MediaBrowser.Controller/Providers/Music/LastfmBaseProvider.cs index d8b4c387f..26817a41c 100644 --- a/MediaBrowser.Controller/Providers/Music/LastfmBaseProvider.cs +++ b/MediaBrowser.Controller/Providers/Music/LastfmBaseProvider.cs @@ -196,7 +196,7 @@ namespace MediaBrowser.Controller.Providers.Music /// <param name="force">if set to <c>true</c> [force].</param> /// <param name="cancellationToken">The cancellation token</param> /// <returns>Task{System.Boolean}.</returns> - protected override async Task<bool> FetchAsyncInternal(BaseItem item, bool force, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) { if (item.DontFetchMeta) { diff --git a/MediaBrowser.Controller/Providers/Music/MusicArtistProviderFromJson.cs b/MediaBrowser.Controller/Providers/Music/MusicArtistProviderFromJson.cs index fab468492..8b9b07bce 100644 --- a/MediaBrowser.Controller/Providers/Music/MusicArtistProviderFromJson.cs +++ b/MediaBrowser.Controller/Providers/Music/MusicArtistProviderFromJson.cs @@ -34,7 +34,7 @@ namespace MediaBrowser.Controller.Providers.Music } - protected override Task<bool> FetchAsyncInternal(BaseItem item, bool force, CancellationToken cancellationToken) + public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) { return Task.Run(() => { diff --git a/MediaBrowser.Controller/Providers/ProviderManager.cs b/MediaBrowser.Controller/Providers/ProviderManager.cs deleted file mode 100644 index 0df5f64d3..000000000 --- a/MediaBrowser.Controller/Providers/ProviderManager.cs +++ /dev/null @@ -1,372 +0,0 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.IO; -using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Model.Logging; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; - -namespace MediaBrowser.Controller.Providers -{ - /// <summary> - /// Class ProviderManager - /// </summary> - public class ProviderManager : IDisposable - { - /// <summary> - /// The remote image cache - /// </summary> - private readonly FileSystemRepository _remoteImageCache; - - /// <summary> - /// The currently running metadata providers - /// </summary> - private readonly ConcurrentDictionary<string, Tuple<BaseMetadataProvider, BaseItem, CancellationTokenSource>> _currentlyRunningProviders = - new ConcurrentDictionary<string, Tuple<BaseMetadataProvider, BaseItem, CancellationTokenSource>>(); - - /// <summary> - /// The _logger - /// </summary> - private readonly ILogger _logger; - - /// <summary> - /// The _HTTP client - /// </summary> - private readonly IHttpClient _httpClient; - - private IServerConfigurationManager ConfigurationManager { get; set; } - - private Kernel Kernel { get; set; } - - /// <summary> - /// Initializes a new instance of the <see cref="ProviderManager" /> class. - /// </summary> - /// <param name="kernel">The kernel.</param> - /// <param name="httpClient">The HTTP client.</param> - /// <param name="logger">The logger.</param> - public ProviderManager(Kernel kernel, IHttpClient httpClient, ILogger logger, IServerConfigurationManager configurationManager) - { - _logger = logger; - Kernel = kernel; - _httpClient = httpClient; - ConfigurationManager = configurationManager; - _remoteImageCache = new FileSystemRepository(ImagesDataPath); - - configurationManager.ConfigurationUpdated += configurationManager_ConfigurationUpdated; - } - - /// <summary> - /// Handles the ConfigurationUpdated event of the configurationManager control. - /// </summary> - /// <param name="sender">The source of the event.</param> - /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param> - void configurationManager_ConfigurationUpdated(object sender, EventArgs e) - { - // Validate currently executing providers, in the background - Task.Run(() => - { - ValidateCurrentlyRunningProviders(); - }); - } - - /// <summary> - /// The _images data path - /// </summary> - private string _imagesDataPath; - /// <summary> - /// Gets the images data path. - /// </summary> - /// <value>The images data path.</value> - public string ImagesDataPath - { - get - { - if (_imagesDataPath == null) - { - _imagesDataPath = Path.Combine(ConfigurationManager.ApplicationPaths.DataPath, "remote-images"); - - if (!Directory.Exists(_imagesDataPath)) - { - Directory.CreateDirectory(_imagesDataPath); - } - } - - return _imagesDataPath; - } - } - - /// <summary> - /// Gets or sets the supported providers key. - /// </summary> - /// <value>The supported providers key.</value> - private Guid SupportedProvidersKey { get; set; } - - /// <summary> - /// Runs all metadata providers for an entity, and returns true or false indicating if at least one was refreshed and requires persistence - /// </summary> - /// <param name="item">The item.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <param name="force">if set to <c>true</c> [force].</param> - /// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param> - /// <returns>Task{System.Boolean}.</returns> - internal async Task<bool> ExecuteMetadataProviders(BaseItem item, CancellationToken cancellationToken, bool force = false, bool allowSlowProviders = true) - { - // Allow providers of the same priority to execute in parallel - MetadataProviderPriority? currentPriority = null; - var currentTasks = new List<Task<bool>>(); - - var result = false; - - cancellationToken.ThrowIfCancellationRequested(); - - // Determine if supported providers have changed - var supportedProviders = Kernel.MetadataProviders.Where(p => p.Supports(item)).ToList(); - - BaseProviderInfo supportedProvidersInfo; - - if (SupportedProvidersKey == Guid.Empty) - { - SupportedProvidersKey = "SupportedProviders".GetMD5(); - } - - var supportedProvidersHash = string.Join("+", supportedProviders.Select(i => i.GetType().Name)).GetMD5(); - bool providersChanged; - - item.ProviderData.TryGetValue(SupportedProvidersKey, out supportedProvidersInfo); - if (supportedProvidersInfo == null) - { - // First time - supportedProvidersInfo = new BaseProviderInfo { ProviderId = SupportedProvidersKey, FileSystemStamp = supportedProvidersHash }; - providersChanged = force = true; - } - else - { - // Force refresh if the supported providers have changed - providersChanged = force = force || supportedProvidersInfo.FileSystemStamp != supportedProvidersHash; - } - - // If providers have changed, clear provider info and update the supported providers hash - if (providersChanged) - { - _logger.Debug("Providers changed for {0}. Clearing and forcing refresh.", item.Name); - item.ProviderData.Clear(); - supportedProvidersInfo.FileSystemStamp = supportedProvidersHash; - } - - if (force) item.ClearMetaValues(); - - // Run the normal providers sequentially in order of priority - foreach (var provider in supportedProviders) - { - cancellationToken.ThrowIfCancellationRequested(); - - // Skip if internet providers are currently disabled - if (provider.RequiresInternet && !ConfigurationManager.Configuration.EnableInternetProviders) - { - continue; - } - - // Skip if is slow and we aren't allowing slow ones - if (provider.IsSlow && !allowSlowProviders) - { - continue; - } - - // Skip if internet provider and this type is not allowed - if (provider.RequiresInternet && ConfigurationManager.Configuration.EnableInternetProviders && ConfigurationManager.Configuration.InternetProviderExcludeTypes.Contains(item.GetType().Name, StringComparer.OrdinalIgnoreCase)) - { - continue; - } - - // When a new priority is reached, await the ones that are currently running and clear the list - if (currentPriority.HasValue && currentPriority.Value != provider.Priority && currentTasks.Count > 0) - { - var results = await Task.WhenAll(currentTasks).ConfigureAwait(false); - result |= results.Contains(true); - - currentTasks.Clear(); - } - - // Put this check below the await because the needs refresh of the next tier of providers may depend on the previous ones running - // This is the case for the fan art provider which depends on the movie and tv providers having run before them - if (!force && !provider.NeedsRefresh(item)) - { - continue; - } - - currentTasks.Add(provider.FetchAsync(item, force, cancellationToken)); - currentPriority = provider.Priority; - } - - if (currentTasks.Count > 0) - { - var results = await Task.WhenAll(currentTasks).ConfigureAwait(false); - result |= results.Contains(true); - } - - if (providersChanged) - { - item.ProviderData[SupportedProvidersKey] = supportedProvidersInfo; - } - - return result || providersChanged; - } - - /// <summary> - /// Notifies the kernal that a provider has begun refreshing - /// </summary> - /// <param name="provider">The provider.</param> - /// <param name="item">The item.</param> - /// <param name="cancellationTokenSource">The cancellation token source.</param> - internal void OnProviderRefreshBeginning(BaseMetadataProvider provider, BaseItem item, CancellationTokenSource cancellationTokenSource) - { - var key = item.Id + provider.GetType().Name; - - Tuple<BaseMetadataProvider, BaseItem, CancellationTokenSource> current; - - if (_currentlyRunningProviders.TryGetValue(key, out current)) - { - try - { - current.Item3.Cancel(); - } - catch (ObjectDisposedException) - { - - } - } - - var tuple = new Tuple<BaseMetadataProvider, BaseItem, CancellationTokenSource>(provider, item, cancellationTokenSource); - - _currentlyRunningProviders.AddOrUpdate(key, tuple, (k, v) => tuple); - } - - /// <summary> - /// Notifies the kernal that a provider has completed refreshing - /// </summary> - /// <param name="provider">The provider.</param> - /// <param name="item">The item.</param> - internal void OnProviderRefreshCompleted(BaseMetadataProvider provider, BaseItem item) - { - var key = item.Id + provider.GetType().Name; - - Tuple<BaseMetadataProvider, BaseItem, CancellationTokenSource> current; - - if (_currentlyRunningProviders.TryRemove(key, out current)) - { - current.Item3.Dispose(); - } - } - - /// <summary> - /// Validates the currently running providers and cancels any that should not be run due to configuration changes - /// </summary> - internal void ValidateCurrentlyRunningProviders() - { - _logger.Info("Validing currently running providers"); - - var enableInternetProviders = ConfigurationManager.Configuration.EnableInternetProviders; - var internetProviderExcludeTypes = ConfigurationManager.Configuration.InternetProviderExcludeTypes; - - foreach (var tuple in _currentlyRunningProviders.Values - .Where(p => p.Item1.RequiresInternet && (!enableInternetProviders || internetProviderExcludeTypes.Contains(p.Item2.GetType().Name, StringComparer.OrdinalIgnoreCase))) - .ToList()) - { - tuple.Item3.Cancel(); - } - } - - /// <summary> - /// Downloads the and save image. - /// </summary> - /// <param name="item">The item.</param> - /// <param name="source">The source.</param> - /// <param name="targetName">Name of the target.</param> - /// <param name="resourcePool">The resource pool.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task{System.String}.</returns> - /// <exception cref="System.ArgumentNullException">item</exception> - public async Task<string> DownloadAndSaveImage(BaseItem item, string source, string targetName, SemaphoreSlim resourcePool, CancellationToken cancellationToken) - { - if (item == null) - { - throw new ArgumentNullException("item"); - } - if (string.IsNullOrEmpty(source)) - { - throw new ArgumentNullException("source"); - } - if (string.IsNullOrEmpty(targetName)) - { - throw new ArgumentNullException("targetName"); - } - if (resourcePool == null) - { - throw new ArgumentNullException("resourcePool"); - } - - //download and save locally - var localPath = ConfigurationManager.Configuration.SaveLocalMeta ? - Path.Combine(item.MetaLocation, targetName) : - _remoteImageCache.GetResourcePath(item.GetType().FullName + item.Path.ToLower(), targetName); - - var img = await _httpClient.GetMemoryStream(source, resourcePool, cancellationToken).ConfigureAwait(false); - - if (ConfigurationManager.Configuration.SaveLocalMeta) // queue to media directories - { - await Kernel.FileSystemManager.SaveToLibraryFilesystem(item, localPath, img, cancellationToken).ConfigureAwait(false); - } - else - { - // we can write directly here because it won't affect the watchers - - try - { - using (var fs = new FileStream(localPath, FileMode.Create, FileAccess.Write, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, FileOptions.Asynchronous)) - { - await img.CopyToAsync(fs, StreamDefaults.DefaultCopyToBufferSize, cancellationToken).ConfigureAwait(false); - } - } - catch (OperationCanceledException) - { - throw; - } - catch (Exception e) - { - _logger.ErrorException("Error downloading and saving image " + localPath, e); - throw; - } - finally - { - img.Dispose(); - } - - } - return localPath; - } - - /// <summary> - /// Releases unmanaged and - optionally - managed resources. - /// </summary> - /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> - protected virtual void Dispose(bool dispose) - { - if (dispose) - { - _remoteImageCache.Dispose(); - } - } - - public void Dispose() - { - Dispose(true); - } - } -} diff --git a/MediaBrowser.Controller/Providers/SortNameProvider.cs b/MediaBrowser.Controller/Providers/SortNameProvider.cs index 2214d8a08..c36bcb656 100644 --- a/MediaBrowser.Controller/Providers/SortNameProvider.cs +++ b/MediaBrowser.Controller/Providers/SortNameProvider.cs @@ -49,6 +49,17 @@ namespace MediaBrowser.Controller.Providers return !string.IsNullOrEmpty(item.Name) && string.IsNullOrEmpty(item.SortName); } + // Cache these since they will be used a lot + /// <summary> + /// The false task result + /// </summary> + protected static readonly Task<bool> FalseTaskResult = Task.FromResult(false); + + /// <summary> + /// The true task result + /// </summary> + protected static readonly Task<bool> TrueTaskResult = Task.FromResult(true); + /// <summary> /// Fetches metadata and returns true or false indicating if any work that requires persistence was done /// </summary> @@ -56,7 +67,7 @@ namespace MediaBrowser.Controller.Providers /// <param name="force">if set to <c>true</c> [force].</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{System.Boolean}.</returns> - protected override Task<bool> FetchAsyncInternal(BaseItem item, bool force, CancellationToken cancellationToken) + public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) { return SetSortName(item, cancellationToken) ? TrueTaskResult : FalseTaskResult; } diff --git a/MediaBrowser.Controller/Providers/TV/EpisodeImageFromMediaLocationProvider.cs b/MediaBrowser.Controller/Providers/TV/EpisodeImageFromMediaLocationProvider.cs index e4ef73892..ac22b43bf 100644 --- a/MediaBrowser.Controller/Providers/TV/EpisodeImageFromMediaLocationProvider.cs +++ b/MediaBrowser.Controller/Providers/TV/EpisodeImageFromMediaLocationProvider.cs @@ -51,13 +51,18 @@ namespace MediaBrowser.Controller.Providers.TV } /// <summary> + /// The true task result + /// </summary> + protected static readonly Task<bool> TrueTaskResult = Task.FromResult(true); + + /// <summary> /// Fetches metadata and returns true or false indicating if any work that requires persistence was done /// </summary> /// <param name="item">The item.</param> /// <param name="force">if set to <c>true</c> [force].</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{System.Boolean}.</returns> - protected override Task<bool> FetchAsyncInternal(BaseItem item, bool force, CancellationToken cancellationToken) + public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); diff --git a/MediaBrowser.Controller/Providers/TV/EpisodeProviderFromXml.cs b/MediaBrowser.Controller/Providers/TV/EpisodeProviderFromXml.cs index 1913397d4..483d1ddce 100644 --- a/MediaBrowser.Controller/Providers/TV/EpisodeProviderFromXml.cs +++ b/MediaBrowser.Controller/Providers/TV/EpisodeProviderFromXml.cs @@ -53,7 +53,7 @@ namespace MediaBrowser.Controller.Providers.TV /// <param name="force">if set to <c>true</c> [force].</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{System.Boolean}.</returns> - protected override Task<bool> FetchAsyncInternal(BaseItem item, bool force, CancellationToken cancellationToken) + public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) { return Task.Run(() => Fetch(item, cancellationToken)); } diff --git a/MediaBrowser.Controller/Providers/TV/FanArtTVProvider.cs b/MediaBrowser.Controller/Providers/TV/FanArtTVProvider.cs index 5dcead7b1..5690ba47f 100644 --- a/MediaBrowser.Controller/Providers/TV/FanArtTVProvider.cs +++ b/MediaBrowser.Controller/Providers/TV/FanArtTVProvider.cs @@ -25,7 +25,9 @@ namespace MediaBrowser.Controller.Providers.TV /// <value>The HTTP client.</value> protected IHttpClient HttpClient { get; private set; } - public FanArtTvProvider(IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager) + private readonly IProviderManager _providerManager; + + public FanArtTvProvider(IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager) : base(logManager, configurationManager) { if (httpClient == null) @@ -33,6 +35,7 @@ namespace MediaBrowser.Controller.Providers.TV throw new ArgumentNullException("httpClient"); } HttpClient = httpClient; + _providerManager = providerManager; } public override bool Supports(BaseItem item) @@ -53,7 +56,7 @@ namespace MediaBrowser.Controller.Providers.TV || (!thumbExists && ConfigurationManager.Configuration.DownloadSeriesImages.Thumb); } - protected override async Task<bool> FetchAsyncInternal(BaseItem item, bool force, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -90,7 +93,7 @@ namespace MediaBrowser.Controller.Providers.TV Logger.Debug("FanArtProvider getting ClearLogo for " + series.Name); try { - series.SetImage(ImageType.Logo, await Kernel.Instance.ProviderManager.DownloadAndSaveImage(series, path, LOGO_FILE, FanArtMovieProvider.Current.FanArtResourcePool, cancellationToken).ConfigureAwait(false)); + series.SetImage(ImageType.Logo, await _providerManager.DownloadAndSaveImage(series, path, LOGO_FILE, FanArtMovieProvider.Current.FanArtResourcePool, cancellationToken).ConfigureAwait(false)); } catch (HttpException) { @@ -114,7 +117,7 @@ namespace MediaBrowser.Controller.Providers.TV Logger.Debug("FanArtProvider getting ClearArt for " + series.Name); try { - series.SetImage(ImageType.Art, await Kernel.Instance.ProviderManager.DownloadAndSaveImage(series, path, ART_FILE, FanArtMovieProvider.Current.FanArtResourcePool, cancellationToken).ConfigureAwait(false)); + series.SetImage(ImageType.Art, await _providerManager.DownloadAndSaveImage(series, path, ART_FILE, FanArtMovieProvider.Current.FanArtResourcePool, cancellationToken).ConfigureAwait(false)); } catch (HttpException) { @@ -138,7 +141,7 @@ namespace MediaBrowser.Controller.Providers.TV Logger.Debug("FanArtProvider getting ThumbArt for " + series.Name); try { - series.SetImage(ImageType.Disc, await Kernel.Instance.ProviderManager.DownloadAndSaveImage(series, path, THUMB_FILE, FanArtMovieProvider.Current.FanArtResourcePool, cancellationToken).ConfigureAwait(false)); + series.SetImage(ImageType.Disc, await _providerManager.DownloadAndSaveImage(series, path, THUMB_FILE, FanArtMovieProvider.Current.FanArtResourcePool, cancellationToken).ConfigureAwait(false)); } catch (HttpException) { diff --git a/MediaBrowser.Controller/Providers/TV/RemoteEpisodeProvider.cs b/MediaBrowser.Controller/Providers/TV/RemoteEpisodeProvider.cs index eee43016c..46bb21c48 100644 --- a/MediaBrowser.Controller/Providers/TV/RemoteEpisodeProvider.cs +++ b/MediaBrowser.Controller/Providers/TV/RemoteEpisodeProvider.cs @@ -22,6 +22,8 @@ namespace MediaBrowser.Controller.Providers.TV /// </summary> class RemoteEpisodeProvider : BaseMetadataProvider { + private readonly IProviderManager _providerManager; + /// <summary> /// Gets the HTTP client. /// </summary> @@ -34,10 +36,11 @@ namespace MediaBrowser.Controller.Providers.TV /// <param name="httpClient">The HTTP client.</param> /// <param name="logManager">The log manager.</param> /// <param name="configurationManager">The configuration manager.</param> - public RemoteEpisodeProvider(IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager) + public RemoteEpisodeProvider(IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager) : base(logManager, configurationManager) { HttpClient = httpClient; + _providerManager = providerManager; } /// <summary> @@ -117,7 +120,7 @@ namespace MediaBrowser.Controller.Providers.TV /// <param name="item">The item.</param> /// <param name="force">if set to <c>true</c> [force].</param> /// <returns>Task{System.Boolean}.</returns> - protected override async Task<bool> FetchAsyncInternal(BaseItem item, bool force, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -229,7 +232,7 @@ namespace MediaBrowser.Controller.Providers.TV try { - episode.PrimaryImagePath = await Kernel.Instance.ProviderManager.DownloadAndSaveImage(episode, TVUtils.BannerUrl + p, Path.GetFileName(p), RemoteSeriesProvider.Current.TvDbResourcePool, cancellationToken); + episode.PrimaryImagePath = await _providerManager.DownloadAndSaveImage(episode, TVUtils.BannerUrl + p, Path.GetFileName(p), RemoteSeriesProvider.Current.TvDbResourcePool, cancellationToken); } catch (HttpException) { @@ -282,7 +285,7 @@ namespace MediaBrowser.Controller.Providers.TV var ms = new MemoryStream(); doc.Save(ms); - await Kernel.Instance.FileSystemManager.SaveToLibraryFilesystem(episode, Path.Combine(episode.MetaLocation, Path.GetFileNameWithoutExtension(episode.Path) + ".xml"), ms, cancellationToken).ConfigureAwait(false); + await _providerManager.SaveToLibraryFilesystem(episode, Path.Combine(episode.MetaLocation, Path.GetFileNameWithoutExtension(episode.Path) + ".xml"), ms, cancellationToken).ConfigureAwait(false); } return true; diff --git a/MediaBrowser.Controller/Providers/TV/RemoteSeasonProvider.cs b/MediaBrowser.Controller/Providers/TV/RemoteSeasonProvider.cs index 03d7d3353..f39e91834 100644 --- a/MediaBrowser.Controller/Providers/TV/RemoteSeasonProvider.cs +++ b/MediaBrowser.Controller/Providers/TV/RemoteSeasonProvider.cs @@ -25,8 +25,10 @@ namespace MediaBrowser.Controller.Providers.TV /// </summary> /// <value>The HTTP client.</value> protected IHttpClient HttpClient { get; private set; } + + private readonly IProviderManager _providerManager; - public RemoteSeasonProvider(IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager) + public RemoteSeasonProvider(IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager) : base(logManager, configurationManager) { if (httpClient == null) @@ -34,6 +36,7 @@ namespace MediaBrowser.Controller.Providers.TV throw new ArgumentNullException("httpClient"); } HttpClient = httpClient; + _providerManager = providerManager; } /// <summary> @@ -97,7 +100,7 @@ namespace MediaBrowser.Controller.Providers.TV /// <param name="force">if set to <c>true</c> [force].</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{System.Boolean}.</returns> - protected override async Task<bool> FetchAsyncInternal(BaseItem item, bool force, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -174,7 +177,7 @@ namespace MediaBrowser.Controller.Providers.TV try { if (n != null) - season.PrimaryImagePath = await Kernel.Instance.ProviderManager.DownloadAndSaveImage(season, TVUtils.BannerUrl + n.InnerText, "folder" + Path.GetExtension(n.InnerText), RemoteSeriesProvider.Current.TvDbResourcePool, cancellationToken).ConfigureAwait(false); + season.PrimaryImagePath = await _providerManager.DownloadAndSaveImage(season, TVUtils.BannerUrl + n.InnerText, "folder" + Path.GetExtension(n.InnerText), RemoteSeriesProvider.Current.TvDbResourcePool, cancellationToken).ConfigureAwait(false); } catch (HttpException) { @@ -197,8 +200,7 @@ namespace MediaBrowser.Controller.Providers.TV try { var bannerImagePath = - await - Kernel.Instance.ProviderManager.DownloadAndSaveImage(season, + await _providerManager.DownloadAndSaveImage(season, TVUtils.BannerUrl + n.InnerText, "banner" + Path.GetExtension(n.InnerText), @@ -229,7 +231,7 @@ namespace MediaBrowser.Controller.Providers.TV try { if (season.BackdropImagePaths == null) season.BackdropImagePaths = new List<string>(); - season.BackdropImagePaths.Add(await Kernel.Instance.ProviderManager.DownloadAndSaveImage(season, TVUtils.BannerUrl + n.InnerText, "backdrop" + Path.GetExtension(n.InnerText), RemoteSeriesProvider.Current.TvDbResourcePool, cancellationToken).ConfigureAwait(false)); + season.BackdropImagePaths.Add(await _providerManager.DownloadAndSaveImage(season, TVUtils.BannerUrl + n.InnerText, "backdrop" + Path.GetExtension(n.InnerText), RemoteSeriesProvider.Current.TvDbResourcePool, cancellationToken).ConfigureAwait(false)); } catch (HttpException) { @@ -257,8 +259,7 @@ namespace MediaBrowser.Controller.Providers.TV try { season.BackdropImagePaths.Add( - await - Kernel.Instance.ProviderManager.DownloadAndSaveImage(season, + await _providerManager.DownloadAndSaveImage(season, TVUtils.BannerUrl + n.InnerText, "backdrop" + diff --git a/MediaBrowser.Controller/Providers/TV/RemoteSeriesProvider.cs b/MediaBrowser.Controller/Providers/TV/RemoteSeriesProvider.cs index efb158b1e..ddc4e7fca 100644 --- a/MediaBrowser.Controller/Providers/TV/RemoteSeriesProvider.cs +++ b/MediaBrowser.Controller/Providers/TV/RemoteSeriesProvider.cs @@ -22,8 +22,10 @@ namespace MediaBrowser.Controller.Providers.TV /// <summary> /// Class RemoteSeriesProvider /// </summary> - class RemoteSeriesProvider : BaseMetadataProvider + class RemoteSeriesProvider : BaseMetadataProvider, IDisposable { + private readonly IProviderManager _providerManager; + /// <summary> /// The tv db /// </summary> @@ -44,7 +46,7 @@ namespace MediaBrowser.Controller.Providers.TV /// <param name="logManager">The log manager.</param> /// <param name="configurationManager">The configuration manager.</param> /// <exception cref="System.ArgumentNullException">httpClient</exception> - public RemoteSeriesProvider(IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager) + public RemoteSeriesProvider(IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager) : base(logManager, configurationManager) { if (httpClient == null) @@ -52,6 +54,7 @@ namespace MediaBrowser.Controller.Providers.TV throw new ArgumentNullException("httpClient"); } HttpClient = httpClient; + _providerManager = providerManager; Current = this; } @@ -59,13 +62,12 @@ namespace MediaBrowser.Controller.Providers.TV /// Releases unmanaged and - optionally - managed resources. /// </summary> /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> - protected override void Dispose(bool dispose) + protected virtual void Dispose(bool dispose) { if (dispose) { TvDbResourcePool.Dispose(); } - base.Dispose(dispose); } /// <summary> @@ -149,7 +151,7 @@ namespace MediaBrowser.Controller.Providers.TV /// <param name="force">if set to <c>true</c> [force].</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{System.Boolean}.</returns> - protected override async Task<bool> FetchAsyncInternal(BaseItem item, bool force, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -252,8 +254,8 @@ namespace MediaBrowser.Controller.Providers.TV { var ms = new MemoryStream(); doc.Save(ms); - - await Kernel.Instance.FileSystemManager.SaveToLibraryFilesystem(series, Path.Combine(series.MetaLocation, LOCAL_META_FILE_NAME), ms, cancellationToken).ConfigureAwait(false); + + await _providerManager.SaveToLibraryFilesystem(series, Path.Combine(series.MetaLocation, LOCAL_META_FILE_NAME), ms, cancellationToken).ConfigureAwait(false); } } } @@ -366,7 +368,7 @@ namespace MediaBrowser.Controller.Providers.TV { try { - series.PrimaryImagePath = await Kernel.Instance.ProviderManager.DownloadAndSaveImage(series, TVUtils.BannerUrl + n.InnerText, "folder" + Path.GetExtension(n.InnerText), TvDbResourcePool, cancellationToken).ConfigureAwait(false); + series.PrimaryImagePath = await _providerManager.DownloadAndSaveImage(series, TVUtils.BannerUrl + n.InnerText, "folder" + Path.GetExtension(n.InnerText), TvDbResourcePool, cancellationToken).ConfigureAwait(false); } catch (HttpException) { @@ -389,7 +391,7 @@ namespace MediaBrowser.Controller.Providers.TV { try { - var bannerImagePath = await Kernel.Instance.ProviderManager.DownloadAndSaveImage(series, TVUtils.BannerUrl + n.InnerText, "banner" + Path.GetExtension(n.InnerText), TvDbResourcePool, cancellationToken); + var bannerImagePath = await _providerManager.DownloadAndSaveImage(series, TVUtils.BannerUrl + n.InnerText, "banner" + Path.GetExtension(n.InnerText), TvDbResourcePool, cancellationToken); series.SetImage(ImageType.Banner, bannerImagePath); } @@ -418,7 +420,7 @@ namespace MediaBrowser.Controller.Providers.TV { try { - series.BackdropImagePaths.Add(await Kernel.Instance.ProviderManager.DownloadAndSaveImage(series, TVUtils.BannerUrl + p.InnerText, bdName + Path.GetExtension(p.InnerText), TvDbResourcePool, cancellationToken).ConfigureAwait(false)); + series.BackdropImagePaths.Add(await _providerManager.DownloadAndSaveImage(series, TVUtils.BannerUrl + p.InnerText, bdName + Path.GetExtension(p.InnerText), TvDbResourcePool, cancellationToken).ConfigureAwait(false)); } catch (HttpException) { @@ -584,7 +586,9 @@ namespace MediaBrowser.Controller.Providers.TV return name.Trim(); } - - + public void Dispose() + { + Dispose(true); + } } } diff --git a/MediaBrowser.Controller/Providers/TV/SeriesProviderFromXml.cs b/MediaBrowser.Controller/Providers/TV/SeriesProviderFromXml.cs index f9d409c18..8e42e9d55 100644 --- a/MediaBrowser.Controller/Providers/TV/SeriesProviderFromXml.cs +++ b/MediaBrowser.Controller/Providers/TV/SeriesProviderFromXml.cs @@ -57,7 +57,7 @@ namespace MediaBrowser.Controller.Providers.TV /// <param name="force">if set to <c>true</c> [force].</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{System.Boolean}.</returns> - protected override Task<bool> FetchAsyncInternal(BaseItem item, bool force, CancellationToken cancellationToken) + public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) { return Task.Run(() => Fetch(item, cancellationToken)); } |
