diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index 43a1b9eaa1..5faf85b2a0 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -46,6 +46,7 @@ namespace MediaBrowser.Controller.Entities public string NameStartsWith { get; set; } public string NameLessThan { get; set; } public string NameContains { get; set; } + public string MinSortName { get; set; } public string PresentationUniqueKey { get; set; } public string Path { get; set; } diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 096cdf880e..d0c351c5df 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -2663,6 +2663,12 @@ namespace MediaBrowser.Server.Implementations.Persistence cmd.Parameters.Add(cmd, "@SlugName", DbType.String).Value = query.SlugName; } + if (!string.IsNullOrWhiteSpace(query.MinSortName)) + { + whereClauses.Add("SortName>=@MinSortName"); + cmd.Parameters.Add(cmd, "@MinSortName", DbType.String).Value = query.MinSortName; + } + if (!string.IsNullOrWhiteSpace(query.Name)) { whereClauses.Add("CleanName=@Name"); @@ -3773,7 +3779,8 @@ namespace MediaBrowser.Server.Implementations.Persistence } else { - whereText += " And itemTypes not null"; + //whereText += " And itemTypes not null"; + whereText += " And CleanName In (Select CleanValue from ItemValues where Type=@ItemValueType AND ItemId in (select guid from TypedBaseItems" + innerWhereText + "))"; } var outerQuery = new InternalItemsQuery(query.User) @@ -3855,7 +3862,7 @@ namespace MediaBrowser.Server.Implementations.Persistence ? (CommandBehavior.SequentialAccess | CommandBehavior.SingleResult) : CommandBehavior.SequentialAccess; - //Logger.Debug("GetItemValues: " + cmd.CommandText); + Logger.Debug("GetItemValues: " + cmd.CommandText); using (var reader = cmd.ExecuteReader(commandBehavior)) { diff --git a/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs b/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs index 82232ffae0..ba6534a7c3 100644 --- a/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs +++ b/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs @@ -107,7 +107,6 @@ namespace MediaBrowser.Server.Implementations.TV var currentUser = user; 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))) @@ -124,6 +123,19 @@ namespace MediaBrowser.Server.Implementations.TV /// Task{Episode}. private Tuple GetNextUp(Series series, User user) { + var lastWatchedEpisode = _libraryManager.GetItemList(new InternalItemsQuery(user) + { + AncestorWithPresentationUniqueKey = series.PresentationUniqueKey, + IncludeItemTypes = new[] { typeof(Episode).Name }, + SortBy = new[] { ItemSortBy.SortName }, + SortOrder = SortOrder.Descending, + IsPlayed = true, + Limit = 1, + IsVirtualItem = false, + ParentIndexNumberNotEquals = 0 + + }).FirstOrDefault(); + var firstUnwatchedEpisode = _libraryManager.GetItemList(new InternalItemsQuery(user) { AncestorWithPresentationUniqueKey = series.PresentationUniqueKey, @@ -133,59 +145,11 @@ namespace MediaBrowser.Server.Implementations.TV Limit = 1, IsPlayed = false, IsVirtualItem = false, - ParentIndexNumberNotEquals = 0 + ParentIndexNumberNotEquals = 0, + MinSortName = lastWatchedEpisode == null ? null : lastWatchedEpisode.SortName }).Cast().FirstOrDefault(); - // series is fully played - if (firstUnwatchedEpisode == null) - { - return new Tuple(null, DateTime.MinValue, true); - } - - var lastWatchedEpisode = _libraryManager.GetItemList(new InternalItemsQuery(user) - { - AncestorWithPresentationUniqueKey = series.PresentationUniqueKey, - IncludeItemTypes = new[] { typeof(Episode).Name }, - SortBy = new[] { ItemSortBy.DatePlayed }, - SortOrder = SortOrder.Descending, - Limit = 1, - IsVirtualItem = false, - ParentIndexNumberNotEquals = 0 - - }).FirstOrDefault(); - - //// Get them in display order, then reverse - //var allEpisodes = series.GetEpisodes(user, false, false) - // .Where(i => !i.ParentIndexNumber.HasValue || i.ParentIndexNumber.Value != 0) - // .Reverse() - // .ToList(); - - //Episode lastWatched = null; - //var lastWatchedDate = DateTime.MinValue; - //Episode nextUp = null; - - //// Go back starting with the most recent episodes - //foreach (var episode in allEpisodes) - //{ - // var userData = _userDataManager.GetUserData(user, episode); - - // if (userData.Played) - // { - // if (lastWatched != null || nextUp == null) - // { - // break; - // } - - // lastWatched = episode; - // lastWatchedDate = userData.LastPlayedDate ?? DateTime.MinValue; - // } - // else - // { - // nextUp = episode; - // } - //} - if (lastWatchedEpisode != null) { var userData = _userDataManager.GetUserData(user, lastWatchedEpisode);