From 27d898e59e5c225baa3db0ee114f1c4034b74e31 Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Sat, 29 Aug 2026 21:39:14 +0200 Subject: Count a season's episodes by the season they belong to --- .../Item/ItemCountService.cs | 31 +++++++++++++++++----- 1 file changed, 25 insertions(+), 6 deletions(-) (limited to 'Jellyfin.Server.Implementations') diff --git a/Jellyfin.Server.Implementations/Item/ItemCountService.cs b/Jellyfin.Server.Implementations/Item/ItemCountService.cs index c42b5f9581..14b120363f 100644 --- a/Jellyfin.Server.Implementations/Item/ItemCountService.cs +++ b/Jellyfin.Server.Implementations/Item/ItemCountService.cs @@ -319,7 +319,7 @@ public class ItemCountService : IItemCountService } /// - public Dictionary GetChildCountBatch(IReadOnlyList parentIds, Guid? userId) + public Dictionary GetChildCountBatch(IReadOnlyList parentIds, User? user) { ArgumentNullException.ThrowIfNull(parentIds); @@ -332,20 +332,32 @@ public class ItemCountService : IItemCountService var parentIdsArray = parentIds.ToArray(); + var includeVirtual = user is null || user.DisplayMissingEpisodes; + var hierarchicalCounts = dbContext.BaseItems - .Where(b => b.ParentId.HasValue) + .Where(b => b.ParentId.HasValue && !b.SeasonId.HasValue && (includeVirtual || !b.IsVirtualItem)) .WhereOneOrMany(parentIdsArray, b => b.ParentId!.Value) .GroupBy(b => b.ParentId!.Value) .Select(g => new { ParentId = g.Key, Count = g.Count() }) .ToDictionary(x => x.ParentId, x => x.Count); + // An episode is a child of its season even when it is not stored under one: with a flat + // structure ParentId points at the series, so counting by ParentId alone leaves the season + // empty and counts its episodes towards the series instead. + var seasonCounts = dbContext.BaseItems + .Where(b => b.SeasonId.HasValue && (includeVirtual || !b.IsVirtualItem)) + .WhereOneOrMany(parentIdsArray, b => b.SeasonId!.Value) + .GroupBy(b => b.SeasonId!.Value) + .Select(g => new { SeasonId = g.Key, Count = g.Count() }) + .ToDictionary(x => x.SeasonId, x => x.Count); + var linkedCounts = dbContext.LinkedChildren .WhereOneOrMany(parentIdsArray, lc => lc.ParentId) .GroupBy(lc => lc.ParentId) .Select(g => new { ParentId = g.Key, Count = g.Count() }) .ToDictionary(x => x.ParentId, x => x.Count); - var mergedChildCounts = GetMergedChildCounts(dbContext, parentIdsArray); + var mergedChildCounts = GetMergedChildCounts(dbContext, parentIdsArray, includeVirtual); var result = new Dictionary(); foreach (var parentId in parentIds) @@ -356,7 +368,8 @@ public class ItemCountService : IItemCountService continue; } - var hierarchicalCount = hierarchicalCounts.GetValueOrDefault(parentId, 0); + var hierarchicalCount = hierarchicalCounts.GetValueOrDefault(parentId, 0) + + seasonCounts.GetValueOrDefault(parentId, 0); var linkedCount = linkedCounts.GetValueOrDefault(parentId, 0); result[parentId] = linkedCount > 0 ? linkedCount : hierarchicalCount; @@ -365,7 +378,7 @@ public class ItemCountService : IItemCountService return result; } - private static Dictionary GetMergedChildCounts(JellyfinDbContext dbContext, IReadOnlyList parentIds) + private static Dictionary GetMergedChildCounts(JellyfinDbContext dbContext, IReadOnlyList parentIds, bool includeVirtual) { var mergedGroups = GetPresentationKeyGroups(dbContext, parentIds) .Where(group => group.Value.Count > 1) @@ -380,10 +393,16 @@ public class ItemCountService : IItemCountService var memberIds = mergedGroups.SelectMany(group => group.Value).Distinct().ToArray(); var children = dbContext.BaseItems .AsNoTracking() - .Where(b => b.ParentId.HasValue) + .Where(b => b.ParentId.HasValue && !b.SeasonId.HasValue && (includeVirtual || !b.IsVirtualItem)) .WhereOneOrMany(memberIds, b => b.ParentId!.Value) .Select(b => new { ParentId = b.ParentId!.Value, b.Id, b.PresentationUniqueKey }) .ToArray() + .Concat(dbContext.BaseItems + .AsNoTracking() + .Where(b => b.SeasonId.HasValue && (includeVirtual || !b.IsVirtualItem)) + .WhereOneOrMany(memberIds, b => b.SeasonId!.Value) + .Select(b => new { ParentId = b.SeasonId!.Value, b.Id, b.PresentationUniqueKey }) + .ToArray()) .GroupBy(b => b.ParentId) .ToDictionary( g => g.Key, -- cgit v1.2.3