diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index fcb45e7e58..235495c0c6 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 083f12746e..8444382578 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 d704208cde..dd3df510ff 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 2389bce577..13aa6226e7 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)