Forráskód Böngészése

support pooling series and seasons

Luke Pulverenti 9 éve
szülő
commit
cd02373e55

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

@@ -46,6 +46,7 @@ namespace MediaBrowser.Controller.Entities
         public string NameLessThan { get; set; }
         public string NameContains { get; set; }
 
+        public string PresentationUniqueKey { get; set; }
         public string Path { get; set; }
         
         public string Person { get; set; }

+ 14 - 19
MediaBrowser.Controller/Entities/TV/Episode.cs

@@ -58,25 +58,7 @@ namespace MediaBrowser.Controller.Entities.TV
         {
             get
             {
-                return AirsAfterSeasonNumber ?? AirsBeforeSeasonNumber ?? PhysicalSeasonNumber;
-            }
-        }
-
-        [IgnoreDataMember]
-        public int? PhysicalSeasonNumber
-        {
-            get
-            {
-                var value = ParentIndexNumber;
-
-                if (value.HasValue)
-                {
-                    return value;
-                }
-
-                var season = Season;
-
-                return season != null ? season.IndexNumber : null;
+                return AirsAfterSeasonNumber ?? AirsBeforeSeasonNumber ?? ParentIndexNumber;
             }
         }
 
@@ -316,6 +298,19 @@ namespace MediaBrowser.Controller.Entities.TV
                 Logger.ErrorException("Error in FillMissingEpisodeNumbersFromPath. Episode: {0}", ex, Path ?? Name ?? Id.ToString());
             }
 
+            if (!ParentIndexNumber.HasValue)
+            {
+                var season = Season;
+                if (season != null)
+                {
+                    if (season.ParentIndexNumber.HasValue)
+                    {
+                        ParentIndexNumber = season.ParentIndexNumber;
+                        hasChanges = true;
+                    }
+                }
+            }
+
             return hasChanges;
         }
     }

+ 22 - 4
MediaBrowser.Controller/Entities/TV/Season.cs

@@ -92,6 +92,24 @@ namespace MediaBrowser.Controller.Entities.TV
             }
         }
 
+        [IgnoreDataMember]
+        public override string PresentationUniqueKey
+        {
+            get
+            {
+                if (IndexNumber.HasValue)
+                {
+                    var series = Series;
+                    if (series != null)
+                    {
+                        return series.PresentationUniqueKey + "-" + (IndexNumber ?? 0).ToString("000");
+                    }
+                }
+
+                return base.PresentationUniqueKey;
+            }
+        }
+
         /// <summary>
         /// Creates the name of the sort.
         /// </summary>
@@ -169,16 +187,16 @@ namespace MediaBrowser.Controller.Entities.TV
 
         public IEnumerable<Episode> GetEpisodes(User user, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes)
         {
-            var episodes = GetRecursiveChildren(user)
-                .OfType<Episode>();
-
             var series = Series;
 
             if (IndexNumber.HasValue && series != null)
             {
-                return series.GetEpisodes(user, IndexNumber.Value, includeMissingEpisodes, includeVirtualUnairedEpisodes, episodes);
+                return series.GetEpisodes(user, IndexNumber.Value, includeMissingEpisodes, includeVirtualUnairedEpisodes);
             }
 
+            var episodes = GetRecursiveChildren(user)
+                .OfType<Episode>();
+
             if (series != null && series.ContainsEpisodesWithoutSeasonFolders)
             {
                 var seasonNumber = IndexNumber;

+ 47 - 16
MediaBrowser.Controller/Entities/TV/Series.cs

@@ -94,7 +94,7 @@ namespace MediaBrowser.Controller.Entities.TV
         [IgnoreDataMember]
         public override string PresentationUniqueKey
         {
-            get { return GetUserDataKey(); }
+            get { return GetUserDataKeys().First(); }
         }
 
         /// <summary>
@@ -191,8 +191,28 @@ namespace MediaBrowser.Controller.Entities.TV
 
         public IEnumerable<Season> GetSeasons(User user, bool includeMissingSeasons, bool includeVirtualUnaired)
         {
-            var seasons = base.GetChildren(user, true)
-                .OfType<Season>();
+            var seriesIds = LibraryManager.GetItemIds(new InternalItemsQuery(user)
+            {
+                PresentationUniqueKey = PresentationUniqueKey,
+                IncludeItemTypes = new[] { typeof(Series).Name }
+            });
+
+            IEnumerable<Season> seasons;
+
+            if (seriesIds.Count > 1)
+            {
+                seasons = LibraryManager.GetItemList(new InternalItemsQuery(user)
+                {
+                    AncestorIds = seriesIds.Select(i => i.ToString("N")).ToArray(),
+                    IncludeItemTypes = new[] { typeof(Season).Name },
+                    SortBy = new[] { ItemSortBy.SortName }
+
+                }).OfType<Season>();
+            }
+            else
+            {
+                seasons = base.GetChildren(user, true).OfType<Season>();
+            }
 
             if (!includeMissingSeasons && !includeVirtualUnaired)
             {
@@ -210,9 +230,7 @@ namespace MediaBrowser.Controller.Entities.TV
                 }
             }
 
-            return LibraryManager
-                .Sort(seasons, user, new[] { ItemSortBy.SortName }, SortOrder.Ascending)
-                .Cast<Season>();
+            return seasons;
         }
 
         public IEnumerable<Episode> GetEpisodes(User user)
@@ -321,18 +339,31 @@ namespace MediaBrowser.Controller.Entities.TV
 
         public IEnumerable<Episode> GetEpisodes(User user, int seasonNumber, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes)
         {
-            return GetEpisodes(user, seasonNumber, includeMissingEpisodes, includeVirtualUnairedEpisodes,
-                new List<Episode>());
-        }
+            var seriesIds = LibraryManager.GetItemIds(new InternalItemsQuery(user)
+            {
+                PresentationUniqueKey = PresentationUniqueKey,
+                IncludeItemTypes = new[] { typeof(Series).Name }
+            });
 
-        internal IEnumerable<Episode> GetEpisodes(User user, int seasonNumber, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes, IEnumerable<Episode> additionalEpisodes)
-        {
-            var episodes = GetRecursiveChildren(user, i => i is Episode)
-                .Cast<Episode>();
+            IEnumerable<Episode> episodes;
 
-            episodes = FilterEpisodesBySeason(episodes, seasonNumber, DisplaySpecialsWithSeasons);
+            if (seriesIds.Count > 1)
+            {
+                episodes = LibraryManager.GetItemList(new InternalItemsQuery(user)
+                {
+                    AncestorIds = seriesIds.Select(i => i.ToString("N")).ToArray(),
+                    IncludeItemTypes = new[] { typeof(Episode).Name },
+                    SortBy = new[] { ItemSortBy.SortName }
 
-            episodes = episodes.Concat(additionalEpisodes).Distinct();
+                }).OfType<Episode>();
+            }
+            else
+            {
+                episodes = GetRecursiveChildren(user, i => i is Episode)
+                    .Cast<Episode>();
+            }
+
+            episodes = FilterEpisodesBySeason(episodes, seasonNumber, DisplaySpecialsWithSeasons);
 
             if (!includeMissingEpisodes)
             {
@@ -360,7 +391,7 @@ namespace MediaBrowser.Controller.Entities.TV
         {
             if (!includeSpecials || seasonNumber < 1)
             {
-                return episodes.Where(i => (i.PhysicalSeasonNumber ?? -1) == seasonNumber);
+                return episodes.Where(i => (i.ParentIndexNumber ?? -1) == seasonNumber);
             }
 
             return episodes.Where(i =>

+ 14 - 2
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 = 66;
+        public const int LatestSchemaVersion = 68;
 
         /// <summary>
         /// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
@@ -1936,6 +1936,12 @@ namespace MediaBrowser.Server.Implementations.Persistence
                 cmd.Parameters.Add(cmd, "@Path", DbType.String).Value = query.Path;
             }
 
+            if (!string.IsNullOrWhiteSpace(query.PresentationUniqueKey))
+            {
+                whereClauses.Add("PresentationUniqueKey=@PresentationUniqueKey");
+                cmd.Parameters.Add(cmd, "@PresentationUniqueKey", DbType.String).Value = query.PresentationUniqueKey;
+            }
+
             if (query.MinCommunityRating.HasValue)
             {
                 whereClauses.Add("CommunityRating>=@MinCommunityRating");
@@ -2323,6 +2329,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
 
         private bool EnableGroupByPresentationUniqueKey(InternalItemsQuery query)
         {
+            if (!string.IsNullOrWhiteSpace(query.PresentationUniqueKey))
+            {
+                return false;
+            }
+
             if (query.IncludeItemTypes.Length == 0)
             {
                 return true;
@@ -2333,7 +2344,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
                 typeof(Video).Name ,
                 typeof(Movie).Name ,
                 typeof(MusicVideo).Name ,
-                typeof(Series).Name };
+                typeof(Series).Name ,
+                typeof(Season).Name };
 
             if (types.Any(i => query.IncludeItemTypes.Contains(i, StringComparer.OrdinalIgnoreCase)))
             {

+ 5 - 5
MediaBrowser.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs

@@ -49,8 +49,8 @@ namespace MediaBrowser.Server.Implementations.Sorting
 
         private int Compare(Episode x, Episode y)
         {
-            var isXSpecial = (x.PhysicalSeasonNumber ?? -1) == 0;
-            var isYSpecial = (y.PhysicalSeasonNumber ?? -1) == 0;
+            var isXSpecial = (x.ParentIndexNumber ?? -1) == 0;
+            var isYSpecial = (y.ParentIndexNumber ?? -1) == 0;
 
             if (isXSpecial && isYSpecial)
             {
@@ -74,7 +74,7 @@ namespace MediaBrowser.Server.Implementations.Sorting
         {
             // http://thetvdb.com/wiki/index.php?title=Special_Episodes
 
-            var xSeason = x.PhysicalSeasonNumber ?? -1;
+            var xSeason = x.ParentIndexNumber ?? -1;
             var ySeason = y.AirsAfterSeasonNumber ?? y.AirsBeforeSeasonNumber ?? -1;
 
             if (xSeason != ySeason)
@@ -142,8 +142,8 @@ namespace MediaBrowser.Server.Implementations.Sorting
 
         private int CompareEpisodes(Episode x, Episode y)
         {
-            var xValue = (x.PhysicalSeasonNumber ?? -1) * 1000 + (x.IndexNumber ?? -1);
-            var yValue = (y.PhysicalSeasonNumber ?? -1) * 1000 + (y.IndexNumber ?? -1);
+            var xValue = (x.ParentIndexNumber ?? -1) * 1000 + (x.IndexNumber ?? -1);
+            var yValue = (y.ParentIndexNumber ?? -1) * 1000 + (y.IndexNumber ?? -1);
 
             return xValue.CompareTo(yValue);
         }

+ 50 - 32
MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs

@@ -36,10 +36,25 @@ namespace MediaBrowser.Server.Implementations.TV
                 ? new string[] { }
                 : new[] { request.ParentId };
 
+            string presentationUniqueKey = null;
+            int? limit = null;
+            if (!string.IsNullOrWhiteSpace(request.SeriesId))
+            {
+                var series = _libraryManager.GetItemById(request.SeriesId);
+
+                if (series != null)
+                {
+                    presentationUniqueKey = series.PresentationUniqueKey;
+                    limit = 1;
+                }
+            }
+
             var items = _libraryManager.GetItemList(new InternalItemsQuery(user)
             {
                 IncludeItemTypes = new[] { typeof(Series).Name },
-                SortOrder = SortOrder.Ascending
+                SortOrder = SortOrder.Ascending,
+                PresentationUniqueKey = presentationUniqueKey,
+                Limit = limit
 
             }, parentIds).Cast<Series>();
 
@@ -58,10 +73,25 @@ namespace MediaBrowser.Server.Implementations.TV
                 throw new ArgumentException("User not found");
             }
 
+            string presentationUniqueKey = null;
+            int? limit = null;
+            if (!string.IsNullOrWhiteSpace(request.SeriesId))
+            {
+                var series = _libraryManager.GetItemById(request.SeriesId);
+
+                if (series != null)
+                {
+                    presentationUniqueKey = series.PresentationUniqueKey;
+                    limit = 1;
+                }
+            }
+
             var items = _libraryManager.GetItemList(new InternalItemsQuery(user)
             {
                 IncludeItemTypes = new[] { typeof(Series).Name },
-                SortOrder = SortOrder.Ascending
+                SortOrder = SortOrder.Ascending,
+                PresentationUniqueKey = presentationUniqueKey,
+                Limit = limit
 
             }, parentsFolders.Select(i => i.Id.ToString("N"))).Cast<Series>();
 
@@ -76,30 +106,30 @@ namespace MediaBrowser.Server.Implementations.TV
             // Avoid implicitly captured closure
             var currentUser = user;
 
-            return FilterSeries(request, series)
+            return series
                 .AsParallel()
                 .Select(i => GetNextUp(i, currentUser))
                 // Include if an episode was found, and either the series is not unwatched or the specific series was requested
                 .Where(i => i.Item1 != null && (!i.Item3 || !string.IsNullOrWhiteSpace(request.SeriesId)))
-                .OrderByDescending(i =>
-                {
-                    var episode = i.Item1;
+                //.OrderByDescending(i =>
+                //{
+                //    var episode = i.Item1;
 
-                    var seriesUserData = _userDataManager.GetUserData(user, episode.Series);
+                //    var seriesUserData = _userDataManager.GetUserData(user, episode.Series);
 
-                    if (seriesUserData.IsFavorite)
-                    {
-                        return 2;
-                    }
+                //    if (seriesUserData.IsFavorite)
+                //    {
+                //        return 2;
+                //    }
 
-                    if (seriesUserData.Likes.HasValue)
-                    {
-                        return seriesUserData.Likes.Value ? 1 : -1;
-                    }
+                //    if (seriesUserData.Likes.HasValue)
+                //    {
+                //        return seriesUserData.Likes.Value ? 1 : -1;
+                //    }
 
-                    return 0;
-                })
-                .ThenByDescending(i => i.Item2)
+                //    return 0;
+                //})
+                .OrderByDescending(i => i.Item2)
                 .ThenByDescending(i => i.Item1.PremiereDate ?? DateTime.MinValue)
                 .Select(i => i.Item1);
         }
@@ -142,7 +172,7 @@ namespace MediaBrowser.Server.Implementations.TV
                 }
                 else
                 {
-                    if (!episode.IsVirtualUnaired && (!episode.IsMissingEpisode || includeMissing))
+                    if (!episode.IsVirtualUnaired && (includeMissing || !episode.IsMissingEpisode))
                     {
                         nextUp = episode;
                     }
@@ -154,24 +184,12 @@ namespace MediaBrowser.Server.Implementations.TV
                 return new Tuple<Episode, DateTime, bool>(nextUp, lastWatchedDate, false);
             }
 
-            var firstEpisode = allEpisodes.LastOrDefault(i => !i.IsVirtualUnaired && (!i.IsMissingEpisode || includeMissing) && !i.IsPlayed(user));
+            var firstEpisode = allEpisodes.LastOrDefault(i => !i.IsVirtualUnaired && (includeMissing || !i.IsMissingEpisode) && !i.IsPlayed(user));
 
             // Return the first episode
             return new Tuple<Episode, DateTime, bool>(firstEpisode, DateTime.MinValue, true);
         }
 
-        private IEnumerable<Series> FilterSeries(NextUpQuery request, IEnumerable<Series> items)
-        {
-            if (!string.IsNullOrWhiteSpace(request.SeriesId))
-            {
-                var id = new Guid(request.SeriesId);
-
-                items = items.Where(i => i.Id == id);
-            }
-
-            return items;
-        }
-
         private QueryResult<BaseItem> GetResult(IEnumerable<BaseItem> items, int? totalRecordLimit, NextUpQuery query)
         {
             var itemsArray = totalRecordLimit.HasValue ? items.Take(totalRecordLimit.Value).ToArray() : items.ToArray();