diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs index cf886ae826..adeb889b72 100644 --- a/Emby.Server.Implementations/Dto/DtoService.cs +++ b/Emby.Server.Implementations/Dto/DtoService.cs @@ -102,21 +102,9 @@ namespace Emby.Server.Implementations.Dto (programTuples ??= []).Add((item, dto)); } - if (item is IItemByName byName) + if (item is IItemByName itemByName && options.ContainsField(ItemFields.ItemCounts)) { - if (options.ContainsField(ItemFields.ItemCounts)) - { - var libraryItems = byName.GetTaggedItems(new InternalItemsQuery(user) - { - Recursive = true, - DtoOptions = new DtoOptions(false) - { - EnableImages = false - } - }); - - SetItemByNameInfo(item, dto, libraryItems); - } + SetItemByNameInfo(itemByName, dto, user); } returnItems[index] = dto; @@ -147,34 +135,14 @@ namespace Emby.Server.Implementations.Dto LivetvManager.AddInfoToProgramDto(new[] { (item, dto) }, options.Fields, user).GetAwaiter().GetResult(); } - if (item is IItemByName itemByName - && options.ContainsField(ItemFields.ItemCounts)) + if (item is IItemByName itemByName && options.ContainsField(ItemFields.ItemCounts)) { - SetItemByNameInfo( - item, - dto, - GetTaggedItems( - itemByName, - user, - new DtoOptions(false) - { - EnableImages = false - })); + SetItemByNameInfo(itemByName, dto, user); } return dto; } - private static IReadOnlyList GetTaggedItems(IItemByName byName, User? user, DtoOptions options) - { - return byName.GetTaggedItems( - new InternalItemsQuery(user) - { - Recursive = true, - DtoOptions = options - }); - } - private BaseItemDto GetBaseItemDtoInternal(BaseItem item, DtoOptions options, User? user = null, BaseItem? owner = null) { var dto = new BaseItemDto @@ -319,14 +287,43 @@ namespace Emby.Server.Implementations.Dto { var dto = GetBaseItemDtoInternal(item, options, user); - if (taggedItems is not null && options.ContainsField(ItemFields.ItemCounts)) + if (options.ContainsField(ItemFields.ItemCounts)) { - SetItemByNameInfo(item, dto, taggedItems); + if (taggedItems is not null) + { + SetItemByNameInfo(item, dto, taggedItems!); + } + else if (item is IItemByName itemByName) + { + SetItemByNameInfo(itemByName, dto, user); + } } return dto; } + private static void SetItemByNameInfo(IItemByName item, BaseItemDto dto, User? user) + { + var query = new InternalItemsQuery(user) + { + Recursive = true, + DtoOptions = new DtoOptions(false) { EnableImages = false } + }; + + var counts = item.GetTaggedItemCounts(query); + + dto.AlbumCount = counts.AlbumCount; + dto.ArtistCount = counts.ArtistCount; + dto.EpisodeCount = counts.EpisodeCount; + dto.MovieCount = counts.MovieCount; + dto.MusicVideoCount = counts.MusicVideoCount; + dto.ProgramCount = counts.ProgramCount; + dto.SeriesCount = counts.SeriesCount; + dto.SongCount = counts.SongCount; + dto.TrailerCount = counts.TrailerCount; + dto.ChildCount = counts.ChildCount; + } + private static void SetItemByNameInfo(BaseItem item, BaseItemDto dto, IReadOnlyList taggedItems) { if (item is MusicArtist) diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs index 58841e5b78..cde4cd6b3e 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs @@ -98,6 +98,24 @@ namespace MediaBrowser.Controller.Entities.Audio return LibraryManager.GetItemList(query); } + public TaggedItemCounts GetTaggedItemCounts(InternalItemsQuery query) + { + query.ArtistIds = [Id]; + + var counts = new TaggedItemCounts(); + + query.IncludeItemTypes = [BaseItemKind.MusicAlbum]; + counts.AlbumCount = LibraryManager.GetCount(query); + + query.IncludeItemTypes = [BaseItemKind.MusicVideo]; + counts.MusicVideoCount = LibraryManager.GetCount(query); + + query.IncludeItemTypes = [BaseItemKind.Audio]; + counts.SongCount = LibraryManager.GetCount(query); + + return counts; + } + public override int GetChildCount(User user) { return IsAccessedByName ? 0 : base.GetChildCount(user); diff --git a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs index 65669e6804..9538e0cfaa 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs @@ -73,6 +73,27 @@ namespace MediaBrowser.Controller.Entities.Audio return LibraryManager.GetItemList(query); } + public TaggedItemCounts GetTaggedItemCounts(InternalItemsQuery query) + { + query.GenreIds = [Id]; + + var counts = new TaggedItemCounts(); + + query.IncludeItemTypes = [BaseItemKind.MusicAlbum]; + counts.AlbumCount = LibraryManager.GetCount(query); + + query.IncludeItemTypes = [BaseItemKind.MusicArtist]; + counts.ArtistCount = LibraryManager.GetCount(query); + + query.IncludeItemTypes = [BaseItemKind.MusicVideo]; + counts.MusicVideoCount = LibraryManager.GetCount(query); + + query.IncludeItemTypes = [BaseItemKind.Audio]; + counts.SongCount = LibraryManager.GetCount(query); + + return counts; + } + public static string GetPath(string name) { return GetPath(name, true); diff --git a/MediaBrowser.Controller/Entities/Genre.cs b/MediaBrowser.Controller/Entities/Genre.cs index 6ec78a270e..20fab93b2d 100644 --- a/MediaBrowser.Controller/Entities/Genre.cs +++ b/MediaBrowser.Controller/Entities/Genre.cs @@ -76,6 +76,37 @@ namespace MediaBrowser.Controller.Entities return LibraryManager.GetItemList(query); } + public TaggedItemCounts GetTaggedItemCounts(InternalItemsQuery query) + { + query.GenreIds = [Id]; + query.ExcludeItemTypes = + [ + BaseItemKind.MusicVideo, + BaseItemKind.Audio, + BaseItemKind.MusicAlbum, + BaseItemKind.MusicArtist + ]; + + var counts = new TaggedItemCounts(); + + query.IncludeItemTypes = [BaseItemKind.Episode]; + counts.EpisodeCount = LibraryManager.GetCount(query); + + query.IncludeItemTypes = [BaseItemKind.Movie]; + counts.MovieCount = LibraryManager.GetCount(query); + + query.IncludeItemTypes = [BaseItemKind.LiveTvProgram]; + counts.ProgramCount = LibraryManager.GetCount(query); + + query.IncludeItemTypes = [BaseItemKind.Series]; + counts.SeriesCount = LibraryManager.GetCount(query); + + query.IncludeItemTypes = [BaseItemKind.Trailer]; + counts.TrailerCount = LibraryManager.GetCount(query); + + return counts; + } + public static string GetPath(string name) { return GetPath(name, true); diff --git a/MediaBrowser.Controller/Entities/IItemByName.cs b/MediaBrowser.Controller/Entities/IItemByName.cs index 4928bda7a2..3e79e3f00a 100644 --- a/MediaBrowser.Controller/Entities/IItemByName.cs +++ b/MediaBrowser.Controller/Entities/IItemByName.cs @@ -10,10 +10,35 @@ namespace MediaBrowser.Controller.Entities public interface IItemByName { IReadOnlyList GetTaggedItems(InternalItemsQuery query); + + TaggedItemCounts GetTaggedItemCounts(InternalItemsQuery query); } public interface IHasDualAccess : IItemByName { bool IsAccessedByName { get; } } + + public class TaggedItemCounts + { + public int? AlbumCount { get; set; } + + public int? ArtistCount { get; set; } + + public int? EpisodeCount { get; set; } + + public int? MovieCount { get; set; } + + public int? MusicVideoCount { get; set; } + + public int? ProgramCount { get; set; } + + public int? SeriesCount { get; set; } + + public int? SongCount { get; set; } + + public int? TrailerCount { get; set; } + + public int ChildCount => (AlbumCount ?? 0) + (ArtistCount ?? 0) + (EpisodeCount ?? 0) + (MovieCount ?? 0) + (MusicVideoCount ?? 0) + (ProgramCount ?? 0) + (SeriesCount ?? 0) + (SongCount ?? 0) + (TrailerCount ?? 0); + } } diff --git a/MediaBrowser.Controller/Entities/Person.cs b/MediaBrowser.Controller/Entities/Person.cs index 5cc4d322f7..d4158655bf 100644 --- a/MediaBrowser.Controller/Entities/Person.cs +++ b/MediaBrowser.Controller/Entities/Person.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Text.Json.Serialization; +using Jellyfin.Data.Enums; using Jellyfin.Extensions; using MediaBrowser.Controller.Providers; using Microsoft.Extensions.Logging; @@ -70,6 +71,43 @@ namespace MediaBrowser.Controller.Entities return LibraryManager.GetItemList(query); } + public TaggedItemCounts GetTaggedItemCounts(InternalItemsQuery query) + { + query.PersonIds = [Id]; + + var counts = new TaggedItemCounts(); + + // TODO: Remove MusicAlbum and MusicArtist when the relationship between Persons and Music is removed + query.IncludeItemTypes = [BaseItemKind.MusicAlbum]; + counts.AlbumCount = LibraryManager.GetCount(query); + + query.IncludeItemTypes = [BaseItemKind.MusicArtist]; + counts.ArtistCount = LibraryManager.GetCount(query); + + query.IncludeItemTypes = [BaseItemKind.Episode]; + counts.EpisodeCount = LibraryManager.GetCount(query); + + query.IncludeItemTypes = [BaseItemKind.Movie]; + counts.MovieCount = LibraryManager.GetCount(query); + + query.IncludeItemTypes = [BaseItemKind.MusicVideo]; + counts.MusicVideoCount = LibraryManager.GetCount(query); + + query.IncludeItemTypes = [BaseItemKind.LiveTvProgram]; + counts.ProgramCount = LibraryManager.GetCount(query); + + query.IncludeItemTypes = [BaseItemKind.Series]; + counts.SeriesCount = LibraryManager.GetCount(query); + + query.IncludeItemTypes = [BaseItemKind.Audio]; + counts.SongCount = LibraryManager.GetCount(query); + + query.IncludeItemTypes = [BaseItemKind.Trailer]; + counts.TrailerCount = LibraryManager.GetCount(query); + + return counts; + } + public override bool CanDelete() { return false; diff --git a/MediaBrowser.Controller/Entities/Studio.cs b/MediaBrowser.Controller/Entities/Studio.cs index 9103b09a95..a44b32d85b 100644 --- a/MediaBrowser.Controller/Entities/Studio.cs +++ b/MediaBrowser.Controller/Entities/Studio.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Text.Json.Serialization; +using Jellyfin.Data.Enums; using Jellyfin.Extensions; using Microsoft.Extensions.Logging; @@ -71,6 +72,42 @@ namespace MediaBrowser.Controller.Entities return LibraryManager.GetItemList(query); } + public TaggedItemCounts GetTaggedItemCounts(InternalItemsQuery query) + { + query.StudioIds = [Id]; + + var counts = new TaggedItemCounts(); + + query.IncludeItemTypes = [BaseItemKind.MusicAlbum]; + counts.AlbumCount = LibraryManager.GetCount(query); + + query.IncludeItemTypes = [BaseItemKind.MusicArtist]; + counts.ArtistCount = LibraryManager.GetCount(query); + + query.IncludeItemTypes = [BaseItemKind.Episode]; + counts.EpisodeCount = LibraryManager.GetCount(query); + + query.IncludeItemTypes = [BaseItemKind.Movie]; + counts.MovieCount = LibraryManager.GetCount(query); + + query.IncludeItemTypes = [BaseItemKind.MusicVideo]; + counts.MusicVideoCount = LibraryManager.GetCount(query); + + query.IncludeItemTypes = [BaseItemKind.LiveTvProgram]; + counts.ProgramCount = LibraryManager.GetCount(query); + + query.IncludeItemTypes = [BaseItemKind.Series]; + counts.SeriesCount = LibraryManager.GetCount(query); + + query.IncludeItemTypes = [BaseItemKind.Audio]; + counts.SongCount = LibraryManager.GetCount(query); + + query.IncludeItemTypes = [BaseItemKind.Trailer]; + counts.TrailerCount = LibraryManager.GetCount(query); + + return counts; + } + public static string GetPath(string name) { return GetPath(name, true); diff --git a/MediaBrowser.Controller/Entities/Year.cs b/MediaBrowser.Controller/Entities/Year.cs index 37820296cc..a1ff9f4d4b 100644 --- a/MediaBrowser.Controller/Entities/Year.cs +++ b/MediaBrowser.Controller/Entities/Year.cs @@ -6,6 +6,7 @@ using System; using System.Collections.Generic; using System.Globalization; using System.Text.Json.Serialization; +using Jellyfin.Data.Enums; using Microsoft.Extensions.Logging; namespace MediaBrowser.Controller.Entities @@ -68,6 +69,47 @@ namespace MediaBrowser.Controller.Entities return LibraryManager.GetItemList(query); } + public TaggedItemCounts GetTaggedItemCounts(InternalItemsQuery query) + { + if (!int.TryParse(Name, NumberStyles.Integer, CultureInfo.InvariantCulture, out var year)) + { + return new TaggedItemCounts(); + } + + query.Years = [year]; + + var counts = new TaggedItemCounts(); + + query.IncludeItemTypes = [BaseItemKind.MusicAlbum]; + counts.AlbumCount = LibraryManager.GetCount(query); + + query.IncludeItemTypes = [BaseItemKind.MusicArtist]; + counts.ArtistCount = LibraryManager.GetCount(query); + + query.IncludeItemTypes = [BaseItemKind.Episode]; + counts.EpisodeCount = LibraryManager.GetCount(query); + + query.IncludeItemTypes = [BaseItemKind.Movie]; + counts.MovieCount = LibraryManager.GetCount(query); + + query.IncludeItemTypes = [BaseItemKind.MusicVideo]; + counts.MusicVideoCount = LibraryManager.GetCount(query); + + query.IncludeItemTypes = [BaseItemKind.LiveTvProgram]; + counts.ProgramCount = LibraryManager.GetCount(query); + + query.IncludeItemTypes = [BaseItemKind.Series]; + counts.SeriesCount = LibraryManager.GetCount(query); + + query.IncludeItemTypes = [BaseItemKind.Audio]; + counts.SongCount = LibraryManager.GetCount(query); + + query.IncludeItemTypes = [BaseItemKind.Trailer]; + counts.TrailerCount = LibraryManager.GetCount(query); + + return counts; + } + public int? GetYearValue() { if (int.TryParse(Name, NumberStyles.Integer, CultureInfo.InvariantCulture, out var year))