2
0
Эх сурвалжийг харах

Fix only returning one item from /Item/Latest api. (#12492)

* Updated to EFcore

* Remove unused using

* Dont use DateCreated not from episode type or music type

* use TranslateQuery to filter out instead and then do the grouping and retrival of min and max datecreated instead

* Album also
JQ 2 сар өмнө
parent
commit
d06ce1f1e0

+ 15 - 0
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);

+ 15 - 0
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);
         }
     }

+ 42 - 0
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)
     {

+ 9 - 0
MediaBrowser.Controller/Library/ILibraryManager.cs

@@ -567,6 +567,15 @@ namespace MediaBrowser.Controller.Library
         /// <returns>List of items.</returns>
         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>

+ 9 - 0
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;
@@ -59,6 +60,14 @@ public interface IItemRepository
     /// <returns>List&lt;BaseItem&gt;.</returns>
     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&lt;BaseItem&gt;.</returns>
+    IReadOnlyList<BaseItem> GetLatestItemList(InternalItemsQuery filter, CollectionType collectionType);
+
     /// <summary>
     /// Gets the list of series presentation keys for next up.
     /// </summary>