diff options
Diffstat (limited to 'MediaBrowser.Controller/Entities/Folder.cs')
| -rw-r--r-- | MediaBrowser.Controller/Entities/Folder.cs | 222 |
1 files changed, 119 insertions, 103 deletions
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 2761aa5d7..a4f8955d0 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -6,7 +6,6 @@ using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Querying; -using MoreLinq; using System; using System.Collections; using System.Collections.Generic; @@ -21,7 +20,7 @@ namespace MediaBrowser.Controller.Entities /// <summary> /// Class Folder /// </summary> - public class Folder : BaseItem, IHasThemeMedia, IHasTags + public class Folder : BaseItem, IHasThemeMedia, IHasTags, IHasPreferredMetadataLanguage { public static IUserManager UserManager { get; set; } public static IUserViewManager UserViewManager { get; set; } @@ -30,6 +29,14 @@ namespace MediaBrowser.Controller.Entities public List<Guid> ThemeVideoIds { get; set; } public List<string> Tags { get; set; } + public string PreferredMetadataLanguage { get; set; } + + /// <summary> + /// Gets or sets the preferred metadata country code. + /// </summary> + /// <value>The preferred metadata country code.</value> + public string PreferredMetadataCountryCode { get; set; } + public Folder() { LinkedChildren = new List<LinkedChild>(); @@ -98,6 +105,7 @@ namespace MediaBrowser.Controller.Entities public virtual List<LinkedChild> LinkedChildren { get; set; } + [IgnoreDataMember] protected virtual bool SupportsShortcutChildren { get { return true; } @@ -275,7 +283,17 @@ namespace MediaBrowser.Controller.Entities { get { - return _children ?? (_children = LoadChildrenInternal()); + if (_children == null) + { + lock (_childrenSyncLock) + { + if (_children == null) + { + _children = LoadChildrenInternal(); + } + } + } + return _children; } } @@ -301,14 +319,24 @@ namespace MediaBrowser.Controller.Entities public override bool IsVisible(User user) { - if (this is ICollectionFolder) + if (this is ICollectionFolder && !(this is BasePluginFolder)) { - if (user.Policy.BlockedMediaFolders.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase) || + if (user.Policy.BlockedMediaFolders != null) + { + if (user.Policy.BlockedMediaFolders.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase) || - // Backwards compatibility - user.Policy.BlockedMediaFolders.Contains(Name, StringComparer.OrdinalIgnoreCase)) + // Backwards compatibility + user.Policy.BlockedMediaFolders.Contains(Name, StringComparer.OrdinalIgnoreCase)) + { + return false; + } + } + else { - return false; + if (!user.Policy.EnableAllFolders && !user.Policy.EnabledFolders.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase)) + { + return false; + } } } @@ -345,12 +373,7 @@ namespace MediaBrowser.Controller.Entities /// <returns>Task.</returns> public Task ValidateChildren(IProgress<double> progress, CancellationToken cancellationToken, MetadataRefreshOptions metadataRefreshOptions, bool recursive = true) { - return ValidateChildrenWithCancellationSupport(progress, cancellationToken, recursive, true, metadataRefreshOptions, metadataRefreshOptions.DirectoryService); - } - - private Task ValidateChildrenWithCancellationSupport(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService) - { - return ValidateChildrenInternal(progress, cancellationToken, recursive, refreshChildMetadata, refreshOptions, directoryService); + return ValidateChildrenInternal(progress, cancellationToken, recursive, true, metadataRefreshOptions, metadataRefreshOptions.DirectoryService); } private Dictionary<Guid, BaseItem> GetActualChildrenDictionary() @@ -540,50 +563,49 @@ namespace MediaBrowser.Controller.Entities var children = ActualChildren.ToList(); var percentages = new Dictionary<Guid, double>(children.Count); - - var tasks = new List<Task>(); + var numComplete = 0; + var count = children.Count; foreach (var child in children) { - if (tasks.Count >= 2) - { - await Task.WhenAll(tasks).ConfigureAwait(false); - tasks.Clear(); - } - cancellationToken.ThrowIfCancellationRequested(); - var innerProgress = new ActionableProgress<double>(); - // Avoid implicitly captured closure - var currentChild = child; - innerProgress.RegisterAction(p => + if (child.IsFolder) { - lock (percentages) + var innerProgress = new ActionableProgress<double>(); + + // Avoid implicitly captured closure + var currentChild = child; + innerProgress.RegisterAction(p => { - percentages[currentChild.Id] = p / 100; + lock (percentages) + { + percentages[currentChild.Id] = p / 100; - var percent = percentages.Values.Sum(); - percent /= children.Count; - percent *= 100; - progress.Report(percent); - } - }); + var innerPercent = percentages.Values.Sum(); + innerPercent /= count; + innerPercent *= 100; + progress.Report(innerPercent); + } + }); - if (child.IsFolder) - { await RefreshChildMetadata(child, refreshOptions, recursive, innerProgress, cancellationToken) .ConfigureAwait(false); } else { - // Avoid implicitly captured closure - var taskChild = child; - - tasks.Add(Task.Run(async () => await RefreshChildMetadata(taskChild, refreshOptions, false, innerProgress, cancellationToken).ConfigureAwait(false), cancellationToken)); + await RefreshChildMetadata(child, refreshOptions, false, new Progress<double>(), cancellationToken) + .ConfigureAwait(false); } + + numComplete++; + double percent = numComplete; + percent /= count; + percent *= 100; + + progress.Report(percent); } - await Task.WhenAll(tasks).ConfigureAwait(false); progress.Report(100); } @@ -648,7 +670,7 @@ namespace MediaBrowser.Controller.Entities } }); - await child.ValidateChildrenWithCancellationSupport(innerProgress, cancellationToken, true, false, null, directoryService) + await child.ValidateChildrenInternal(innerProgress, cancellationToken, true, false, null, directoryService) .ConfigureAwait(false); } } @@ -678,12 +700,12 @@ namespace MediaBrowser.Controller.Entities path = System.IO.Path.GetDirectoryName(path); } - if (ContainsPath(LibraryManager.GetDefaultVirtualFolders(), originalPath)) + if (ContainsPath(LibraryManager.GetVirtualFolders(), originalPath)) { return true; } - return UserManager.Users.Any(user => ContainsPath(LibraryManager.GetVirtualFolders(user), originalPath)); + return ContainsPath(LibraryManager.GetVirtualFolders(), originalPath); } /// <summary> @@ -731,28 +753,6 @@ namespace MediaBrowser.Controller.Entities return childrenItems; } - /// <summary> - /// Retrieves the child. - /// </summary> - /// <param name="child">The child.</param> - /// <returns>BaseItem.</returns> - private BaseItem RetrieveChild(Guid child) - { - var item = LibraryManager.GetItemById(child); - - if (item != null) - { - if (item is IByReferenceItem) - { - return LibraryManager.GetOrAddByReferenceItem(item); - } - - item.Parent = this; - } - - return item; - } - private BaseItem RetrieveChild(BaseItem child) { if (child.Id == Guid.Empty) @@ -786,18 +786,20 @@ namespace MediaBrowser.Controller.Entities { var user = query.User; + Func<BaseItem, bool> filter = i => UserViewBuilder.Filter(i, user, query, UserDataManager, LibraryManager); + var items = query.Recursive - ? GetRecursiveChildren(user) - : GetChildren(user, true); + ? GetRecursiveChildren(user, filter) + : GetChildren(user, true).Where(filter); - var result = SortAndFilter(items, query); + var result = PostFilterAndSort(items, query); return Task.FromResult(result); } - protected QueryResult<BaseItem> SortAndFilter(IEnumerable<BaseItem> items, InternalItemsQuery query) + protected QueryResult<BaseItem> PostFilterAndSort(IEnumerable<BaseItem> items, InternalItemsQuery query) { - return UserViewBuilder.SortAndFilter(items, this, null, query, LibraryManager, UserDataManager); + return UserViewBuilder.PostFilterAndSort(items, this, null, query, LibraryManager); } /// <summary> @@ -822,11 +824,11 @@ namespace MediaBrowser.Controller.Entities //the true root should return our users root folder children if (IsPhysicalRoot) return user.RootFolder.GetChildren(user, includeLinkedChildren); - var list = new List<BaseItem>(); + var result = new Dictionary<Guid, BaseItem>(); - var hasLinkedChildren = AddChildrenToList(user, includeLinkedChildren, list, includeHidden, false); + AddChildren(user, includeLinkedChildren, result, includeHidden, false, null); - return hasLinkedChildren ? list.DistinctBy(i => i.Id).ToList() : list; + return result.Values; } protected virtual IEnumerable<BaseItem> GetEligibleChildrenForRecursiveChildren(User user) @@ -839,31 +841,30 @@ namespace MediaBrowser.Controller.Entities /// </summary> /// <param name="user">The user.</param> /// <param name="includeLinkedChildren">if set to <c>true</c> [include linked children].</param> - /// <param name="list">The list.</param> + /// <param name="result">The result.</param> /// <param name="includeHidden">if set to <c>true</c> [include hidden].</param> /// <param name="recursive">if set to <c>true</c> [recursive].</param> + /// <param name="filter">The filter.</param> /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns> - private bool AddChildrenToList(User user, bool includeLinkedChildren, List<BaseItem> list, bool includeHidden, bool recursive) + private void AddChildren(User user, bool includeLinkedChildren, Dictionary<Guid, BaseItem> result, bool includeHidden, bool recursive, Func<BaseItem, bool> filter) { - var hasLinkedChildren = false; - foreach (var child in GetEligibleChildrenForRecursiveChildren(user)) { if (child.IsVisible(user)) { if (includeHidden || !child.IsHiddenFromUser(user)) { - list.Add(child); + if (filter == null || filter(child)) + { + result[child.Id] = child; + } } if (recursive && child.IsFolder) { var folder = (Folder)child; - if (folder.AddChildrenToList(user, includeLinkedChildren, list, includeHidden, true)) - { - hasLinkedChildren = true; - } + folder.AddChildren(user, includeLinkedChildren, result, includeHidden, true, filter); } } } @@ -874,14 +875,13 @@ namespace MediaBrowser.Controller.Entities { if (child.IsVisible(user)) { - hasLinkedChildren = true; - - list.Add(child); + if (filter == null || filter(child)) + { + result[child.Id] = child; + } } } } - - return hasLinkedChildren; } /// <summary> @@ -891,18 +891,23 @@ namespace MediaBrowser.Controller.Entities /// <param name="includeLinkedChildren">if set to <c>true</c> [include linked children].</param> /// <returns>IEnumerable{BaseItem}.</returns> /// <exception cref="System.ArgumentNullException"></exception> - public virtual IEnumerable<BaseItem> GetRecursiveChildren(User user, bool includeLinkedChildren = true) + public IEnumerable<BaseItem> GetRecursiveChildren(User user, bool includeLinkedChildren = true) + { + return GetRecursiveChildren(user, i => true); + } + + public virtual IEnumerable<BaseItem> GetRecursiveChildren(User user, Func<BaseItem, bool> filter) { if (user == null) { throw new ArgumentNullException("user"); } - var list = new List<BaseItem>(); + var result = new Dictionary<Guid, BaseItem>(); - var hasLinkedChildren = AddChildrenToList(user, includeLinkedChildren, list, false, true); + AddChildren(user, true, result, false, true, filter); - return hasLinkedChildren ? list.DistinctBy(i => i.Id).ToList() : list; + return result.Values; } /// <summary> @@ -911,9 +916,14 @@ namespace MediaBrowser.Controller.Entities /// <returns>IList{BaseItem}.</returns> public IList<BaseItem> GetRecursiveChildren() { + return GetRecursiveChildren(i => true); + } + + public IList<BaseItem> GetRecursiveChildren(Func<BaseItem, bool> filter) + { var list = new List<BaseItem>(); - AddChildrenToList(list, true, null); + AddChildrenToList(list, true, filter); return list; } @@ -1022,6 +1032,15 @@ namespace MediaBrowser.Controller.Entities .Where(i => i.Item2 != null); } + [IgnoreDataMember] + protected override bool SupportsOwnedItems + { + get + { + return base.SupportsOwnedItems || SupportsShortcutChildren; + } + } + protected override async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, List<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken) { var changesFound = false; @@ -1126,8 +1145,7 @@ namespace MediaBrowser.Controller.Entities bool resetPosition) { // Sweep through recursively and update status - var tasks = GetRecursiveChildren(user, true) - .Where(i => !i.IsFolder && i.LocationType != LocationType.Virtual) + var tasks = GetRecursiveChildren(user, i => !i.IsFolder && i.LocationType != LocationType.Virtual) .Select(c => c.MarkPlayed(user, datePlayed, resetPosition)); await Task.WhenAll(tasks).ConfigureAwait(false); @@ -1141,8 +1159,7 @@ namespace MediaBrowser.Controller.Entities public override async Task MarkUnplayed(User user) { // Sweep through recursively and update status - var tasks = GetRecursiveChildren(user, true) - .Where(i => !i.IsFolder && i.LocationType != LocationType.Virtual) + var tasks = GetRecursiveChildren(user, i => !i.IsFolder && i.LocationType != LocationType.Virtual) .Select(c => c.MarkUnplayed(user)); await Task.WhenAll(tasks).ConfigureAwait(false); @@ -1171,15 +1188,15 @@ namespace MediaBrowser.Controller.Entities return this; } - return RecursiveChildren.FirstOrDefault(i => string.Equals(i.Path, path, StringComparison.OrdinalIgnoreCase) || + return GetRecursiveChildren(i => string.Equals(i.Path, path, StringComparison.OrdinalIgnoreCase) || (!i.IsFolder && !i.IsInMixedFolder && string.Equals(i.ContainingFolderPath, path, StringComparison.OrdinalIgnoreCase)) || - i.PhysicalLocations.Contains(path, StringComparer.OrdinalIgnoreCase)); + i.PhysicalLocations.Contains(path, StringComparer.OrdinalIgnoreCase)) + .FirstOrDefault(); } public override bool IsPlayed(User user) { - return GetRecursiveChildren(user) - .Where(i => !i.IsFolder && i.LocationType != LocationType.Virtual) + return GetRecursiveChildren(user, i => !i.IsFolder && i.LocationType != LocationType.Virtual) .All(i => i.IsPlayed(user)); } @@ -1206,8 +1223,7 @@ namespace MediaBrowser.Controller.Entities } else { - children = folder.GetRecursiveChildren(user) - .Where(i => !i.IsFolder && i.LocationType != LocationType.Virtual); + children = folder.GetRecursiveChildren(user, i => !i.IsFolder && i.LocationType != LocationType.Virtual); } // Loop through each recursive child |
