From 9eab2bfe4145808a98b754a8b30a2ae79b44c82c Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Mon, 24 Jun 2024 20:29:00 -0400 Subject: [PATCH] Backport pull request #12050 from jellyfin/release-10.9.z Fix season handling Original-merge: 4601097d3e30bb166f18672de82a13e3ca525343 Merged-by: Bond-009 Backported-by: Joshua M. Boniface --- MediaBrowser.Controller/Entities/TV/Series.cs | 11 ++------- .../TV/SeriesMetadataService.cs | 23 +++++++++++-------- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index d704208cde..6297b67e46 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -350,17 +350,10 @@ namespace MediaBrowser.Controller.Entities.TV public List GetSeasonEpisodes(Season parentSeason, User user, DtoOptions options, bool shouldIncludeMissingEpisodes) { - var queryFromSeries = ConfigurationManager.Configuration.DisplaySpecialsWithinSeasons; - - // add optimization when this setting is not enabled - var seriesKey = queryFromSeries ? - GetUniqueSeriesKey(this) : - GetUniqueSeriesKey(parentSeason); - var query = new InternalItemsQuery(user) { - AncestorWithPresentationUniqueKey = queryFromSeries ? null : seriesKey, - SeriesPresentationUniqueKey = queryFromSeries ? seriesKey : null, + AncestorWithPresentationUniqueKey = null, + SeriesPresentationUniqueKey = GetUniqueSeriesKey(this), IncludeItemTypes = new[] { BaseItemKind.Episode }, OrderBy = new[] { (ItemSortBy.SortName, SortOrder.Ascending) }, DtoOptions = options diff --git a/MediaBrowser.Providers/TV/SeriesMetadataService.cs b/MediaBrowser.Providers/TV/SeriesMetadataService.cs index 2389bce577..b03d6ffb56 100644 --- a/MediaBrowser.Providers/TV/SeriesMetadataService.cs +++ b/MediaBrowser.Providers/TV/SeriesMetadataService.cs @@ -61,8 +61,8 @@ namespace MediaBrowser.Providers.TV await base.AfterMetadataRefresh(item, refreshOptions, cancellationToken).ConfigureAwait(false); RemoveObsoleteEpisodes(item); - RemoveObsoleteSeasons(item); await CreateSeasonsAsync(item, cancellationToken).ConfigureAwait(false); + RemoveObsoleteSeasons(item); } /// @@ -91,7 +91,7 @@ namespace MediaBrowser.Providers.TV private void RemoveObsoleteSeasons(Series series) { - // TODO Legacy. It's not really "physical" seasons as any virtual seasons are always converted to non-virtual in UpdateAndCreateSeasonsAsync. + // TODO Legacy. It's not really "physical" seasons as any virtual seasons are always converted to non-virtual in CreateSeasonsAsync. var physicalSeasonNumbers = new HashSet(); var virtualSeasons = new List(); foreach (var existingSeason in series.Children.OfType()) @@ -203,11 +203,16 @@ namespace MediaBrowser.Providers.TV foreach (var seasonNumber in uniqueSeasonNumbers) { // Null season numbers will have a 'dummy' season created because seasons are always required. - if (!seasons.Any(i => i.IndexNumber == seasonNumber)) + var existingSeason = seasons.FirstOrDefault(i => i.IndexNumber == seasonNumber); + if (existingSeason is null) { var seasonName = GetValidSeasonNameForSeries(series, null, seasonNumber); - var season = await CreateSeasonAsync(series, seasonName, seasonNumber, cancellationToken).ConfigureAwait(false); - series.AddChild(season); + await CreateSeasonAsync(series, seasonName, seasonNumber, cancellationToken).ConfigureAwait(false); + } + else if (existingSeason.IsVirtualItem) + { + existingSeason.IsVirtualItem = false; + await existingSeason.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, cancellationToken).ConfigureAwait(false); } } } @@ -220,7 +225,7 @@ namespace MediaBrowser.Providers.TV /// The season number. /// The cancellation token. /// The newly created season. - private async Task CreateSeasonAsync( + private async Task CreateSeasonAsync( Series series, string? seasonName, int? seasonNumber, @@ -237,14 +242,12 @@ namespace MediaBrowser.Providers.TV typeof(Season)), IsVirtualItem = false, SeriesId = series.Id, - SeriesName = series.Name + SeriesName = series.Name, + SeriesPresentationUniqueKey = series.GetPresentationUniqueKey() }; series.AddChild(season); - await season.RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(FileSystem)), cancellationToken).ConfigureAwait(false); - - return season; } private string GetValidSeasonNameForSeries(Series series, string? seasonName, int? seasonNumber)