diff options
Diffstat (limited to 'MediaBrowser.Controller/Entities/Folder.cs')
| -rw-r--r-- | MediaBrowser.Controller/Entities/Folder.cs | 296 |
1 files changed, 152 insertions, 144 deletions
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index f4cdc8fa1..77e362419 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -28,6 +28,9 @@ namespace MediaBrowser.Controller.Entities public List<Guid> ThemeSongIds { get; set; } public List<Guid> ThemeVideoIds { get; set; } + [IgnoreDataMember] + public DateTime? DateLastMediaAdded { get; set; } + public Folder() { LinkedChildren = new List<LinkedChild>(); @@ -56,6 +59,36 @@ namespace MediaBrowser.Controller.Entities } [IgnoreDataMember] + public virtual bool SupportsCumulativeRunTimeTicks + { + get + { + return false; + } + } + + [IgnoreDataMember] + public virtual bool SupportsDateLastMediaAdded + { + get + { + return false; + } + } + + public override bool RequiresRefresh() + { + var baseResult = base.RequiresRefresh(); + + if (SupportsCumulativeRunTimeTicks && !RunTimeTicks.HasValue) + { + baseResult = true; + } + + return baseResult; + } + + [IgnoreDataMember] public override string FileNameWithoutExtension { get @@ -199,8 +232,8 @@ namespace MediaBrowser.Controller.Entities /// <returns>Dictionary{System.StringFunc{UserIEnumerable{BaseItem}}}.</returns> protected virtual IEnumerable<string> GetIndexByOptions() { - return new List<string> { - {"None"}, + return new List<string> { + {"None"}, {"Performer"}, {"Genre"}, {"Director"}, @@ -707,8 +740,8 @@ namespace MediaBrowser.Controller.Entities { return ItemRepository.GetItemIdsList(new InternalItemsQuery { - ParentId = Id - + ParentId = Id, + GroupByPresentationUniqueKey = false }); } @@ -751,39 +784,44 @@ namespace MediaBrowser.Controller.Entities return true; } } + + var supportsUserDataQueries = ConfigurationManager.Configuration.SchemaVersion >= 76; if (query.SortBy != null && query.SortBy.Length > 0) { - if (query.SortBy.Contains(ItemSortBy.DatePlayed, StringComparer.OrdinalIgnoreCase)) - { - Logger.Debug("Query requires post-filtering due to ItemSortBy.DatePlayed"); - return true; - } - if (query.SortBy.Contains(ItemSortBy.IsFavoriteOrLiked, StringComparer.OrdinalIgnoreCase)) - { - Logger.Debug("Query requires post-filtering due to ItemSortBy.IsFavoriteOrLiked"); - return true; - } - if (query.SortBy.Contains(ItemSortBy.IsPlayed, StringComparer.OrdinalIgnoreCase)) + if (!supportsUserDataQueries) { - Logger.Debug("Query requires post-filtering due to ItemSortBy.IsPlayed"); - return true; - } - if (query.SortBy.Contains(ItemSortBy.IsUnplayed, StringComparer.OrdinalIgnoreCase)) - { - Logger.Debug("Query requires post-filtering due to ItemSortBy.IsUnplayed"); - return true; + if (query.SortBy.Contains(ItemSortBy.DatePlayed, StringComparer.OrdinalIgnoreCase)) + { + Logger.Debug("Query requires post-filtering due to ItemSortBy.IsFavoriteOrLiked"); + return true; + } + if (query.SortBy.Contains(ItemSortBy.PlayCount, StringComparer.OrdinalIgnoreCase)) + { + Logger.Debug("Query requires post-filtering due to ItemSortBy.PlayCount"); + return true; + } + if (query.SortBy.Contains(ItemSortBy.IsFavoriteOrLiked, StringComparer.OrdinalIgnoreCase)) + { + Logger.Debug("Query requires post-filtering due to ItemSortBy.IsFavoriteOrLiked"); + return true; + } + if (query.SortBy.Contains(ItemSortBy.IsPlayed, StringComparer.OrdinalIgnoreCase)) + { + Logger.Debug("Query requires post-filtering due to ItemSortBy.IsPlayed"); + return true; + } + if (query.SortBy.Contains(ItemSortBy.IsUnplayed, StringComparer.OrdinalIgnoreCase)) + { + Logger.Debug("Query requires post-filtering due to ItemSortBy.IsUnplayed"); + return true; + } } if (query.SortBy.Contains(ItemSortBy.AiredEpisodeOrder, StringComparer.OrdinalIgnoreCase)) { Logger.Debug("Query requires post-filtering due to ItemSortBy.AiredEpisodeOrder"); return true; } - if (query.SortBy.Contains(ItemSortBy.Album, StringComparer.OrdinalIgnoreCase)) - { - Logger.Debug("Query requires post-filtering due to ItemSortBy.Album"); - return true; - } if (query.SortBy.Contains(ItemSortBy.AlbumArtist, StringComparer.OrdinalIgnoreCase)) { Logger.Debug("Query requires post-filtering due to ItemSortBy.AlbumArtist"); @@ -799,11 +837,6 @@ namespace MediaBrowser.Controller.Entities Logger.Debug("Query requires post-filtering due to ItemSortBy.Budget"); return true; } - if (query.SortBy.Contains(ItemSortBy.DateLastContentAdded, StringComparer.OrdinalIgnoreCase)) - { - Logger.Debug("Query requires post-filtering due to ItemSortBy.DateLastContentAdded"); - return true; - } if (query.SortBy.Contains(ItemSortBy.GameSystem, StringComparer.OrdinalIgnoreCase)) { Logger.Debug("Query requires post-filtering due to ItemSortBy.GameSystem"); @@ -819,11 +852,6 @@ namespace MediaBrowser.Controller.Entities Logger.Debug("Query requires post-filtering due to ItemSortBy.OfficialRating"); return true; } - if (query.SortBy.Contains(ItemSortBy.PlayCount, StringComparer.OrdinalIgnoreCase)) - { - Logger.Debug("Query requires post-filtering due to ItemSortBy.PlayCount"); - return true; - } if (query.SortBy.Contains(ItemSortBy.Players, StringComparer.OrdinalIgnoreCase)) { Logger.Debug("Query requires post-filtering due to ItemSortBy.Players"); @@ -839,11 +867,6 @@ namespace MediaBrowser.Controller.Entities Logger.Debug("Query requires post-filtering due to ItemSortBy.SeriesSortName"); return true; } - if (query.SortBy.Contains(ItemSortBy.StartDate, StringComparer.OrdinalIgnoreCase)) - { - Logger.Debug("Query requires post-filtering due to ItemSortBy.StartDate"); - return true; - } if (query.SortBy.Contains(ItemSortBy.Studio, StringComparer.OrdinalIgnoreCase)) { Logger.Debug("Query requires post-filtering due to ItemSortBy.Studio"); @@ -868,34 +891,37 @@ namespace MediaBrowser.Controller.Entities return true; } - if (query.IsLiked.HasValue) + if (!supportsUserDataQueries) { - Logger.Debug("Query requires post-filtering due to IsLiked"); - return true; - } + if (query.IsLiked.HasValue) + { + Logger.Debug("Query requires post-filtering due to IsLiked"); + return true; + } - if (query.IsFavoriteOrLiked.HasValue) - { - Logger.Debug("Query requires post-filtering due to IsFavoriteOrLiked"); - return true; - } + if (query.IsFavoriteOrLiked.HasValue) + { + Logger.Debug("Query requires post-filtering due to IsFavoriteOrLiked"); + return true; + } - if (query.IsFavorite.HasValue) - { - Logger.Debug("Query requires post-filtering due to IsFavorite"); - return true; - } + if (query.IsFavorite.HasValue) + { + Logger.Debug("Query requires post-filtering due to IsFavorite"); + return true; + } - if (query.IsResumable.HasValue) - { - Logger.Debug("Query requires post-filtering due to IsResumable"); - return true; - } + if (query.IsResumable.HasValue) + { + Logger.Debug("Query requires post-filtering due to IsResumable"); + return true; + } - if (query.IsPlayed.HasValue) - { - Logger.Debug("Query requires post-filtering due to IsPlayed"); - return true; + if (query.IsPlayed.HasValue) + { + Logger.Debug("Query requires post-filtering due to IsPlayed"); + return true; + } } if (query.IsInBoxSet.HasValue) @@ -1059,30 +1085,6 @@ namespace MediaBrowser.Controller.Entities return true; } - if (!string.IsNullOrWhiteSpace(query.NameContains)) - { - Logger.Debug("Query requires post-filtering due to NameContains"); - return true; - } - - if (!string.IsNullOrWhiteSpace(query.NameLessThan)) - { - Logger.Debug("Query requires post-filtering due to NameLessThan"); - return true; - } - - if (!string.IsNullOrWhiteSpace(query.NameStartsWith)) - { - Logger.Debug("Query requires post-filtering due to NameStartsWith"); - return true; - } - - if (!string.IsNullOrWhiteSpace(query.NameStartsWithOrGreater)) - { - Logger.Debug("Query requires post-filtering due to NameStartsWithOrGreater"); - return true; - } - if (query.AirDays.Length > 0) { Logger.Debug("Query requires post-filtering due to AirDays"); @@ -1107,12 +1109,6 @@ namespace MediaBrowser.Controller.Entities return true; } - if (query.AlbumNames.Length > 0) - { - Logger.Debug("Query requires post-filtering due to AlbumNames"); - return true; - } - if (query.ArtistNames.Length > 0) { Logger.Debug("Query requires post-filtering due to ArtistNames"); @@ -1297,33 +1293,42 @@ namespace MediaBrowser.Controller.Entities public IList<BaseItem> GetRecursiveChildren(Func<BaseItem, bool> filter) { - var list = new List<BaseItem>(); + var result = new Dictionary<Guid, BaseItem>(); - AddChildrenToList(list, true, filter); + AddChildrenToList(result, true, true, filter); - return list; + return result.Values.ToList(); } /// <summary> /// Adds the children to list. /// </summary> - /// <param name="list">The list.</param> - /// <param name="recursive">if set to <c>true</c> [recursive].</param> - /// <param name="filter">The filter.</param> - private void AddChildrenToList(List<BaseItem> list, bool recursive, Func<BaseItem, bool> filter) + private void AddChildrenToList(Dictionary<Guid,BaseItem> result, bool includeLinkedChildren, bool recursive, Func<BaseItem, bool> filter) { foreach (var child in Children) { if (filter == null || filter(child)) { - list.Add(child); + result[child.Id] = child; } if (recursive && child.IsFolder) { var folder = (Folder)child; - folder.AddChildrenToList(list, true, filter); + // We can only support includeLinkedChildren for the first folder, or we might end up stuck in a loop of linked items + folder.AddChildrenToList(result, false, true, filter); + } + } + + if (includeLinkedChildren) + { + foreach (var child in GetLinkedChildren()) + { + if (filter == null || filter(child)) + { + result[child.Id] = child; + } } } } @@ -1567,38 +1572,17 @@ namespace MediaBrowser.Controller.Entities await Task.WhenAll(tasks).ConfigureAwait(false); } - /// <summary> - /// Finds an item by path, recursively - /// </summary> - /// <param name="path">The path.</param> - /// <returns>BaseItem.</returns> - /// <exception cref="System.ArgumentNullException"></exception> - public BaseItem FindByPath(string path) + public override bool IsPlayed(User user) { - if (string.IsNullOrEmpty(path)) + var itemsResult = GetItems(new InternalItemsQuery(user) { - throw new ArgumentNullException(); - } - - if (string.Equals(Path, path, StringComparison.OrdinalIgnoreCase)) - { - return this; - } - - if (PhysicalLocations.Contains(path, StringComparer.OrdinalIgnoreCase)) - { - return this; - } + Recursive = true, + IsFolder = false, + ExcludeLocationTypes = new[] { LocationType.Virtual } - 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)) - .FirstOrDefault(); - } + }).Result; - public override bool IsPlayed(User user) - { - return GetRecursiveChildren(user, i => !i.IsFolder && i.LocationType != LocationType.Virtual) + return itemsResult.Items .All(i => i.IsPlayed(user)); } @@ -1607,26 +1591,50 @@ namespace MediaBrowser.Controller.Entities return !IsPlayed(user); } + [IgnoreDataMember] + public virtual bool SupportsUserDataFromChildren + { + get + { + // These are just far too slow. + if (this is ICollectionFolder) + { + return false; + } + if (this is UserView) + { + return false; + } + if (this is UserRootFolder) + { + return false; + } + + return true; + } + } + public override void FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, User user) { + if (!SupportsUserDataFromChildren) + { + return; + } + var recursiveItemCount = 0; var unplayed = 0; double totalPercentPlayed = 0; - IEnumerable<BaseItem> children; - var folder = this; + var itemsResult = GetItems(new InternalItemsQuery(user) + { + Recursive = true, + IsFolder = false, + ExcludeLocationTypes = new[] { LocationType.Virtual } - var season = folder as Season; + }).Result; - if (season != null) - { - children = season.GetEpisodes(user).Where(i => i.LocationType != LocationType.Virtual); - } - else - { - children = folder.GetRecursiveChildren(user, i => !i.IsFolder && i.LocationType != LocationType.Virtual); - } + var children = itemsResult.Items; // Loop through each recursive child foreach (var child in children) @@ -1635,7 +1643,7 @@ namespace MediaBrowser.Controller.Entities var isUnplayed = true; - var itemUserData = UserDataManager.GetUserData(user.Id, child.GetUserDataKey()); + var itemUserData = UserDataManager.GetUserData(user, child); // Incrememt totalPercentPlayed if (itemUserData != null) |
