From e4078f984aaeead74b435f80b3ef989f8fdc680a Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Sun, 9 Jun 2024 18:47:21 +0200 Subject: [PATCH 1/3] Fix season handling --- MediaBrowser.Controller/Entities/Folder.cs | 2 +- MediaBrowser.Controller/Entities/TV/Season.cs | 15 ++++++++++++ MediaBrowser.Controller/Entities/TV/Series.cs | 24 ++++++++++++------- .../TV/SeriesMetadataService.cs | 20 ++++++++-------- 4 files changed, 41 insertions(+), 20 deletions(-) diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index fcb45e7e5..235495c0c 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -194,7 +194,7 @@ namespace MediaBrowser.Controller.Entities /// /// The item. /// Unable to add + item.Name. - public void AddChild(BaseItem item) + public virtual void AddChild(BaseItem item) { item.SetParent(this); diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs index 083f12746..844438257 100644 --- a/MediaBrowser.Controller/Entities/TV/Season.cs +++ b/MediaBrowser.Controller/Entities/TV/Season.cs @@ -265,5 +265,20 @@ namespace MediaBrowser.Controller.Entities.TV return hasChanges; } + + /// + public override void AddChild(BaseItem item) + { + if (item is Episode episode) + { + episode.SeriesPresentationUniqueKey = SeriesPresentationUniqueKey; + episode.SeriesId = SeriesId; + episode.SeriesName = SeriesName; + episode.SeasonId = Id; + episode.SeasonName = Name; + } + + base.AddChild(item); + } } } diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index d704208cd..dd3df510f 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 @@ -506,5 +499,18 @@ namespace MediaBrowser.Controller.Entities.TV return list; } + + /// + public override void AddChild(BaseItem item) + { + if (item is IHasSeries typedItem) + { + typedItem.SeriesId = Id; + typedItem.SeriesName = Name; + typedItem.SeriesPresentationUniqueKey = PresentationUniqueKey; + } + + base.AddChild(item); + } } } diff --git a/MediaBrowser.Providers/TV/SeriesMetadataService.cs b/MediaBrowser.Providers/TV/SeriesMetadataService.cs index 2389bce57..13aa6226e 100644 --- a/MediaBrowser.Providers/TV/SeriesMetadataService.cs +++ b/MediaBrowser.Providers/TV/SeriesMetadataService.cs @@ -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, @@ -236,15 +241,10 @@ namespace MediaBrowser.Providers.TV series.Id + (seasonNumber ?? -1).ToString(CultureInfo.InvariantCulture) + seasonName, typeof(Season)), IsVirtualItem = false, - SeriesId = series.Id, - SeriesName = series.Name }; 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) From 1a14902da854591c4bcb8cac45315d9e85913188 Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Tue, 11 Jun 2024 18:48:38 +0200 Subject: [PATCH 2/3] Apply review suggestion --- MediaBrowser.Controller/Entities/Folder.cs | 2 +- MediaBrowser.Controller/Entities/TV/Season.cs | 15 --------------- MediaBrowser.Controller/Entities/TV/Series.cs | 13 ------------- .../TV/SeriesMetadataService.cs | 3 +++ 4 files changed, 4 insertions(+), 29 deletions(-) diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 235495c0c..fcb45e7e5 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -194,7 +194,7 @@ namespace MediaBrowser.Controller.Entities /// /// The item. /// Unable to add + item.Name. - public virtual void AddChild(BaseItem item) + public void AddChild(BaseItem item) { item.SetParent(this); diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs index 844438257..083f12746 100644 --- a/MediaBrowser.Controller/Entities/TV/Season.cs +++ b/MediaBrowser.Controller/Entities/TV/Season.cs @@ -265,20 +265,5 @@ namespace MediaBrowser.Controller.Entities.TV return hasChanges; } - - /// - public override void AddChild(BaseItem item) - { - if (item is Episode episode) - { - episode.SeriesPresentationUniqueKey = SeriesPresentationUniqueKey; - episode.SeriesId = SeriesId; - episode.SeriesName = SeriesName; - episode.SeasonId = Id; - episode.SeasonName = Name; - } - - base.AddChild(item); - } } } diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index dd3df510f..6297b67e4 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -499,18 +499,5 @@ namespace MediaBrowser.Controller.Entities.TV return list; } - - /// - public override void AddChild(BaseItem item) - { - if (item is IHasSeries typedItem) - { - typedItem.SeriesId = Id; - typedItem.SeriesName = Name; - typedItem.SeriesPresentationUniqueKey = PresentationUniqueKey; - } - - base.AddChild(item); - } } } diff --git a/MediaBrowser.Providers/TV/SeriesMetadataService.cs b/MediaBrowser.Providers/TV/SeriesMetadataService.cs index 13aa6226e..5ede023f1 100644 --- a/MediaBrowser.Providers/TV/SeriesMetadataService.cs +++ b/MediaBrowser.Providers/TV/SeriesMetadataService.cs @@ -241,6 +241,9 @@ namespace MediaBrowser.Providers.TV series.Id + (seasonNumber ?? -1).ToString(CultureInfo.InvariantCulture) + seasonName, typeof(Season)), IsVirtualItem = false, + SeriesId = series.Id, + SeriesName = series.Name, + SeriesPresentationUniqueKey = series.GetPresentationUniqueKey() }; series.AddChild(season); From a00f9e1a106c15410d62a13a772c9fdf11f6451a Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Thu, 20 Jun 2024 22:03:01 +0200 Subject: [PATCH 3/3] Cleanup seasons after creating real ones --- MediaBrowser.Providers/TV/SeriesMetadataService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Providers/TV/SeriesMetadataService.cs b/MediaBrowser.Providers/TV/SeriesMetadataService.cs index 5ede023f1..b03d6ffb5 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); } ///