diff options
Diffstat (limited to 'MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs')
| -rw-r--r-- | MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs | 184 |
1 files changed, 107 insertions, 77 deletions
diff --git a/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs b/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs index 3e43ebe9b..ddc1de9cd 100644 --- a/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs +++ b/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs @@ -7,6 +7,7 @@ using MediaBrowser.Model.Querying; using System; using System.Collections.Generic; using System.Linq; +using MediaBrowser.Controller.Configuration; namespace MediaBrowser.Server.Implementations.TV { @@ -15,12 +16,14 @@ namespace MediaBrowser.Server.Implementations.TV private readonly IUserManager _userManager; private readonly IUserDataManager _userDataManager; private readonly ILibraryManager _libraryManager; + private readonly IServerConfigurationManager _config; - public TVSeriesManager(IUserManager userManager, IUserDataManager userDataManager, ILibraryManager libraryManager) + public TVSeriesManager(IUserManager userManager, IUserDataManager userDataManager, ILibraryManager libraryManager, IServerConfigurationManager config) { _userManager = userManager; _userDataManager = userDataManager; _libraryManager = libraryManager; + _config = config; } public QueryResult<BaseItem> GetNextUp(NextUpQuery request) @@ -32,16 +35,36 @@ namespace MediaBrowser.Server.Implementations.TV throw new ArgumentException("User not found"); } - var parentIds = string.IsNullOrEmpty(request.ParentId) - ? new string[] { } - : new[] { request.ParentId }; + var parentIdGuid = string.IsNullOrWhiteSpace(request.ParentId) ? (Guid?)null : new Guid(request.ParentId); + + string presentationUniqueKey = null; + int? limit = null; + if (!string.IsNullOrWhiteSpace(request.SeriesId)) + { + var series = _libraryManager.GetItemById(request.SeriesId); + + if (series != null) + { + presentationUniqueKey = GetUniqueSeriesKey(series); + limit = 1; + } + } + + if (string.IsNullOrWhiteSpace(presentationUniqueKey) && limit.HasValue) + { + limit = limit.Value + 10; + } var items = _libraryManager.GetItemList(new InternalItemsQuery(user) { IncludeItemTypes = new[] { typeof(Series).Name }, - SortOrder = SortOrder.Ascending + SortOrder = SortOrder.Ascending, + PresentationUniqueKey = presentationUniqueKey, + Limit = limit, + ParentId = parentIdGuid, + Recursive = true - }, parentIds).Cast<Series>(); + }).Cast<Series>(); // Avoid implicitly captured closure var episodes = GetNextUpEpisodes(request, user, items); @@ -58,10 +81,30 @@ 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 = GetUniqueSeriesKey(series); + limit = 1; + } + } + + if (string.IsNullOrWhiteSpace(presentationUniqueKey) && limit.HasValue) + { + limit = limit.Value + 10; + } + 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,32 +119,40 @@ namespace MediaBrowser.Server.Implementations.TV // Avoid implicitly captured closure var currentUser = user; - return FilterSeries(request, series) - .AsParallel() + var allNextUp = series .Select(i => GetNextUp(i, currentUser)) + .Where(i => i.Item1 != null) // 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 => i.Item2) + .ThenByDescending(i => i.Item1.PremiereDate ?? DateTime.MinValue) + .ToList(); - var seriesUserData = _userDataManager.GetUserData(user.Id, episode.Series.GetUserDataKey()); + // If viewing all next up for all series, remove first episodes + if (string.IsNullOrWhiteSpace(request.SeriesId)) + { + var withoutFirstEpisode = allNextUp + .Where(i => !i.Item3) + .ToList(); - if (seriesUserData.IsFavorite) - { - return 2; - } + // But if that returns empty, keep those first episodes (avoid completely empty view) + if (withoutFirstEpisode.Count > 0) + { + allNextUp = withoutFirstEpisode; + } + } - if (seriesUserData.Likes.HasValue) - { - return seriesUserData.Likes.Value ? 1 : -1; - } + return allNextUp + .Select(i => i.Item1) + .Take(request.Limit ?? int.MaxValue); + } - return 0; - }) - .ThenByDescending(i => i.Item2) - .ThenByDescending(i => i.Item1.PremiereDate ?? DateTime.MinValue) - .Select(i => i.Item1); + private string GetUniqueSeriesKey(BaseItem series) + { + if (_config.Configuration.SchemaVersion < 97) + { + return series.Id.ToString("N"); + } + return series.PresentationUniqueKey; } /// <summary> @@ -112,64 +163,43 @@ namespace MediaBrowser.Server.Implementations.TV /// <returns>Task{Episode}.</returns> private Tuple<Episode, DateTime, bool> GetNextUp(Series series, User user) { - // Get them in display order, then reverse - var allEpisodes = series.GetSeasons(user, true, true) - .Where(i => !i.IndexNumber.HasValue || i.IndexNumber.Value != 0) - .SelectMany(i => i.GetEpisodes(user)) - .Reverse() - .ToList(); - - Episode lastWatched = null; - var lastWatchedDate = DateTime.MinValue; - Episode nextUp = null; - - var includeMissing = user.Configuration.DisplayMissingEpisodes; - - // Go back starting with the most recent episodes - foreach (var episode in allEpisodes) + var lastWatchedEpisode = _libraryManager.GetItemList(new InternalItemsQuery(user) { - var userData = _userDataManager.GetUserData(user.Id, episode.GetUserDataKey()); + AncestorWithPresentationUniqueKey = GetUniqueSeriesKey(series), + IncludeItemTypes = new[] { typeof(Episode).Name }, + SortBy = new[] { ItemSortBy.SortName }, + SortOrder = SortOrder.Descending, + IsPlayed = true, + Limit = 1, + ParentIndexNumberNotEquals = 0 - if (userData.Played) - { - if (lastWatched != null || nextUp == null) - { - break; - } - - lastWatched = episode; - lastWatchedDate = userData.LastPlayedDate ?? DateTime.MinValue; - } - else - { - if (!episode.IsVirtualUnaired && (!episode.IsMissingEpisode || includeMissing)) - { - nextUp = episode; - } - } - } + }).FirstOrDefault(); - if (lastWatched != null) + var firstUnwatchedEpisode = _libraryManager.GetItemList(new InternalItemsQuery(user) { - return new Tuple<Episode, DateTime, bool>(nextUp, lastWatchedDate, false); - } - - var firstEpisode = allEpisodes.LastOrDefault(i => !i.IsVirtualUnaired && (!i.IsMissingEpisode || includeMissing) && !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)) + AncestorWithPresentationUniqueKey = GetUniqueSeriesKey(series), + IncludeItemTypes = new[] { typeof(Episode).Name }, + SortBy = new[] { ItemSortBy.SortName }, + SortOrder = SortOrder.Ascending, + Limit = 1, + IsPlayed = false, + IsVirtualItem = false, + ParentIndexNumberNotEquals = 0, + MinSortName = lastWatchedEpisode == null ? null : lastWatchedEpisode.SortName + + }).Cast<Episode>().FirstOrDefault(); + + if (lastWatchedEpisode != null && firstUnwatchedEpisode != null) { - var id = new Guid(request.SeriesId); + var userData = _userDataManager.GetUserData(user, lastWatchedEpisode); + + var lastWatchedDate = userData.LastPlayedDate ?? DateTime.MinValue.AddDays(1); - items = items.Where(i => i.Id == id); + return new Tuple<Episode, DateTime, bool>(firstUnwatchedEpisode, lastWatchedDate, false); } - return items; + // Return the first episode + return new Tuple<Episode, DateTime, bool>(firstUnwatchedEpisode, DateTime.MinValue, true); } private QueryResult<BaseItem> GetResult(IEnumerable<BaseItem> items, int? totalRecordLimit, NextUpQuery query) |
