Browse Source

update artist queries

Luke Pulverenti 9 năm trước cách đây
mục cha
commit
d1d0487fee

+ 2 - 1
MediaBrowser.Api/FilterService.cs

@@ -103,7 +103,8 @@ namespace MediaBrowser.Api
                 User = user,
                 User = user,
                 MediaTypes = request.GetMediaTypes(),
                 MediaTypes = request.GetMediaTypes(),
                 IncludeItemTypes = request.GetIncludeItemTypes(),
                 IncludeItemTypes = request.GetIncludeItemTypes(),
-                Recursive = true
+                Recursive = true,
+                EnableTotalRecordCount = false
             };
             };
 
 
             return query;
             return query;

+ 4 - 1
MediaBrowser.Api/GamesService.cs

@@ -162,7 +162,10 @@ namespace MediaBrowser.Api
 
 
             var items = user == null ? 
             var items = user == null ? 
                 system.GetRecursiveChildren(i => i is Game) :
                 system.GetRecursiveChildren(i => i is Game) :
-                system.GetRecursiveChildren(user, i => i is Game);
+                system.GetRecursiveChildren(user, new InternalItemsQuery(user)
+                {
+                    IncludeItemTypes = new[] { typeof(Game).Name }
+                });
 
 
             var games = items.Cast<Game>().ToList();
             var games = items.Cast<Game>().ToList();
 
 

+ 8 - 1
MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs

@@ -121,6 +121,13 @@ namespace MediaBrowser.Api.UserLibrary
             var includeItemTypes = request.GetIncludeItemTypes();
             var includeItemTypes = request.GetIncludeItemTypes();
             var mediaTypes = request.GetMediaTypes();
             var mediaTypes = request.GetMediaTypes();
 
 
+            var query = new InternalItemsQuery(user)
+            {
+                ExcludeItemTypes = excludeItemTypes,
+                IncludeItemTypes = includeItemTypes,
+                MediaTypes = mediaTypes
+            };
+
             Func<BaseItem, bool> filter = i => FilterItem(request, i, excludeItemTypes, includeItemTypes, mediaTypes);
             Func<BaseItem, bool> filter = i => FilterItem(request, i, excludeItemTypes, includeItemTypes, mediaTypes);
 
 
             if (parentItem.IsFolder)
             if (parentItem.IsFolder)
@@ -130,7 +137,7 @@ namespace MediaBrowser.Api.UserLibrary
                 if (!string.IsNullOrWhiteSpace(request.UserId))
                 if (!string.IsNullOrWhiteSpace(request.UserId))
                 {
                 {
                     items = request.Recursive ?
                     items = request.Recursive ?
-                        folder.GetRecursiveChildren(user, filter) :
+                        folder.GetRecursiveChildren(user, query) :
                         folder.GetChildren(user, true).Where(filter);
                         folder.GetChildren(user, true).Where(filter);
                 }
                 }
                 else
                 else

+ 3 - 9
MediaBrowser.Api/UserLibrary/ItemsService.cs

@@ -138,25 +138,19 @@ namespace MediaBrowser.Api.UserLibrary
 
 
             if (request.Recursive)
             if (request.Recursive)
             {
             {
-                var result = await ((Folder)item).GetItems(GetItemsQuery(request, user)).ConfigureAwait(false);
-
-                return result;
+                return await ((Folder)item).GetItems(GetItemsQuery(request, user)).ConfigureAwait(false);
             }
             }
 
 
             if (user == null)
             if (user == null)
             {
             {
-                var result = await ((Folder)item).GetItems(GetItemsQuery(request, null)).ConfigureAwait(false);
-
-                return result;
+                return await ((Folder)item).GetItems(GetItemsQuery(request, null)).ConfigureAwait(false);
             }
             }
 
 
             var userRoot = item as UserRootFolder;
             var userRoot = item as UserRootFolder;
 
 
             if (userRoot == null)
             if (userRoot == null)
             {
             {
-                var result = await ((Folder)item).GetItems(GetItemsQuery(request, user)).ConfigureAwait(false);
-
-                return result;
+                return await ((Folder)item).GetItems(GetItemsQuery(request, user)).ConfigureAwait(false);
             }
             }
 
 
             IEnumerable<BaseItem> items = ((Folder)item).GetChildren(user, true);
             IEnumerable<BaseItem> items = ((Folder)item).GetChildren(user, true);

+ 10 - 26
MediaBrowser.Controller/Entities/Audio/MusicArtist.cs

@@ -56,36 +56,20 @@ namespace MediaBrowser.Controller.Entities.Audio
 
 
         public IEnumerable<BaseItem> GetTaggedItems(InternalItemsQuery query)
         public IEnumerable<BaseItem> GetTaggedItems(InternalItemsQuery query)
         {
         {
-            var itemByNameFilter = GetItemFilter();
+            if (query.IncludeItemTypes.Length == 0)
+            {
+                query.IncludeItemTypes = new[] { typeof(Audio).Name, typeof(MusicVideo).Name, typeof(MusicAlbum).Name };
+                query.ArtistNames = new[] { Name };
+            }
 
 
-            if (query.User != null)
+            // Need this for now since the artist filter isn't yet supported by the db
+            if (ConfigurationManager.Configuration.SchemaVersion < 79)
             {
             {
-                return query.User.RootFolder
-                    .GetRecursiveChildren(query.User, i =>
-                    {
-                        if (query.IsFolder.HasValue)
-                        {
-                            if (query.IsFolder.Value != i.IsFolder)
-                            {
-                                return false;
-                            }
-                        }
-                        return itemByNameFilter(i);
-                    });
+                var filter = GetItemFilter();
+                return LibraryManager.GetItemList(query).Where(filter);
             }
             }
 
 
-            return LibraryManager.RootFolder
-                .GetRecursiveChildren(i =>
-                {
-                    if (query.IsFolder.HasValue)
-                    {
-                        if (query.IsFolder.Value != i.IsFolder)
-                        {
-                            return false;
-                        }
-                    }
-                    return itemByNameFilter(i);
-                });
+            return LibraryManager.GetItemList(query);
         }
         }
 
 
         protected override IEnumerable<BaseItem> ActualChildren
         protected override IEnumerable<BaseItem> ActualChildren

+ 39 - 32
MediaBrowser.Controller/Entities/Folder.cs

@@ -749,7 +749,7 @@ namespace MediaBrowser.Controller.Entities
         {
         {
             var user = query.User;
             var user = query.User;
 
 
-            if (RequiresPostFiltering(query))
+            if (!query.ForceDirect && RequiresPostFiltering(query))
             {
             {
                 IEnumerable<BaseItem> items;
                 IEnumerable<BaseItem> items;
                 Func<BaseItem, bool> filter = i => UserViewBuilder.Filter(i, user, query, UserDataManager, LibraryManager);
                 Func<BaseItem, bool> filter = i => UserViewBuilder.Filter(i, user, query, UserDataManager, LibraryManager);
@@ -760,7 +760,7 @@ namespace MediaBrowser.Controller.Entities
                 }
                 }
                 else
                 else
                 {
                 {
-                    items = GetRecursiveChildren(user, filter);
+                    items = GetRecursiveChildren(user, query);
                 }
                 }
 
 
                 return PostFilterAndSort(items, query);
                 return PostFilterAndSort(items, query);
@@ -817,19 +817,24 @@ namespace MediaBrowser.Controller.Entities
                         return true;
                         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.AlbumArtist, StringComparer.OrdinalIgnoreCase))
+
+                if (ConfigurationManager.Configuration.SchemaVersion < 79)
                 {
                 {
-                    Logger.Debug("Query requires post-filtering due to ItemSortBy.AlbumArtist");
-                    return true;
+                    if (query.SortBy.Contains(ItemSortBy.AlbumArtist, StringComparer.OrdinalIgnoreCase))
+                    {
+                        Logger.Debug("Query requires post-filtering due to ItemSortBy.AlbumArtist");
+                        return true;
+                    }
+                    if (query.SortBy.Contains(ItemSortBy.Artist, StringComparer.OrdinalIgnoreCase))
+                    {
+                        Logger.Debug("Query requires post-filtering due to ItemSortBy.Artist");
+                        return true;
+                    }
                 }
                 }
-                if (query.SortBy.Contains(ItemSortBy.Artist, StringComparer.OrdinalIgnoreCase))
+
+                if (query.SortBy.Contains(ItemSortBy.AiredEpisodeOrder, StringComparer.OrdinalIgnoreCase))
                 {
                 {
-                    Logger.Debug("Query requires post-filtering due to ItemSortBy.Artist");
+                    Logger.Debug("Query requires post-filtering due to ItemSortBy.AiredEpisodeOrder");
                     return true;
                     return true;
                 }
                 }
                 if (query.SortBy.Contains(ItemSortBy.Budget, StringComparer.OrdinalIgnoreCase))
                 if (query.SortBy.Contains(ItemSortBy.Budget, StringComparer.OrdinalIgnoreCase))
@@ -1109,10 +1114,13 @@ namespace MediaBrowser.Controller.Entities
                 return true;
                 return true;
             }
             }
 
 
-            if (query.ArtistNames.Length > 0)
+            if (ConfigurationManager.Configuration.SchemaVersion < 79)
             {
             {
-                Logger.Debug("Query requires post-filtering due to ArtistNames");
-                return true;
+                if (query.ArtistNames.Length > 0)
+                {
+                    Logger.Debug("Query requires post-filtering due to ArtistNames");
+                    return true;
+                }
             }
             }
 
 
             return false;
             return false;
@@ -1178,7 +1186,7 @@ namespace MediaBrowser.Controller.Entities
             else
             else
             {
             {
                 items = query.Recursive
                 items = query.Recursive
-                   ? GetRecursiveChildren(user, filter)
+                   ? GetRecursiveChildren(user, query)
                    : GetChildren(user, true).Where(filter);
                    : GetChildren(user, true).Where(filter);
             }
             }
 
 
@@ -1215,19 +1223,14 @@ namespace MediaBrowser.Controller.Entities
         /// <summary>
         /// <summary>
         /// Adds the children to list.
         /// Adds the children to list.
         /// </summary>
         /// </summary>
-        /// <param name="user">The user.</param>
-        /// <param name="includeLinkedChildren">if set to <c>true</c> [include linked children].</param>
-        /// <param name="result">The result.</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>
         /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
-        private void AddChildren(User user, bool includeLinkedChildren, Dictionary<Guid, BaseItem> result, bool recursive, Func<BaseItem, bool> filter)
+        private void AddChildren(User user, bool includeLinkedChildren, Dictionary<Guid, BaseItem> result, bool recursive, InternalItemsQuery query)
         {
         {
             foreach (var child in GetEligibleChildrenForRecursiveChildren(user))
             foreach (var child in GetEligibleChildrenForRecursiveChildren(user))
             {
             {
                 if (child.IsVisible(user))
                 if (child.IsVisible(user))
                 {
                 {
-                    if (filter == null || filter(child))
+                    if (query == null || UserViewBuilder.FilterItem(child, query))
                     {
                     {
                         result[child.Id] = child;
                         result[child.Id] = child;
                     }
                     }
@@ -1236,7 +1239,7 @@ namespace MediaBrowser.Controller.Entities
                     {
                     {
                         var folder = (Folder)child;
                         var folder = (Folder)child;
 
 
-                        folder.AddChildren(user, includeLinkedChildren, result, true, filter);
+                        folder.AddChildren(user, includeLinkedChildren, result, true, query);
                     }
                     }
                 }
                 }
             }
             }
@@ -1247,7 +1250,7 @@ namespace MediaBrowser.Controller.Entities
                 {
                 {
                     if (child.IsVisible(user))
                     if (child.IsVisible(user))
                     {
                     {
-                        if (filter == null || filter(child))
+                        if (query == null || UserViewBuilder.FilterItem(child, query))
                         {
                         {
                             result[child.Id] = child;
                             result[child.Id] = child;
                         }
                         }
@@ -1265,10 +1268,10 @@ namespace MediaBrowser.Controller.Entities
         /// <exception cref="System.ArgumentNullException"></exception>
         /// <exception cref="System.ArgumentNullException"></exception>
         public IEnumerable<BaseItem> GetRecursiveChildren(User user, bool includeLinkedChildren = true)
         public IEnumerable<BaseItem> GetRecursiveChildren(User user, bool includeLinkedChildren = true)
         {
         {
-            return GetRecursiveChildren(user, i => true);
+            return GetRecursiveChildren(user, null);
         }
         }
 
 
-        public virtual IEnumerable<BaseItem> GetRecursiveChildren(User user, Func<BaseItem, bool> filter)
+        public virtual IEnumerable<BaseItem> GetRecursiveChildren(User user, InternalItemsQuery query)
         {
         {
             if (user == null)
             if (user == null)
             {
             {
@@ -1277,7 +1280,7 @@ namespace MediaBrowser.Controller.Entities
 
 
             var result = new Dictionary<Guid, BaseItem>();
             var result = new Dictionary<Guid, BaseItem>();
 
 
-            AddChildren(user, true, result, true, filter);
+            AddChildren(user, true, result, true, query);
 
 
             return result.Values;
             return result.Values;
         }
         }
@@ -1534,7 +1537,8 @@ namespace MediaBrowser.Controller.Entities
                 User = user,
                 User = user,
                 Recursive = true,
                 Recursive = true,
                 IsFolder = false,
                 IsFolder = false,
-                IsUnaired = false
+                IsUnaired = false,
+                EnableTotalRecordCount = false
 
 
             };
             };
 
 
@@ -1562,7 +1566,8 @@ namespace MediaBrowser.Controller.Entities
             {
             {
                 User = user,
                 User = user,
                 Recursive = true,
                 Recursive = true,
-                IsFolder = false
+                IsFolder = false,
+                EnableTotalRecordCount = false
 
 
             }).ConfigureAwait(false);
             }).ConfigureAwait(false);
 
 
@@ -1578,7 +1583,8 @@ namespace MediaBrowser.Controller.Entities
             {
             {
                 Recursive = true,
                 Recursive = true,
                 IsFolder = false,
                 IsFolder = false,
-                ExcludeLocationTypes = new[] { LocationType.Virtual }
+                ExcludeLocationTypes = new[] { LocationType.Virtual },
+                EnableTotalRecordCount = false
 
 
             }).Result;
             }).Result;
 
 
@@ -1630,7 +1636,8 @@ namespace MediaBrowser.Controller.Entities
             {
             {
                 Recursive = true,
                 Recursive = true,
                 IsFolder = false,
                 IsFolder = false,
-                ExcludeLocationTypes = new[] { LocationType.Virtual }
+                ExcludeLocationTypes = new[] { LocationType.Virtual },
+                EnableTotalRecordCount = false
 
 
             }).Result;
             }).Result;
 
 

+ 0 - 6
MediaBrowser.Controller/Entities/IItemByName.cs

@@ -15,12 +15,6 @@ namespace MediaBrowser.Controller.Entities
         /// <returns>IEnumerable{BaseItem}.</returns>
         /// <returns>IEnumerable{BaseItem}.</returns>
         IEnumerable<BaseItem> GetTaggedItems(IEnumerable<BaseItem> inputItems);
         IEnumerable<BaseItem> GetTaggedItems(IEnumerable<BaseItem> inputItems);
 
 
-        /// <summary>
-        /// Gets the item filter.
-        /// </summary>
-        /// <returns>Func&lt;BaseItem, System.Boolean&gt;.</returns>
-        Func<BaseItem, bool> GetItemFilter();
-
         IEnumerable<BaseItem> GetTaggedItems(InternalItemsQuery query);
         IEnumerable<BaseItem> GetTaggedItems(InternalItemsQuery query);
     }
     }
 
 

+ 1 - 2
MediaBrowser.Controller/Entities/InternalItemsQuery.cs

@@ -19,8 +19,6 @@ namespace MediaBrowser.Controller.Entities
 
 
         public User User { get; set; }
         public User User { get; set; }
 
 
-        public Func<BaseItem, bool> Filter { get; set; }
-
         public bool? IsFolder { get; set; }
         public bool? IsFolder { get; set; }
         public bool? IsFavorite { get; set; }
         public bool? IsFavorite { get; set; }
         public bool? IsFavoriteOrLiked { get; set; }
         public bool? IsFavoriteOrLiked { get; set; }
@@ -138,6 +136,7 @@ namespace MediaBrowser.Controller.Entities
 
 
         public bool GroupByPresentationUniqueKey { get; set; }
         public bool GroupByPresentationUniqueKey { get; set; }
         public bool EnableTotalRecordCount { get; set; }
         public bool EnableTotalRecordCount { get; set; }
+        public bool ForceDirect { get; set; }
 
 
         public InternalItemsQuery()
         public InternalItemsQuery()
         {
         {

+ 8 - 4
MediaBrowser.Controller/Entities/TV/Series.cs

@@ -381,14 +381,18 @@ namespace MediaBrowser.Controller.Entities.TV
                 }
                 }
                 else
                 else
                 {
                 {
-                    episodes = GetRecursiveChildren(user, i => i is Episode)
-                        .Cast<Episode>();
+                    episodes = GetRecursiveChildren(user, new InternalItemsQuery(user)
+                    {
+                        IncludeItemTypes = new[] { typeof(Episode).Name }
+                    }).Cast<Episode>();
                 }
                 }
             }
             }
             else
             else
             {
             {
-                episodes = GetRecursiveChildren(user, i => i is Episode)
-                    .Cast<Episode>();
+                episodes = GetRecursiveChildren(user, new InternalItemsQuery(user)
+                {
+                    IncludeItemTypes = new[] { typeof(Episode).Name }
+                }).Cast<Episode>();
             }
             }
 
 
             episodes = FilterEpisodesBySeason(episodes, seasonNumber, DisplaySpecialsWithSeasons);
             episodes = FilterEpisodesBySeason(episodes, seasonNumber, DisplaySpecialsWithSeasons);

+ 7 - 4
MediaBrowser.Controller/Entities/UserView.cs

@@ -66,7 +66,8 @@ namespace MediaBrowser.Controller.Entities
         {
         {
             var result = GetItems(new InternalItemsQuery
             var result = GetItems(new InternalItemsQuery
             {
             {
-                User = user
+                User = user,
+                EnableTotalRecordCount = false
 
 
             }).Result;
             }).Result;
 
 
@@ -83,17 +84,19 @@ namespace MediaBrowser.Controller.Entities
             return true;
             return true;
         }
         }
 
 
-        public override IEnumerable<BaseItem> GetRecursiveChildren(User user, Func<BaseItem, bool> filter)
+        public override IEnumerable<BaseItem> GetRecursiveChildren(User user, InternalItemsQuery query)
         {
         {
             var result = GetItems(new InternalItemsQuery
             var result = GetItems(new InternalItemsQuery
             {
             {
                 User = user,
                 User = user,
                 Recursive = true,
                 Recursive = true,
-                Filter = filter
+                EnableTotalRecordCount = false,
+
+                ForceDirect = true
 
 
             }).Result;
             }).Result;
 
 
-            return result.Items;
+            return result.Items.Where(i => UserViewBuilder.FilterItem(i, query));
         }
         }
 
 
         protected override IEnumerable<BaseItem> GetEligibleChildrenForRecursiveChildren(User user)
         protected override IEnumerable<BaseItem> GetEligibleChildrenForRecursiveChildren(User user)

+ 28 - 17
MediaBrowser.Controller/Entities/UserViewBuilder.cs

@@ -128,7 +128,11 @@ namespace MediaBrowser.Controller.Entities
                     {
                     {
                         if (query.Recursive)
                         if (query.Recursive)
                         {
                         {
-                            return GetResult(queryParent.GetRecursiveChildren(user, true), queryParent, query);
+                            query.Recursive = true;
+                            query.ParentId = queryParent.Id;
+                            query.SetUser(user);
+
+                            return _libraryManager.GetItemsResult(query);
                         }
                         }
                         return GetResult(queryParent.GetChildren(user, true), queryParent, query);
                         return GetResult(queryParent.GetChildren(user, true), queryParent, query);
                     }
                     }
@@ -328,9 +332,13 @@ namespace MediaBrowser.Controller.Entities
 
 
         private QueryResult<BaseItem> GetMusicAlbumArtists(Folder parent, User user, InternalItemsQuery query)
         private QueryResult<BaseItem> GetMusicAlbumArtists(Folder parent, User user, InternalItemsQuery query)
         {
         {
-            var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos })
-                .Where(i => !i.IsFolder)
-                .OfType<IHasAlbumArtist>();
+            var items = _libraryManager.GetItemList(new InternalItemsQuery(user)
+            {
+                Recursive = true,
+                ParentId = parent.Id,
+                IncludeItemTypes = new[] { typeof(Audio.Audio).Name }
+
+            }).Cast<IHasAlbumArtist>();
 
 
             var artists = _libraryManager.GetAlbumArtists(items);
             var artists = _libraryManager.GetAlbumArtists(items);
 
 
@@ -339,9 +347,13 @@ namespace MediaBrowser.Controller.Entities
 
 
         private QueryResult<BaseItem> GetMusicArtists(Folder parent, User user, InternalItemsQuery query)
         private QueryResult<BaseItem> GetMusicArtists(Folder parent, User user, InternalItemsQuery query)
         {
         {
-            var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos })
-                .Where(i => !i.IsFolder)
-                .OfType<IHasArtist>();
+            var items = _libraryManager.GetItemList(new InternalItemsQuery(user)
+            {
+                Recursive = true,
+                ParentId = parent.Id,
+                IncludeItemTypes = new[] { typeof(Audio.Audio).Name, typeof(MusicVideo).Name }
+
+            }).Cast<IHasArtist>();
 
 
             var artists = _libraryManager.GetArtists(items);
             var artists = _libraryManager.GetArtists(items);
 
 
@@ -350,9 +362,13 @@ namespace MediaBrowser.Controller.Entities
 
 
         private QueryResult<BaseItem> GetFavoriteArtists(Folder parent, User user, InternalItemsQuery query)
         private QueryResult<BaseItem> GetFavoriteArtists(Folder parent, User user, InternalItemsQuery query)
         {
         {
-            var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos })
-                .Where(i => !i.IsFolder)
-                .OfType<IHasAlbumArtist>();
+            var items = _libraryManager.GetItemList(new InternalItemsQuery(user)
+            {
+                Recursive = true,
+                ParentId = parent.Id,
+                IncludeItemTypes = new[] { typeof(Audio.Audio).Name }
+
+            }).Cast<IHasAlbumArtist>();
 
 
             var artists = _libraryManager.GetAlbumArtists(items).Where(i => _userDataManager.GetUserData(user, i).IsFavorite);
             var artists = _libraryManager.GetAlbumArtists(items).Where(i => _userDataManager.GetUserData(user, i).IsFavorite);
 
 
@@ -753,9 +769,9 @@ namespace MediaBrowser.Controller.Entities
             return PostFilterAndSort(items, queryParent, null, query, _libraryManager);
             return PostFilterAndSort(items, queryParent, null, query, _libraryManager);
         }
         }
 
 
-        public bool FilterItem(BaseItem item, InternalItemsQuery query)
+        public static bool FilterItem(BaseItem item, InternalItemsQuery query)
         {
         {
-            return Filter(item, query.User, query, _userDataManager, _libraryManager);
+            return Filter(item, query.User, query, BaseItem.UserDataManager, BaseItem.LibraryManager);
         }
         }
 
 
         private QueryResult<BaseItem> PostFilterAndSort(IEnumerable<BaseItem> items,
         private QueryResult<BaseItem> PostFilterAndSort(IEnumerable<BaseItem> items,
@@ -1274,11 +1290,6 @@ namespace MediaBrowser.Controller.Entities
                 return false;
                 return false;
             }
             }
 
 
-            if (query.Filter != null && !query.Filter(item))
-            {
-                return false;
-            }
-
             UserItemData userData = null;
             UserItemData userData = null;
 
 
             if (query.IsLiked.HasValue)
             if (query.IsLiked.HasValue)

+ 8 - 4
MediaBrowser.Controller/Playlists/Playlist.cs

@@ -63,13 +63,13 @@ namespace MediaBrowser.Controller.Playlists
             return GetPlayableItems(user).Result;
             return GetPlayableItems(user).Result;
         }
         }
 
 
-        public override IEnumerable<BaseItem> GetRecursiveChildren(User user, Func<BaseItem, bool> filter)
+        public override IEnumerable<BaseItem> GetRecursiveChildren(User user, InternalItemsQuery query)
         {
         {
             var items = GetPlayableItems(user).Result;
             var items = GetPlayableItems(user).Result;
 
 
-            if (filter != null)
+            if (query != null)
             {
             {
-                items = items.Where(filter);
+                items = items.Where(i => UserViewBuilder.FilterItem(i, query));
             }
             }
 
 
             return items;
             return items;
@@ -129,7 +129,11 @@ namespace MediaBrowser.Controller.Playlists
 
 
                 var items = user == null
                 var items = user == null
                     ? LibraryManager.RootFolder.GetRecursiveChildren(filter)
                     ? LibraryManager.RootFolder.GetRecursiveChildren(filter)
-                    : user.RootFolder.GetRecursiveChildren(user, filter);
+                    : user.RootFolder.GetRecursiveChildren(user, new InternalItemsQuery(user)
+                    {
+                        IncludeItemTypes = new[] { typeof(Audio).Name },
+                        ArtistNames = new[] { musicArtist.Name }
+                    });
 
 
                 return LibraryManager.Sort(items, user, new[] { ItemSortBy.AlbumArtist, ItemSortBy.Album, ItemSortBy.SortName }, SortOrder.Ascending);
                 return LibraryManager.Sort(items, user, new[] { ItemSortBy.AlbumArtist, ItemSortBy.Album, ItemSortBy.SortName }, SortOrder.Ascending);
             }
             }

+ 6 - 27
MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs

@@ -401,10 +401,10 @@ namespace MediaBrowser.Dlna.ContentDirectory
                 SortOrder = sort.SortOrder,
                 SortOrder = sort.SortOrder,
                 User = user,
                 User = user,
                 Recursive = true,
                 Recursive = true,
-                Filter = FilterUnsupportedContent,
+                IsMissing = false,
+                ExcludeItemTypes = new[] { typeof(Game).Name, typeof(Book).Name },
                 IsFolder = isFolder,
                 IsFolder = isFolder,
                 MediaTypes = mediaTypes.ToArray()
                 MediaTypes = mediaTypes.ToArray()
-
             });
             });
         }
         }
 
 
@@ -461,8 +461,10 @@ namespace MediaBrowser.Dlna.ContentDirectory
                 SortBy = sortOrders.ToArray(),
                 SortBy = sortOrders.ToArray(),
                 SortOrder = sort.SortOrder,
                 SortOrder = sort.SortOrder,
                 User = user,
                 User = user,
-                Filter = FilterUnsupportedContent,
-                PresetViews = new[] { CollectionType.Movies, CollectionType.TvShows, CollectionType.Music }
+                IsMissing = false,
+                PresetViews = new[] { CollectionType.Movies, CollectionType.TvShows, CollectionType.Music },
+                ExcludeItemTypes = new[] { typeof(Game).Name, typeof(Book).Name },
+                IsPlaceHolder = false
 
 
             }).ConfigureAwait(false);
             }).ConfigureAwait(false);
 
 
@@ -579,29 +581,6 @@ namespace MediaBrowser.Dlna.ContentDirectory
             });
             });
         }
         }
 
 
-        private bool FilterUnsupportedContent(BaseItem i)
-        {
-            // Unplayable
-            if (i.LocationType == LocationType.Virtual && !i.IsFolder)
-            {
-                return false;
-            }
-
-            // Unplayable
-            var supportsPlaceHolder = i as ISupportsPlaceHolders;
-            if (supportsPlaceHolder != null && supportsPlaceHolder.IsPlaceHolder)
-            {
-                return false;
-            }
-
-            if (i is Game || i is Book)
-            {
-                //return false;
-            }
-
-            return true;
-        }
-
         private ServerItem GetItemFromObjectId(string id, User user)
         private ServerItem GetItemFromObjectId(string id, User user)
         {
         {
             return DidlBuilder.IsIdRoot(id)
             return DidlBuilder.IsIdRoot(id)

+ 6 - 2
MediaBrowser.Server.Implementations/Library/LibraryManager.cs

@@ -1448,8 +1448,12 @@ namespace MediaBrowser.Server.Implementations.Library
                 // Handle grouping
                 // Handle grouping
                 if (user != null && !string.IsNullOrWhiteSpace(view.ViewType) && UserView.IsEligibleForGrouping(view.ViewType))
                 if (user != null && !string.IsNullOrWhiteSpace(view.ViewType) && UserView.IsEligibleForGrouping(view.ViewType))
                 {
                 {
-                    var collectionFolders = user.RootFolder.GetChildren(user, true).OfType<CollectionFolder>().Where(i => string.IsNullOrWhiteSpace(i.CollectionType) || string.Equals(i.CollectionType, view.ViewType, StringComparison.OrdinalIgnoreCase));
-                    return collectionFolders.SelectMany(i => GetTopParentsForQuery(i, user));
+                    return user.RootFolder
+                        .GetChildren(user, true)
+                        .OfType<CollectionFolder>()
+                        .Where(i => string.IsNullOrWhiteSpace(i.CollectionType) || string.Equals(i.CollectionType, view.ViewType, StringComparison.OrdinalIgnoreCase))
+                        .Where(i => user.Configuration.GroupedFolders.Contains(i.Id.ToString("N"), StringComparer.OrdinalIgnoreCase))
+                        .SelectMany(i => GetTopParentsForQuery(i, user));
                 }
                 }
                 return new BaseItem[] { };
                 return new BaseItem[] { };
             }
             }

+ 16 - 4
MediaBrowser.Server.Implementations/Library/MusicManager.cs

@@ -30,7 +30,10 @@ namespace MediaBrowser.Server.Implementations.Library
         public IEnumerable<Audio> GetInstantMixFromArtist(MusicArtist artist, User user)
         public IEnumerable<Audio> GetInstantMixFromArtist(MusicArtist artist, User user)
         {
         {
             var genres = user.RootFolder
             var genres = user.RootFolder
-                .GetRecursiveChildren(user, i => i is Audio)
+                .GetRecursiveChildren(user, new InternalItemsQuery(user)
+                {
+                    IncludeItemTypes = new[] { typeof(Audio).Name }
+                })
                 .Cast<Audio>()
                 .Cast<Audio>()
                 .Where(i => i.HasAnyArtist(artist.Name))
                 .Where(i => i.HasAnyArtist(artist.Name))
                 .SelectMany(i => i.Genres)
                 .SelectMany(i => i.Genres)
@@ -43,7 +46,10 @@ namespace MediaBrowser.Server.Implementations.Library
         public IEnumerable<Audio> GetInstantMixFromAlbum(MusicAlbum item, User user)
         public IEnumerable<Audio> GetInstantMixFromAlbum(MusicAlbum item, User user)
         {
         {
             var genres = item
             var genres = item
-                .GetRecursiveChildren(user, i => i is Audio)
+                .GetRecursiveChildren(user, new InternalItemsQuery(user)
+                {
+                    IncludeItemTypes = new[] { typeof(Audio).Name }
+                })
                .Cast<Audio>()
                .Cast<Audio>()
                .SelectMany(i => i.Genres)
                .SelectMany(i => i.Genres)
                .Concat(item.Genres)
                .Concat(item.Genres)
@@ -55,7 +61,10 @@ namespace MediaBrowser.Server.Implementations.Library
         public IEnumerable<Audio> GetInstantMixFromFolder(Folder item, User user)
         public IEnumerable<Audio> GetInstantMixFromFolder(Folder item, User user)
         {
         {
             var genres = item
             var genres = item
-               .GetRecursiveChildren(user, i => i is Audio)
+               .GetRecursiveChildren(user, new InternalItemsQuery(user)
+               {
+                   IncludeItemTypes = new[] {typeof(Audio).Name}
+               })
                .Cast<Audio>()
                .Cast<Audio>()
                .SelectMany(i => i.Genres)
                .SelectMany(i => i.Genres)
                .Concat(item.Genres)
                .Concat(item.Genres)
@@ -67,7 +76,10 @@ namespace MediaBrowser.Server.Implementations.Library
         public IEnumerable<Audio> GetInstantMixFromPlaylist(Playlist item, User user)
         public IEnumerable<Audio> GetInstantMixFromPlaylist(Playlist item, User user)
         {
         {
             var genres = item
             var genres = item
-               .GetRecursiveChildren(user, i => i is Audio)
+               .GetRecursiveChildren(user, new InternalItemsQuery(user)
+               {
+                   IncludeItemTypes = new[] { typeof(Audio).Name }
+               })
                .Cast<Audio>()
                .Cast<Audio>()
                .SelectMany(i => i.Genres)
                .SelectMany(i => i.Genres)
                .Concat(item.Genres)
                .Concat(item.Genres)

+ 1 - 3
MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs

@@ -1410,7 +1410,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                 .Where(i => i.IsVisibleStandalone(user))
                 .Where(i => i.IsVisibleStandalone(user))
                 .ToList();
                 .ToList();
 
 
-            var items = _libraryManager.GetItemsResult(new InternalItemsQuery(user)
+            return _libraryManager.GetItemsResult(new InternalItemsQuery(user)
             {
             {
                 MediaTypes = new[] { MediaType.Video },
                 MediaTypes = new[] { MediaType.Video },
                 Recursive = true,
                 Recursive = true,
@@ -1418,8 +1418,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                 ExcludeLocationTypes = new[] { LocationType.Virtual },
                 ExcludeLocationTypes = new[] { LocationType.Virtual },
                 Limit = Math.Min(10, query.Limit ?? int.MaxValue)
                 Limit = Math.Min(10, query.Limit ?? int.MaxValue)
             });
             });
-
-            return items;
         }
         }
 
 
         public async Task<QueryResult<BaseItem>> GetInternalRecordings(RecordingQuery query, CancellationToken cancellationToken)
         public async Task<QueryResult<BaseItem>> GetInternalRecordings(RecordingQuery query, CancellationToken cancellationToken)

+ 98 - 3
MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs

@@ -81,10 +81,13 @@ namespace MediaBrowser.Server.Implementations.Persistence
         private IDbCommand _deleteUserDataKeysCommand;
         private IDbCommand _deleteUserDataKeysCommand;
         private IDbCommand _saveUserDataKeysCommand;
         private IDbCommand _saveUserDataKeysCommand;
 
 
+        private IDbCommand _deleteItemValuesCommand;
+        private IDbCommand _saveItemValuesCommand;
+
         private IDbCommand _updateInheritedRatingCommand;
         private IDbCommand _updateInheritedRatingCommand;
         private IDbCommand _updateInheritedTagsCommand;
         private IDbCommand _updateInheritedTagsCommand;
 
 
-        public const int LatestSchemaVersion = 78;
+        public const int LatestSchemaVersion = 79;
 
 
         /// <summary>
         /// <summary>
         /// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
         /// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
@@ -136,6 +139,9 @@ namespace MediaBrowser.Server.Implementations.Persistence
                                 "create table if not exists UserDataKeys (ItemId GUID, UserDataKey TEXT, PRIMARY KEY (ItemId, UserDataKey))",
                                 "create table if not exists UserDataKeys (ItemId GUID, UserDataKey TEXT, PRIMARY KEY (ItemId, UserDataKey))",
                                 "create index if not exists idx_UserDataKeys1 on UserDataKeys(ItemId)",
                                 "create index if not exists idx_UserDataKeys1 on UserDataKeys(ItemId)",
 
 
+                                "create table if not exists ItemValues (ItemId GUID, Type INT, Value TEXT)",
+                                "create index if not exists idx_ItemValues on ItemValues(ItemId)",
+
                                 "create table if not exists People (ItemId GUID, Name TEXT NOT NULL, Role TEXT, PersonType TEXT, SortOrder int, ListOrder int)",
                                 "create table if not exists People (ItemId GUID, Name TEXT NOT NULL, Role TEXT, PersonType TEXT, SortOrder int, ListOrder int)",
                                 "create index if not exists idxPeopleItemId on People(ItemId)",
                                 "create index if not exists idxPeopleItemId on People(ItemId)",
                                 "create index if not exists idxPeopleName on People(Name)",
                                 "create index if not exists idxPeopleName on People(Name)",
@@ -565,6 +571,17 @@ namespace MediaBrowser.Server.Implementations.Persistence
             _saveUserDataKeysCommand.Parameters.Add(_saveUserDataKeysCommand, "@UserDataKey");
             _saveUserDataKeysCommand.Parameters.Add(_saveUserDataKeysCommand, "@UserDataKey");
             _saveUserDataKeysCommand.Parameters.Add(_saveUserDataKeysCommand, "@Priority");
             _saveUserDataKeysCommand.Parameters.Add(_saveUserDataKeysCommand, "@Priority");
 
 
+            // item values
+            _deleteItemValuesCommand = _connection.CreateCommand();
+            _deleteItemValuesCommand.CommandText = "delete from ItemValues where ItemId=@Id";
+            _deleteItemValuesCommand.Parameters.Add(_deleteItemValuesCommand, "@Id");
+
+            _saveItemValuesCommand = _connection.CreateCommand();
+            _saveItemValuesCommand.CommandText = "insert into ItemValues (ItemId, Type, Value) values (@ItemId, @Type, @Value)";
+            _saveItemValuesCommand.Parameters.Add(_saveItemValuesCommand, "@ItemId");
+            _saveItemValuesCommand.Parameters.Add(_saveItemValuesCommand, "@Type");
+            _saveItemValuesCommand.Parameters.Add(_saveItemValuesCommand, "@Value");
+
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -851,6 +868,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
                     }
                     }
 
 
                     UpdateUserDataKeys(item.Id, item.GetUserDataKeys().Distinct(StringComparer.OrdinalIgnoreCase).ToList(), transaction);
                     UpdateUserDataKeys(item.Id, item.GetUserDataKeys().Distinct(StringComparer.OrdinalIgnoreCase).ToList(), transaction);
+                    UpdateItemValues(item.Id, GetItemValues(item), transaction);
                 }
                 }
 
 
                 transaction.Commit();
                 transaction.Commit();
@@ -1661,7 +1679,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
         {
         {
             var elapsed = (DateTime.UtcNow - startDate).TotalMilliseconds;
             var elapsed = (DateTime.UtcNow - startDate).TotalMilliseconds;
 
 
-            if (elapsed >= 500)
+            if (elapsed >= 400)
             {
             {
                 Logger.Debug("{2} query time (slow): {0}ms. Query: {1}",
                 Logger.Debug("{2} query time (slow): {0}ms. Query: {1}",
                     Convert.ToInt32(elapsed),
                     Convert.ToInt32(elapsed),
@@ -1795,7 +1813,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
             }).ToArray());
             }).ToArray());
         }
         }
 
 
-        private Tuple<string,bool> MapOrderByField(string name)
+        private Tuple<string, bool> MapOrderByField(string name)
         {
         {
             if (string.Equals(name, ItemSortBy.AirTime, StringComparison.OrdinalIgnoreCase))
             if (string.Equals(name, ItemSortBy.AirTime, StringComparison.OrdinalIgnoreCase))
             {
             {
@@ -1838,6 +1856,14 @@ namespace MediaBrowser.Server.Implementations.Persistence
             {
             {
                 return new Tuple<string, bool>("DateLastMediaAdded", false);
                 return new Tuple<string, bool>("DateLastMediaAdded", false);
             }
             }
+            if (string.Equals(name, ItemSortBy.Artist, StringComparison.OrdinalIgnoreCase))
+            {
+                return new Tuple<string, bool>("(select value from itemvalues where ItemId=Guid and Type=0 LIMIT 1)", false);
+            }
+            if (string.Equals(name, ItemSortBy.AlbumArtist, StringComparison.OrdinalIgnoreCase))
+            {
+                return new Tuple<string, bool>("(select value from itemvalues where ItemId=Guid and Type=1 LIMIT 1)", false);
+            }
 
 
             return new Tuple<string, bool>(name, false);
             return new Tuple<string, bool>(name, false);
         }
         }
@@ -2433,6 +2459,20 @@ namespace MediaBrowser.Server.Implementations.Persistence
                 }
                 }
             }
             }
 
 
+            if (query.ArtistNames.Length > 0)
+            {
+                var clauses = new List<string>();
+                var index = 0;
+                foreach (var artist in query.ArtistNames)
+                {
+                    clauses.Add("@ArtistName" + index + " in (select value from itemvalues where ItemId=Guid and Type <= 1)");
+                    cmd.Parameters.Add(cmd, "@ArtistName" + index, DbType.String).Value = artist;
+                    index++;
+                }
+                var clause = "(" + string.Join(" OR ", clauses.ToArray()) + ")";
+                whereClauses.Add(clause);
+            }
+
             if (query.Genres.Length > 0)
             if (query.Genres.Length > 0)
             {
             {
                 var clauses = new List<string>();
                 var clauses = new List<string>();
@@ -2970,6 +3010,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
                 _deleteUserDataKeysCommand.Transaction = transaction;
                 _deleteUserDataKeysCommand.Transaction = transaction;
                 _deleteUserDataKeysCommand.ExecuteNonQuery();
                 _deleteUserDataKeysCommand.ExecuteNonQuery();
 
 
+                // Delete item values
+                _deleteItemValuesCommand.GetParameter(0).Value = id;
+                _deleteItemValuesCommand.Transaction = transaction;
+                _deleteItemValuesCommand.ExecuteNonQuery();
+
                 // Delete the item
                 // Delete the item
                 _deleteItemCommand.GetParameter(0).Value = id;
                 _deleteItemCommand.GetParameter(0).Value = id;
                 _deleteItemCommand.Transaction = transaction;
                 _deleteItemCommand.Transaction = transaction;
@@ -3162,6 +3207,56 @@ namespace MediaBrowser.Server.Implementations.Persistence
             }
             }
         }
         }
 
 
+        private List<Tuple<int, string>> GetItemValues(BaseItem item)
+        {
+            var list = new List<Tuple<int, string>>();
+
+            var hasArtist = item as IHasArtist;
+            if (hasArtist != null)
+            {
+                list.AddRange(hasArtist.Artists.Select(i => new Tuple<int, string>(0, i)));
+            }
+
+            var hasAlbumArtist = item as IHasAlbumArtist;
+            if (hasAlbumArtist != null)
+            {
+                list.AddRange(hasAlbumArtist.AlbumArtists.Select(i => new Tuple<int, string>(1, i)));
+            }
+
+            return list;
+        }
+
+        private void UpdateItemValues(Guid itemId, List<Tuple<int, string>> values, IDbTransaction transaction)
+        {
+            if (itemId == Guid.Empty)
+            {
+                throw new ArgumentNullException("itemId");
+            }
+
+            if (values == null)
+            {
+                throw new ArgumentNullException("keys");
+            }
+
+            CheckDisposed();
+
+            // First delete 
+            _deleteItemValuesCommand.GetParameter(0).Value = itemId;
+            _deleteItemValuesCommand.Transaction = transaction;
+
+            _deleteItemValuesCommand.ExecuteNonQuery();
+
+            foreach (var pair in values)
+            {
+                _saveItemValuesCommand.GetParameter(0).Value = itemId;
+                _saveItemValuesCommand.GetParameter(1).Value = pair.Item1;
+                _saveItemValuesCommand.GetParameter(2).Value = pair.Item2;
+                _saveItemValuesCommand.Transaction = transaction;
+
+                _saveItemValuesCommand.ExecuteNonQuery();
+            }
+        }
+
         private void UpdateUserDataKeys(Guid itemId, List<string> keys, IDbTransaction transaction)
         private void UpdateUserDataKeys(Guid itemId, List<string> keys, IDbTransaction transaction)
         {
         {
             if (itemId == Guid.Empty)
             if (itemId == Guid.Empty)