aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Controller/Entities/UserViewBuilder.cs
diff options
context:
space:
mode:
authorShadowghost <Ghost_of_Stone@web.de>2026-01-17 17:10:07 +0100
committerShadowghost <Ghost_of_Stone@web.de>2026-01-18 19:48:46 +0100
commit5996c4afce11249804d24f1caa3a99b390543c4d (patch)
treed84b98428d95c801492b1354571e2ab3fc0cc99b /MediaBrowser.Controller/Entities/UserViewBuilder.cs
parentdfa78590c2899c7e74b142ebbced4140a354aed0 (diff)
Complete LinkedChildren integration and batch DTO optimizations
This commit integrates remaining performance changes: - Add batch user data fetching in DtoService to reduce N+1 queries - Add GetNextUpEpisodesBatch in TVSeriesManager for efficient batch retrieval - Update Video/Movie/BoxSet to use LibraryManager for alternate versions - Transition LinkedChild to use ItemId instead of Path (obsolete Path/LibraryItemId) - Update providers and controllers for LinkedChildren-based references - Add NextUpEpisodeBatchResult for batched episode queries - Integrate IDescendantQueryProvider in SqliteDatabaseProvider
Diffstat (limited to 'MediaBrowser.Controller/Entities/UserViewBuilder.cs')
-rw-r--r--MediaBrowser.Controller/Entities/UserViewBuilder.cs243
1 files changed, 27 insertions, 216 deletions
diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
index bed7554b19..47d732c745 100644
--- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs
+++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
@@ -16,9 +16,7 @@ using MediaBrowser.Controller.TV;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Querying;
using Microsoft.Extensions.Logging;
-using Episode = MediaBrowser.Controller.Entities.TV.Episode;
using MetadataProvider = MediaBrowser.Model.Entities.MetadataProvider;
-using Series = MediaBrowser.Controller.Entities.TV.Series;
namespace MediaBrowser.Controller.Entities
{
@@ -140,7 +138,7 @@ namespace MediaBrowser.Controller.Entities
if (query.IncludeItemTypes.Length == 0)
{
- query.IncludeItemTypes = new[] { BaseItemKind.Movie };
+ query.IncludeItemTypes = [BaseItemKind.Movie];
}
return parent.QueryRecursive(query);
@@ -165,7 +163,7 @@ namespace MediaBrowser.Controller.Entities
query.Parent = parent;
query.SetUser(user);
query.IsFavorite = true;
- query.IncludeItemTypes = new[] { BaseItemKind.Movie };
+ query.IncludeItemTypes = [BaseItemKind.Movie];
return _libraryManager.GetItemsResult(query);
}
@@ -176,7 +174,7 @@ namespace MediaBrowser.Controller.Entities
query.Parent = parent;
query.SetUser(user);
query.IsFavorite = true;
- query.IncludeItemTypes = new[] { BaseItemKind.Series };
+ query.IncludeItemTypes = [BaseItemKind.Series];
return _libraryManager.GetItemsResult(query);
}
@@ -187,7 +185,7 @@ namespace MediaBrowser.Controller.Entities
query.Parent = parent;
query.SetUser(user);
query.IsFavorite = true;
- query.IncludeItemTypes = new[] { BaseItemKind.Episode };
+ query.IncludeItemTypes = [BaseItemKind.Episode];
return _libraryManager.GetItemsResult(query);
}
@@ -198,7 +196,7 @@ namespace MediaBrowser.Controller.Entities
query.Parent = parent;
query.SetUser(user);
- query.IncludeItemTypes = new[] { BaseItemKind.Movie };
+ query.IncludeItemTypes = [BaseItemKind.Movie];
return _libraryManager.GetItemsResult(query);
}
@@ -206,7 +204,7 @@ namespace MediaBrowser.Controller.Entities
private QueryResult<BaseItem> GetMovieCollections(User user, InternalItemsQuery query)
{
query.Parent = null;
- query.IncludeItemTypes = new[] { BaseItemKind.BoxSet };
+ query.IncludeItemTypes = [BaseItemKind.BoxSet];
query.SetUser(user);
query.Recursive = true;
@@ -215,25 +213,25 @@ namespace MediaBrowser.Controller.Entities
private QueryResult<BaseItem> GetMovieLatest(Folder parent, User user, InternalItemsQuery query)
{
- query.OrderBy = new[] { (ItemSortBy.DateCreated, SortOrder.Descending), (ItemSortBy.SortName, SortOrder.Descending) };
+ query.OrderBy = [(ItemSortBy.DateCreated, SortOrder.Descending), (ItemSortBy.SortName, SortOrder.Descending)];
query.Recursive = true;
query.Parent = parent;
query.SetUser(user);
query.Limit = GetSpecialItemsLimit();
- query.IncludeItemTypes = new[] { BaseItemKind.Movie };
+ query.IncludeItemTypes = [BaseItemKind.Movie];
return ConvertToResult(_libraryManager.GetItemList(query));
}
private QueryResult<BaseItem> GetMovieResume(Folder parent, User user, InternalItemsQuery query)
{
- query.OrderBy = new[] { (ItemSortBy.DatePlayed, SortOrder.Descending), (ItemSortBy.SortName, SortOrder.Descending) };
+ query.OrderBy = [(ItemSortBy.DatePlayed, SortOrder.Descending), (ItemSortBy.SortName, SortOrder.Descending)];
query.IsResumable = true;
query.Recursive = true;
query.Parent = parent;
query.SetUser(user);
query.Limit = GetSpecialItemsLimit();
- query.IncludeItemTypes = new[] { BaseItemKind.Movie };
+ query.IncludeItemTypes = [BaseItemKind.Movie];
return ConvertToResult(_libraryManager.GetItemList(query));
}
@@ -247,7 +245,7 @@ namespace MediaBrowser.Controller.Entities
{
var genres = parent.QueryRecursive(new InternalItemsQuery(user)
{
- IncludeItemTypes = new[] { BaseItemKind.Movie },
+ IncludeItemTypes = [BaseItemKind.Movie],
Recursive = true,
EnableTotalRecordCount = false
}).Items
@@ -275,10 +273,10 @@ namespace MediaBrowser.Controller.Entities
{
query.Recursive = true;
query.Parent = queryParent;
- query.GenreIds = new[] { displayParent.Id };
+ query.GenreIds = [displayParent.Id];
query.SetUser(user);
- query.IncludeItemTypes = new[] { BaseItemKind.Movie };
+ query.IncludeItemTypes = [BaseItemKind.Movie];
return _libraryManager.GetItemsResult(query);
}
@@ -292,12 +290,12 @@ namespace MediaBrowser.Controller.Entities
if (query.IncludeItemTypes.Length == 0)
{
- query.IncludeItemTypes = new[]
- {
+ query.IncludeItemTypes =
+ [
BaseItemKind.Series,
BaseItemKind.Season,
BaseItemKind.Episode
- };
+ ];
}
return parent.QueryRecursive(query);
@@ -319,12 +317,12 @@ namespace MediaBrowser.Controller.Entities
private QueryResult<BaseItem> GetTvLatest(Folder parent, User user, InternalItemsQuery query)
{
- query.OrderBy = new[] { (ItemSortBy.DateCreated, SortOrder.Descending), (ItemSortBy.SortName, SortOrder.Descending) };
+ query.OrderBy = [(ItemSortBy.DateCreated, SortOrder.Descending), (ItemSortBy.SortName, SortOrder.Descending)];
query.Recursive = true;
query.Parent = parent;
query.SetUser(user);
query.Limit = GetSpecialItemsLimit();
- query.IncludeItemTypes = new[] { BaseItemKind.Episode };
+ query.IncludeItemTypes = [BaseItemKind.Episode];
query.IsVirtualItem = false;
return ConvertToResult(_libraryManager.GetItemList(query));
@@ -332,7 +330,7 @@ namespace MediaBrowser.Controller.Entities
private QueryResult<BaseItem> GetTvNextUp(Folder parent, InternalItemsQuery query)
{
- var parentFolders = GetMediaFolders(parent, query.User, new[] { CollectionType.tvshows });
+ var parentFolders = GetMediaFolders(parent, query.User, [CollectionType.tvshows]);
var result = _tvSeriesManager.GetNextUp(
new NextUpQuery
@@ -349,13 +347,13 @@ namespace MediaBrowser.Controller.Entities
private QueryResult<BaseItem> GetTvResume(Folder parent, User user, InternalItemsQuery query)
{
- query.OrderBy = new[] { (ItemSortBy.DatePlayed, SortOrder.Descending), (ItemSortBy.SortName, SortOrder.Descending) };
+ query.OrderBy = [(ItemSortBy.DatePlayed, SortOrder.Descending), (ItemSortBy.SortName, SortOrder.Descending)];
query.IsResumable = true;
query.Recursive = true;
query.Parent = parent;
query.SetUser(user);
query.Limit = GetSpecialItemsLimit();
- query.IncludeItemTypes = new[] { BaseItemKind.Episode };
+ query.IncludeItemTypes = [BaseItemKind.Episode];
return ConvertToResult(_libraryManager.GetItemList(query));
}
@@ -366,7 +364,7 @@ namespace MediaBrowser.Controller.Entities
query.Parent = parent;
query.SetUser(user);
- query.IncludeItemTypes = new[] { BaseItemKind.Series };
+ query.IncludeItemTypes = [BaseItemKind.Series];
return _libraryManager.GetItemsResult(query);
}
@@ -375,7 +373,7 @@ namespace MediaBrowser.Controller.Entities
{
var genres = parent.QueryRecursive(new InternalItemsQuery(user)
{
- IncludeItemTypes = new[] { BaseItemKind.Series },
+ IncludeItemTypes = [BaseItemKind.Series],
Recursive = true,
EnableTotalRecordCount = false
}).Items
@@ -403,10 +401,10 @@ namespace MediaBrowser.Controller.Entities
{
query.Recursive = true;
query.Parent = queryParent;
- query.GenreIds = new[] { displayParent.Id };
+ query.GenreIds = [displayParent.Id];
query.SetUser(user);
- query.IncludeItemTypes = new[] { BaseItemKind.Series };
+ query.IncludeItemTypes = [BaseItemKind.Series];
return _libraryManager.GetItemsResult(query);
}
@@ -418,7 +416,7 @@ namespace MediaBrowser.Controller.Entities
{
items = items.Where(i => Filter(i, query.User, query, _userDataManager, _libraryManager));
- return PostFilterAndSort(items, null, query, _libraryManager);
+ return SortAndPage(items, null, query, _libraryManager);
}
public static bool FilterItem(BaseItem item, InternalItemsQuery query)
@@ -426,21 +424,6 @@ namespace MediaBrowser.Controller.Entities
return Filter(item, query.User, query, BaseItem.UserDataManager, BaseItem.LibraryManager);
}
- public static QueryResult<BaseItem> PostFilterAndSort(
- IEnumerable<BaseItem> items,
- int? totalRecordLimit,
- InternalItemsQuery query,
- ILibraryManager libraryManager)
- {
- // This must be the last filter
- if (!query.AdjacentTo.IsNullOrEmpty())
- {
- items = FilterForAdjacency(items.ToList(), query.AdjacentTo.Value);
- }
-
- return SortAndPage(items, totalRecordLimit, query, libraryManager);
- }
-
public static QueryResult<BaseItem> SortAndPage(
IEnumerable<BaseItem> items,
int? totalRecordLimit,
@@ -556,38 +539,6 @@ namespace MediaBrowser.Controller.Entities
}
}
- if (query.IsPlayed.HasValue)
- {
- userData ??= userDataManager.GetUserData(user, item);
- if (item.IsPlayed(user, userData) != query.IsPlayed.Value)
- {
- return false;
- }
- }
-
- // Filter by Video3DFormat
- if (query.Is3D.HasValue)
- {
- var val = query.Is3D.Value;
- var video = item as Video;
-
- if (video is null || val != video.Video3DFormat.HasValue)
- {
- return false;
- }
- }
-
- /*
- * fuck - fix this
- if (query.IsHD.HasValue)
- {
- if (item.IsHD != query.IsHD.Value)
- {
- return false;
- }
- }
- */
-
if (query.IsLocked.HasValue)
{
var val = query.IsLocked.Value;
@@ -645,68 +596,6 @@ namespace MediaBrowser.Controller.Entities
}
}
- if (query.HasOfficialRating.HasValue)
- {
- var filterValue = query.HasOfficialRating.Value;
-
- var hasValue = !string.IsNullOrEmpty(item.OfficialRating);
-
- if (hasValue != filterValue)
- {
- return false;
- }
- }
-
- if (query.IsPlaceHolder.HasValue)
- {
- var filterValue = query.IsPlaceHolder.Value;
-
- var isPlaceHolder = false;
-
- if (item is ISupportsPlaceHolders hasPlaceHolder)
- {
- isPlaceHolder = hasPlaceHolder.IsPlaceHolder;
- }
-
- if (isPlaceHolder != filterValue)
- {
- return false;
- }
- }
-
- if (query.HasSpecialFeature.HasValue)
- {
- var filterValue = query.HasSpecialFeature.Value;
-
- if (item is IHasSpecialFeatures movie)
- {
- var ok = filterValue
- ? movie.SpecialFeatureIds.Count > 0
- : movie.SpecialFeatureIds.Count == 0;
-
- if (!ok)
- {
- return false;
- }
- }
- else
- {
- return false;
- }
- }
-
- if (query.HasSubtitles.HasValue)
- {
- var val = query.HasSubtitles.Value;
-
- var video = item as Video;
-
- if (video is null || val != video.HasSubtitles)
- {
- return false;
- }
- }
-
if (query.HasParentalRating.HasValue)
{
var val = query.HasParentalRating.Value;
@@ -734,66 +623,12 @@ namespace MediaBrowser.Controller.Entities
}
}
- if (query.HasTrailer.HasValue)
- {
- var val = query.HasTrailer.Value;
- var trailerCount = 0;
-
- if (item is IHasTrailers hasTrailers)
- {
- trailerCount = hasTrailers.GetTrailerCount();
- }
-
- var ok = val ? trailerCount > 0 : trailerCount == 0;
-
- if (!ok)
- {
- return false;
- }
- }
-
- if (query.HasThemeSong.HasValue)
- {
- var filterValue = query.HasThemeSong.Value;
-
- var themeCount = item.GetThemeSongs(user).Count;
- var ok = filterValue ? themeCount > 0 : themeCount == 0;
-
- if (!ok)
- {
- return false;
- }
- }
-
- if (query.HasThemeVideo.HasValue)
- {
- var filterValue = query.HasThemeVideo.Value;
-
- var themeCount = item.GetThemeVideos(user).Count;
- var ok = filterValue ? themeCount > 0 : themeCount == 0;
-
- if (!ok)
- {
- return false;
- }
- }
-
// Apply genre filter
if (query.Genres.Count > 0 && !query.Genres.Any(v => item.Genres.Contains(v, StringComparison.OrdinalIgnoreCase)))
{
return false;
}
- // Filter by VideoType
- if (query.VideoTypes.Length > 0)
- {
- var video = item as Video;
- if (video is null || !query.VideoTypes.Contains(video.VideoType))
- {
- return false;
- }
- }
-
if (query.ImageTypes.Length > 0 && !query.ImageTypes.Any(item.HasImage))
{
return false;
@@ -912,30 +747,6 @@ namespace MediaBrowser.Controller.Entities
}
}
- if (query.SeriesStatuses.Length > 0)
- {
- var ok = new[] { item }.OfType<Series>().Any(p => p.Status.HasValue && query.SeriesStatuses.Contains(p.Status.Value));
- if (!ok)
- {
- return false;
- }
- }
-
- if (query.AiredDuringSeason.HasValue)
- {
- var episode = item as Episode;
-
- if (episode is null)
- {
- return false;
- }
-
- if (!Series.FilterEpisodesBySeason(new[] { episode }, query.AiredDuringSeason.Value, true).Any())
- {
- return false;
- }
- }
-
if (query.ExcludeItemIds.Contains(item.Id))
{
return false;
@@ -989,7 +800,7 @@ namespace MediaBrowser.Controller.Entities
return GetMediaFolders(user, viewTypes);
}
- return new BaseItem[] { parent };
+ return [parent];
}
private UserView GetUserViewWithName(CollectionType? type, string sortName, BaseItem parent)