< Summary - Jellyfin

Information
Class: MediaBrowser.Controller.Entities.TV.Series
Assembly: MediaBrowser.Controller
File(s): /srv/git/jellyfin/MediaBrowser.Controller/Entities/TV/Series.cs
Line coverage
2%
Covered lines: 5
Uncovered lines: 241
Coverable lines: 246
Total lines: 574
Line coverage: 2%
Branch coverage
0%
Covered branches: 0
Total branches: 90
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: 1.7% (4/227) Branch coverage: 0% (0/82) Total lines: 5266/2/2026 - 12:15:49 AM Line coverage: 3.5% (8/227) Branch coverage: 0% (0/82) Total lines: 5267/18/2026 - 12:15:19 AM Line coverage: 2.2% (5/227) Branch coverage: 0% (0/82) Total lines: 5267/27/2026 - 12:16:14 AM Line coverage: 2.1% (5/236) Branch coverage: 0% (0/88) Total lines: 55010/29/2026 - 12:17:11 AM Line coverage: 2% (5/246) Branch coverage: 0% (0/90) Total lines: 574 5/16/2026 - 12:15:55 AM Line coverage: 1.7% (4/227) Branch coverage: 0% (0/82) Total lines: 5266/2/2026 - 12:15:49 AM Line coverage: 3.5% (8/227) Branch coverage: 0% (0/82) Total lines: 5267/18/2026 - 12:15:19 AM Line coverage: 2.2% (5/227) Branch coverage: 0% (0/82) Total lines: 5267/27/2026 - 12:16:14 AM Line coverage: 2.1% (5/236) Branch coverage: 0% (0/88) Total lines: 55010/29/2026 - 12:17:11 AM Line coverage: 2% (5/246) Branch coverage: 0% (0/90) Total lines: 574

Coverage delta

Coverage delta 2 -2

Metrics

File(s)

/srv/git/jellyfin/MediaBrowser.Controller/Entities/TV/Series.cs

#LineLine coverage
 1#nullable disable
 2
 3#pragma warning disable CS1591
 4
 5using System;
 6using System.Collections.Generic;
 7using System.Globalization;
 8using System.Linq;
 9using System.Text.Json.Serialization;
 10using System.Threading;
 11using System.Threading.Tasks;
 12using Jellyfin.Data;
 13using Jellyfin.Data.Enums;
 14using Jellyfin.Database.Implementations.Entities;
 15using Jellyfin.Database.Implementations.Enums;
 16using MediaBrowser.Controller.Dto;
 17using MediaBrowser.Controller.Providers;
 18using MediaBrowser.Model.Entities;
 19using MediaBrowser.Model.Querying;
 20using MetadataProvider = MediaBrowser.Model.Entities.MetadataProvider;
 21
 22namespace MediaBrowser.Controller.Entities.TV
 23{
 24    /// <summary>
 25    /// Class Series.
 26    /// </summary>
 27    public class Series : Folder, IHasTrailers, IHasDisplayOrder, IHasLookupInfo<SeriesInfo>, IMetadataContainer, ISuppo
 28    {
 21029        public Series()
 30        {
 21031            AirDays = Array.Empty<DayOfWeek>();
 21032        }
 33
 34        public DayOfWeek[] AirDays { get; set; }
 35
 36        public string AirTime { get; set; }
 37
 38        [JsonIgnore]
 039        public override bool SupportsAddingToPlaylist => true;
 40
 41        [JsonIgnore]
 042        public override bool IsPreSorted => true;
 43
 44        [JsonIgnore]
 045        public override bool SupportsDateLastMediaAdded => true;
 46
 47        [JsonIgnore]
 348        public override bool SupportsInheritedParentImages => false;
 49
 50        [JsonIgnore]
 051        public override bool SupportsPeople => true;
 52
 53        /// <inheritdoc />
 54        [JsonIgnore]
 055        public IReadOnlyList<BaseItem> LocalTrailers => GetExtras([Model.Entities.ExtraType.Trailer]).ToArray();
 56
 57        /// <summary>
 58        /// Gets or sets the display order.
 59        /// </summary>
 60        /// <remarks>
 61        /// Valid options are airdate, dvd or absolute.
 62        /// </remarks>
 63        public string DisplayOrder { get; set; }
 64
 65        /// <summary>
 66        /// Gets or sets the status.
 67        /// </summary>
 68        /// <value>The status.</value>
 69        public SeriesStatus? Status { get; set; }
 70
 71        public override double GetDefaultPrimaryImageAspectRatio()
 72        {
 073            double value = 2;
 074            value /= 3;
 75
 076            return value;
 77        }
 78
 79        public override string CreatePresentationUniqueKey()
 80        {
 081            if (LibraryManager.GetLibraryOptions(this).EnableAutomaticSeriesGrouping)
 82            {
 083                var userdatakeys = GetUserDataKeys();
 84
 85                // The first user data key is a stable cross-folder identity.
 86                // When none exists, fall back to the (normalized) series name.
 087                var groupingKey = userdatakeys.Count > 1
 088                    ? userdatakeys[0]
 089                    : GetNameBasedGroupingKey();
 90
 091                if (!string.IsNullOrEmpty(groupingKey))
 92                {
 093                    return AddLibrariesToPresentationUniqueKey(groupingKey);
 94                }
 95            }
 96
 097            return base.CreatePresentationUniqueKey();
 98        }
 99
 100        private string AddLibrariesToPresentationUniqueKey(string key)
 101        {
 0102            var lang = GetPreferredMetadataLanguage();
 0103            if (!string.IsNullOrEmpty(lang))
 104            {
 0105                key += "-" + lang;
 106            }
 107
 0108            var folders = LibraryManager.GetCollectionFolders(this)
 0109                .Select(i => i.Id.ToString("N", CultureInfo.InvariantCulture))
 0110                .Order(StringComparer.Ordinal)
 0111                .ToArray();
 112
 0113            if (folders.Length == 0)
 114            {
 0115                return key;
 116            }
 117
 0118            return key + "-" + string.Join('-', folders);
 119        }
 120
 121        private string GetNameBasedGroupingKey()
 122        {
 123            // Prefix with the type so a series can never collide with a same-named item of another kind.
 0124            return string.IsNullOrEmpty(Name)
 0125                ? null
 0126                : "series-" + Name.ToLowerInvariant();
 127        }
 128
 129        private static string GetUniqueSeriesKey(BaseItem series)
 130        {
 0131            return series.GetPresentationUniqueKey();
 132        }
 133
 134        public override int GetChildCount(User user)
 135        {
 0136            var seriesKey = GetUniqueSeriesKey(this);
 137
 0138            var result = LibraryManager.GetItemIds(new InternalItemsQuery(user)
 0139            {
 0140                AncestorWithPresentationUniqueKey = null,
 0141                SeriesPresentationUniqueKey = seriesKey,
 0142                IncludeItemTypes = new[] { BaseItemKind.Season },
 0143                IsVirtualItem = false,
 0144                DtoOptions = new DtoOptions(false)
 0145                {
 0146                    EnableImages = false
 0147                }
 0148            });
 149
 0150            return result.Count;
 151        }
 152
 153        public override int GetRecursiveChildCount(User user)
 154        {
 0155            var seriesKey = GetUniqueSeriesKey(this);
 156
 0157            var query = new InternalItemsQuery(user)
 0158            {
 0159                AncestorWithPresentationUniqueKey = null,
 0160                SeriesPresentationUniqueKey = seriesKey,
 0161                DtoOptions = new DtoOptions(false)
 0162                {
 0163                    EnableImages = false
 0164                }
 0165            };
 166
 0167            if (query.IncludeItemTypes.Length == 0)
 168            {
 0169                query.IncludeItemTypes = new[] { BaseItemKind.Episode };
 170            }
 171
 0172            query.IsVirtualItem = false;
 0173            query.Limit = 0;
 0174            var totalRecordCount = LibraryManager.GetCount(query);
 175
 0176            return totalRecordCount;
 177        }
 178
 179        /// <summary>
 180        /// Gets the user data key.
 181        /// </summary>
 182        /// <returns>System.String.</returns>
 183        public override List<string> GetUserDataKeys()
 184        {
 0185            var list = base.GetUserDataKeys();
 186
 0187            if (this.TryGetProviderId(MetadataProvider.Imdb, out var key))
 188            {
 0189                list.Insert(0, key);
 190            }
 191
 0192            if (this.TryGetProviderId(MetadataProvider.Tvdb, out key))
 193            {
 0194                list.Insert(0, key);
 195            }
 196
 0197            if (this.TryGetProviderId(MetadataProvider.Custom, out key))
 198            {
 0199                list.Insert(0, key);
 200            }
 201
 0202            return list;
 203        }
 204
 205        /// <inheritdoc />
 206        protected override Guid[] GetExtraOwnerIds()
 207        {
 0208            if (!LibraryManager.GetLibraryOptions(this).EnableAutomaticSeriesGrouping)
 209            {
 0210                return base.GetExtraOwnerIds();
 211            }
 212
 213            // Setting PresentationUniqueKey on the query disables presentation-key grouping, so this
 214            // returns every folder-item of the merged series rather than the collapsed survivor.
 0215            var ids = LibraryManager.GetItemIds(new InternalItemsQuery
 0216            {
 0217                PresentationUniqueKey = GetPresentationUniqueKey(),
 0218                IncludeItemTypes = [BaseItemKind.Series]
 0219            });
 220
 0221            return ids.Count == 0 ? base.GetExtraOwnerIds() : ids.ToArray();
 222        }
 223
 224        public override IReadOnlyList<BaseItem> GetChildren(User user, bool includeLinkedChildren, InternalItemsQuery qu
 225        {
 0226            return GetSeasons(user, new DtoOptions(true));
 227        }
 228
 229        public IReadOnlyList<BaseItem> GetSeasons(User user, DtoOptions options)
 230        {
 0231            var query = new InternalItemsQuery(user)
 0232            {
 0233                DtoOptions = options
 0234            };
 235
 0236            SetSeasonQueryOptions(query, user);
 237
 0238            return LibraryManager.GetItemList(query);
 239        }
 240
 241        private void SetSeasonQueryOptions(InternalItemsQuery query, User user)
 242        {
 0243            var seriesKey = GetUniqueSeriesKey(this);
 244
 0245            query.AncestorWithPresentationUniqueKey = null;
 0246            query.SeriesPresentationUniqueKey = seriesKey;
 0247            query.IncludeItemTypes = new[] { BaseItemKind.Season };
 0248            query.OrderBy = new[] { (ItemSortBy.SortName, SortOrder.Ascending) };
 249
 0250            if (user is not null && !user.DisplayMissingEpisodes)
 251            {
 0252                query.IsMissing = false;
 253            }
 0254        }
 255
 256        protected override QueryResult<BaseItem> GetItemsInternal(InternalItemsQuery query)
 257        {
 0258            var user = query.User;
 259
 0260            if (SourceType == SourceType.Channel)
 261            {
 262                try
 263                {
 0264                    query.Parent = this;
 0265                    query.ChannelIds = [ChannelId];
 0266                    return ChannelManager.GetChannelItemsInternal(query, new Progress<double>(), CancellationToken.None)
 267                }
 0268                catch
 269                {
 270                    // Already logged at lower levels
 0271                    return new QueryResult<BaseItem>();
 272                }
 273            }
 274
 0275            if (query.Recursive)
 276            {
 0277                var seriesKey = GetUniqueSeriesKey(this);
 278
 0279                query.AncestorWithPresentationUniqueKey = null;
 0280                query.SeriesPresentationUniqueKey = seriesKey;
 0281                if (query.OrderBy.Count == 0)
 282                {
 0283                    query.OrderBy = new[] { (ItemSortBy.SortName, SortOrder.Ascending) };
 284                }
 285
 0286                if (query.IncludeItemTypes.Length == 0)
 287                {
 0288                    query.IncludeItemTypes = new[] { BaseItemKind.Episode, BaseItemKind.Season };
 289                }
 290
 0291                query.IsVirtualItem = false;
 0292                return LibraryManager.GetItemsResult(query);
 293            }
 294
 0295            SetSeasonQueryOptions(query, user);
 296
 0297            return LibraryManager.GetItemsResult(query);
 0298        }
 299
 300        public IEnumerable<BaseItem> GetEpisodes(User user, DtoOptions options, bool shouldIncludeMissingEpisodes)
 301        {
 0302            var seriesKey = GetUniqueSeriesKey(this);
 303
 0304            var query = new InternalItemsQuery(user)
 0305            {
 0306                AncestorWithPresentationUniqueKey = null,
 0307                SeriesPresentationUniqueKey = seriesKey,
 0308                IncludeItemTypes = new[] { BaseItemKind.Episode, BaseItemKind.Season },
 0309                OrderBy = new[] { (ItemSortBy.SortName, SortOrder.Ascending) },
 0310                DtoOptions = options,
 0311            };
 312
 0313            if (!shouldIncludeMissingEpisodes)
 314            {
 0315                query.IsMissing = false;
 316            }
 317
 0318            var allItems = LibraryManager.GetItemList(query);
 319
 0320            var allSeriesEpisodes = allItems.OfType<Episode>().ToList();
 321
 0322            var allEpisodes = allItems.OfType<Season>()
 0323                .SelectMany(i => i.GetEpisodes(this, user, allSeriesEpisodes, options, shouldIncludeMissingEpisodes))
 0324                .Reverse();
 325
 326            // Specials could appear twice based on above - once in season 0, once in the aired season
 327            // This depends on settings for that series
 328            // When this happens, remove the duplicate from season 0
 329
 0330            return allEpisodes.DistinctBy(i => i.Id).Reverse();
 331        }
 332
 333        public async Task RefreshAllMetadata(MetadataRefreshOptions refreshOptions, IProgress<double> progress, Cancella
 334        {
 0335            Children = null; // invalidate cached children.
 336
 337            try
 338            {
 0339                await RefreshAllMetadataInternal(refreshOptions, progress, cancellationToken).ConfigureAwait(false);
 0340            }
 341            finally
 342            {
 0343                ReleaseCachedChildren();
 344            }
 0345        }
 346
 347        private async Task RefreshAllMetadataInternal(MetadataRefreshOptions refreshOptions, IProgress<double> progress,
 348        {
 349            // Refresh bottom up, seasons and episodes first, then the series
 0350            var items = GetRecursiveChildren();
 351
 0352            var totalItems = items.Count;
 0353            var numComplete = 0;
 354
 355            // Refresh seasons
 0356            foreach (var item in items)
 357            {
 0358                if (item is not Season)
 359                {
 360                    continue;
 361                }
 362
 0363                cancellationToken.ThrowIfCancellationRequested();
 364
 0365                if (refreshOptions.RefreshItem(item))
 366                {
 0367                    await item.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
 368                }
 369
 0370                numComplete++;
 0371                double percent = numComplete;
 0372                percent /= totalItems;
 0373                progress.Report(percent * 100);
 374            }
 375
 376            // Refresh episodes and other children
 0377            foreach (var item in items)
 378            {
 0379                if (item is Season)
 380                {
 381                    continue;
 382                }
 383
 0384                cancellationToken.ThrowIfCancellationRequested();
 385
 0386                bool skipItem = item is Episode episode
 0387                    && refreshOptions.MetadataRefreshMode != MetadataRefreshMode.FullRefresh
 0388                    && !refreshOptions.ReplaceAllMetadata
 0389                    && episode.IsMissingEpisode
 0390                    && episode.LocationType == LocationType.Virtual
 0391                    && episode.PremiereDate.HasValue
 0392                    && (DateTime.UtcNow - episode.PremiereDate.Value).TotalDays > 30;
 393
 0394                if (!skipItem)
 395                {
 0396                    if (refreshOptions.RefreshItem(item))
 397                    {
 0398                        await item.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
 399                    }
 400                }
 401
 0402                numComplete++;
 0403                double percent = numComplete;
 0404                percent /= totalItems;
 0405                progress.Report(percent * 100);
 406            }
 407
 0408            refreshOptions = new MetadataRefreshOptions(refreshOptions);
 0409            await ProviderManager.RefreshSingleItem(this, refreshOptions, cancellationToken).ConfigureAwait(false);
 0410        }
 411
 412        public List<BaseItem> GetSeasonEpisodes(Season parentSeason, User user, DtoOptions options, bool shouldIncludeMi
 413        {
 0414            var queryFromSeries = ConfigurationManager.Configuration.DisplaySpecialsWithinSeasons;
 415
 416            // add optimization when this setting is not enabled
 0417            var seriesKey = queryFromSeries ?
 0418                GetUniqueSeriesKey(this) :
 0419                GetUniqueSeriesKey(parentSeason);
 420
 0421            var query = new InternalItemsQuery(user)
 0422            {
 0423                AncestorWithPresentationUniqueKey = queryFromSeries ? null : seriesKey,
 0424                SeriesPresentationUniqueKey = queryFromSeries ? seriesKey : null,
 0425                IncludeItemTypes = new[] { BaseItemKind.Episode },
 0426                OrderBy = new[] { (ItemSortBy.SortName, SortOrder.Ascending) },
 0427                DtoOptions = options
 0428            };
 429
 0430            if (!shouldIncludeMissingEpisodes)
 431            {
 0432                query.IsMissing = false;
 433            }
 434
 435            IReadOnlyList<BaseItem> allItems;
 0436            if (SourceType == SourceType.Channel)
 437            {
 438                try
 439                {
 0440                    query.Parent = parentSeason;
 0441                    query.ChannelIds = [ChannelId];
 0442                    allItems = [.. ChannelManager.GetChannelItemsInternal(query, new Progress<double>(), CancellationTok
 0443                }
 0444                catch
 445                {
 446                    // Already logged at lower levels
 0447                    return [];
 448                }
 449            }
 450            else
 451            {
 0452                allItems = LibraryManager.GetItemList(query);
 453            }
 454
 0455            return GetSeasonEpisodes(parentSeason, user, allItems, options, shouldIncludeMissingEpisodes);
 0456        }
 457
 458        public List<BaseItem> GetSeasonEpisodes(Season parentSeason, User user, IEnumerable<BaseItem> allSeriesEpisodes,
 459        {
 0460            if (allSeriesEpisodes is null)
 461            {
 0462                return GetSeasonEpisodes(parentSeason, user, options, shouldIncludeMissingEpisodes);
 463            }
 464
 0465            var episodes = FilterEpisodesBySeason(allSeriesEpisodes, parentSeason, ConfigurationManager.Configuration.Di
 466
 0467            var sortBy = (parentSeason.IndexNumber ?? -1) == 0 ? ItemSortBy.SortName : ItemSortBy.AiredEpisodeOrder;
 468
 0469            return LibraryManager.Sort(episodes, user, new[] { sortBy }, SortOrder.Ascending).ToList();
 470        }
 471
 472        /// <summary>
 473        /// Filters the episodes by season.
 474        /// </summary>
 475        /// <param name="episodes">The episodes.</param>
 476        /// <param name="parentSeason">The season.</param>
 477        /// <param name="includeSpecials"><c>true</c> to include special, <c>false</c> to not.</param>
 478        /// <returns>The set of episodes.</returns>
 479        public static IEnumerable<BaseItem> FilterEpisodesBySeason(IEnumerable<BaseItem> episodes, Season parentSeason, 
 480        {
 0481            var seasonNumber = parentSeason.IndexNumber;
 0482            var seasonPresentationKey = GetUniqueSeriesKey(parentSeason);
 483
 0484            var supportSpecialsInSeason = includeSpecials && seasonNumber.HasValue && seasonNumber.Value != 0;
 485
 0486            return episodes.Where(episode =>
 0487            {
 0488                var episodeItem = (Episode)episode;
 0489
 0490                var currentSeasonNumber = supportSpecialsInSeason ? episodeItem.AiredSeasonNumber : episode.ParentIndexN
 0491                if (currentSeasonNumber.HasValue && seasonNumber.HasValue && currentSeasonNumber.Value == seasonNumber.V
 0492                {
 0493                    return true;
 0494                }
 0495
 0496                if (!currentSeasonNumber.HasValue && !seasonNumber.HasValue && parentSeason.LocationType == LocationType
 0497                {
 0498                    return episodeItem.Season is null or { LocationType: LocationType.Virtual };
 0499                }
 0500
 0501                var season = episodeItem.Season;
 0502                return season is not null && string.Equals(GetUniqueSeriesKey(season), seasonPresentationKey, StringComp
 0503            });
 504        }
 505
 506        /// <summary>
 507        /// Filters the episodes by season.
 508        /// </summary>
 509        /// <param name="episodes">The episodes.</param>
 510        /// <param name="seasonNumber">The season.</param>
 511        /// <param name="includeSpecials"><c>true</c> to include special, <c>false</c> to not.</param>
 512        /// <returns>The set of episodes.</returns>
 513        public static IEnumerable<Episode> FilterEpisodesBySeason(IEnumerable<Episode> episodes, int seasonNumber, bool 
 514        {
 0515            if (!includeSpecials || seasonNumber < 1)
 516            {
 0517                return episodes.Where(i => (i.ParentIndexNumber ?? -1) == seasonNumber);
 518            }
 519
 0520            return episodes.Where(i =>
 0521            {
 0522                var episode = i;
 0523
 0524                if (episode is not null)
 0525                {
 0526                    var currentSeasonNumber = episode.AiredSeasonNumber;
 0527
 0528                    return currentSeasonNumber.HasValue && currentSeasonNumber.Value == seasonNumber;
 0529                }
 0530
 0531                return false;
 0532            });
 533        }
 534
 535        protected override bool GetBlockUnratedValue(User user)
 536        {
 0537            return user.GetPreferenceValues<UnratedItem>(PreferenceKind.BlockUnratedItems).Contains(UnratedItem.Series);
 538        }
 539
 540        public override UnratedItem GetBlockUnratedType()
 541        {
 10542            return UnratedItem.Series;
 543        }
 544
 545        public SeriesInfo GetLookupInfo()
 546        {
 0547            var info = GetItemLookupInfo<SeriesInfo>();
 548
 0549            info.DisplayOrder = DisplayOrder;
 550
 0551            return info;
 552        }
 553
 554        public override bool BeforeMetadataRefresh(bool replaceAllMetadata)
 555        {
 0556            var hasChanges = base.BeforeMetadataRefresh(replaceAllMetadata);
 557
 0558            if (ProductionYear is null)
 559            {
 0560                var info = LibraryManager.ParseName(Name);
 561
 0562                var yearInName = info.Year;
 563
 0564                if (yearInName.HasValue)
 565                {
 0566                    ProductionYear = yearInName;
 0567                    hasChanges = true;
 568                }
 569            }
 570
 0571            return hasChanges;
 572        }
 573    }
 574}

Methods/Properties

.ctor()
get_SupportsAddingToPlaylist()
get_IsPreSorted()
get_SupportsDateLastMediaAdded()
get_SupportsInheritedParentImages()
get_SupportsPeople()
get_LocalTrailers()
GetDefaultPrimaryImageAspectRatio()
CreatePresentationUniqueKey()
AddLibrariesToPresentationUniqueKey(System.String)
GetNameBasedGroupingKey()
GetUniqueSeriesKey(MediaBrowser.Controller.Entities.BaseItem)
GetChildCount(Jellyfin.Database.Implementations.Entities.User)
GetRecursiveChildCount(Jellyfin.Database.Implementations.Entities.User)
GetUserDataKeys()
GetExtraOwnerIds()
GetChildren(Jellyfin.Database.Implementations.Entities.User,System.Boolean,MediaBrowser.Controller.Entities.InternalItemsQuery)
GetSeasons(Jellyfin.Database.Implementations.Entities.User,MediaBrowser.Controller.Dto.DtoOptions)
SetSeasonQueryOptions(MediaBrowser.Controller.Entities.InternalItemsQuery,Jellyfin.Database.Implementations.Entities.User)
GetItemsInternal(MediaBrowser.Controller.Entities.InternalItemsQuery)
GetEpisodes(Jellyfin.Database.Implementations.Entities.User,MediaBrowser.Controller.Dto.DtoOptions,System.Boolean)
RefreshAllMetadata()
RefreshAllMetadataInternal()
GetSeasonEpisodes(MediaBrowser.Controller.Entities.TV.Season,Jellyfin.Database.Implementations.Entities.User,MediaBrowser.Controller.Dto.DtoOptions,System.Boolean)
GetSeasonEpisodes(MediaBrowser.Controller.Entities.TV.Season,Jellyfin.Database.Implementations.Entities.User,System.Collections.Generic.IEnumerable`1<MediaBrowser.Controller.Entities.BaseItem>,MediaBrowser.Controller.Dto.DtoOptions,System.Boolean)
FilterEpisodesBySeason(System.Collections.Generic.IEnumerable`1<MediaBrowser.Controller.Entities.BaseItem>,MediaBrowser.Controller.Entities.TV.Season,System.Boolean)
FilterEpisodesBySeason(System.Collections.Generic.IEnumerable`1<MediaBrowser.Controller.Entities.TV.Episode>,System.Int32,System.Boolean)
GetBlockUnratedValue(Jellyfin.Database.Implementations.Entities.User)
GetBlockUnratedType()
GetLookupInfo()
BeforeMetadataRefresh(System.Boolean)