diff options
| author | Luke Pulverenti <luke.pulverenti@gmail.com> | 2013-12-06 15:07:34 -0500 |
|---|---|---|
| committer | Luke Pulverenti <luke.pulverenti@gmail.com> | 2013-12-06 15:07:34 -0500 |
| commit | 63c9104e624d0d22e6c5baf79db2d7bb9deb74d0 (patch) | |
| tree | e1669e9bc317952b51b2de6da5abf6dc73fd1d0e | |
| parent | 9f4f2281cdd9d3cdbb9b96c19b8034f235b36b80 (diff) | |
Pull ProviderData out of memory
54 files changed, 483 insertions, 346 deletions
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 7022dad7f..541887598 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -202,29 +202,6 @@ namespace MediaBrowser.Controller.Entities } /// <summary> - /// The _provider data - /// </summary> - private Dictionary<Guid, BaseProviderInfo> _providerData; - /// <summary> - /// Holds persistent data for providers like last refresh date. - /// Providers can use this to determine if they need to refresh. - /// The BaseProviderInfo class can be extended to hold anything a provider may need. - /// Keyed by a unique provider ID. - /// </summary> - /// <value>The provider data.</value> - public Dictionary<Guid, BaseProviderInfo> ProviderData - { - get - { - return _providerData ?? (_providerData = new Dictionary<Guid, BaseProviderInfo>()); - } - set - { - _providerData = value; - } - } - - /// <summary> /// Gets the type of the media. /// </summary> /// <value>The type of the media.</value> diff --git a/MediaBrowser.Controller/Persistence/IItemRepository.cs b/MediaBrowser.Controller/Persistence/IItemRepository.cs index 3a5cb4e87..3affe48e7 100644 --- a/MediaBrowser.Controller/Persistence/IItemRepository.cs +++ b/MediaBrowser.Controller/Persistence/IItemRepository.cs @@ -1,4 +1,5 @@ using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; using System; using System.Collections.Generic; @@ -111,6 +112,22 @@ namespace MediaBrowser.Controller.Persistence /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> Task SaveMediaStreams(Guid id, IEnumerable<MediaStream> streams, CancellationToken cancellationToken); + + /// <summary> + /// Gets the provider history. + /// </summary> + /// <param name="itemId">The item identifier.</param> + /// <returns>IEnumerable{BaseProviderInfo}.</returns> + IEnumerable<BaseProviderInfo> GetProviderHistory(Guid itemId); + + /// <summary> + /// Saves the provider history. + /// </summary> + /// <param name="id">The identifier.</param> + /// <param name="history">The history.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task.</returns> + Task SaveProviderHistory(Guid id, IEnumerable<BaseProviderInfo> history, CancellationToken cancellationToken); } } diff --git a/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs b/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs index 07bb7d5b2..40afe0b54 100644 --- a/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs +++ b/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs @@ -36,7 +36,7 @@ namespace MediaBrowser.Controller.Providers /// <summary> /// The _id /// </summary> - protected readonly Guid Id; + public readonly Guid Id; /// <summary> /// The true task result @@ -132,41 +132,33 @@ namespace MediaBrowser.Controller.Providers /// <param name="item">The item.</param> /// <param name="value">The value.</param> /// <param name="providerVersion">The provider version.</param> + /// <param name="providerInfo">The provider information.</param> /// <param name="status">The status.</param> /// <exception cref="System.ArgumentNullException">item</exception> public virtual void SetLastRefreshed(BaseItem item, DateTime value, string providerVersion, - ProviderRefreshStatus status = ProviderRefreshStatus.Success) + BaseProviderInfo providerInfo, ProviderRefreshStatus status = ProviderRefreshStatus.Success) { if (item == null) { throw new ArgumentNullException("item"); } - BaseProviderInfo data; - - if (!item.ProviderData.TryGetValue(Id, out data)) - { - data = new BaseProviderInfo(); - } - - data.LastRefreshed = value; - data.LastRefreshStatus = status; - data.ProviderVersion = providerVersion; + providerInfo.LastRefreshed = value; + providerInfo.LastRefreshStatus = status; + providerInfo.ProviderVersion = providerVersion; // Save the file system stamp for future comparisons if (RefreshOnFileSystemStampChange && item.LocationType == LocationType.FileSystem) { try { - data.FileStamp = GetCurrentFileSystemStamp(item); + providerInfo.FileStamp = GetCurrentFileSystemStamp(item); } catch (IOException ex) { Logger.ErrorException("Error getting file stamp for {0}", ex, item.Path); } } - - item.ProviderData[Id] = data; } /// <summary> @@ -174,11 +166,12 @@ namespace MediaBrowser.Controller.Providers /// </summary> /// <param name="item">The item.</param> /// <param name="value">The value.</param> + /// <param name="providerInfo">The provider information.</param> /// <param name="status">The status.</param> public void SetLastRefreshed(BaseItem item, DateTime value, - ProviderRefreshStatus status = ProviderRefreshStatus.Success) + BaseProviderInfo providerInfo, ProviderRefreshStatus status = ProviderRefreshStatus.Success) { - SetLastRefreshed(item, value, ProviderVersion, status); + SetLastRefreshed(item, value, ProviderVersion, providerInfo, status); } /// <summary> @@ -189,20 +182,13 @@ namespace MediaBrowser.Controller.Providers /// <param name="item">The item.</param> /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns> /// <exception cref="System.ArgumentNullException"></exception> - public bool NeedsRefresh(BaseItem item) + public bool NeedsRefresh(BaseItem item, BaseProviderInfo data) { if (item == null) { throw new ArgumentNullException(); } - BaseProviderInfo data; - - if (!item.ProviderData.TryGetValue(Id, out data)) - { - data = new BaseProviderInfo(); - } - return NeedsRefreshInternal(item, data); } @@ -299,10 +285,11 @@ namespace MediaBrowser.Controller.Providers /// </summary> /// <param name="item">The item.</param> /// <param name="force">if set to <c>true</c> [force].</param> + /// <param name="providerInfo">The provider information.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{System.Boolean}.</returns> /// <exception cref="System.ArgumentNullException"></exception> - public abstract Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken); + public abstract Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken); /// <summary> /// Gets the priority. diff --git a/MediaBrowser.Controller/Providers/BaseProviderInfo.cs b/MediaBrowser.Controller/Providers/BaseProviderInfo.cs index 243ce32af..829dd34c8 100644 --- a/MediaBrowser.Controller/Providers/BaseProviderInfo.cs +++ b/MediaBrowser.Controller/Providers/BaseProviderInfo.cs @@ -7,6 +7,7 @@ namespace MediaBrowser.Controller.Providers /// </summary> public class BaseProviderInfo { + public Guid ProviderId { get; set; } /// <summary> /// Gets or sets the last refreshed. /// </summary> diff --git a/MediaBrowser.Providers/FolderProviderFromXml.cs b/MediaBrowser.Providers/FolderProviderFromXml.cs index 253ff6785..31e4bc8bc 100644 --- a/MediaBrowser.Providers/FolderProviderFromXml.cs +++ b/MediaBrowser.Providers/FolderProviderFromXml.cs @@ -61,20 +61,10 @@ namespace MediaBrowser.Providers /// </summary> /// <param name="item">The item.</param> /// <param name="force">if set to <c>true</c> [force].</param> + /// <param name="providerInfo">The provider information.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{System.Boolean}.</returns> - public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) - { - return Fetch(item, cancellationToken); - } - - /// <summary> - /// Fetches the specified item. - /// </summary> - /// <param name="item">The item.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns> - private async Task<bool> Fetch(BaseItem item, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -94,12 +84,10 @@ namespace MediaBrowser.Providers { XmlParsingResourcePool.Release(); } - - SetLastRefreshed(item, DateTime.UtcNow); - return true; } - return false; + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); + return true; } } } diff --git a/MediaBrowser.Providers/Games/GameProviderFromXml.cs b/MediaBrowser.Providers/Games/GameProviderFromXml.cs index dcde7df49..ab1f96a8e 100644 --- a/MediaBrowser.Providers/Games/GameProviderFromXml.cs +++ b/MediaBrowser.Providers/Games/GameProviderFromXml.cs @@ -57,19 +57,9 @@ namespace MediaBrowser.Providers.Games /// <param name="force"></param> /// <param name="cancellationToken"></param> /// <returns></returns> - public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) - { - return Fetch((Game)item, cancellationToken); - } - - /// <summary> - /// - /// </summary> - /// <param name="game"></param> - /// <param name="cancellationToken"></param> - /// <returns></returns> - private async Task<bool> Fetch(Game game, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { + var game = (Game)item; cancellationToken.ThrowIfCancellationRequested(); var metaFile = GameXmlSaver.GetGameSavePath(game); @@ -88,7 +78,7 @@ namespace MediaBrowser.Providers.Games } } - SetLastRefreshed(game, DateTime.UtcNow); + SetLastRefreshed(game, DateTime.UtcNow, providerInfo); return true; } diff --git a/MediaBrowser.Providers/Games/GameSystemProviderFromXml.cs b/MediaBrowser.Providers/Games/GameSystemProviderFromXml.cs index 12ae4b75b..58143ce3d 100644 --- a/MediaBrowser.Providers/Games/GameSystemProviderFromXml.cs +++ b/MediaBrowser.Providers/Games/GameSystemProviderFromXml.cs @@ -60,18 +60,7 @@ namespace MediaBrowser.Providers.Games /// <param name="force">if set to <c>true</c> [force].</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{System.Boolean}.</returns> - public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) - { - return Fetch(item, cancellationToken); - } - - /// <summary> - /// Fetches the specified item. - /// </summary> - /// <param name="item">The item.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns> - private async Task<bool> Fetch(BaseItem item, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -92,7 +81,7 @@ namespace MediaBrowser.Providers.Games XmlParsingResourcePool.Release(); } - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } diff --git a/MediaBrowser.Providers/ImageFromMediaLocationProvider.cs b/MediaBrowser.Providers/ImageFromMediaLocationProvider.cs index 3914ba264..08e62afc5 100644 --- a/MediaBrowser.Providers/ImageFromMediaLocationProvider.cs +++ b/MediaBrowser.Providers/ImageFromMediaLocationProvider.cs @@ -97,7 +97,7 @@ namespace MediaBrowser.Providers /// <param name="force">if set to <c>true</c> [force].</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{System.Boolean}.</returns> - public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) + public override Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -121,7 +121,7 @@ namespace MediaBrowser.Providers PopulateBaseItemImages(item, args); - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return TrueTaskResult; } diff --git a/MediaBrowser.Providers/LiveTv/ChannelProviderFromXml.cs b/MediaBrowser.Providers/LiveTv/ChannelProviderFromXml.cs index 73564fa2b..b0bc1b875 100644 --- a/MediaBrowser.Providers/LiveTv/ChannelProviderFromXml.cs +++ b/MediaBrowser.Providers/LiveTv/ChannelProviderFromXml.cs @@ -60,18 +60,7 @@ namespace MediaBrowser.Providers.LiveTv /// <param name="force">if set to <c>true</c> [force].</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{System.Boolean}.</returns> - public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) - { - return Fetch(item, cancellationToken); - } - - /// <summary> - /// Fetches the specified item. - /// </summary> - /// <param name="item">The item.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns> - private async Task<bool> Fetch(BaseItem item, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -92,7 +81,7 @@ namespace MediaBrowser.Providers.LiveTv XmlParsingResourcePool.Release(); } - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } diff --git a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs index 914f5b290..264b24b87 100644 --- a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs @@ -121,7 +121,7 @@ namespace MediaBrowser.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> - public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { item.ValidateImages(); @@ -139,7 +139,7 @@ namespace MediaBrowser.Providers.MediaInfo } } - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfoProvider.cs b/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfoProvider.cs index 42ba2d7b0..673abea57 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfoProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfoProvider.cs @@ -4,6 +4,7 @@ using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Persistence; +using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; @@ -28,7 +29,7 @@ namespace MediaBrowser.Providers.MediaInfo _itemRepo = itemRepo; } - public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { var myItem = (Audio)item; @@ -44,7 +45,7 @@ namespace MediaBrowser.Providers.MediaInfo await Fetch(myItem, cancellationToken, result).ConfigureAwait(false); - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfoProvider.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfoProvider.cs index c09076bff..7e3e3da3b 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfoProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfoProvider.cs @@ -138,7 +138,7 @@ namespace MediaBrowser.Providers.MediaInfo base.OnPreFetch(item, mount); } - public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { var video = (Video)item; @@ -154,7 +154,7 @@ namespace MediaBrowser.Providers.MediaInfo if (video.PlayableStreamFileNames.Count == 0) { Logger.Error("No playable vobs found in dvd structure, skipping ffprobe."); - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } } @@ -167,7 +167,7 @@ namespace MediaBrowser.Providers.MediaInfo cancellationToken.ThrowIfCancellationRequested(); - await Fetch(video, force, cancellationToken, result, isoMount).ConfigureAwait(false); + await Fetch(video, force, providerInfo, cancellationToken, result, isoMount).ConfigureAwait(false); } finally @@ -178,7 +178,7 @@ namespace MediaBrowser.Providers.MediaInfo } } - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } @@ -291,7 +291,7 @@ namespace MediaBrowser.Providers.MediaInfo /// <param name="data">The data.</param> /// <param name="isoMount">The iso mount.</param> /// <returns>Task.</returns> - protected async Task Fetch(Video video, bool force, CancellationToken cancellationToken, MediaInfoResult data, IIsoMount isoMount) + protected async Task Fetch(Video video, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken, MediaInfoResult data, IIsoMount isoMount) { if (data.format != null) { @@ -345,13 +345,7 @@ namespace MediaBrowser.Providers.MediaInfo await Kernel.Instance.FFMpegManager.PopulateChapterImages(video, chapters, false, false, cancellationToken).ConfigureAwait(false); - BaseProviderInfo providerInfo; - var videoFileChanged = false; - - if (video.ProviderData.TryGetValue(Id, out providerInfo)) - { - videoFileChanged = CompareDate(video) > providerInfo.LastRefreshed; - } + var videoFileChanged = CompareDate(video) > providerInfo.LastRefreshed; await _itemRepo.SaveMediaStreams(video.Id, mediaStreams, cancellationToken).ConfigureAwait(false); diff --git a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs index 551f9d8f2..2864983ce 100644 --- a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs @@ -171,7 +171,7 @@ namespace MediaBrowser.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> - public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { item.ValidateImages(); @@ -192,7 +192,7 @@ namespace MediaBrowser.Providers.MediaInfo } } - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } diff --git a/MediaBrowser.Providers/Movies/BoxSetProviderFromXml.cs b/MediaBrowser.Providers/Movies/BoxSetProviderFromXml.cs index 43c0bd680..7c88243b3 100644 --- a/MediaBrowser.Providers/Movies/BoxSetProviderFromXml.cs +++ b/MediaBrowser.Providers/Movies/BoxSetProviderFromXml.cs @@ -65,18 +65,7 @@ namespace MediaBrowser.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> - public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) - { - return Fetch(item, cancellationToken); - } - - /// <summary> - /// Fetches the specified item. - /// </summary> - /// <param name="item">The item.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns> - private async Task<bool> Fetch(BaseItem item, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -97,7 +86,7 @@ namespace MediaBrowser.Providers.Movies XmlParsingResourcePool.Release(); } - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } diff --git a/MediaBrowser.Providers/Movies/FanArtMovieProvider.cs b/MediaBrowser.Providers/Movies/FanArtMovieProvider.cs index be195d6d2..e483b1d61 100644 --- a/MediaBrowser.Providers/Movies/FanArtMovieProvider.cs +++ b/MediaBrowser.Providers/Movies/FanArtMovieProvider.cs @@ -187,7 +187,7 @@ namespace MediaBrowser.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> - public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -208,7 +208,7 @@ namespace MediaBrowser.Providers.Movies await FetchImages(item, images.ToList(), cancellationToken).ConfigureAwait(false); } - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } diff --git a/MediaBrowser.Providers/Movies/MovieDbImagesProvider.cs b/MediaBrowser.Providers/Movies/MovieDbImagesProvider.cs index d2a12ac21..d63fcec5c 100644 --- a/MediaBrowser.Providers/Movies/MovieDbImagesProvider.cs +++ b/MediaBrowser.Providers/Movies/MovieDbImagesProvider.cs @@ -164,13 +164,13 @@ namespace MediaBrowser.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> - public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { var images = await _providerManager.GetAvailableRemoteImages(item, cancellationToken, ManualMovieDbImageProvider.ProviderName).ConfigureAwait(false); await ProcessImages(item, images.ToList(), cancellationToken).ConfigureAwait(false); - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } diff --git a/MediaBrowser.Providers/Movies/MovieDbPersonImageProvider.cs b/MediaBrowser.Providers/Movies/MovieDbPersonImageProvider.cs index 43550c358..8fa2ea249 100644 --- a/MediaBrowser.Providers/Movies/MovieDbPersonImageProvider.cs +++ b/MediaBrowser.Providers/Movies/MovieDbPersonImageProvider.cs @@ -161,13 +161,13 @@ namespace MediaBrowser.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> - public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { var images = await _providerManager.GetAvailableRemoteImages(item, cancellationToken, ManualMovieDbPersonImageProvider.ProviderName).ConfigureAwait(false); await ProcessImages(item, images.ToList(), cancellationToken).ConfigureAwait(false); - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } diff --git a/MediaBrowser.Providers/Movies/MovieDbPersonProvider.cs b/MediaBrowser.Providers/Movies/MovieDbPersonProvider.cs index af9bef448..3efd8d7fe 100644 --- a/MediaBrowser.Providers/Movies/MovieDbPersonProvider.cs +++ b/MediaBrowser.Providers/Movies/MovieDbPersonProvider.cs @@ -91,7 +91,7 @@ namespace MediaBrowser.Providers.Movies return base.NeedsRefreshInternal(item, providerInfo); } - + protected override bool NeedsRefreshBasedOnCompareDate(BaseItem item, BaseProviderInfo providerInfo) { var provderId = item.GetProviderId(MetadataProviders.Tmdb); @@ -152,7 +152,7 @@ namespace MediaBrowser.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> - public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -173,7 +173,7 @@ namespace MediaBrowser.Providers.Movies await FetchInfo(person, id, force, cancellationToken).ConfigureAwait(false); } - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } diff --git a/MediaBrowser.Providers/Movies/MovieDbProvider.cs b/MediaBrowser.Providers/Movies/MovieDbProvider.cs index fb75a9499..ecf5a5951 100644 --- a/MediaBrowser.Providers/Movies/MovieDbProvider.cs +++ b/MediaBrowser.Providers/Movies/MovieDbProvider.cs @@ -252,7 +252,7 @@ namespace MediaBrowser.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> - public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -275,7 +275,7 @@ namespace MediaBrowser.Providers.Movies await FetchMovieData(item, id, force, cancellationToken).ConfigureAwait(false); } - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } diff --git a/MediaBrowser.Providers/Movies/MovieProviderFromXml.cs b/MediaBrowser.Providers/Movies/MovieProviderFromXml.cs index ff6339034..bb1299f67 100644 --- a/MediaBrowser.Providers/Movies/MovieProviderFromXml.cs +++ b/MediaBrowser.Providers/Movies/MovieProviderFromXml.cs @@ -81,18 +81,7 @@ namespace MediaBrowser.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> - public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) - { - return Fetch(item, cancellationToken); - } - - /// <summary> - /// Fetches the specified item. - /// </summary> - /// <param name="item">The item.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns> - private async Task<bool> Fetch(BaseItem item, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -114,7 +103,7 @@ namespace MediaBrowser.Providers.Movies } } - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } diff --git a/MediaBrowser.Providers/Movies/OpenMovieDatabaseProvider.cs b/MediaBrowser.Providers/Movies/OpenMovieDatabaseProvider.cs index d881859c6..379b7c62c 100644 --- a/MediaBrowser.Providers/Movies/OpenMovieDatabaseProvider.cs +++ b/MediaBrowser.Providers/Movies/OpenMovieDatabaseProvider.cs @@ -107,13 +107,13 @@ namespace MediaBrowser.Providers.Movies protected readonly CultureInfo UsCulture = new CultureInfo("en-US"); - public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { var imdbId = item.GetProviderId(MetadataProviders.Imdb); if (string.IsNullOrEmpty(imdbId)) { - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } @@ -174,7 +174,7 @@ namespace MediaBrowser.Providers.Movies ParseAdditionalMetadata(item, result); } - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } diff --git a/MediaBrowser.Providers/Movies/PersonProviderFromXml.cs b/MediaBrowser.Providers/Movies/PersonProviderFromXml.cs index 1422fffa9..60722f980 100644 --- a/MediaBrowser.Providers/Movies/PersonProviderFromXml.cs +++ b/MediaBrowser.Providers/Movies/PersonProviderFromXml.cs @@ -59,18 +59,7 @@ namespace MediaBrowser.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> - public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) - { - return Fetch(item, cancellationToken); - } - - /// <summary> - /// Fetches the specified item. - /// </summary> - /// <param name="item">The item.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns> - private async Task<bool> Fetch(BaseItem item, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -91,7 +80,7 @@ namespace MediaBrowser.Providers.Movies XmlParsingResourcePool.Release(); } - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } diff --git a/MediaBrowser.Providers/Music/AlbumInfoFromSongProvider.cs b/MediaBrowser.Providers/Music/AlbumInfoFromSongProvider.cs index da49d36ed..c4b4af97f 100644 --- a/MediaBrowser.Providers/Music/AlbumInfoFromSongProvider.cs +++ b/MediaBrowser.Providers/Music/AlbumInfoFromSongProvider.cs @@ -84,17 +84,10 @@ namespace MediaBrowser.Providers.Music return string.Join(string.Empty, albumArtistNames.OrderBy(i => i).ToArray()).GetMD5(); } - public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) + public override Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { var album = (MusicAlbum)item; - BaseProviderInfo data; - if (!item.ProviderData.TryGetValue(Id, out data)) - { - data = new BaseProviderInfo(); - item.ProviderData[Id] = data; - } - var songs = album.RecursiveChildren.OfType<Audio>().ToList(); if (!item.LockedFields.Contains(MetadataFields.Name)) @@ -148,9 +141,9 @@ namespace MediaBrowser.Providers.Music } - data.FileStamp = GetComparisonData(songs); + providerInfo.FileStamp = GetComparisonData(songs); - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return TrueTaskResult; } diff --git a/MediaBrowser.Providers/Music/AlbumProviderFromXml.cs b/MediaBrowser.Providers/Music/AlbumProviderFromXml.cs index 02730b725..32d45d1ae 100644 --- a/MediaBrowser.Providers/Music/AlbumProviderFromXml.cs +++ b/MediaBrowser.Providers/Music/AlbumProviderFromXml.cs @@ -61,18 +61,7 @@ namespace MediaBrowser.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> - public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) - { - return Fetch(item, cancellationToken); - } - - /// <summary> - /// Fetches the specified item. - /// </summary> - /// <param name="item">The item.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns> - private async Task<bool> Fetch(BaseItem item, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -93,7 +82,7 @@ namespace MediaBrowser.Providers.Music XmlParsingResourcePool.Release(); } - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } diff --git a/MediaBrowser.Providers/Music/ArtistInfoFromSongProvider.cs b/MediaBrowser.Providers/Music/ArtistInfoFromSongProvider.cs index 7069e65ef..05f7d4efe 100644 --- a/MediaBrowser.Providers/Music/ArtistInfoFromSongProvider.cs +++ b/MediaBrowser.Providers/Music/ArtistInfoFromSongProvider.cs @@ -61,19 +61,12 @@ namespace MediaBrowser.Providers.Music return string.Join(string.Empty, genres.OrderBy(i => i).ToArray()).GetMD5(); } - public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) + public override Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { var artist = (MusicArtist)item; if (!artist.IsAccessedByName) { - BaseProviderInfo data; - if (!item.ProviderData.TryGetValue(Id, out data)) - { - data = new BaseProviderInfo(); - item.ProviderData[Id] = data; - } - var songs = artist.RecursiveChildren.OfType<Audio>().ToList(); if (!item.LockedFields.Contains(MetadataFields.Genres)) @@ -83,10 +76,10 @@ namespace MediaBrowser.Providers.Music .ToList(); } - data.FileStamp = GetComparisonData(songs); + providerInfo.FileStamp = GetComparisonData(songs); } - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return TrueTaskResult; } diff --git a/MediaBrowser.Providers/Music/ArtistProviderFromXml.cs b/MediaBrowser.Providers/Music/ArtistProviderFromXml.cs index c0bf564af..a25fd0093 100644 --- a/MediaBrowser.Providers/Music/ArtistProviderFromXml.cs +++ b/MediaBrowser.Providers/Music/ArtistProviderFromXml.cs @@ -61,18 +61,7 @@ namespace MediaBrowser.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> - public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) - { - return Fetch(item, cancellationToken); - } - - /// <summary> - /// Fetches the specified item. - /// </summary> - /// <param name="item">The item.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns> - private async Task<bool> Fetch(BaseItem item, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -93,7 +82,7 @@ namespace MediaBrowser.Providers.Music XmlParsingResourcePool.Release(); } - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } diff --git a/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs b/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs index a49de9a29..161c96a5d 100644 --- a/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs +++ b/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs @@ -152,13 +152,13 @@ namespace MediaBrowser.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> - public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { var images = await _providerManager.GetAvailableRemoteImages(item, cancellationToken, ManualFanartAlbumProvider.ProviderName).ConfigureAwait(false); await FetchFromXml(item, images.ToList(), cancellationToken).ConfigureAwait(false); - - SetLastRefreshed(item, DateTime.UtcNow); + + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } diff --git a/MediaBrowser.Providers/Music/FanArtArtistProvider.cs b/MediaBrowser.Providers/Music/FanArtArtistProvider.cs index 1b0a80d9a..4830d15b1 100644 --- a/MediaBrowser.Providers/Music/FanArtArtistProvider.cs +++ b/MediaBrowser.Providers/Music/FanArtArtistProvider.cs @@ -197,7 +197,7 @@ namespace MediaBrowser.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> - public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -223,7 +223,7 @@ namespace MediaBrowser.Providers.Music await FetchFromXml(item, images.ToList(), cancellationToken).ConfigureAwait(false); } - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } diff --git a/MediaBrowser.Providers/Music/LastFmImageProvider.cs b/MediaBrowser.Providers/Music/LastFmImageProvider.cs index a2ae597d7..2a30a3a2e 100644 --- a/MediaBrowser.Providers/Music/LastFmImageProvider.cs +++ b/MediaBrowser.Providers/Music/LastFmImageProvider.cs @@ -68,7 +68,7 @@ namespace MediaBrowser.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> - public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { if (!item.HasImage(ImageType.Primary)) { @@ -77,7 +77,7 @@ namespace MediaBrowser.Providers.Music await DownloadImages(item, images.ToList(), cancellationToken).ConfigureAwait(false); } - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } diff --git a/MediaBrowser.Providers/Music/LastfmAlbumProvider.cs b/MediaBrowser.Providers/Music/LastfmAlbumProvider.cs index 3c6bc19be..04946fabc 100644 --- a/MediaBrowser.Providers/Music/LastfmAlbumProvider.cs +++ b/MediaBrowser.Providers/Music/LastfmAlbumProvider.cs @@ -80,7 +80,7 @@ namespace MediaBrowser.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> - public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -92,17 +92,10 @@ namespace MediaBrowser.Providers.Music { LastfmHelper.ProcessAlbumData(item, result.album); } - - BaseProviderInfo data; - if (!item.ProviderData.TryGetValue(Id, out data)) - { - data = new BaseProviderInfo(); - item.ProviderData[Id] = data; - } - data.FileStamp = GetComparisonData(album); + providerInfo.FileStamp = GetComparisonData(album); - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } diff --git a/MediaBrowser.Providers/Music/LastfmArtistProvider.cs b/MediaBrowser.Providers/Music/LastfmArtistProvider.cs index ae14d62c7..02babb4e6 100644 --- a/MediaBrowser.Providers/Music/LastfmArtistProvider.cs +++ b/MediaBrowser.Providers/Music/LastfmArtistProvider.cs @@ -108,7 +108,7 @@ namespace MediaBrowser.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> - public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -123,7 +123,7 @@ namespace MediaBrowser.Providers.Music await FetchLastfmData(item, id, force, cancellationToken).ConfigureAwait(false); } - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } diff --git a/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs b/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs index c01b445ca..e678271f2 100644 --- a/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs +++ b/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs @@ -34,7 +34,7 @@ namespace MediaBrowser.Providers.Music return item is MusicAlbum; } - public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { var releaseId = item.GetProviderId(MetadataProviders.Musicbrainz); var releaseGroupId = item.GetProviderId(MetadataProviders.MusicBrainzReleaseGroup); @@ -64,7 +64,7 @@ namespace MediaBrowser.Providers.Music item.SetProviderId(MetadataProviders.MusicBrainzReleaseGroup, releaseGroupId); } - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } diff --git a/MediaBrowser.Providers/TV/EpisodeImageFromMediaLocationProvider.cs b/MediaBrowser.Providers/TV/EpisodeImageFromMediaLocationProvider.cs index 00e836936..83d36bb3c 100644 --- a/MediaBrowser.Providers/TV/EpisodeImageFromMediaLocationProvider.cs +++ b/MediaBrowser.Providers/TV/EpisodeImageFromMediaLocationProvider.cs @@ -80,7 +80,7 @@ namespace MediaBrowser.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> - public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) + public override Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -96,7 +96,7 @@ namespace MediaBrowser.Providers.TV SetPrimaryImagePath(episode, parent, item.MetaLocation, episodeFileName); - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return TrueTaskResult; } diff --git a/MediaBrowser.Providers/TV/EpisodeIndexNumberProvider.cs b/MediaBrowser.Providers/TV/EpisodeIndexNumberProvider.cs index 592c5dcac..4427e60e4 100644 --- a/MediaBrowser.Providers/TV/EpisodeIndexNumberProvider.cs +++ b/MediaBrowser.Providers/TV/EpisodeIndexNumberProvider.cs @@ -60,7 +60,7 @@ namespace MediaBrowser.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> - public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) + public override Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { var episode = (Episode)item; @@ -77,7 +77,7 @@ namespace MediaBrowser.Providers.TV } } - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return TrueTaskResult; } diff --git a/MediaBrowser.Providers/TV/EpisodeProviderFromXml.cs b/MediaBrowser.Providers/TV/EpisodeProviderFromXml.cs index 322867f2f..38921c008 100644 --- a/MediaBrowser.Providers/TV/EpisodeProviderFromXml.cs +++ b/MediaBrowser.Providers/TV/EpisodeProviderFromXml.cs @@ -54,61 +54,50 @@ namespace MediaBrowser.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> - public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { - return Fetch(item, cancellationToken); - } + cancellationToken.ThrowIfCancellationRequested(); - /// <summary> - /// Needses the refresh based on compare date. - /// </summary> - /// <param name="item">The item.</param> - /// <param name="providerInfo">The provider info.</param> - /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns> - protected override bool NeedsRefreshBasedOnCompareDate(BaseItem item, BaseProviderInfo providerInfo) - { var metadataFile = Path.Combine(item.MetaLocation, Path.ChangeExtension(Path.GetFileName(item.Path), ".xml")); var file = item.ResolveArgs.Parent.ResolveArgs.GetMetaFileByPath(metadataFile); - if (file == null) + if (file != null) { - return false; + await XmlParsingResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); + + try + { + await new EpisodeXmlParser(Logger, _itemRepo).FetchAsync((Episode)item, metadataFile, cancellationToken).ConfigureAwait(false); + } + finally + { + XmlParsingResourcePool.Release(); + } } - return _fileSystem.GetLastWriteTimeUtc(file) > item.DateLastSaved; + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); + return true; } /// <summary> - /// Fetches the specified item. + /// Needses the refresh based on compare date. /// </summary> /// <param name="item">The item.</param> - /// <param name="cancellationToken">The cancellation token.</param> + /// <param name="providerInfo">The provider info.</param> /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns> - private async Task<bool> Fetch(BaseItem item, CancellationToken cancellationToken) + protected override bool NeedsRefreshBasedOnCompareDate(BaseItem item, BaseProviderInfo providerInfo) { - cancellationToken.ThrowIfCancellationRequested(); - var metadataFile = Path.Combine(item.MetaLocation, Path.ChangeExtension(Path.GetFileName(item.Path), ".xml")); var file = item.ResolveArgs.Parent.ResolveArgs.GetMetaFileByPath(metadataFile); - if (file != null) + if (file == null) { - await XmlParsingResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); - - try - { - await new EpisodeXmlParser(Logger, _itemRepo).FetchAsync((Episode)item, metadataFile, cancellationToken).ConfigureAwait(false); - } - finally - { - XmlParsingResourcePool.Release(); - } + return false; } - SetLastRefreshed(item, DateTime.UtcNow); - return true; + return _fileSystem.GetLastWriteTimeUtc(file) > item.DateLastSaved; } } } diff --git a/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs b/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs index bf52ca349..ed5145bc2 100644 --- a/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs +++ b/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs @@ -97,7 +97,7 @@ namespace MediaBrowser.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> - public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -108,7 +108,7 @@ namespace MediaBrowser.Providers.TV await FetchImages(season, images.ToList(), cancellationToken).ConfigureAwait(false); - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } diff --git a/MediaBrowser.Providers/TV/FanArtTVProvider.cs b/MediaBrowser.Providers/TV/FanArtTVProvider.cs index 037e0b5bc..251420261 100644 --- a/MediaBrowser.Providers/TV/FanArtTVProvider.cs +++ b/MediaBrowser.Providers/TV/FanArtTVProvider.cs @@ -160,8 +160,8 @@ namespace MediaBrowser.Providers.TV } protected readonly CultureInfo UsCulture = new CultureInfo("en-US"); - - public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) + + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -182,7 +182,7 @@ namespace MediaBrowser.Providers.TV await FetchFromXml(item, images.ToList(), cancellationToken).ConfigureAwait(false); } - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } diff --git a/MediaBrowser.Providers/TV/SeasonProviderFromXml.cs b/MediaBrowser.Providers/TV/SeasonProviderFromXml.cs index 9a031ecd8..2127234dc 100644 --- a/MediaBrowser.Providers/TV/SeasonProviderFromXml.cs +++ b/MediaBrowser.Providers/TV/SeasonProviderFromXml.cs @@ -65,18 +65,7 @@ namespace MediaBrowser.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> - public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) - { - return Fetch(item, cancellationToken); - } - - /// <summary> - /// Fetches the specified item. - /// </summary> - /// <param name="item">The item.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns> - private async Task<bool> Fetch(BaseItem item, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -97,7 +86,7 @@ namespace MediaBrowser.Providers.TV XmlParsingResourcePool.Release(); } - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } diff --git a/MediaBrowser.Providers/TV/SeriesDynamicInfoProvider.cs b/MediaBrowser.Providers/TV/SeriesDynamicInfoProvider.cs index 59faaa931..ff31ce4aa 100644 --- a/MediaBrowser.Providers/TV/SeriesDynamicInfoProvider.cs +++ b/MediaBrowser.Providers/TV/SeriesDynamicInfoProvider.cs @@ -21,7 +21,7 @@ namespace MediaBrowser.Providers.TV return item is Series; } - public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) + public override Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { var series = (Series)item; diff --git a/MediaBrowser.Providers/TV/SeriesProviderFromXml.cs b/MediaBrowser.Providers/TV/SeriesProviderFromXml.cs index ab5e2d8fe..ff99a95c1 100644 --- a/MediaBrowser.Providers/TV/SeriesProviderFromXml.cs +++ b/MediaBrowser.Providers/TV/SeriesProviderFromXml.cs @@ -65,21 +65,10 @@ namespace MediaBrowser.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> - public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) - { - return Fetch(item, cancellationToken); - } - - /// <summary> - /// Fetches the specified item. - /// </summary> - /// <param name="item">The item.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns> - private async Task<bool> Fetch(BaseItem item, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - + var metadataFile = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, XmlFileName)); if (metadataFile != null) @@ -97,12 +86,10 @@ namespace MediaBrowser.Providers.TV XmlParsingResourcePool.Release(); } - SetLastRefreshed(item, DateTime.UtcNow); - - return true; } - return false; + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); + return true; } } } diff --git a/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs b/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs index 54e446380..5d9f387fe 100644 --- a/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs @@ -242,7 +242,7 @@ namespace MediaBrowser.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> - public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -266,7 +266,7 @@ namespace MediaBrowser.Providers.TV } } - SetLastRefreshed(item, DateTime.UtcNow, status); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo, status); return true; } diff --git a/MediaBrowser.Providers/TV/TvdbPersonImageProvider.cs b/MediaBrowser.Providers/TV/TvdbPersonImageProvider.cs index 53f1c7bdb..3a503ea20 100644 --- a/MediaBrowser.Providers/TV/TvdbPersonImageProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbPersonImageProvider.cs @@ -58,7 +58,7 @@ namespace MediaBrowser.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> - public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(item.PrimaryImagePath)) { @@ -68,11 +68,11 @@ namespace MediaBrowser.Providers.TV await DownloadImages(item, images.ToList(), cancellationToken).ConfigureAwait(false); - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } private async Task DownloadImages(BaseItem item, List<RemoteImageInfo> images, CancellationToken cancellationToken) diff --git a/MediaBrowser.Providers/TV/TvdbSeasonProvider.cs b/MediaBrowser.Providers/TV/TvdbSeasonProvider.cs index 05fee7861..cdfe86dac 100644 --- a/MediaBrowser.Providers/TV/TvdbSeasonProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbSeasonProvider.cs @@ -141,7 +141,7 @@ namespace MediaBrowser.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> - public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -151,7 +151,7 @@ namespace MediaBrowser.Providers.TV await DownloadImages(item, images.ToList(), backdropLimit, cancellationToken).ConfigureAwait(false); - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } diff --git a/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs b/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs index b56b50bec..c1ac0e386 100644 --- a/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs @@ -151,7 +151,7 @@ namespace MediaBrowser.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> - public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -161,7 +161,7 @@ namespace MediaBrowser.Providers.TV await DownloadImages(item, images.ToList(), backdropLimit, cancellationToken).ConfigureAwait(false); - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } diff --git a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs index 29e191a59..5691f885e 100644 --- a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs @@ -205,7 +205,7 @@ namespace MediaBrowser.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> - public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -227,7 +227,7 @@ namespace MediaBrowser.Providers.TV await FetchSeriesData(series, seriesId, seriesDataPath, force, cancellationToken).ConfigureAwait(false); } - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } diff --git a/MediaBrowser.Providers/UserRootFolderNameProvider.cs b/MediaBrowser.Providers/UserRootFolderNameProvider.cs index 513020213..551dd4257 100644 --- a/MediaBrowser.Providers/UserRootFolderNameProvider.cs +++ b/MediaBrowser.Providers/UserRootFolderNameProvider.cs @@ -21,7 +21,7 @@ namespace MediaBrowser.Providers return item is UserRootFolder; } - public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) + public override Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { var parentName = Path.GetFileNameWithoutExtension(item.Path); @@ -30,7 +30,7 @@ namespace MediaBrowser.Providers item.Name = "Media Library"; } - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return TrueTaskResult; } diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs index 04d0f6ab2..4243aecfe 100644 --- a/MediaBrowser.Server.Implementations/Library/UserManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs @@ -196,6 +196,8 @@ namespace MediaBrowser.Server.Implementations.Library var user = InstantiateNewUser(name); + user.DateLastSaved = DateTime.UtcNow; + var task = UserRepository.SaveUser(user, CancellationToken.None); // Hate having to block threads @@ -274,6 +276,7 @@ namespace MediaBrowser.Server.Implementations.Library } user.DateModified = DateTime.UtcNow; + user.DateLastSaved = DateTime.UtcNow; await UserRepository.SaveUser(user, CancellationToken.None).ConfigureAwait(false); @@ -307,6 +310,8 @@ namespace MediaBrowser.Server.Implementations.Library list.Add(user); Users = list; + user.DateLastSaved = DateTime.UtcNow; + await UserRepository.SaveUser(user, CancellationToken.None).ConfigureAwait(false); EventHelper.QueueEventIfNotNull(UserCreated, this, new GenericEventArgs<User> { Argument = user }, _logger); diff --git a/MediaBrowser.Server.Implementations/LiveTv/ChannelImageProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/ChannelImageProvider.cs index 322948bad..e16430e69 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/ChannelImageProvider.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/ChannelImageProvider.cs @@ -36,11 +36,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv return !item.HasImage(ImageType.Primary); } - public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) + public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { if (item.HasImage(ImageType.Primary)) { - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } @@ -58,7 +58,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv } - SetLastRefreshed(item, DateTime.UtcNow); + SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return true; } diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index a4eec43f7..4b30672d0 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -170,6 +170,7 @@ <Compile Include="Persistence\SqliteExtensions.cs" /> <Compile Include="Persistence\SqliteMediaStreamsRepository.cs" /> <Compile Include="Persistence\SqliteNotificationsRepository.cs" /> + <Compile Include="Persistence\SqliteProviderInfoRepository.cs" /> <Compile Include="Persistence\TypeMapper.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Providers\ImageSaver.cs" /> diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 799b74fe2..893d6ea62 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -1,6 +1,7 @@ using MediaBrowser.Common.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Persistence; +using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; @@ -57,6 +58,7 @@ namespace MediaBrowser.Server.Implementations.Persistence private SqliteChapterRepository _chapterRepository; private SqliteMediaStreamsRepository _mediaStreamsRepository; + private SqliteProviderInfoRepository _providerInfoRepository; private IDbCommand _deleteChildrenCommand; private IDbCommand _saveChildrenCommand; @@ -91,16 +93,16 @@ namespace MediaBrowser.Server.Implementations.Persistence _logger = logManager.GetLogger(GetType().Name); var chapterDbFile = Path.Combine(_appPaths.DataPath, "chapters.db"); - var chapterConnection = SqliteExtensions.ConnectToDb(chapterDbFile, _logger).Result; - _chapterRepository = new SqliteChapterRepository(chapterConnection, logManager); var mediaStreamsDbFile = Path.Combine(_appPaths.DataPath, "mediainfo.db"); - var mediaStreamsConnection = SqliteExtensions.ConnectToDb(mediaStreamsDbFile, _logger).Result; - _mediaStreamsRepository = new SqliteMediaStreamsRepository(mediaStreamsConnection, logManager); + + var providerInfosDbFile = Path.Combine(_appPaths.DataPath, "providerinfo.db"); + var providerInfoConnection = SqliteExtensions.ConnectToDb(providerInfosDbFile, _logger).Result; + _providerInfoRepository = new SqliteProviderInfoRepository(providerInfoConnection, logManager); } /// <summary> @@ -128,8 +130,9 @@ namespace MediaBrowser.Server.Implementations.Persistence _connection.RunQueries(queries, _logger); PrepareStatements(); - + _mediaStreamsRepository.Initialize(); + _providerInfoRepository.Initialize(); _chapterRepository.Initialize(); } @@ -427,6 +430,12 @@ namespace MediaBrowser.Server.Implementations.Persistence _mediaStreamsRepository.Dispose(); _mediaStreamsRepository = null; } + + if (_providerInfoRepository != null) + { + _providerInfoRepository.Dispose(); + _providerInfoRepository = null; + } } } @@ -535,5 +544,15 @@ namespace MediaBrowser.Server.Implementations.Persistence { return _mediaStreamsRepository.SaveMediaStreams(id, streams, cancellationToken); } + + public IEnumerable<BaseProviderInfo> GetProviderHistory(Guid itemId) + { + return _providerInfoRepository.GetBaseProviderInfos(itemId); + } + + public Task SaveProviderHistory(Guid id, IEnumerable<BaseProviderInfo> history, CancellationToken cancellationToken) + { + return _providerInfoRepository.SaveProviderInfos(id, history, cancellationToken); + } } }
\ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteProviderInfoRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteProviderInfoRepository.cs new file mode 100644 index 000000000..c704808f3 --- /dev/null +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteProviderInfoRepository.cs @@ -0,0 +1,265 @@ +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Logging; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Server.Implementations.Persistence +{ + class SqliteProviderInfoRepository + { + private IDbConnection _connection; + + private readonly ILogger _logger; + + private IDbCommand _deleteInfosCommand; + private IDbCommand _saveInfoCommand; + + public SqliteProviderInfoRepository(IDbConnection connection, ILogManager logManager) + { + _connection = connection; + + _logger = logManager.GetLogger(GetType().Name); + } + + /// <summary> + /// Opens the connection to the database + /// </summary> + /// <returns>Task.</returns> + public void Initialize() + { + var createTableCommand + = "create table if not exists providerinfos "; + + createTableCommand += "(ItemId GUID, ProviderId GUID, ProviderVersion TEXT, FileStamp GUID, LastRefreshStatus TEXT, LastRefreshed datetime, PRIMARY KEY (ItemId, ProviderId))"; + + string[] queries = { + + createTableCommand, + "create index if not exists idx_providerinfos on providerinfos(ItemId, ProviderId)", + + //pragmas + "pragma temp_store = memory" + }; + + _connection.RunQueries(queries, _logger); + + PrepareStatements(); + } + + private static readonly string[] SaveColumns = + { + "ItemId", + "ProviderId", + "ProviderVersion", + "FileStamp", + "LastRefreshStatus", + "LastRefreshed" + }; + + private readonly string[] _selectColumns = SaveColumns.Skip(1).ToArray(); + + /// <summary> + /// The _write lock + /// </summary> + private readonly SemaphoreSlim _writeLock = new SemaphoreSlim(1, 1); + + /// <summary> + /// Prepares the statements. + /// </summary> + private void PrepareStatements() + { + _deleteInfosCommand = _connection.CreateCommand(); + _deleteInfosCommand.CommandText = "delete from providerinfos where ItemId=@ItemId"; + _deleteInfosCommand.Parameters.Add(_deleteInfosCommand, "@ItemId"); + + _saveInfoCommand = _connection.CreateCommand(); + + _saveInfoCommand.CommandText = string.Format("replace into providerinfos ({0}) values ({1})", + string.Join(",", SaveColumns), + string.Join(",", SaveColumns.Select(i => "@" + i).ToArray())); + + foreach (var col in SaveColumns) + { + _saveInfoCommand.Parameters.Add(_saveInfoCommand, "@" + col); + } + } + + public IEnumerable<BaseProviderInfo> GetBaseProviderInfos(Guid itemId) + { + if (itemId == Guid.Empty) + { + throw new ArgumentNullException("itemId"); + } + + using (var cmd = _connection.CreateCommand()) + { + var cmdText = "select " + string.Join(",", _selectColumns) + " from providerinfos where"; + + cmdText += " ItemId=@ItemId"; + cmd.Parameters.Add(cmd, "@ItemId", DbType.Guid).Value = itemId; + + cmd.CommandText = cmdText; + + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) + { + while (reader.Read()) + { + yield return GetBaseProviderInfo(reader); + } + } + } + } + + /// <summary> + /// Gets the chapter. + /// </summary> + /// <param name="reader">The reader.</param> + /// <returns>ChapterInfo.</returns> + private BaseProviderInfo GetBaseProviderInfo(IDataReader reader) + { + var item = new BaseProviderInfo + { + ProviderId = reader.GetGuid(0) + }; + + if (!reader.IsDBNull(1)) + { + item.ProviderVersion = reader.GetString(1); + } + + item.FileStamp = reader.GetGuid(2); + item.LastRefreshStatus = (ProviderRefreshStatus)Enum.Parse(typeof(ProviderRefreshStatus), reader.GetString(3), true); + item.LastRefreshed = reader.GetDateTime(4).ToUniversalTime(); + + return item; + } + + public async Task SaveProviderInfos(Guid id, IEnumerable<BaseProviderInfo> infos, CancellationToken cancellationToken) + { + if (id == Guid.Empty) + { + throw new ArgumentNullException("id"); + } + + if (infos == null) + { + throw new ArgumentNullException("infos"); + } + + cancellationToken.ThrowIfCancellationRequested(); + + await _writeLock.WaitAsync(cancellationToken).ConfigureAwait(false); + + IDbTransaction transaction = null; + + try + { + transaction = _connection.BeginTransaction(); + + // First delete chapters + _deleteInfosCommand.GetParameter(0).Value = id; + + _deleteInfosCommand.Transaction = transaction; + + _deleteInfosCommand.ExecuteNonQuery(); + + foreach (var stream in infos) + { + if (stream.LastRefreshed == DateTime.MinValue) + { + throw new Exception("LastRefreshed still has DateTime.MinValue"); + + } + cancellationToken.ThrowIfCancellationRequested(); + + _saveInfoCommand.GetParameter(0).Value = id; + _saveInfoCommand.GetParameter(1).Value = stream.ProviderId; + _saveInfoCommand.GetParameter(2).Value = stream.ProviderVersion; + _saveInfoCommand.GetParameter(3).Value = stream.FileStamp; + _saveInfoCommand.GetParameter(4).Value = stream.LastRefreshStatus.ToString(); + _saveInfoCommand.GetParameter(5).Value = stream.LastRefreshed; + + _saveInfoCommand.Transaction = transaction; + _saveInfoCommand.ExecuteNonQuery(); + } + + transaction.Commit(); + } + catch (OperationCanceledException) + { + if (transaction != null) + { + transaction.Rollback(); + } + + throw; + } + catch (Exception e) + { + _logger.ErrorException("Failed to save provider info:", e); + + if (transaction != null) + { + transaction.Rollback(); + } + + throw; + } + finally + { + if (transaction != null) + { + transaction.Dispose(); + } + + _writeLock.Release(); + } + } + + /// <summary> + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// </summary> + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private readonly object _disposeLock = new object(); + + /// <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) + { + try + { + lock (_disposeLock) + { + if (_connection != null) + { + if (_connection.IsOpen()) + { + _connection.Close(); + } + + _connection.Dispose(); + _connection = null; + } + } + } + catch (Exception ex) + { + _logger.ErrorException("Error disposing database", ex); + } + } + } + } +} diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs index c174eb08e..fa195859b 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs @@ -233,7 +233,7 @@ namespace MediaBrowser.Server.Implementations.Persistence if (!reader.IsDBNull(5)) { - userData.LastPlayedDate = reader.GetDateTime(5); + userData.LastPlayedDate = reader.GetDateTime(5).ToUniversalTime(); } } } diff --git a/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs b/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs index fa0620082..511092759 100644 --- a/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs +++ b/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs @@ -4,6 +4,7 @@ using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.IO; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; @@ -52,6 +53,8 @@ namespace MediaBrowser.Server.Implementations.Providers private IImageProvider[] ImageProviders { get; set; } private readonly IFileSystem _fileSystem; + private readonly IItemRepository _itemRepo; + /// <summary> /// Initializes a new instance of the <see cref="ProviderManager" /> class. /// </summary> @@ -59,13 +62,14 @@ namespace MediaBrowser.Server.Implementations.Providers /// <param name="configurationManager">The configuration manager.</param> /// <param name="directoryWatchers">The directory watchers.</param> /// <param name="logManager">The log manager.</param> - public ProviderManager(IHttpClient httpClient, IServerConfigurationManager configurationManager, IDirectoryWatchers directoryWatchers, ILogManager logManager, IFileSystem fileSystem) + public ProviderManager(IHttpClient httpClient, IServerConfigurationManager configurationManager, IDirectoryWatchers directoryWatchers, ILogManager logManager, IFileSystem fileSystem, IItemRepository itemRepo) { _logger = logManager.GetLogger("ProviderManager"); _httpClient = httpClient; ConfigurationManager = configurationManager; _directoryWatchers = directoryWatchers; _fileSystem = fileSystem; + _itemRepo = itemRepo; } /// <summary> @@ -102,6 +106,10 @@ namespace MediaBrowser.Server.Implementations.Providers var enableInternetProviders = ConfigurationManager.Configuration.EnableInternetProviders; var excludeTypes = ConfigurationManager.Configuration.InternetProviderExcludeTypes; + var providerHistories = item.DateLastSaved == DateTime.MinValue ? + new List<BaseProviderInfo>() : + _itemRepo.GetProviderHistory(item.Id).ToList(); + // Run the normal providers sequentially in order of priority foreach (var provider in MetadataProviders) { @@ -140,9 +148,20 @@ namespace MediaBrowser.Server.Implementations.Providers continue; } + var providerInfo = providerHistories.FirstOrDefault(i => i.ProviderId == provider.Id); + + if (providerInfo == null) + { + providerInfo = new BaseProviderInfo + { + ProviderId = provider.Id + }; + providerHistories.Add(providerInfo); + } + try { - if (!force && !provider.NeedsRefresh(item)) + if (!force && !provider.NeedsRefresh(item, providerInfo)) { continue; } @@ -152,7 +171,7 @@ namespace MediaBrowser.Server.Implementations.Providers _logger.Error("Error determining NeedsRefresh for {0}", ex, item.Path); } - var updateType = await FetchAsync(provider, item, force, cancellationToken).ConfigureAwait(false); + var updateType = await FetchAsync(provider, item, providerInfo, force, cancellationToken).ConfigureAwait(false); if (updateType.HasValue) { @@ -167,6 +186,11 @@ namespace MediaBrowser.Server.Implementations.Providers } } + if (result.HasValue || force) + { + await _itemRepo.SaveProviderHistory(item.Id, providerHistories, cancellationToken); + } + return result; } @@ -194,11 +218,12 @@ namespace MediaBrowser.Server.Implementations.Providers /// </summary> /// <param name="provider">The provider.</param> /// <param name="item">The item.</param> + /// <param name="providerInfo">The provider information.</param> /// <param name="force">if set to <c>true</c> [force].</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{System.Boolean}.</returns> - /// <exception cref="System.ArgumentNullException"></exception> - private async Task<ItemUpdateType?> FetchAsync(BaseMetadataProvider provider, BaseItem item, bool force, CancellationToken cancellationToken) + /// <exception cref="System.ArgumentNullException">item</exception> + private async Task<ItemUpdateType?> FetchAsync(BaseMetadataProvider provider, BaseItem item, BaseProviderInfo providerInfo, bool force, CancellationToken cancellationToken) { if (item == null) { @@ -215,7 +240,7 @@ namespace MediaBrowser.Server.Implementations.Providers try { - var changed = await provider.FetchAsync(item, force, cancellationToken).ConfigureAwait(false); + var changed = await provider.FetchAsync(item, force, providerInfo, cancellationToken).ConfigureAwait(false); if (changed) { @@ -240,7 +265,7 @@ namespace MediaBrowser.Server.Implementations.Providers { _logger.ErrorException("{0} failed refreshing {1} {2}", ex, provider.GetType().Name, item.Name, item.Path ?? string.Empty); - provider.SetLastRefreshed(item, DateTime.UtcNow, ProviderRefreshStatus.Failure); + provider.SetLastRefreshed(item, DateTime.UtcNow, providerInfo, ProviderRefreshStatus.Failure); return ItemUpdateType.Unspecified; } diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs index ecd6a923b..39871df66 100644 --- a/MediaBrowser.ServerApplication/ApplicationHost.cs +++ b/MediaBrowser.ServerApplication/ApplicationHost.cs @@ -269,7 +269,7 @@ namespace MediaBrowser.ServerApplication DirectoryWatchers = new DirectoryWatchers(LogManager, TaskManager, LibraryManager, ServerConfigurationManager, FileSystemManager); RegisterSingleInstance(DirectoryWatchers); - ProviderManager = new ProviderManager(HttpClient, ServerConfigurationManager, DirectoryWatchers, LogManager, FileSystemManager); + ProviderManager = new ProviderManager(HttpClient, ServerConfigurationManager, DirectoryWatchers, LogManager, FileSystemManager, ItemRepository); RegisterSingleInstance(ProviderManager); RegisterSingleInstance<ILibrarySearchEngine>(() => new LuceneSearchEngine(ApplicationPaths, LogManager, LibraryManager)); |
