diff options
5 files changed, 90 insertions, 0 deletions
diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 27f682668..eb8e31072 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -1364,6 +1364,21 @@ namespace Emby.Server.Implementations.Library return _itemRepository.GetItemList(query); } + public IReadOnlyList<BaseItem> GetLatestItemList(InternalItemsQuery query, IReadOnlyList<BaseItem> parents, CollectionType collectionType) + { + SetTopParentIdsOrAncestors(query, parents); + + if (query.AncestorIds.Length == 0 && query.TopParentIds.Length == 0) + { + if (query.User is not null) + { + AddUserToQuery(query, query.User); + } + } + + return _itemRepository.GetLatestItemList(query, collectionType); + } + public IReadOnlyList<string> GetNextUpSeriesKeys(InternalItemsQuery query, IReadOnlyCollection<BaseItem> parents, DateTime dateCutoff) { SetTopParentIdsOrAncestors(query, parents); diff --git a/Emby.Server.Implementations/Library/UserViewManager.cs b/Emby.Server.Implementations/Library/UserViewManager.cs index 5a9315a92..87214c273 100644 --- a/Emby.Server.Implementations/Library/UserViewManager.cs +++ b/Emby.Server.Implementations/Library/UserViewManager.cs @@ -372,6 +372,21 @@ namespace Emby.Server.Implementations.Library MediaTypes = mediaTypes }; + if (request.GroupItems) + { + if (parents.OfType<ICollectionFolder>().All(i => i.CollectionType == CollectionType.tvshows)) + { + query.Limit = limit; + return _libraryManager.GetLatestItemList(query, parents, CollectionType.tvshows); + } + + if (parents.OfType<ICollectionFolder>().All(i => i.CollectionType == CollectionType.music)) + { + query.Limit = limit; + return _libraryManager.GetLatestItemList(query, parents, CollectionType.music); + } + } + return _libraryManager.GetItemList(query, parents); } } diff --git a/Jellyfin.Server.Implementations/Item/BaseItemRepository.cs b/Jellyfin.Server.Implementations/Item/BaseItemRepository.cs index 4f6902244..7b5b6b94d 100644 --- a/Jellyfin.Server.Implementations/Item/BaseItemRepository.cs +++ b/Jellyfin.Server.Implementations/Item/BaseItemRepository.cs @@ -264,6 +264,48 @@ public sealed class BaseItemRepository return dbQuery.AsEnumerable().Where(e => e is not null).Select(w => DeserialiseBaseItem(w, filter.SkipDeserialization)).ToArray(); } + /// <inheritdoc/> + public IReadOnlyList<BaseItem> GetLatestItemList(InternalItemsQuery filter, CollectionType collectionType) + { + ArgumentNullException.ThrowIfNull(filter); + PrepareFilterQuery(filter); + + // Early exit if collection type is not tvshows or music + if (collectionType != CollectionType.tvshows && collectionType != CollectionType.music) + { + return Array.Empty<BaseItem>(); + } + + using var context = _dbProvider.CreateDbContext(); + + // Subquery to group by SeriesNames/Album and get the max Date Created for each group. + var subquery = PrepareItemQuery(context, filter); + subquery = TranslateQuery(subquery, context, filter); + var subqueryGrouped = subquery.GroupBy(g => collectionType == CollectionType.tvshows ? g.SeriesName : g.Album) + .Select(g => new + { + Key = g.Key, + MaxDateCreated = g.Max(a => a.DateCreated) + }) + .OrderByDescending(g => g.MaxDateCreated) + .Select(g => g); + + if (filter.Limit.HasValue) + { + subqueryGrouped = subqueryGrouped.Take(filter.Limit.Value); + } + + filter.Limit = null; + + var mainquery = PrepareItemQuery(context, filter); + mainquery = TranslateQuery(mainquery, context, filter); + mainquery = mainquery.Where(g => g.DateCreated >= subqueryGrouped.Min(s => s.MaxDateCreated)); + mainquery = ApplyGroupingFilter(mainquery, filter); + mainquery = ApplyQueryPaging(mainquery, filter); + + return mainquery.AsEnumerable().Where(e => e is not null).Select(w => DeserialiseBaseItem(w, filter.SkipDeserialization)).ToArray(); + } + /// <inheritdoc /> public IReadOnlyList<string> GetNextUpSeriesKeys(InternalItemsQuery filter, DateTime dateCutoff) { diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index a3e3e4991..df90f546c 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -568,6 +568,15 @@ namespace MediaBrowser.Controller.Library IReadOnlyList<BaseItem> GetItemList(InternalItemsQuery query, List<BaseItem> parents); /// <summary> + /// Gets the TVShow/Album items for Latest api. + /// </summary> + /// <param name="query">The query to use.</param> + /// <param name="parents">Items to use for query.</param> + /// <param name="collectionType">Collection Type.</param> + /// <returns>List of items.</returns> + IReadOnlyList<BaseItem> GetLatestItemList(InternalItemsQuery query, IReadOnlyList<BaseItem> parents, CollectionType collectionType); + + /// <summary> /// Gets the list of series presentation keys for next up. /// </summary> /// <param name="query">The query to use.</param> diff --git a/MediaBrowser.Controller/Persistence/IItemRepository.cs b/MediaBrowser.Controller/Persistence/IItemRepository.cs index f1ed4fe27..e185898bf 100644 --- a/MediaBrowser.Controller/Persistence/IItemRepository.cs +++ b/MediaBrowser.Controller/Persistence/IItemRepository.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Threading; +using Jellyfin.Data.Enums; using MediaBrowser.Controller.Entities; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Querying; @@ -60,6 +61,14 @@ public interface IItemRepository IReadOnlyList<BaseItem> GetItemList(InternalItemsQuery filter); /// <summary> + /// Gets the item list. Used mainly by the Latest api endpoint. + /// </summary> + /// <param name="filter">The query.</param> + /// <param name="collectionType">Collection Type.</param> + /// <returns>List<BaseItem>.</returns> + IReadOnlyList<BaseItem> GetLatestItemList(InternalItemsQuery filter, CollectionType collectionType); + + /// <summary> /// Gets the list of series presentation keys for next up. /// </summary> /// <param name="filter">The query.</param> |
