aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJQ <81431263+scampower3@users.noreply.github.com>2025-03-27 10:26:47 +0800
committerGitHub <noreply@github.com>2025-03-26 20:26:47 -0600
commitd06ce1f1e035d4630121f45dcadbdebc95cb07e2 (patch)
tree231b0acda3903f266acdca4a42eaaaf6a18af0b2
parentcafb7cd002e4214643dcdb5e5592d6c5a811ca1c (diff)
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
-rw-r--r--Emby.Server.Implementations/Library/LibraryManager.cs15
-rw-r--r--Emby.Server.Implementations/Library/UserViewManager.cs15
-rw-r--r--Jellyfin.Server.Implementations/Item/BaseItemRepository.cs42
-rw-r--r--MediaBrowser.Controller/Library/ILibraryManager.cs9
-rw-r--r--MediaBrowser.Controller/Persistence/IItemRepository.cs9
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&lt;BaseItem&gt;.</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>