From ad82c9f5e95e2b1f94ba7adda047dbfbc38004ea Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 28 Jan 2014 13:37:01 -0500 Subject: New provider system. Only for people right now --- MediaBrowser.Controller/Drawing/ImageExtensions.cs | 8 +- MediaBrowser.Controller/Drawing/ImageFormat.cs | 11 ++ MediaBrowser.Controller/Entities/BaseItem.cs | 115 ++++++++++++++++----- MediaBrowser.Controller/Entities/Folder.cs | 13 ++- MediaBrowser.Controller/Entities/IHasImages.cs | 27 ++++- .../Entities/IHasScreenshots.cs | 6 +- MediaBrowser.Controller/Entities/Movies/Movie.cs | 19 ++-- MediaBrowser.Controller/Entities/User.cs | 20 ++-- MediaBrowser.Controller/Entities/Video.cs | 16 +-- MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs | 5 +- .../LiveTv/StreamResponseInfo.cs | 5 +- .../MediaBrowser.Controller.csproj | 8 ++ MediaBrowser.Controller/Providers/IHasMetadata.cs | 31 ++++++ .../Providers/IImageProvider.cs | 28 +---- .../Providers/ILocalImageProvider.cs | 58 +++++++++++ .../Providers/IMetadataProvider.cs | 90 ++++++++++++++++ .../Providers/IMetadataService.cs | 38 +++++++ .../Providers/IProviderManager.cs | 20 +++- .../Providers/IRemoteImageProvider.cs | 48 +++++++++ .../Providers/MetadataRefreshOptions.cs | 49 +++++++++ .../Providers/ProviderResult.cs | 60 +++++++++++ 21 files changed, 585 insertions(+), 90 deletions(-) create mode 100644 MediaBrowser.Controller/Drawing/ImageFormat.cs create mode 100644 MediaBrowser.Controller/Providers/IHasMetadata.cs create mode 100644 MediaBrowser.Controller/Providers/ILocalImageProvider.cs create mode 100644 MediaBrowser.Controller/Providers/IMetadataProvider.cs create mode 100644 MediaBrowser.Controller/Providers/IMetadataService.cs create mode 100644 MediaBrowser.Controller/Providers/IRemoteImageProvider.cs create mode 100644 MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs create mode 100644 MediaBrowser.Controller/Providers/ProviderResult.cs (limited to 'MediaBrowser.Controller') diff --git a/MediaBrowser.Controller/Drawing/ImageExtensions.cs b/MediaBrowser.Controller/Drawing/ImageExtensions.cs index 9dc58b3d2f..c7e1968e7b 100644 --- a/MediaBrowser.Controller/Drawing/ImageExtensions.cs +++ b/MediaBrowser.Controller/Drawing/ImageExtensions.cs @@ -18,17 +18,17 @@ namespace MediaBrowser.Controller.Drawing /// The image. /// To stream. /// The quality. - public static void Save(this Image image, ImageFormat outputFormat, Stream toStream, int quality) + public static void Save(this Image image, System.Drawing.Imaging.ImageFormat outputFormat, Stream toStream, int quality) { // Use special save methods for jpeg and png that will result in a much higher quality image // All other formats use the generic Image.Save - if (ImageFormat.Jpeg.Equals(outputFormat)) + if (System.Drawing.Imaging.ImageFormat.Jpeg.Equals(outputFormat)) { SaveAsJpeg(image, toStream, quality); } - else if (ImageFormat.Png.Equals(outputFormat)) + else if (System.Drawing.Imaging.ImageFormat.Png.Equals(outputFormat)) { - image.Save(toStream, ImageFormat.Png); + image.Save(toStream, System.Drawing.Imaging.ImageFormat.Png); } else { diff --git a/MediaBrowser.Controller/Drawing/ImageFormat.cs b/MediaBrowser.Controller/Drawing/ImageFormat.cs new file mode 100644 index 0000000000..f785625567 --- /dev/null +++ b/MediaBrowser.Controller/Drawing/ImageFormat.cs @@ -0,0 +1,11 @@ + +namespace MediaBrowser.Controller.Drawing +{ + public enum ImageFormat + { + Jpg, + Png, + Gif, + Bmp + } +} diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 7840fb3f07..a50a0f4674 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -23,7 +23,7 @@ namespace MediaBrowser.Controller.Entities /// /// Class BaseItem /// - public abstract class BaseItem : IHasProviderIds, ILibraryItem, IHasImages, IHasUserData + public abstract class BaseItem : IHasProviderIds, ILibraryItem, IHasImages, IHasUserData, IHasMetadata { protected BaseItem() { @@ -767,25 +767,35 @@ namespace MediaBrowser.Controller.Entities }).ToList(); } + public Task RefreshMetadata(CancellationToken cancellationToken, bool resetResolveArgs = true) + { + return RefreshMetadata(new MetadataRefreshOptions { ResetResolveArgs = resetResolveArgs }, cancellationToken); + } + /// /// Overrides the base implementation to refresh metadata for local trailers /// + /// The options. /// The cancellation token. - /// if set to true [is new item]. - /// if set to true [force]. - /// if set to true [allow slow providers]. - /// if set to true [reset resolve args]. /// true if a provider reports we changed - public virtual async Task RefreshMetadata(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false, bool allowSlowProviders = true, bool resetResolveArgs = true) + public async Task RefreshMetadata(MetadataRefreshOptions options, CancellationToken cancellationToken) { - if (resetResolveArgs) + if (options.ResetResolveArgs) { // Reload this ResetResolveArgs(); } + await ProviderManager.RefreshMetadata(this, options, cancellationToken).ConfigureAwait(false); + + return false; + } + + [Obsolete] + public virtual async Task RefreshMetadataDirect(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false) + { // Refresh for the item - var itemRefreshTask = ProviderManager.ExecuteMetadataProviders(this, cancellationToken, forceRefresh, allowSlowProviders); + var itemRefreshTask = ProviderManager.ExecuteMetadataProviders(this, cancellationToken, forceRefresh); cancellationToken.ThrowIfCancellationRequested(); @@ -800,15 +810,15 @@ namespace MediaBrowser.Controller.Entities var hasThemeMedia = this as IHasThemeMedia; if (hasThemeMedia != null) { - themeSongsChanged = await RefreshThemeSongs(hasThemeMedia, cancellationToken, forceSave, forceRefresh, allowSlowProviders).ConfigureAwait(false); + themeSongsChanged = await RefreshThemeSongs(hasThemeMedia, cancellationToken, forceSave, forceRefresh).ConfigureAwait(false); - themeVideosChanged = await RefreshThemeVideos(hasThemeMedia, cancellationToken, forceSave, forceRefresh, allowSlowProviders).ConfigureAwait(false); + themeVideosChanged = await RefreshThemeVideos(hasThemeMedia, cancellationToken, forceSave, forceRefresh).ConfigureAwait(false); } var hasTrailers = this as IHasTrailers; if (hasTrailers != null) { - localTrailersChanged = await RefreshLocalTrailers(hasTrailers, cancellationToken, forceSave, forceRefresh, allowSlowProviders).ConfigureAwait(false); + localTrailersChanged = await RefreshLocalTrailers(hasTrailers, cancellationToken, forceSave, forceRefresh).ConfigureAwait(false); } } @@ -829,14 +839,20 @@ namespace MediaBrowser.Controller.Entities return changed; } - private async Task RefreshLocalTrailers(IHasTrailers item, CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false, bool allowSlowProviders = true) + private async Task RefreshLocalTrailers(IHasTrailers item, CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false) { var newItems = LoadLocalTrailers().ToList(); var newItemIds = newItems.Select(i => i.Id).ToList(); var itemsChanged = !item.LocalTrailerIds.SequenceEqual(newItemIds); - var tasks = newItems.Select(i => i.RefreshMetadata(cancellationToken, forceSave, forceRefresh, allowSlowProviders, resetResolveArgs: false)); + var tasks = newItems.Select(i => i.RefreshMetadata(new MetadataRefreshOptions + { + ForceSave = forceSave, + ReplaceAllMetadata = forceRefresh, + ResetResolveArgs = false + + }, cancellationToken)); var results = await Task.WhenAll(tasks).ConfigureAwait(false); @@ -845,14 +861,20 @@ namespace MediaBrowser.Controller.Entities return itemsChanged || results.Contains(true); } - private async Task RefreshThemeVideos(IHasThemeMedia item, CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false, bool allowSlowProviders = true) + private async Task RefreshThemeVideos(IHasThemeMedia item, CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false) { var newThemeVideos = LoadThemeVideos().ToList(); var newThemeVideoIds = newThemeVideos.Select(i => i.Id).ToList(); var themeVideosChanged = !item.ThemeVideoIds.SequenceEqual(newThemeVideoIds); - var tasks = newThemeVideos.Select(i => i.RefreshMetadata(cancellationToken, forceSave, forceRefresh, allowSlowProviders, resetResolveArgs: false)); + var tasks = newThemeVideos.Select(i => i.RefreshMetadata(new MetadataRefreshOptions + { + ForceSave = forceSave, + ReplaceAllMetadata = forceRefresh, + ResetResolveArgs = false + + }, cancellationToken)); var results = await Task.WhenAll(tasks).ConfigureAwait(false); @@ -864,14 +886,20 @@ namespace MediaBrowser.Controller.Entities /// /// Refreshes the theme songs. /// - private async Task RefreshThemeSongs(IHasThemeMedia item, CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false, bool allowSlowProviders = true) + private async Task RefreshThemeSongs(IHasThemeMedia item, CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false) { var newThemeSongs = LoadThemeSongs().ToList(); var newThemeSongIds = newThemeSongs.Select(i => i.Id).ToList(); var themeSongsChanged = !item.ThemeSongIds.SequenceEqual(newThemeSongIds); - var tasks = newThemeSongs.Select(i => i.RefreshMetadata(cancellationToken, forceSave, forceRefresh, allowSlowProviders, resetResolveArgs: false)); + var tasks = newThemeSongs.Select(i => i.RefreshMetadata(new MetadataRefreshOptions + { + ForceSave = forceSave, + ReplaceAllMetadata = forceRefresh, + ResetResolveArgs = false + + }, cancellationToken)); var results = await Task.WhenAll(tasks).ConfigureAwait(false); @@ -1456,7 +1484,13 @@ namespace MediaBrowser.Controller.Entities // Refresh metadata // Need to disable slow providers or the image might get re-downloaded - return RefreshMetadata(CancellationToken.None, forceSave: true, allowSlowProviders: false); + return RefreshMetadata(new MetadataRefreshOptions + { + ForceSave = true, + ImageRefreshMode = MetadataRefreshMode.None, + MetadataRefreshMode = MetadataRefreshMode.None + + }, CancellationToken.None); } /// @@ -1482,8 +1516,10 @@ namespace MediaBrowser.Controller.Entities /// /// Validates that images within the item are still on the file system /// - public void ValidateImages() + public bool ValidateImages() { + var changed = false; + // Only validate paths from the same directory - need to copy to a list because we are going to potentially modify the collection below var deletedKeys = Images .Where(image => !File.Exists(image.Value)) @@ -1494,14 +1530,28 @@ namespace MediaBrowser.Controller.Entities foreach (var key in deletedKeys) { Images.Remove(key); + changed = true; } + + if (ValidateBackdrops()) + { + changed = true; + } + if (ValidateScreenshots()) + { + changed = true; + } + + return changed; } /// /// Validates that backdrops within the item are still on the file system /// - public void ValidateBackdrops() + private bool ValidateBackdrops() { + var changed = false; + // Only validate paths from the same directory - need to copy to a list because we are going to potentially modify the collection below var deletedImages = BackdropImagePaths .Where(path => !File.Exists(path)) @@ -1513,7 +1563,11 @@ namespace MediaBrowser.Controller.Entities BackdropImagePaths.Remove(path); RemoveImageSourceForPath(path); + + changed = true; } + + return changed; } /// @@ -1593,9 +1647,16 @@ namespace MediaBrowser.Controller.Entities /// /// Validates the screenshots. /// - public void ValidateScreenshots() + private bool ValidateScreenshots() { - var hasScreenshots = (IHasScreenshots)this; + var changed = false; + + var hasScreenshots = this as IHasScreenshots; + + if (hasScreenshots == null) + { + return changed; + } // Only validate paths from the same directory - need to copy to a list because we are going to potentially modify the collection below var deletedImages = hasScreenshots.ScreenshotImagePaths @@ -1606,7 +1667,10 @@ namespace MediaBrowser.Controller.Entities foreach (var path in deletedImages) { hasScreenshots.ScreenshotImagePaths.Remove(path); + changed = true; } + + return changed; } /// @@ -1699,7 +1763,12 @@ namespace MediaBrowser.Controller.Entities FileSystem.SwapFiles(file1, file2); // Directory watchers should repeat this, but do a quick refresh first - return RefreshMetadata(CancellationToken.None, forceSave: true, allowSlowProviders: false); + return RefreshMetadata(new MetadataRefreshOptions + { + ForceSave = true, + MetadataRefreshMode = MetadataRefreshMode.None + + }, CancellationToken.None); } public virtual bool IsPlayed(User user) diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index a0fefeac77..a4257b2a5b 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -3,6 +3,7 @@ using MediaBrowser.Common.Progress; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Localization; +using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Resolvers; using MediaBrowser.Model.Entities; using MoreLinq; @@ -535,7 +536,13 @@ namespace MediaBrowser.Controller.Entities try { //refresh it - await child.RefreshMetadata(cancellationToken, forceSave: currentTuple.Item2, forceRefresh: forceRefreshMetadata, resetResolveArgs: false).ConfigureAwait(false); + await child.RefreshMetadata(new MetadataRefreshOptions + { + ForceSave = currentTuple.Item2, + ReplaceAllMetadata = forceRefreshMetadata, + ResetResolveArgs = false + + }, cancellationToken).ConfigureAwait(false); } catch (IOException ex) { @@ -907,9 +914,9 @@ namespace MediaBrowser.Controller.Entities return item; } - public override async Task RefreshMetadata(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false, bool allowSlowProviders = true, bool resetResolveArgs = true) + public override async Task RefreshMetadataDirect(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false) { - var changed = await base.RefreshMetadata(cancellationToken, forceSave, forceRefresh, allowSlowProviders, resetResolveArgs).ConfigureAwait(false); + var changed = await base.RefreshMetadataDirect(cancellationToken, forceSave, forceRefresh).ConfigureAwait(false); return (SupportsShortcutChildren && LocationType == LocationType.FileSystem && RefreshLinkedChildren()) || changed; } diff --git a/MediaBrowser.Controller/Entities/IHasImages.cs b/MediaBrowser.Controller/Entities/IHasImages.cs index a7cd76a66a..784337e3bb 100644 --- a/MediaBrowser.Controller/Entities/IHasImages.cs +++ b/MediaBrowser.Controller/Entities/IHasImages.cs @@ -1,5 +1,6 @@ using MediaBrowser.Model.Entities; using System; +using System.Collections.Generic; using System.Threading.Tasks; namespace MediaBrowser.Controller.Entities @@ -10,7 +11,7 @@ namespace MediaBrowser.Controller.Entities /// Gets the name. /// /// The name. - string Name { get; } + string Name { get; set; } /// /// Gets the path. @@ -24,6 +25,12 @@ namespace MediaBrowser.Controller.Entities /// The identifier. Guid Id { get; } + /// + /// Gets the type of the location. + /// + /// The type of the location. + LocationType LocationType { get; } + /// /// Gets the image path. /// @@ -81,6 +88,24 @@ namespace MediaBrowser.Controller.Entities /// /// System.String. string GetPreferredMetadataLanguage(); + + /// + /// Validates the images and returns true or false indicating if any were removed. + /// + bool ValidateImages(); + + /// + /// Gets or sets the backdrop image paths. + /// + /// The backdrop image paths. + List BackdropImagePaths { get; set; } + + /// + /// Determines whether [contains image with source URL] [the specified URL]. + /// + /// The URL. + /// true if [contains image with source URL] [the specified URL]; otherwise, false. + bool ContainsImageWithSourceUrl(string url); } public static class HasImagesExtensions diff --git a/MediaBrowser.Controller/Entities/IHasScreenshots.cs b/MediaBrowser.Controller/Entities/IHasScreenshots.cs index 2276c707a7..70d154a958 100644 --- a/MediaBrowser.Controller/Entities/IHasScreenshots.cs +++ b/MediaBrowser.Controller/Entities/IHasScreenshots.cs @@ -14,8 +14,10 @@ namespace MediaBrowser.Controller.Entities List ScreenshotImagePaths { get; set; } /// - /// Validates the screenshots. + /// Determines whether [contains image with source URL] [the specified URL]. /// - void ValidateScreenshots(); + /// The URL. + /// true if [contains image with source URL] [the specified URL]; otherwise, false. + bool ContainsImageWithSourceUrl(string url); } } diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs index 2b252a6c21..dbbe5ce018 100644 --- a/MediaBrowser.Controller/Entities/Movies/Movie.cs +++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Model.Configuration; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using System; using System.Collections.Generic; @@ -108,13 +109,11 @@ namespace MediaBrowser.Controller.Entities.Movies /// The cancellation token. /// if set to true [is new item]. /// if set to true [force]. - /// if set to true [allow slow providers]. - /// The reset resolve args. /// Task{System.Boolean}. - public override async Task RefreshMetadata(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false, bool allowSlowProviders = true, bool resetResolveArgs = true) + public override async Task RefreshMetadataDirect(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false) { // Kick off a task to refresh the main item - var result = await base.RefreshMetadata(cancellationToken, forceSave, forceRefresh, allowSlowProviders, resetResolveArgs).ConfigureAwait(false); + var result = await base.RefreshMetadataDirect(cancellationToken, forceSave, forceRefresh).ConfigureAwait(false); var specialFeaturesChanged = false; @@ -122,7 +121,7 @@ namespace MediaBrowser.Controller.Entities.Movies // In other words, it must be part of the Parent/Child tree if (LocationType == LocationType.FileSystem && Parent != null && !IsInMixedFolder) { - specialFeaturesChanged = await RefreshSpecialFeatures(cancellationToken, forceSave, forceRefresh, allowSlowProviders).ConfigureAwait(false); + specialFeaturesChanged = await RefreshSpecialFeatures(cancellationToken, forceSave, forceRefresh).ConfigureAwait(false); } return specialFeaturesChanged || result; @@ -135,7 +134,13 @@ namespace MediaBrowser.Controller.Entities.Movies var itemsChanged = !SpecialFeatureIds.SequenceEqual(newItemIds); - var tasks = newItems.Select(i => i.RefreshMetadata(cancellationToken, forceSave, forceRefresh, allowSlowProviders, resetResolveArgs: false)); + var tasks = newItems.Select(i => i.RefreshMetadata(new MetadataRefreshOptions + { + ForceSave = forceSave, + ReplaceAllMetadata = forceRefresh, + ResetResolveArgs = false + + }, cancellationToken)); var results = await Task.WhenAll(tasks).ConfigureAwait(false); diff --git a/MediaBrowser.Controller/Entities/User.cs b/MediaBrowser.Controller/Entities/User.cs index 466e709dd0..c109e1d0cd 100644 --- a/MediaBrowser.Controller/Entities/User.cs +++ b/MediaBrowser.Controller/Entities/User.cs @@ -1,5 +1,6 @@ using MediaBrowser.Common.Configuration; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Serialization; using System; @@ -212,7 +213,12 @@ namespace MediaBrowser.Controller.Entities // Kick off a task to validate the media library Task.Run(() => ValidateMediaLibrary(new Progress(), CancellationToken.None)); - return RefreshMetadata(CancellationToken.None, forceSave: true, forceRefresh: true); + return RefreshMetadata(new MetadataRefreshOptions + { + ForceSave = true, + ReplaceAllMetadata = true + + }, CancellationToken.None); } /// @@ -275,17 +281,13 @@ namespace MediaBrowser.Controller.Entities /// The cancellation token. /// if set to true [is new item]. /// if set to true [force]. - /// if set to true [allow slow providers]. /// true if a provider reports we changed - public override async Task RefreshMetadata(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false, bool allowSlowProviders = true, bool resetResolveArgs = true) + public override async Task RefreshMetadataDirect(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false) { - if (resetResolveArgs) - { - // Reload this - ResetResolveArgs(); - } + // Reload this + ResetResolveArgs(); - var updateReason = await ProviderManager.ExecuteMetadataProviders(this, cancellationToken, forceRefresh, allowSlowProviders).ConfigureAwait(false); + var updateReason = await ProviderManager.ExecuteMetadataProviders(this, cancellationToken, forceRefresh).ConfigureAwait(false); var changed = updateReason.HasValue; diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs index e663c83538..9c94667669 100644 --- a/MediaBrowser.Controller/Entities/Video.cs +++ b/MediaBrowser.Controller/Entities/Video.cs @@ -1,4 +1,5 @@ using MediaBrowser.Controller.Persistence; +using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Resolvers; using MediaBrowser.Model.Entities; using System; @@ -164,13 +165,11 @@ namespace MediaBrowser.Controller.Entities /// The cancellation token. /// if set to true [is new item]. /// if set to true [force]. - /// if set to true [allow slow providers]. - /// The reset resolve args. /// true if a provider reports we changed - public override async Task RefreshMetadata(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false, bool allowSlowProviders = true, bool resetResolveArgs = true) + public override async Task RefreshMetadataDirect(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false) { // Kick off a task to refresh the main item - var result = await base.RefreshMetadata(cancellationToken, forceSave, forceRefresh, allowSlowProviders, resetResolveArgs).ConfigureAwait(false); + var result = await base.RefreshMetadataDirect(cancellationToken, forceSave, forceRefresh).ConfigureAwait(false); var additionalPartsChanged = false; @@ -181,7 +180,7 @@ namespace MediaBrowser.Controller.Entities { try { - additionalPartsChanged = await RefreshAdditionalParts(cancellationToken, forceSave, forceRefresh, allowSlowProviders).ConfigureAwait(false); + additionalPartsChanged = await RefreshAdditionalParts(cancellationToken, forceSave, forceRefresh).ConfigureAwait(false); } catch (IOException ex) { @@ -208,7 +207,12 @@ namespace MediaBrowser.Controller.Entities var itemsChanged = !AdditionalPartIds.SequenceEqual(newItemIds); - var tasks = newItems.Select(i => i.RefreshMetadata(cancellationToken, forceSave, forceRefresh, allowSlowProviders)); + var tasks = newItems.Select(i => i.RefreshMetadata(new MetadataRefreshOptions + { + ForceSave = forceSave, + ReplaceAllMetadata = forceRefresh + + }, cancellationToken)); var results = await Task.WhenAll(tasks).ConfigureAwait(false); diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs b/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs index d9bceb6cad..c94a25a304 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs @@ -1,4 +1,5 @@ using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; using System.Threading; using System.Threading.Tasks; @@ -11,8 +12,6 @@ namespace MediaBrowser.Controller.LiveTv string MediaType { get; } - LocationType LocationType { get; } - RecordingInfo RecordingInfo { get; set; } string GetClientTypeName(); @@ -21,6 +20,6 @@ namespace MediaBrowser.Controller.LiveTv bool IsParentalAllowed(User user); - Task RefreshMetadata(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false, bool allowSlowProviders = true, bool resetResolveArgs = true); + Task RefreshMetadata(MetadataRefreshOptions options, CancellationToken cancellationToken); } } diff --git a/MediaBrowser.Controller/LiveTv/StreamResponseInfo.cs b/MediaBrowser.Controller/LiveTv/StreamResponseInfo.cs index c3b438c5ee..b133874d09 100644 --- a/MediaBrowser.Controller/LiveTv/StreamResponseInfo.cs +++ b/MediaBrowser.Controller/LiveTv/StreamResponseInfo.cs @@ -1,4 +1,5 @@ -using System.IO; +using MediaBrowser.Controller.Drawing; +using System.IO; namespace MediaBrowser.Controller.LiveTv { @@ -14,6 +15,6 @@ namespace MediaBrowser.Controller.LiveTv /// Gets or sets the type of the MIME. /// /// The type of the MIME. - public string MimeType { get; set; } + public ImageFormat Format { get; set; } } } diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 56ac695a2d..ef87c30c78 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -69,6 +69,7 @@ Properties\SharedVersion.cs + @@ -143,8 +144,15 @@ + + + + + + + diff --git a/MediaBrowser.Controller/Providers/IHasMetadata.cs b/MediaBrowser.Controller/Providers/IHasMetadata.cs new file mode 100644 index 0000000000..33c5184b8b --- /dev/null +++ b/MediaBrowser.Controller/Providers/IHasMetadata.cs @@ -0,0 +1,31 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Model.Entities; +using System; +using System.Collections.Generic; + +namespace MediaBrowser.Controller.Providers +{ + /// + /// Interface IHasMetadata + /// + public interface IHasMetadata : IHasImages, IHasProviderIds + { + /// + /// Gets the preferred metadata country code. + /// + /// System.String. + string GetPreferredMetadataCountryCode(); + + /// + /// Gets the locked fields. + /// + /// The locked fields. + List LockedFields { get; } + + /// + /// Gets or sets the date last saved. + /// + /// The date last saved. + DateTime DateLastSaved { get; set; } + } +} diff --git a/MediaBrowser.Controller/Providers/IImageProvider.cs b/MediaBrowser.Controller/Providers/IImageProvider.cs index ccf1998445..61f5579f4b 100644 --- a/MediaBrowser.Controller/Providers/IImageProvider.cs +++ b/MediaBrowser.Controller/Providers/IImageProvider.cs @@ -1,9 +1,4 @@ using MediaBrowser.Controller.Entities; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Providers; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; namespace MediaBrowser.Controller.Providers { @@ -26,26 +21,9 @@ namespace MediaBrowser.Controller.Providers bool Supports(IHasImages item); /// - /// Gets the images. + /// Gets the order. /// - /// The item. - /// Type of the image. - /// The cancellation token. - /// Task{IEnumerable{RemoteImageInfo}}. - Task> GetImages(IHasImages item, ImageType imageType, CancellationToken cancellationToken); - - /// - /// Gets the images. - /// - /// The item. - /// The cancellation token. - /// Task{IEnumerable{RemoteImageInfo}}. - Task> GetAllImages(IHasImages item, CancellationToken cancellationToken); - - /// - /// Gets the priority. - /// - /// The priority. - int Priority { get; } + /// The order. + int Order { get; } } } diff --git a/MediaBrowser.Controller/Providers/ILocalImageProvider.cs b/MediaBrowser.Controller/Providers/ILocalImageProvider.cs new file mode 100644 index 0000000000..30f2136059 --- /dev/null +++ b/MediaBrowser.Controller/Providers/ILocalImageProvider.cs @@ -0,0 +1,58 @@ +using MediaBrowser.Controller.Drawing; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Model.Entities; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; + +namespace MediaBrowser.Controller.Providers +{ + /// + /// This is just a marker interface + /// + public interface ILocalImageProvider : IImageProvider + { + } + + public interface IImageFileProvider : ILocalImageProvider + { + List GetImages(IHasImages item); + } + + public class LocalImageInfo + { + public string Path { get; set; } + public ImageType Type { get; set; } + } + + public interface IDynamicImageProvider : ILocalImageProvider + { + /// + /// Gets the images. + /// + /// The item. + /// List{DynamicImageInfo}. + List GetImageInfos(IHasImages item); + + /// + /// Gets the image. + /// + /// The item. + /// The information. + /// Task{DynamicImageResponse}. + Task GetImage(IHasImages item, DynamicImageInfo info); + } + + public class DynamicImageInfo + { + public string ImageId { get; set; } + public ImageType Type { get; set; } + } + + public class DynamicImageResponse + { + public string Path { get; set; } + public Stream Stream { get; set; } + public ImageFormat Format { get; set; } + } +} diff --git a/MediaBrowser.Controller/Providers/IMetadataProvider.cs b/MediaBrowser.Controller/Providers/IMetadataProvider.cs new file mode 100644 index 0000000000..97249e26d9 --- /dev/null +++ b/MediaBrowser.Controller/Providers/IMetadataProvider.cs @@ -0,0 +1,90 @@ +using MediaBrowser.Model.Entities; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Controller.Providers +{ + /// + /// Marker interface + /// + public interface IMetadataProvider + { + /// + /// Gets the name. + /// + /// The name. + string Name { get; } + } + + public interface IMetadataProvider : IMetadataProvider + where TItemType : IHasMetadata + { + } + + public interface ILocalMetadataProvider : IMetadataProvider + { + /// + /// Determines whether [has local metadata] [the specified item]. + /// + /// The item. + /// true if [has local metadata] [the specified item]; otherwise, false. + bool HasLocalMetadata(IHasMetadata item); + } + + public interface IRemoteMetadataProvider : IMetadataProvider + { + } + + public interface IRemoteMetadataProvider : IMetadataProvider, IRemoteMetadataProvider + where TItemType : IHasMetadata + { + Task> GetMetadata(ItemId id, CancellationToken cancellationToken); + } + + public interface ILocalMetadataProvider : IMetadataProvider, ILocalMetadataProvider + where TItemType : IHasMetadata + { + Task> GetMetadata(string path, CancellationToken cancellationToken); + } + + public interface IHasChangeMonitor + { + /// + /// Determines whether the specified date has changed. + /// + /// The item. + /// The date. + /// true if the specified date has changed; otherwise, false. + bool HasChanged(IHasMetadata item, DateTime date); + } + + public enum MetadataProviderType + { + Embedded = 0, + Local = 1, + Remote = 2 + } + + public class MetadataResult + where T : IHasMetadata + { + public bool HasMetadata { get; set; } + public T Item { get; set; } + } + + public class ItemId : IHasProviderIds + { + public string Name { get; set; } + public string MetadataLanguage { get; set; } + public string MetadataCountryCode { get; set; } + + public Dictionary ProviderIds { get; set; } + + public ItemId() + { + ProviderIds = new Dictionary(StringComparer.OrdinalIgnoreCase); + } + } +} diff --git a/MediaBrowser.Controller/Providers/IMetadataService.cs b/MediaBrowser.Controller/Providers/IMetadataService.cs new file mode 100644 index 0000000000..c6cc2b716e --- /dev/null +++ b/MediaBrowser.Controller/Providers/IMetadataService.cs @@ -0,0 +1,38 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Controller.Providers +{ + public interface IMetadataService + { + /// + /// Adds the parts. + /// + /// The providers. + /// The image providers. + void AddParts(IEnumerable providers, IEnumerable imageProviders); + + /// + /// Determines whether this instance can refresh the specified item. + /// + /// The item. + /// true if this instance can refresh the specified item; otherwise, false. + bool CanRefresh(IHasMetadata item); + + /// + /// Refreshes the metadata. + /// + /// The item. + /// The options. + /// The cancellation token. + /// Task. + Task RefreshMetadata(IHasMetadata item, MetadataRefreshOptions options, CancellationToken cancellationToken); + + /// + /// Gets the order. + /// + /// The order. + int Order { get; } + } +} diff --git a/MediaBrowser.Controller/Providers/IProviderManager.cs b/MediaBrowser.Controller/Providers/IProviderManager.cs index 728030ecc9..dc57552c44 100644 --- a/MediaBrowser.Controller/Providers/IProviderManager.cs +++ b/MediaBrowser.Controller/Providers/IProviderManager.cs @@ -14,15 +14,23 @@ namespace MediaBrowser.Controller.Providers /// public interface IProviderManager { + /// + /// Refreshes the metadata. + /// + /// The item. + /// The options. + /// The cancellation token. + /// Task. + Task RefreshMetadata(IHasMetadata item, MetadataRefreshOptions options, CancellationToken cancellationToken); + /// /// Executes the metadata providers. /// /// The item. /// The cancellation token. /// if set to true [force]. - /// if set to true [allow slow providers]. /// Task{System.Boolean}. - Task ExecuteMetadataProviders(BaseItem item, CancellationToken cancellationToken, bool force = false, bool allowSlowProviders = true); + Task ExecuteMetadataProviders(BaseItem item, CancellationToken cancellationToken, bool force = false); /// /// Saves the image. @@ -54,7 +62,9 @@ namespace MediaBrowser.Controller.Providers /// /// The providers. /// The image providers. - void AddParts(IEnumerable providers, IEnumerable imageProviders); + /// The metadata services. + /// The metadata providers. + void AddParts(IEnumerable providers, IEnumerable imageProviders, IEnumerable metadataServices, IEnumerable metadataProviders); /// /// Gets the available remote images. @@ -70,7 +80,7 @@ namespace MediaBrowser.Controller.Providers /// Gets the image providers. /// /// The item. - /// IEnumerable{IImageProvider}. - IEnumerable GetImageProviders(BaseItem item); + /// IEnumerable{ImageProviderInfo}. + IEnumerable GetImageProviderInfo(BaseItem item); } } \ No newline at end of file diff --git a/MediaBrowser.Controller/Providers/IRemoteImageProvider.cs b/MediaBrowser.Controller/Providers/IRemoteImageProvider.cs new file mode 100644 index 0000000000..23fda2bfa0 --- /dev/null +++ b/MediaBrowser.Controller/Providers/IRemoteImageProvider.cs @@ -0,0 +1,48 @@ +using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Providers; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Controller.Providers +{ + /// + /// Interface IImageProvider + /// + public interface IRemoteImageProvider : IImageProvider + { + /// + /// Gets the supported images. + /// + /// The item. + /// IEnumerable{ImageType}. + IEnumerable GetSupportedImages(IHasImages item); + + /// + /// Gets the images. + /// + /// The item. + /// Type of the image. + /// The cancellation token. + /// Task{IEnumerable{RemoteImageInfo}}. + Task> GetImages(IHasImages item, ImageType imageType, CancellationToken cancellationToken); + + /// + /// Gets the images. + /// + /// The item. + /// The cancellation token. + /// Task{IEnumerable{RemoteImageInfo}}. + Task> GetAllImages(IHasImages item, CancellationToken cancellationToken); + + /// + /// Gets the image response. + /// + /// The URL. + /// The cancellation token. + /// Task{HttpResponseInfo}. + Task GetImageResponse(string url, CancellationToken cancellationToken); + } +} diff --git a/MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs b/MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs new file mode 100644 index 0000000000..d6e8a3afea --- /dev/null +++ b/MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs @@ -0,0 +1,49 @@ +using System; + +namespace MediaBrowser.Controller.Providers +{ + public class MetadataRefreshOptions : ImageRefreshOptions + { + /// + /// When paired with MetadataRefreshMode=FullRefresh, all existing data will be overwritten with new data from the providers. + /// + public bool ReplaceAllMetadata { get; set; } + + public MetadataRefreshMode MetadataRefreshMode { get; set; } + + /// + /// TODO: deprecate. Keeping this for now, for api compatibility + /// + [Obsolete] + public bool ForceSave { get; set; } + + /// + /// TODO: deprecate. Keeping this for now, for api compatibility + /// + [Obsolete] + public bool ResetResolveArgs { get; set; } + } + + public class ImageRefreshOptions + { + public MetadataRefreshMode ImageRefreshMode { get; set; } + } + + public enum MetadataRefreshMode + { + /// + /// Providers will be executed based on default rules + /// + EnsureMetadata, + + /// + /// No providers will be executed + /// + None, + + /// + /// All providers will be executed to search for new metadata + /// + FullRefresh + } +} diff --git a/MediaBrowser.Controller/Providers/ProviderResult.cs b/MediaBrowser.Controller/Providers/ProviderResult.cs new file mode 100644 index 0000000000..2486faeedc --- /dev/null +++ b/MediaBrowser.Controller/Providers/ProviderResult.cs @@ -0,0 +1,60 @@ +using System; + +namespace MediaBrowser.Controller.Providers +{ + public class ProviderResult + { + /// + /// Gets or sets the item identifier. + /// + /// The item identifier. + public Guid ItemId { get; set; } + + /// + /// Gets or sets a value indicating whether this instance has refreshed metadata. + /// + /// true if this instance has refreshed metadata; otherwise, false. + public bool HasRefreshedMetadata { get; set; } + + /// + /// Gets or sets a value indicating whether this instance has refreshed images. + /// + /// true if this instance has refreshed images; otherwise, false. + public bool HasRefreshedImages { get; set; } + + /// + /// Gets or sets the date last refreshed. + /// + /// The date last refreshed. + public DateTime DateLastRefreshed { get; set; } + + /// + /// Gets or sets the last result. + /// + /// The last result. + public ProviderRefreshStatus Status { get; set; } + + /// + /// Gets or sets the last result error message. + /// + /// The last result error message. + public string ErrorMessage { get; set; } + + public void AddStatus(ProviderRefreshStatus status, string errorMessage) + { + if (string.IsNullOrEmpty(ErrorMessage)) + { + ErrorMessage = errorMessage; + } + if (Status == ProviderRefreshStatus.Success) + { + Status = status; + } + } + + public ProviderResult() + { + Status = ProviderRefreshStatus.Success; + } + } +} -- cgit v1.2.3