diff options
| author | Luke <luke.pulverenti@gmail.com> | 2017-07-01 12:24:26 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-07-01 12:24:26 -0400 |
| commit | ff3713153ad2317e1c196f33ac2cba61b449a00e (patch) | |
| tree | 84d2e6ed5bcb556a2395603b6403c8e992535e6b /MediaBrowser.Controller | |
| parent | fad71a6c7d12c8b207cdf473c7dd7daafa53c174 (diff) | |
| parent | 2dcad6b5977f5c5be81b18c42506ed8ad3fb73b6 (diff) | |
Merge pull request #2739 from MediaBrowser/beta
Beta
Diffstat (limited to 'MediaBrowser.Controller')
32 files changed, 467 insertions, 185 deletions
diff --git a/MediaBrowser.Controller/Channels/Channel.cs b/MediaBrowser.Controller/Channels/Channel.cs index 862c8e5ace..c6e750a0c0 100644 --- a/MediaBrowser.Controller/Channels/Channel.cs +++ b/MediaBrowser.Controller/Channels/Channel.cs @@ -6,6 +6,7 @@ using System.Linq; using MediaBrowser.Model.Serialization; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Common.Progress; namespace MediaBrowser.Controller.Channels { @@ -32,6 +33,15 @@ namespace MediaBrowser.Controller.Channels } [IgnoreDataMember] + public override bool SupportsInheritedParentImages + { + get + { + return false; + } + } + + [IgnoreDataMember] public override SourceType SourceType { get { return SourceType.Channel; } @@ -51,7 +61,7 @@ namespace MediaBrowser.Controller.Channels SortBy = query.SortBy, SortOrder = query.SortOrder - }, new Progress<double>(), CancellationToken.None).Result; + }, new SimpleProgress<double>(), CancellationToken.None).Result; } catch { diff --git a/MediaBrowser.Controller/Collections/ManualCollectionsFolder.cs b/MediaBrowser.Controller/Collections/ManualCollectionsFolder.cs index d2d28e5047..160a788f1c 100644 --- a/MediaBrowser.Controller/Collections/ManualCollectionsFolder.cs +++ b/MediaBrowser.Controller/Collections/ManualCollectionsFolder.cs @@ -1,4 +1,5 @@ using MediaBrowser.Controller.Entities; +using MediaBrowser.Model.Serialization; namespace MediaBrowser.Controller.Collections { @@ -18,11 +19,21 @@ namespace MediaBrowser.Controller.Collections } } + [IgnoreDataMember] + public override bool SupportsInheritedParentImages + { + get + { + return false; + } + } + public bool IsHiddenFromUser(User user) { return !ConfigurationManager.Configuration.DisplayCollectionsView; } + [IgnoreDataMember] public override string CollectionType { get { return Model.Entities.CollectionType.BoxSets; } diff --git a/MediaBrowser.Controller/Drawing/IImageProcessor.cs b/MediaBrowser.Controller/Drawing/IImageProcessor.cs index d98638d556..2832462a8d 100644 --- a/MediaBrowser.Controller/Drawing/IImageProcessor.cs +++ b/MediaBrowser.Controller/Drawing/IImageProcessor.cs @@ -33,6 +33,8 @@ namespace MediaBrowser.Controller.Drawing /// <returns>ImageSize.</returns> ImageSize GetImageSize(ItemImageInfo info); + ImageSize GetImageSize(ItemImageInfo info, bool allowSlowMethods); + /// <summary> /// Gets the size of the image. /// </summary> diff --git a/MediaBrowser.Controller/Dto/DtoOptions.cs b/MediaBrowser.Controller/Dto/DtoOptions.cs index b9d9d7ddad..098ba558f8 100644 --- a/MediaBrowser.Controller/Dto/DtoOptions.cs +++ b/MediaBrowser.Controller/Dto/DtoOptions.cs @@ -10,7 +10,8 @@ namespace MediaBrowser.Controller.Dto { private static readonly List<ItemFields> DefaultExcludedFields = new List<ItemFields> { - ItemFields.SeasonUserData + ItemFields.SeasonUserData, + ItemFields.RefreshState }; public List<ItemFields> Fields { get; set; } diff --git a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs index e9eca19cf7..516ab50530 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs @@ -235,8 +235,6 @@ namespace MediaBrowser.Controller.Entities.Audio { await RefreshArtists(refreshOptions, cancellationToken).ConfigureAwait(false); } - - progress.Report(100); } private async Task RefreshArtists(MetadataRefreshOptions refreshOptions, CancellationToken cancellationToken) diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs index 4b232de499..7a37b2e02e 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs @@ -36,6 +36,15 @@ namespace MediaBrowser.Controller.Entities.Audio } [IgnoreDataMember] + public override bool SupportsInheritedParentImages + { + get + { + return false; + } + } + + [IgnoreDataMember] public override bool SupportsCumulativeRunTimeTicks { get @@ -250,8 +259,6 @@ namespace MediaBrowser.Controller.Entities.Audio percent /= totalItems; progress.Report(percent * 100); } - - progress.Report(100); } public ArtistInfo GetLookupInfo() diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 4efea94d8e..b4a3d89eac 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -1058,6 +1058,16 @@ namespace MediaBrowser.Controller.Entities return RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(Logger, FileSystem)), cancellationToken); } + protected virtual void TriggerOnRefreshStart() + { + + } + + protected virtual void TriggerOnRefreshComplete() + { + + } + /// <summary> /// Overrides the base implementation to refresh metadata for local trailers /// </summary> @@ -1066,6 +1076,8 @@ namespace MediaBrowser.Controller.Entities /// <returns>true if a provider reports we changed</returns> public async Task<ItemUpdateType> RefreshMetadata(MetadataRefreshOptions options, CancellationToken cancellationToken) { + TriggerOnRefreshStart(); + var locationType = LocationType; var requiresSave = false; @@ -1091,14 +1103,21 @@ namespace MediaBrowser.Controller.Entities } } - var refreshOptions = requiresSave - ? new MetadataRefreshOptions(options) - { - ForceSave = true - } - : options; + try + { + var refreshOptions = requiresSave + ? new MetadataRefreshOptions(options) + { + ForceSave = true + } + : options; - return await ProviderManager.RefreshSingleItem(this, refreshOptions, cancellationToken).ConfigureAwait(false); + return await ProviderManager.RefreshSingleItem(this, refreshOptions, cancellationToken).ConfigureAwait(false); + } + finally + { + TriggerOnRefreshComplete(); + } } [IgnoreDataMember] @@ -2421,5 +2440,10 @@ namespace MediaBrowser.Controller.Entities { return new List<ExternalUrl>(); } + + public virtual double? GetRefreshProgress() + { + return null; + } } }
\ No newline at end of file diff --git a/MediaBrowser.Controller/Entities/BasePluginFolder.cs b/MediaBrowser.Controller/Entities/BasePluginFolder.cs index 7dbea317c8..a61862f280 100644 --- a/MediaBrowser.Controller/Entities/BasePluginFolder.cs +++ b/MediaBrowser.Controller/Entities/BasePluginFolder.cs @@ -9,6 +9,7 @@ namespace MediaBrowser.Controller.Entities /// </summary> public abstract class BasePluginFolder : Folder, ICollectionFolder { + [IgnoreDataMember] public virtual string CollectionType { get { return null; } @@ -25,6 +26,15 @@ namespace MediaBrowser.Controller.Entities } [IgnoreDataMember] + public override bool SupportsInheritedParentImages + { + get + { + return false; + } + } + + [IgnoreDataMember] public override bool SupportsPeople { get diff --git a/MediaBrowser.Controller/Entities/CollectionFolder.cs b/MediaBrowser.Controller/Entities/CollectionFolder.cs index 8bc23a5819..d88b7da346 100644 --- a/MediaBrowser.Controller/Entities/CollectionFolder.cs +++ b/MediaBrowser.Controller/Entities/CollectionFolder.cs @@ -10,6 +10,7 @@ using System.Threading.Tasks; using MediaBrowser.Controller.Configuration; using MediaBrowser.Model.Configuration; +using MediaBrowser.Model.Entities; using MediaBrowser.Model.Extensions; using MediaBrowser.Model.IO; using MediaBrowser.Model.Serialization; @@ -48,6 +49,15 @@ namespace MediaBrowser.Controller.Entities } } + [IgnoreDataMember] + public override bool SupportsInheritedParentImages + { + get + { + return false; + } + } + public override bool CanDelete() { return false; @@ -199,6 +209,30 @@ namespace MediaBrowser.Controller.Entities return changed; } + public override double? GetRefreshProgress() + { + var folders = GetPhysicalFolders(true).ToList(); + double totalProgresses = 0; + var foldersWithProgress = 0; + + foreach (var folder in folders) + { + var progress = ProviderManager.GetRefreshProgress(folder.Id); + if (progress.HasValue) + { + totalProgresses += progress.Value; + foldersWithProgress++; + } + } + + if (foldersWithProgress == 0) + { + return null; + } + + return (totalProgresses / foldersWithProgress); + } + protected override bool RefreshLinkedChildren(IEnumerable<FileSystemMetadata> fileSystemChildren) { return RefreshLinkedChildrenInternal(true); @@ -321,6 +355,11 @@ namespace MediaBrowser.Controller.Entities return GetPhysicalFolders(true).SelectMany(c => c.Children); } + public IEnumerable<Folder> GetPhysicalFolders() + { + return GetPhysicalFolders(true); + } + private IEnumerable<Folder> GetPhysicalFolders(bool enableCache) { if (enableCache) diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 48c9b83aa2..5d74cf218b 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -66,6 +66,15 @@ namespace MediaBrowser.Controller.Entities } [IgnoreDataMember] + public override bool SupportsInheritedParentImages + { + get + { + return true; + } + } + + [IgnoreDataMember] public override bool SupportsPlayedStatus { get @@ -212,33 +221,6 @@ namespace MediaBrowser.Controller.Entities } /// <summary> - /// Returns the valid set of index by options for this folder type. - /// Override or extend to modify. - /// </summary> - /// <returns>Dictionary{System.StringFunc{UserIEnumerable{BaseItem}}}.</returns> - protected virtual IEnumerable<string> GetIndexByOptions() - { - return new List<string> { - {"None"}, - {"Performer"}, - {"Genre"}, - {"Director"}, - {"Year"}, - {"Studio"} - }; - } - - /// <summary> - /// Get the list of indexy by choices for this folder (localized). - /// </summary> - /// <value>The index by option strings.</value> - [IgnoreDataMember] - public IEnumerable<string> IndexByOptionStrings - { - get { return GetIndexByOptions(); } - } - - /// <summary> /// Gets the actual children. /// </summary> /// <value>The actual children.</value> @@ -298,6 +280,11 @@ namespace MediaBrowser.Controller.Entities return GetCachedChildren(); } + public override double? GetRefreshProgress() + { + return ProviderManager.GetRefreshProgress(Id); + } + public Task ValidateChildren(IProgress<double> progress, CancellationToken cancellationToken) { return ValidateChildren(progress, cancellationToken, new MetadataRefreshOptions(new DirectoryService(Logger, FileSystem))); @@ -345,6 +332,14 @@ namespace MediaBrowser.Controller.Entities return current.IsValidFromResolver(newItem); } + protected override void TriggerOnRefreshStart() + { + } + + protected override void TriggerOnRefreshComplete() + { + } + /// <summary> /// Validates the children internal. /// </summary> @@ -355,7 +350,27 @@ namespace MediaBrowser.Controller.Entities /// <param name="refreshOptions">The refresh options.</param> /// <param name="directoryService">The directory service.</param> /// <returns>Task.</returns> - protected async virtual Task ValidateChildrenInternal(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService) + protected virtual async Task ValidateChildrenInternal(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService) + { + if (recursive) + { + ProviderManager.OnRefreshStart(this); + } + + try + { + await ValidateChildrenInternal2(progress, cancellationToken, recursive, refreshChildMetadata, refreshOptions, directoryService).ConfigureAwait(false); + } + finally + { + if (recursive) + { + ProviderManager.OnRefreshComplete(this); + } + } + } + + private async Task ValidateChildrenInternal2(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService) { var locationType = LocationType; @@ -387,6 +402,11 @@ namespace MediaBrowser.Controller.Entities progress.Report(5); + if (recursive) + { + ProviderManager.OnRefreshProgress(this, 5); + } + //build a dictionary of the current children we have now by Id so we can compare quickly and easily var currentChildren = GetActualChildrenDictionary(); @@ -451,76 +471,99 @@ namespace MediaBrowser.Controller.Entities await LibraryManager.CreateItems(newItems, cancellationToken).ConfigureAwait(false); } } + else + { + if (recursive || refreshChildMetadata) + { + // used below + validChildren = Children.ToList(); + } + } progress.Report(10); - cancellationToken.ThrowIfCancellationRequested(); - if (recursive) { - await ValidateSubFolders(Children.ToList().OfType<Folder>().ToList(), directoryService, progress, cancellationToken).ConfigureAwait(false); + ProviderManager.OnRefreshProgress(this, 10); } - progress.Report(20); + cancellationToken.ThrowIfCancellationRequested(); - if (refreshChildMetadata) + if (recursive) { - var container = this as IMetadataContainer; + using (var innerProgress = new ActionableProgress<double>()) + { + var folder = this; + innerProgress.RegisterAction(p => + { + double newPct = .80 * p + 10; + progress.Report(newPct); + ProviderManager.OnRefreshProgress(folder, newPct); + }); - var innerProgress = new ActionableProgress<double>(); + await ValidateSubFolders(validChildren.OfType<Folder>().ToList(), directoryService, innerProgress, cancellationToken).ConfigureAwait(false); + } + } - innerProgress.RegisterAction(p => progress.Report(.80 * p + 20)); + if (refreshChildMetadata) + { + progress.Report(90); - if (container != null) + if (recursive) { - await container.RefreshAllMetadata(refreshOptions, innerProgress, cancellationToken).ConfigureAwait(false); + ProviderManager.OnRefreshProgress(this, 90); } - else + + var container = this as IMetadataContainer; + + using (var innerProgress = new ActionableProgress<double>()) { - await RefreshMetadataRecursive(refreshOptions, recursive, innerProgress, cancellationToken); + var folder = this; + innerProgress.RegisterAction(p => + { + double newPct = .10 * p + 90; + progress.Report(newPct); + if (recursive) + { + ProviderManager.OnRefreshProgress(folder, newPct); + } + }); + + if (container != null) + { + await container.RefreshAllMetadata(refreshOptions, innerProgress, cancellationToken).ConfigureAwait(false); + } + else + { + await RefreshMetadataRecursive(validChildren, refreshOptions, recursive, innerProgress, cancellationToken); + } } } - - progress.Report(100); } - private async Task RefreshMetadataRecursive(MetadataRefreshOptions refreshOptions, bool recursive, IProgress<double> progress, CancellationToken cancellationToken) + private async Task RefreshMetadataRecursive(List<BaseItem> children, MetadataRefreshOptions refreshOptions, bool recursive, IProgress<double> progress, CancellationToken cancellationToken) { - var children = Children.ToList(); - - var percentages = new Dictionary<Guid, double>(children.Count); var numComplete = 0; var count = children.Count; + double currentPercent = 0; foreach (var child in children) { cancellationToken.ThrowIfCancellationRequested(); - if (child.IsFolder) + using (var innerProgress = new ActionableProgress<double>()) { - var innerProgress = new ActionableProgress<double>(); - // Avoid implicitly captured closure - var currentChild = child; + var currentInnerPercent = currentPercent; + innerProgress.RegisterAction(p => { - lock (percentages) - { - percentages[currentChild.Id] = p / 100; - - var innerPercent = percentages.Values.Sum(); - innerPercent /= count; - innerPercent *= 100; - progress.Report(innerPercent); - } + double innerPercent = currentInnerPercent; + innerPercent += p / (count); + progress.Report(innerPercent); }); - await RefreshChildMetadata(child, refreshOptions, recursive, innerProgress, cancellationToken) - .ConfigureAwait(false); - } - else - { - await RefreshChildMetadata(child, refreshOptions, false, new Progress<double>(), cancellationToken) + await RefreshChildMetadata(child, refreshOptions, recursive && child.IsFolder, innerProgress, cancellationToken) .ConfigureAwait(false); } @@ -528,11 +571,10 @@ namespace MediaBrowser.Controller.Entities double percent = numComplete; percent /= count; percent *= 100; + currentPercent = percent; progress.Report(percent); } - - progress.Report(100); } private async Task RefreshChildMetadata(BaseItem child, MetadataRefreshOptions refreshOptions, bool recursive, IProgress<double> progress, CancellationToken cancellationToken) @@ -553,11 +595,10 @@ namespace MediaBrowser.Controller.Entities if (folder != null) { - await folder.RefreshMetadataRecursive(refreshOptions, true, progress, cancellationToken); + await folder.RefreshMetadataRecursive(folder.Children.ToList(), refreshOptions, true, progress, cancellationToken); } } } - progress.Report(100); } /// <summary> @@ -570,47 +611,40 @@ namespace MediaBrowser.Controller.Entities /// <returns>Task.</returns> private async Task ValidateSubFolders(IList<Folder> children, IDirectoryService directoryService, IProgress<double> progress, CancellationToken cancellationToken) { - var list = children; - var childCount = list.Count; - - var percentages = new Dictionary<Guid, double>(list.Count); + var numComplete = 0; + var count = children.Count; + double currentPercent = 0; - foreach (var item in list) + foreach (var child in children) { cancellationToken.ThrowIfCancellationRequested(); - var child = item; - - var innerProgress = new ActionableProgress<double>(); - - innerProgress.RegisterAction(p => + using (var innerProgress = new ActionableProgress<double>()) { - lock (percentages) + // Avoid implicitly captured closure + var currentInnerPercent = currentPercent; + + innerProgress.RegisterAction(p => { - percentages[child.Id] = p / 100; + double innerPercent = currentInnerPercent; + innerPercent += p / (count); + progress.Report(innerPercent); + }); - var percent = percentages.Values.Sum(); - percent /= childCount; + await child.ValidateChildrenInternal(innerProgress, cancellationToken, true, false, null, directoryService) + .ConfigureAwait(false); + } - progress.Report(10 * percent + 10); - } - }); + numComplete++; + double percent = numComplete; + percent /= count; + percent *= 100; + currentPercent = percent; - await child.ValidateChildrenInternal(innerProgress, cancellationToken, true, false, null, directoryService) - .ConfigureAwait(false); + progress.Report(percent); } } - /// <summary> - /// Determines whether the specified path is offline. - /// </summary> - /// <param name="path">The path.</param> - /// <returns><c>true</c> if the specified path is offline; otherwise, <c>false</c>.</returns> - public static bool IsPathOffline(string path) - { - return IsPathOffline(path, LibraryManager.GetVirtualFolders().SelectMany(i => i.Locations).ToList()); - } - public static bool IsPathOffline(string path, List<string> allLibraryPaths) { if (FileSystem.FileExists(path)) @@ -953,7 +987,7 @@ namespace MediaBrowser.Controller.Entities SortBy = query.SortBy, SortOrder = query.SortOrder - }, new Progress<double>(), CancellationToken.None).Result; + }, new SimpleProgress<double>(), CancellationToken.None).Result; } catch { diff --git a/MediaBrowser.Controller/Entities/GameSystem.cs b/MediaBrowser.Controller/Entities/GameSystem.cs index d8879155af..bbaec14a15 100644 --- a/MediaBrowser.Controller/Entities/GameSystem.cs +++ b/MediaBrowser.Controller/Entities/GameSystem.cs @@ -35,6 +35,15 @@ namespace MediaBrowser.Controller.Entities } } + [IgnoreDataMember] + public override bool SupportsInheritedParentImages + { + get + { + return false; + } + } + /// <summary> /// Gets or sets the game system. /// </summary> diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index 4d96c082fb..608e3f56c3 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -56,7 +56,6 @@ namespace MediaBrowser.Controller.Entities public string Path { get; set; } public string PathNotStartsWith { get; set; } public string Name { get; set; } - public string SlugName { get; set; } public string Person { get; set; } public string[] PersonIds { get; set; } diff --git a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs index 406a99f8b7..071ed405f1 100644 --- a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs +++ b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs @@ -29,6 +29,7 @@ namespace MediaBrowser.Controller.Entities.Movies Shares = new List<Share>(); } + [IgnoreDataMember] protected override bool FilterLinkedChildrenPerUser { get @@ -37,6 +38,15 @@ namespace MediaBrowser.Controller.Entities.Movies } } + [IgnoreDataMember] + public override bool SupportsInheritedParentImages + { + get + { + return false; + } + } + public List<Guid> LocalTrailerIds { get; set; } public List<Guid> RemoteTrailerIds { get; set; } @@ -118,6 +128,11 @@ namespace MediaBrowser.Controller.Entities.Movies { get { + if (string.IsNullOrWhiteSpace(Path)) + { + return false; + } + return !FileSystem.ContainsSubPath(ConfigurationManager.ApplicationPaths.DataPath, Path); } } diff --git a/MediaBrowser.Controller/Entities/PhotoAlbum.cs b/MediaBrowser.Controller/Entities/PhotoAlbum.cs index dd3cd98fb9..af9d8c801d 100644 --- a/MediaBrowser.Controller/Entities/PhotoAlbum.cs +++ b/MediaBrowser.Controller/Entities/PhotoAlbum.cs @@ -21,5 +21,14 @@ namespace MediaBrowser.Controller.Entities return false; } } + + [IgnoreDataMember] + public override bool SupportsInheritedParentImages + { + get + { + return false; + } + } } } diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs index 17494eb087..b681fdcb10 100644 --- a/MediaBrowser.Controller/Entities/TV/Season.cs +++ b/MediaBrowser.Controller/Entities/TV/Season.cs @@ -66,17 +66,6 @@ namespace MediaBrowser.Controller.Entities.TV return series == null ? SeriesName : series.SortName; } - // Genre, Rating and Stuido will all be the same - protected override IEnumerable<string> GetIndexByOptions() - { - return new List<string> { - {"None"}, - {"Performer"}, - {"Director"}, - {"Year"}, - }; - } - public override List<string> GetUserDataKeys() { var list = base.GetUserDataKeys(); diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index c54f93f11f..8b73b80b02 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -53,6 +53,15 @@ namespace MediaBrowser.Controller.Entities.TV } } + [IgnoreDataMember] + public override bool SupportsInheritedParentImages + { + get + { + return false; + } + } + public List<Guid> LocalTrailerIds { get; set; } public List<Guid> RemoteTrailerIds { get; set; } @@ -227,17 +236,6 @@ namespace MediaBrowser.Controller.Entities.TV return list; } - // Studio, Genre and Rating will all be the same so makes no sense to index by these - protected override IEnumerable<string> GetIndexByOptions() - { - return new List<string> { - {"None"}, - {"Performer"}, - {"Director"}, - {"Year"}, - }; - } - [IgnoreDataMember] public bool ContainsEpisodesWithoutSeasonFolders { @@ -425,8 +423,6 @@ namespace MediaBrowser.Controller.Entities.TV refreshOptions = new MetadataRefreshOptions(refreshOptions); refreshOptions.IsPostRecursiveRefresh = true; await ProviderManager.RefreshSingleItem(this, refreshOptions, cancellationToken).ConfigureAwait(false); - - progress.Report(100); } public IEnumerable<Episode> GetSeasonEpisodes(Season parentSeason, User user, DtoOptions options) diff --git a/MediaBrowser.Controller/Entities/UserRootFolder.cs b/MediaBrowser.Controller/Entities/UserRootFolder.cs index 3e4931e774..d351563450 100644 --- a/MediaBrowser.Controller/Entities/UserRootFolder.cs +++ b/MediaBrowser.Controller/Entities/UserRootFolder.cs @@ -34,6 +34,15 @@ namespace MediaBrowser.Controller.Entities } [IgnoreDataMember] + public override bool SupportsInheritedParentImages + { + get + { + return false; + } + } + + [IgnoreDataMember] public override bool SupportsPlayedStatus { get diff --git a/MediaBrowser.Controller/Entities/UserView.cs b/MediaBrowser.Controller/Entities/UserView.cs index 27be696ebd..0d2d69c949 100644 --- a/MediaBrowser.Controller/Entities/UserView.cs +++ b/MediaBrowser.Controller/Entities/UserView.cs @@ -41,6 +41,15 @@ namespace MediaBrowser.Controller.Entities } [IgnoreDataMember] + public override bool SupportsInheritedParentImages + { + get + { + return false; + } + } + + [IgnoreDataMember] public override bool SupportsPlayedStatus { get diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs index b6887940ed..7978f47613 100644 --- a/MediaBrowser.Controller/Entities/Video.cs +++ b/MediaBrowser.Controller/Entities/Video.cs @@ -44,6 +44,15 @@ namespace MediaBrowser.Controller.Entities } [IgnoreDataMember] + public override bool SupportsInheritedParentImages + { + get + { + return true; + } + } + + [IgnoreDataMember] public override bool SupportsPositionTicksResume { get diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index 5a702b4f08..b726c267c6 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -132,7 +132,9 @@ namespace MediaBrowser.Controller.Library /// Gets the default view. /// </summary> /// <returns>IEnumerable{VirtualFolderInfo}.</returns> - IEnumerable<VirtualFolderInfo> GetVirtualFolders(); + List<VirtualFolderInfo> GetVirtualFolders(); + + List<VirtualFolderInfo> GetVirtualFolders(bool includeRefreshState); /// <summary> /// Gets the item by id. diff --git a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs index 45786e7959..9f82344029 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs @@ -92,7 +92,20 @@ namespace MediaBrowser.Controller.LiveTv public override double? GetDefaultPrimaryImageAspectRatio() { - return null; + if (IsMovie) + { + double value = 2; + value /= 3; + + return value; + } + else + { + double value = 2; + value /= 3; + + return value; + } } public override string GetClientTypeName() diff --git a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs index 665640dfd1..9f55a9ff23 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs @@ -57,8 +57,13 @@ namespace MediaBrowser.Controller.LiveTv return value; } + else + { + double value = 2; + value /= 3; - return null; + return value; + } } [IgnoreDataMember] @@ -216,12 +221,6 @@ namespace MediaBrowser.Controller.LiveTv public override bool IsInternetMetadataEnabled() { - if (IsMovie) - { - var options = (LiveTvOptions)ConfigurationManager.GetConfiguration("livetv"); - return options.EnableMovieProviders; - } - return false; } diff --git a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs index 2b527c4b09..c29d3dc478 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs @@ -108,6 +108,24 @@ namespace MediaBrowser.Controller.LiveTv return false; } + public override double? GetDefaultPrimaryImageAspectRatio() + { + if (IsMovie) + { + double value = 2; + value /= 3; + + return value; + } + else + { + double value = 2; + value /= 3; + + return value; + } + } + [IgnoreDataMember] public override bool SupportsLocalMetadata { diff --git a/MediaBrowser.Controller/LiveTv/RecordingGroup.cs b/MediaBrowser.Controller/LiveTv/RecordingGroup.cs index b54ca89747..3ee0613605 100644 --- a/MediaBrowser.Controller/LiveTv/RecordingGroup.cs +++ b/MediaBrowser.Controller/LiveTv/RecordingGroup.cs @@ -27,6 +27,15 @@ namespace MediaBrowser.Controller.LiveTv } [IgnoreDataMember] + public override bool SupportsInheritedParentImages + { + get + { + return false; + } + } + + [IgnoreDataMember] public override SourceType SourceType { get { return SourceType.LiveTV; } diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 348cfd343f..22f94695d8 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -320,7 +320,6 @@ <Compile Include="Plugins\IPluginConfigurationPage.cs" /> <Compile Include="Plugins\IServerEntryPoint.cs" /> <Compile Include="Providers\IImageEnhancer.cs" /> - <Compile Include="Providers\ProviderRefreshStatus.cs" /> <Compile Include="Resolvers\IResolverIgnoreRule.cs" /> <Compile Include="Resolvers\ResolverPriority.cs" /> <Compile Include="Library\TVUtils.cs" /> diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index c348ffda72..44bdafc5b2 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -42,6 +42,11 @@ namespace MediaBrowser.Controller.MediaEncoding { var hwType = encodingOptions.HardwareAccelerationType; + if (!encodingOptions.EnableHardwareEncoding) + { + hwType = null; + } + if (string.Equals(hwType, "qsv", StringComparison.OrdinalIgnoreCase) || string.Equals(hwType, "h264_qsv", StringComparison.OrdinalIgnoreCase)) { @@ -196,6 +201,10 @@ namespace MediaBrowser.Controller.MediaEncoding { return null; } + if (string.Equals(container, "tp", StringComparison.OrdinalIgnoreCase)) + { + return null; + } // Seeing reported failures here, not sure yet if this is related to specfying input format if (string.Equals(container, "m4v", StringComparison.OrdinalIgnoreCase)) @@ -228,7 +237,12 @@ namespace MediaBrowser.Controller.MediaEncoding return null; } - return codec; + if (_mediaEncoder.SupportsDecoder(codec)) + { + return codec; + } + + return null; } /// <summary> @@ -1761,14 +1775,11 @@ namespace MediaBrowser.Controller.MediaEncoding return null; } - if (state.VideoStream != null && !string.IsNullOrWhiteSpace(state.VideoStream.Codec)) + if (state.VideoStream != null && + !string.IsNullOrWhiteSpace(state.VideoStream.Codec) && + !string.IsNullOrWhiteSpace(encodingOptions.HardwareAccelerationType) && + encodingOptions.EnableHardwareDecoding) { - if (!string.IsNullOrWhiteSpace(encodingOptions.HardwareAccelerationType)) - { - // causing unpredictable results - //return "-hwaccel auto"; - } - if (string.Equals(encodingOptions.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase)) { switch (state.MediaSource.VideoStream.Codec.ToLower()) @@ -1818,6 +1829,13 @@ namespace MediaBrowser.Controller.MediaEncoding return "-c:v h264_cuvid "; } break; + case "hevc": + case "h265": + if (_mediaEncoder.SupportsDecoder("hevc_cuvid")) + { + return "-c:v hevc_cuvid "; + } + break; } } } diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs index 57c81ddf76..b552579a8c 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.Linq; using MediaBrowser.Controller.Entities; using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dto; @@ -9,6 +10,7 @@ using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.Drawing; +using MediaBrowser.Model.Session; namespace MediaBrowser.Controller.MediaEncoding { @@ -40,6 +42,24 @@ namespace MediaBrowser.Controller.MediaEncoding public bool ReadInputAtNativeFramerate { get; set; } + private List<TranscodeReason> _transcodeReasons = null; + public List<TranscodeReason> TranscodeReasons + { + get + { + if (_transcodeReasons == null) + { + _transcodeReasons = (BaseRequest.TranscodeReasons ?? string.Empty) + .Split(',') + .Where(i => !string.IsNullOrWhiteSpace(i)) + .Select(v => (TranscodeReason)Enum.Parse(typeof(TranscodeReason), v, true)) + .ToList(); + } + + return _transcodeReasons; + } + } + public bool IgnoreInputDts { get @@ -251,7 +271,7 @@ namespace MediaBrowser.Controller.MediaEncoding { return AudioStream.SampleRate; } - } + } else if (BaseRequest.AudioSampleRate.HasValue) { @@ -264,6 +284,29 @@ namespace MediaBrowser.Controller.MediaEncoding } } + public int? OutputAudioBitDepth + { + get + { + if (BaseRequest.Static || string.Equals(OutputAudioCodec, "copy", StringComparison.OrdinalIgnoreCase)) + { + if (AudioStream != null) + { + return AudioStream.BitDepth; + } + } + + //else if (BaseRequest.AudioSampleRate.HasValue) + //{ + // // Don't exceed what the encoder supports + // // Seeing issues of attempting to encode to 88200 + // return Math.Min(44100, BaseRequest.AudioSampleRate.Value); + //} + + return null; + } + } + /// <summary> /// Predicts the audio sample rate that will be in the output stream /// </summary> diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs b/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs index 632c350ad0..5fc93bf382 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs @@ -83,6 +83,8 @@ namespace MediaBrowser.Controller.MediaEncoding [ApiMember(Name = "AudioSampleRate", Description = "Optional. Specify a specific audio sample rate, e.g. 44100", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] public int? AudioSampleRate { get; set; } + public int? MaxAudioBitDepth { get; set; } + /// <summary> /// Gets or sets the audio bit rate. /// </summary> @@ -204,6 +206,8 @@ namespace MediaBrowser.Controller.MediaEncoding public string SubtitleCodec { get; set; } + public string TranscodeReasons { get; set; } + /// <summary> /// Gets or sets the index of the audio stream. /// </summary> diff --git a/MediaBrowser.Controller/Playlists/Playlist.cs b/MediaBrowser.Controller/Playlists/Playlist.cs index 854f8d7a2f..c992ac56a7 100644 --- a/MediaBrowser.Controller/Playlists/Playlist.cs +++ b/MediaBrowser.Controller/Playlists/Playlist.cs @@ -33,6 +33,15 @@ namespace MediaBrowser.Controller.Playlists } [IgnoreDataMember] + public override bool SupportsInheritedParentImages + { + get + { + return false; + } + } + + [IgnoreDataMember] public override bool SupportsPlayedStatus { get diff --git a/MediaBrowser.Controller/Providers/IProviderManager.cs b/MediaBrowser.Controller/Providers/IProviderManager.cs index c0bc902140..0ba573da8b 100644 --- a/MediaBrowser.Controller/Providers/IProviderManager.cs +++ b/MediaBrowser.Controller/Providers/IProviderManager.cs @@ -9,6 +9,7 @@ using System.Collections.Generic; using System.IO; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Model.Events; namespace MediaBrowser.Controller.Providers { @@ -30,7 +31,7 @@ namespace MediaBrowser.Controller.Providers /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> Task RefreshFullItem(IHasMetadata item, MetadataRefreshOptions options, CancellationToken cancellationToken); - + /// <summary> /// Refreshes the metadata. /// </summary> @@ -68,7 +69,7 @@ namespace MediaBrowser.Controller.Providers /// </summary> /// <returns>Task.</returns> Task SaveImage(IHasImages item, string source, string mimeType, ImageType type, int? imageIndex, bool? saveLocallyWithMedia, CancellationToken cancellationToken); - + /// <summary> /// Adds the metadata providers. /// </summary> @@ -128,7 +129,7 @@ namespace MediaBrowser.Controller.Providers /// <param name="savers">The savers.</param> /// <returns>Task.</returns> Task SaveMetadata(IHasMetadata item, ItemUpdateType updateType, IEnumerable<string> savers); - + /// <summary> /// Gets the metadata options. /// </summary> @@ -158,6 +159,18 @@ namespace MediaBrowser.Controller.Providers /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{HttpResponseInfo}.</returns> Task<HttpResponseInfo> GetSearchImage(string providerName, string url, CancellationToken cancellationToken); + + Dictionary<Guid, Guid> GetRefreshQueue(); + + void OnRefreshStart(BaseItem item); + void OnRefreshProgress(BaseItem item, double progress); + void OnRefreshComplete(BaseItem item); + + double? GetRefreshProgress(Guid id); + + event EventHandler<GenericEventArgs<BaseItem>> RefreshStarted; + event EventHandler<GenericEventArgs<BaseItem>> RefreshCompleted; + event EventHandler<GenericEventArgs<Tuple<BaseItem, double>>> RefreshProgress; } public enum RefreshPriority diff --git a/MediaBrowser.Controller/Providers/ProviderRefreshStatus.cs b/MediaBrowser.Controller/Providers/ProviderRefreshStatus.cs deleted file mode 100644 index 6523dc4173..0000000000 --- a/MediaBrowser.Controller/Providers/ProviderRefreshStatus.cs +++ /dev/null @@ -1,22 +0,0 @@ - -namespace MediaBrowser.Controller.Providers -{ - /// <summary> - /// Enum ProviderRefreshStatus - /// </summary> - public enum ProviderRefreshStatus - { - /// <summary> - /// The success - /// </summary> - Success = 0, - /// <summary> - /// The completed with errors - /// </summary> - CompletedWithErrors = 1, - /// <summary> - /// The failure - /// </summary> - Failure = 2 - } -} diff --git a/MediaBrowser.Controller/Subtitles/ISubtitleManager.cs b/MediaBrowser.Controller/Subtitles/ISubtitleManager.cs index 0c814c0d4c..d1d5f27bef 100644 --- a/MediaBrowser.Controller/Subtitles/ISubtitleManager.cs +++ b/MediaBrowser.Controller/Subtitles/ISubtitleManager.cs @@ -28,12 +28,9 @@ namespace MediaBrowser.Controller.Subtitles /// <summary> /// Searches the subtitles. /// </summary> - /// <param name="video">The video.</param> - /// <param name="language">The language.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task{IEnumerable{RemoteSubtitleInfo}}.</returns> Task<IEnumerable<RemoteSubtitleInfo>> SearchSubtitles(Video video, string language, + bool? isPerfectMatch, CancellationToken cancellationToken); /// <summary> |
