< Summary - Jellyfin

Information
Class: MediaBrowser.Controller.Entities.Movies.BoxSet
Assembly: MediaBrowser.Controller
File(s): /srv/git/jellyfin/MediaBrowser.Controller/Entities/Movies/BoxSet.cs
Line coverage
3%
Covered lines: 3
Uncovered lines: 88
Coverable lines: 91
Total lines: 293
Line coverage: 3.2%
Branch coverage
0%
Covered branches: 0
Total branches: 48
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100 5/16/2026 - 12:15:55 AM Line coverage: 3.5% (3/85) Branch coverage: 0% (0/46) Total lines: 27610/29/2026 - 12:17:11 AM Line coverage: 3.2% (3/91) Branch coverage: 0% (0/48) Total lines: 293 5/16/2026 - 12:15:55 AM Line coverage: 3.5% (3/85) Branch coverage: 0% (0/46) Total lines: 27610/29/2026 - 12:17:11 AM Line coverage: 3.2% (3/91) Branch coverage: 0% (0/48) Total lines: 293

Coverage delta

Coverage delta 1 -1

Metrics

File(s)

/srv/git/jellyfin/MediaBrowser.Controller/Entities/Movies/BoxSet.cs

#LineLine coverage
 1#nullable disable
 2
 3#pragma warning disable CA1721, CA1819, CS1591
 4
 5using System;
 6using System.Collections.Generic;
 7using System.Collections.Immutable;
 8using System.Linq;
 9using System.Text.Json.Serialization;
 10using Jellyfin.Data;
 11using Jellyfin.Data.Enums;
 12using Jellyfin.Database.Implementations.Entities;
 13using Jellyfin.Database.Implementations.Enums;
 14using MediaBrowser.Controller.Dto;
 15using MediaBrowser.Controller.Providers;
 16using MediaBrowser.Model.Querying;
 17
 18namespace MediaBrowser.Controller.Entities.Movies
 19{
 20    /// <summary>
 21    /// Class BoxSet.
 22    /// </summary>
 23    public class BoxSet : Folder, IHasTrailers, IHasDisplayOrder, IHasLookupInfo<BoxSetInfo>
 24    {
 625        public BoxSet()
 26        {
 627            DisplayOrder = "PremiereDate";
 628        }
 29
 30        [JsonIgnore]
 031        protected override bool FilterLinkedChildrenPerUser => true;
 32
 33        [JsonIgnore]
 034        public override bool SupportsInheritedParentImages => false;
 35
 36        [JsonIgnore]
 037        public override bool SupportsPeople => true;
 38
 39        /// <inheritdoc />
 40        [JsonIgnore]
 041        public IReadOnlyList<BaseItem> LocalTrailers => GetExtras([Model.Entities.ExtraType.Trailer]).ToArray();
 42
 43        /// <summary>
 44        /// Gets or sets the display order.
 45        /// </summary>
 46        /// <value>The display order.</value>
 47        public string DisplayOrder { get; set; }
 48
 49        [JsonIgnore]
 50        private bool IsLegacyBoxSet
 51        {
 52            get
 53            {
 054                if (string.IsNullOrEmpty(Path))
 55                {
 056                    return false;
 57                }
 58
 059                if (LinkedChildren.Length > 0)
 60                {
 061                    return false;
 62                }
 63
 064                return !FileSystem.ContainsSubPath(ConfigurationManager.ApplicationPaths.DataPath, Path);
 65            }
 66        }
 67
 68        [JsonIgnore]
 069        public override bool IsPreSorted => true;
 70
 71        public Guid[] LibraryFolderIds { get; set; }
 72
 73        protected override bool GetBlockUnratedValue(User user)
 74        {
 075            return user.GetPreferenceValues<UnratedItem>(PreferenceKind.BlockUnratedItems).Contains(UnratedItem.Movie);
 76        }
 77
 78        public override double GetDefaultPrimaryImageAspectRatio()
 079            => 2.0 / 3;
 80
 81        public override UnratedItem GetBlockUnratedType()
 82        {
 083            return UnratedItem.Movie;
 84        }
 85
 86        protected override IEnumerable<BaseItem> GetNonCachedChildren(IDirectoryService directoryService)
 87        {
 088            if (IsLegacyBoxSet)
 89            {
 090                return base.GetNonCachedChildren(directoryService);
 91            }
 92
 093            return [];
 94        }
 95
 96        protected override IReadOnlyList<BaseItem> LoadChildren()
 97        {
 098            if (IsLegacyBoxSet)
 99            {
 0100                return base.LoadChildren();
 101            }
 102
 103            // Save a trip to the database
 0104            return [];
 105        }
 106
 107        public override bool IsAuthorizedToDelete(User user, List<Folder> allCollectionFolders)
 108        {
 0109            return user.HasPermission(PermissionKind.IsAdministrator) || user.HasPermission(PermissionKind.EnableCollect
 110        }
 111
 112        public override bool IsSaveLocalMetadataEnabled()
 113        {
 0114            return true;
 115        }
 116
 117        private IEnumerable<BaseItem> Sort(IEnumerable<BaseItem> items, User user)
 118        {
 0119            if (!Enum.TryParse<ItemSortBy>(DisplayOrder, out var sortBy))
 120            {
 0121                sortBy = ItemSortBy.PremiereDate;
 122            }
 123
 0124            if (sortBy == ItemSortBy.Default)
 125            {
 0126                return items;
 127            }
 128
 0129            return LibraryManager.Sort(items, user, new[] { sortBy }, SortOrder.Ascending);
 130        }
 131
 132        public override IReadOnlyList<BaseItem> GetChildren(User user, bool includeLinkedChildren, InternalItemsQuery qu
 133        {
 0134            var children = base.GetChildren(user, includeLinkedChildren, query);
 0135            return Sort(children, user).ToArray();
 136        }
 137
 138        public override IReadOnlyList<BaseItem> GetChildren(User user, bool includeLinkedChildren, out int totalItemCoun
 139        {
 0140            var children = base.GetChildren(user, includeLinkedChildren, out totalItemCount, query);
 0141            return Sort(children, user).ToArray();
 142        }
 143
 144        public override IReadOnlyList<BaseItem> GetRecursiveChildren(User user, InternalItemsQuery query, out int totalC
 145        {
 0146            var children = base.GetRecursiveChildren(user, query, out totalCount);
 0147            return Sort(children, user).ToArray();
 148        }
 149
 150        public BoxSetInfo GetLookupInfo()
 151        {
 0152            return GetItemLookupInfo<BoxSetInfo>();
 153        }
 154
 155        public override bool IsVisible(User user, bool skipAllowedTagsCheck = false)
 156        {
 0157            if (IsLegacyBoxSet)
 158            {
 0159                return base.IsVisible(user, skipAllowedTagsCheck);
 160            }
 161
 0162            if (!IsParentalAllowed(user, skipAllowedTagsCheck))
 163            {
 0164                return false;
 165            }
 166
 0167            if (LinkedChildren.Length == 0)
 168            {
 0169                return true;
 170            }
 171
 0172            List<BaseItem> linkedItems = null;
 0173            var libraryFolderIds = LibraryFolderIds;
 0174            if (libraryFolderIds is null)
 175            {
 0176                linkedItems = GetLinkedChildren(DtoOptions.StoredColumnsOnly);
 0177                libraryFolderIds = GetLibraryFolderIds(linkedItems);
 178            }
 179
 0180            if (libraryFolderIds.Length == 0)
 181            {
 0182                return true;
 183            }
 184
 0185            var userLibraryFolderIds = GetLibraryFolderIds(user);
 186
 0187            if (!userLibraryFolderIds.Any(i => libraryFolderIds.Contains(i)))
 188            {
 0189                return false;
 190            }
 191
 192            // If user has parental controls, hide the BoxSet when all children are restricted
 0193            if (user.MaxParentalRatingScore.HasValue)
 194            {
 0195                linkedItems ??= GetLinkedChildren(DtoOptions.StoredColumnsOnly);
 0196                if (linkedItems.Count > 0 && linkedItems.All(child => !child.IsParentalAllowed(user, true)))
 197                {
 0198                    return false;
 199                }
 200            }
 201
 0202            return true;
 203        }
 204
 205        public override void MarkPlayed(User user, DateTime? datePlayed, bool resetPosition)
 206        {
 0207            if (IsLegacyBoxSet)
 208            {
 0209                base.MarkPlayed(user, datePlayed, resetPosition);
 0210                return;
 211            }
 212
 0213            foreach (var item in GetLinkedChildren(user))
 214            {
 0215                item.MarkPlayed(user, datePlayed, resetPosition);
 216            }
 0217        }
 218
 219        public override void MarkUnplayed(User user)
 220        {
 0221            if (IsLegacyBoxSet)
 222            {
 0223                base.MarkUnplayed(user);
 0224                return;
 225            }
 226
 0227            foreach (var item in GetLinkedChildren(user))
 228            {
 0229                item.MarkUnplayed(user);
 230            }
 0231        }
 232
 233        public override bool IsVisibleStandalone(User user)
 234        {
 0235            if (IsLegacyBoxSet)
 236            {
 0237                return base.IsVisibleStandalone(user);
 238            }
 239
 0240            return IsVisible(user);
 241        }
 242
 243        private Guid[] GetLibraryFolderIds(User user)
 244        {
 0245            return LibraryManager.GetUserRootFolder().GetChildren(user, true)
 0246                .Select(i => i.Id)
 0247                .ToArray();
 248        }
 249
 250        public Guid[] GetLibraryFolderIds()
 251        {
 0252            return GetLibraryFolderIds(GetLinkedChildren(DtoOptions.StoredColumnsOnly));
 253        }
 254
 255        private Guid[] GetLibraryFolderIds(IEnumerable<BaseItem> linkedChildren)
 256        {
 257            // Seeded with this box set so a cycle through a nested collection terminates.
 0258            var expandedFolders = new List<Guid> { Id };
 259
 260            // The user root children are the same for every item.
 0261            var rootChildren = LibraryManager.GetUserRootFolder().Children.OfType<Folder>().ToList();
 262
 0263            return FlattenItems(linkedChildren, expandedFolders)
 0264                .SelectMany(i => LibraryManager.GetCollectionFolders(i, rootChildren))
 0265                .Select(i => i.Id)
 0266                .Distinct()
 0267                .ToArray();
 268        }
 269
 270        private IEnumerable<BaseItem> FlattenItems(IEnumerable<BaseItem> items, List<Guid> expandedFolders)
 271        {
 0272            return items
 0273                .SelectMany(i => FlattenItems(i, expandedFolders));
 274        }
 275
 276        private IEnumerable<BaseItem> FlattenItems(BaseItem item, List<Guid> expandedFolders)
 277        {
 0278            if (item is BoxSet boxset)
 279            {
 0280                if (!expandedFolders.Contains(item.Id))
 281                {
 0282                    expandedFolders.Add(item.Id);
 283
 0284                    return FlattenItems(boxset.GetLinkedChildren(DtoOptions.StoredColumnsOnly), expandedFolders);
 285                }
 286
 0287                return [];
 288            }
 289
 0290            return [item];
 291        }
 292    }
 293}

Methods/Properties

.ctor()
get_FilterLinkedChildrenPerUser()
get_SupportsInheritedParentImages()
get_SupportsPeople()
get_LocalTrailers()
get_IsLegacyBoxSet()
get_IsPreSorted()
GetBlockUnratedValue(Jellyfin.Database.Implementations.Entities.User)
GetDefaultPrimaryImageAspectRatio()
GetBlockUnratedType()
GetNonCachedChildren(MediaBrowser.Controller.Providers.IDirectoryService)
LoadChildren()
IsAuthorizedToDelete(Jellyfin.Database.Implementations.Entities.User,System.Collections.Generic.List`1<MediaBrowser.Controller.Entities.Folder>)
IsSaveLocalMetadataEnabled()
Sort(System.Collections.Generic.IEnumerable`1<MediaBrowser.Controller.Entities.BaseItem>,Jellyfin.Database.Implementations.Entities.User)
GetChildren(Jellyfin.Database.Implementations.Entities.User,System.Boolean,MediaBrowser.Controller.Entities.InternalItemsQuery)
GetChildren(Jellyfin.Database.Implementations.Entities.User,System.Boolean,System.Int32&,MediaBrowser.Controller.Entities.InternalItemsQuery)
GetRecursiveChildren(Jellyfin.Database.Implementations.Entities.User,MediaBrowser.Controller.Entities.InternalItemsQuery,System.Int32&)
GetLookupInfo()
IsVisible(Jellyfin.Database.Implementations.Entities.User,System.Boolean)
MarkPlayed(Jellyfin.Database.Implementations.Entities.User,System.Nullable`1<System.DateTime>,System.Boolean)
MarkUnplayed(Jellyfin.Database.Implementations.Entities.User)
IsVisibleStandalone(Jellyfin.Database.Implementations.Entities.User)
GetLibraryFolderIds(Jellyfin.Database.Implementations.Entities.User)
GetLibraryFolderIds()
GetLibraryFolderIds(System.Collections.Generic.IEnumerable`1<MediaBrowser.Controller.Entities.BaseItem>)
FlattenItems(System.Collections.Generic.IEnumerable`1<MediaBrowser.Controller.Entities.BaseItem>,System.Collections.Generic.List`1<System.Guid>)
FlattenItems(MediaBrowser.Controller.Entities.BaseItem,System.Collections.Generic.List`1<System.Guid>)