Skip to content

Commit

Permalink
Return missing episodes for series when no user defined (jellyfin#11806)
Browse files Browse the repository at this point in the history
  • Loading branch information
Shadowghost committed May 30, 2024
1 parent 5630337 commit ae584be
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 34 deletions.
3 changes: 2 additions & 1 deletion Emby.Server.Implementations/Session/SessionManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1202,7 +1202,8 @@ public async Task SendPlayCommand(string controllingSessionId, string sessionId,
new DtoOptions(false)
{
EnableImages = false
})
},
user.DisplayMissingEpisodes)
.Where(i => !i.IsVirtualItem)
.SkipWhile(i => !i.Id.Equals(episode.Id))
.ToList();
Expand Down
7 changes: 4 additions & 3 deletions Jellyfin.Api/Controllers/TvShowsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ public class TvShowsController : BaseJellyfinApiController
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
var shouldIncludeMissingEpisodes = (user is not null && user.DisplayMissingEpisodes) || User.GetIsApiKey();

if (seasonId.HasValue) // Season id was supplied. Get episodes by season id.
{
Expand All @@ -240,7 +241,7 @@ public class TvShowsController : BaseJellyfinApiController
return NotFound("No season exists with Id " + seasonId);
}

episodes = seasonItem.GetEpisodes(user, dtoOptions);
episodes = seasonItem.GetEpisodes(user, dtoOptions, shouldIncludeMissingEpisodes);
}
else if (season.HasValue) // Season number was supplied. Get episodes by season number
{
Expand All @@ -256,7 +257,7 @@ public class TvShowsController : BaseJellyfinApiController

episodes = seasonItem is null ?
new List<BaseItem>()
: ((Season)seasonItem).GetEpisodes(user, dtoOptions);
: ((Season)seasonItem).GetEpisodes(user, dtoOptions, shouldIncludeMissingEpisodes);
}
else // No season number or season id was supplied. Returning all episodes.
{
Expand All @@ -265,7 +266,7 @@ public class TvShowsController : BaseJellyfinApiController
return NotFound("Series not found");
}

episodes = series.GetEpisodes(user, dtoOptions).ToList();
episodes = series.GetEpisodes(user, dtoOptions, shouldIncludeMissingEpisodes).ToList();
}

// Filter after the fact in case the ui doesn't want them
Expand Down
19 changes: 10 additions & 9 deletions MediaBrowser.Controller/Entities/TV/Season.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ protected override QueryResult<BaseItem> GetItemsInternal(InternalItemsQuery que

Func<BaseItem, bool> filter = i => UserViewBuilder.Filter(i, user, query, UserDataManager, LibraryManager);

var items = GetEpisodes(user, query.DtoOptions).Where(filter);
var items = GetEpisodes(user, query.DtoOptions, true).Where(filter);

return PostFilterAndSort(items, query, false);
}
Expand All @@ -169,30 +169,31 @@ protected override QueryResult<BaseItem> GetItemsInternal(InternalItemsQuery que
/// </summary>
/// <param name="user">The user.</param>
/// <param name="options">The options to use.</param>
/// <param name="shouldIncludeMissingEpisodes">If missing episodes should be included.</param>
/// <returns>Set of episodes.</returns>
public List<BaseItem> GetEpisodes(User user, DtoOptions options)
public List<BaseItem> GetEpisodes(User user, DtoOptions options, bool shouldIncludeMissingEpisodes)
{
return GetEpisodes(Series, user, options);
return GetEpisodes(Series, user, options, shouldIncludeMissingEpisodes);
}

public List<BaseItem> GetEpisodes(Series series, User user, DtoOptions options)
public List<BaseItem> GetEpisodes(Series series, User user, DtoOptions options, bool shouldIncludeMissingEpisodes)
{
return GetEpisodes(series, user, null, options);
return GetEpisodes(series, user, null, options, shouldIncludeMissingEpisodes);
}

public List<BaseItem> GetEpisodes(Series series, User user, IEnumerable<Episode> allSeriesEpisodes, DtoOptions options)
public List<BaseItem> GetEpisodes(Series series, User user, IEnumerable<Episode> allSeriesEpisodes, DtoOptions options, bool shouldIncludeMissingEpisodes)
{
return series.GetSeasonEpisodes(this, user, allSeriesEpisodes, options);
return series.GetSeasonEpisodes(this, user, allSeriesEpisodes, options, shouldIncludeMissingEpisodes);
}

public List<BaseItem> GetEpisodes()
{
return Series.GetSeasonEpisodes(this, null, null, new DtoOptions(true));
return Series.GetSeasonEpisodes(this, null, null, new DtoOptions(true), true);
}

public override List<BaseItem> GetChildren(User user, bool includeLinkedChildren, InternalItemsQuery query)
{
return GetEpisodes(user, new DtoOptions(true));
return GetEpisodes(user, new DtoOptions(true), true);
}

protected override bool GetBlockUnratedValue(User user)
Expand Down
30 changes: 10 additions & 20 deletions MediaBrowser.Controller/Entities/TV/Series.cs
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ protected override QueryResult<BaseItem> GetItemsInternal(InternalItemsQuery que
return LibraryManager.GetItemsResult(query);
}

public IEnumerable<BaseItem> GetEpisodes(User user, DtoOptions options)
public IEnumerable<BaseItem> GetEpisodes(User user, DtoOptions options, bool shouldIncludeMissingEpisodes)
{
var seriesKey = GetUniqueSeriesKey(this);

Expand All @@ -286,20 +286,16 @@ public IEnumerable<BaseItem> GetEpisodes(User user, DtoOptions options)
SeriesPresentationUniqueKey = seriesKey,
IncludeItemTypes = new[] { BaseItemKind.Episode, BaseItemKind.Season },
OrderBy = new[] { (ItemSortBy.SortName, SortOrder.Ascending) },
DtoOptions = options
DtoOptions = options,
IsMissing = shouldIncludeMissingEpisodes
};

if (user is null || !user.DisplayMissingEpisodes)
{
query.IsMissing = false;
}

var allItems = LibraryManager.GetItemList(query);

var allSeriesEpisodes = allItems.OfType<Episode>().ToList();

var allEpisodes = allItems.OfType<Season>()
.SelectMany(i => i.GetEpisodes(this, user, allSeriesEpisodes, options))
.SelectMany(i => i.GetEpisodes(this, user, allSeriesEpisodes, options, shouldIncludeMissingEpisodes))
.Reverse();

// Specials could appear twice based on above - once in season 0, once in the aired season
Expand Down Expand Up @@ -375,7 +371,7 @@ public async Task RefreshAllMetadata(MetadataRefreshOptions refreshOptions, IPro
await ProviderManager.RefreshSingleItem(this, refreshOptions, cancellationToken).ConfigureAwait(false);
}

public List<BaseItem> GetSeasonEpisodes(Season parentSeason, User user, DtoOptions options)
public List<BaseItem> GetSeasonEpisodes(Season parentSeason, User user, DtoOptions options, bool shouldIncludeMissingEpisodes)
{
var queryFromSeries = ConfigurationManager.Configuration.DisplaySpecialsWithinSeasons;

Expand All @@ -390,26 +386,20 @@ public List<BaseItem> GetSeasonEpisodes(Season parentSeason, User user, DtoOptio
SeriesPresentationUniqueKey = queryFromSeries ? seriesKey : null,
IncludeItemTypes = new[] { BaseItemKind.Episode },
OrderBy = new[] { (ItemSortBy.SortName, SortOrder.Ascending) },
DtoOptions = options
DtoOptions = options,
IsMissing = shouldIncludeMissingEpisodes
};
if (user is not null)
{
if (!user.DisplayMissingEpisodes)
{
query.IsMissing = false;
}
}

var allItems = LibraryManager.GetItemList(query);

return GetSeasonEpisodes(parentSeason, user, allItems, options);
return GetSeasonEpisodes(parentSeason, user, allItems, options, shouldIncludeMissingEpisodes);
}

public List<BaseItem> GetSeasonEpisodes(Season parentSeason, User user, IEnumerable<BaseItem> allSeriesEpisodes, DtoOptions options)
public List<BaseItem> GetSeasonEpisodes(Season parentSeason, User user, IEnumerable<BaseItem> allSeriesEpisodes, DtoOptions options, bool shouldIncludeMissingEpisodes)
{
if (allSeriesEpisodes is null)
{
return GetSeasonEpisodes(parentSeason, user, options);
return GetSeasonEpisodes(parentSeason, user, options, shouldIncludeMissingEpisodes);
}

var episodes = FilterEpisodesBySeason(allSeriesEpisodes, parentSeason, ConfigurationManager.Configuration.DisplaySpecialsWithinSeasons);
Expand Down
2 changes: 1 addition & 1 deletion MediaBrowser.Providers/TV/SeriesMetadataService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ private void RemoveObsoleteSeasons(Series series)

private void RemoveObsoleteEpisodes(Series series)
{
var episodes = series.GetEpisodes(null, new DtoOptions()).OfType<Episode>().ToList();
var episodes = series.GetEpisodes(null, new DtoOptions(), true).OfType<Episode>().ToList();
var numberOfEpisodes = episodes.Count;
// TODO: O(n^2), but can it be done faster without overcomplicating it?
for (var i = 0; i < numberOfEpisodes; i++)
Expand Down

0 comments on commit ae584be

Please sign in to comment.