From d04b39421e54952241f9a3460a87413923cceb3a Mon Sep 17 00:00:00 2001
From: Luke Pulverenti <luke.pulverenti@gmail.com>
Date: Fri, 6 May 2016 22:11:22 -0400
Subject: [PATCH] fix episode query

---
 MediaBrowser.Controller/Entities/Folder.cs    | 32 ++++++++-------
 MediaBrowser.Controller/Entities/TV/Season.cs | 25 +++--------
 MediaBrowser.Controller/Playlists/Playlist.cs | 41 ++++++++++++-------
 .../Persistence/SqliteItemRepository.cs       |  2 +-
 .../Playlists/PlaylistManager.cs              |  4 +-
 5 files changed, 53 insertions(+), 51 deletions(-)

diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index d9c0b7bfe3..4606a5dc72 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -199,8 +199,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"},
@@ -1569,7 +1569,15 @@ namespace MediaBrowser.Controller.Entities
 
         public override bool IsPlayed(User user)
         {
-            return GetRecursiveChildren(user, i => !i.IsFolder && i.LocationType != LocationType.Virtual)
+            var itemsResult = GetItems(new InternalItemsQuery(user)
+            {
+                Recursive = true,
+                IsFolder = false,
+                ExcludeLocationTypes = new[] { LocationType.Virtual }
+
+            }).Result;
+
+            return itemsResult.Items
                 .All(i => i.IsPlayed(user));
         }
 
@@ -1613,19 +1621,15 @@ namespace MediaBrowser.Controller.Entities
 
             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)
diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs
index a6894f5150..4e6128527c 100644
--- a/MediaBrowser.Controller/Entities/TV/Season.cs
+++ b/MediaBrowser.Controller/Entities/TV/Season.cs
@@ -156,24 +156,16 @@ namespace MediaBrowser.Controller.Entities.TV
 
         protected override Task<QueryResult<BaseItem>> GetItemsInternal(InternalItemsQuery query)
         {
+            if (query.User == null)
+            {
+                return base.GetItemsInternal(query);
+            }
+
             var user = query.User;
 
             Func<BaseItem, bool> filter = i => UserViewBuilder.Filter(i, user, query, UserDataManager, LibraryManager);
 
-            IEnumerable<BaseItem> items;
-
-            if (query.User == null)
-            {
-                items = query.Recursive
-                   ? GetRecursiveChildren(filter)
-                   : Children.Where(filter);
-            }
-            else
-            {
-                items = query.Recursive
-                   ? GetRecursiveChildren(user, filter)
-                   : GetChildren(user, true).Where(filter);
-            }
+            var items = GetEpisodes(user).Where(filter);
 
             var result = PostFilterAndSort(items, query);
 
@@ -269,11 +261,6 @@ namespace MediaBrowser.Controller.Entities.TV
             return GetEpisodes(user);
         }
 
-        public override IEnumerable<BaseItem> GetRecursiveChildren(User user, Func<BaseItem, bool> filter)
-        {
-            return GetEpisodes(user).Where(filter);
-        }
-
         protected override bool GetBlockUnratedValue(UserPolicy config)
         {
             // Don't block. Let either the entire series rating or episode rating determine it
diff --git a/MediaBrowser.Controller/Playlists/Playlist.cs b/MediaBrowser.Controller/Playlists/Playlist.cs
index 0f9af6550b..750dea3618 100644
--- a/MediaBrowser.Controller/Playlists/Playlist.cs
+++ b/MediaBrowser.Controller/Playlists/Playlist.cs
@@ -6,6 +6,7 @@ using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Runtime.Serialization;
+using System.Threading.Tasks;
 
 namespace MediaBrowser.Controller.Playlists
 {
@@ -50,12 +51,12 @@ namespace MediaBrowser.Controller.Playlists
 
         public override IEnumerable<BaseItem> GetChildren(User user, bool includeLinkedChildren)
         {
-            return GetPlayableItems(user);
+            return GetPlayableItems(user).Result;
         }
 
         public override IEnumerable<BaseItem> GetRecursiveChildren(User user, Func<BaseItem, bool> filter)
         {
-            var items = GetPlayableItems(user);
+            var items = GetPlayableItems(user).Result;
 
             if (filter != null)
             {
@@ -70,23 +71,30 @@ namespace MediaBrowser.Controller.Playlists
             return GetLinkedChildrenInfos();
         }
 
-        private IEnumerable<BaseItem> GetPlayableItems(User user)
+        private Task<IEnumerable<BaseItem>> GetPlayableItems(User user)
         {
             return GetPlaylistItems(MediaType, base.GetChildren(user, true), user);
         }
 
-        public static IEnumerable<BaseItem> GetPlaylistItems(string playlistMediaType, IEnumerable<BaseItem> inputItems, User user)
+        public static async Task<IEnumerable<BaseItem>> GetPlaylistItems(string playlistMediaType, IEnumerable<BaseItem> inputItems, User user)
         {
             if (user != null)
             {
                 inputItems = inputItems.Where(i => i.IsVisible(user));
             }
 
-            return inputItems.SelectMany(i => GetPlaylistItems(i, user))
-                .Where(m => string.Equals(m.MediaType, playlistMediaType, StringComparison.OrdinalIgnoreCase));
+            var list = new List<BaseItem>();
+
+            foreach (var item in inputItems)
+            {
+                var playlistItems = await GetPlaylistItems(item, user, playlistMediaType).ConfigureAwait(false);
+                list.AddRange(playlistItems);
+            }
+
+            return list;
         }
 
-        private static IEnumerable<BaseItem> GetPlaylistItems(BaseItem item, User user)
+        private static async Task<IEnumerable<BaseItem>> GetPlaylistItems(BaseItem item, User user, string mediaType)
         {
             var musicGenre = item as MusicGenre;
             if (musicGenre != null)
@@ -119,15 +127,18 @@ namespace MediaBrowser.Controller.Playlists
             var folder = item as Folder;
             if (folder != null)
             {
-                var items = user == null
-                    ? folder.GetRecursiveChildren(m => !m.IsFolder)
-                    : folder.GetRecursiveChildren(user, m => !m.IsFolder);
-
-                if (folder.IsPreSorted)
+                var query = new InternalItemsQuery(user)
                 {
-                    return items;
-                }
-                return LibraryManager.Sort(items, user, new[] { ItemSortBy.SortName }, SortOrder.Ascending);
+                    Recursive = true,
+                    IsFolder = false,
+                    SortBy = new[] { ItemSortBy.SortName },
+                    MediaTypes = new[] { mediaType }
+                };
+
+                var itemsResult = await folder.GetItems(query).ConfigureAwait(false);
+                var items = itemsResult.Items;
+
+                return items;
             }
 
             return new[] { item };
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
index 3422a32127..2de458d6e6 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
@@ -82,7 +82,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
         private IDbCommand _updateInheritedRatingCommand;
         private IDbCommand _updateInheritedTagsCommand;
 
-        public const int LatestSchemaVersion = 71;
+        public const int LatestSchemaVersion = 72;
 
         /// <summary>
         /// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
diff --git a/MediaBrowser.Server.Implementations/Playlists/PlaylistManager.cs b/MediaBrowser.Server.Implementations/Playlists/PlaylistManager.cs
index 06ef05951a..53c03b91c1 100644
--- a/MediaBrowser.Server.Implementations/Playlists/PlaylistManager.cs
+++ b/MediaBrowser.Server.Implementations/Playlists/PlaylistManager.cs
@@ -158,7 +158,7 @@ namespace MediaBrowser.Server.Implementations.Playlists
             return path;
         }
 
-        private IEnumerable<BaseItem> GetPlaylistItems(IEnumerable<string> itemIds, string playlistMediaType, User user)
+        private Task<IEnumerable<BaseItem>> GetPlaylistItems(IEnumerable<string> itemIds, string playlistMediaType, User user)
         {
             var items = itemIds.Select(i => _libraryManager.GetItemById(i)).Where(i => i != null);
 
@@ -183,7 +183,7 @@ namespace MediaBrowser.Server.Implementations.Playlists
 
             var list = new List<LinkedChild>();
 
-            var items = GetPlaylistItems(itemIds, playlist.MediaType, user)
+            var items = (await GetPlaylistItems(itemIds, playlist.MediaType, user).ConfigureAwait(false))
                 .Where(i => i.SupportsAddingToPlaylist)
                 .ToList();