Skip to content

Commit

Permalink
fix: fix specials placement by air date
Browse files Browse the repository at this point in the history
- Fixed specials that should had been placed within a season before all episodes.

- Closes #66
  • Loading branch information
revam committed Aug 19, 2024
1 parent e481000 commit 4b92e26
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 12 deletions.
42 changes: 30 additions & 12 deletions Shokofin/API/Info/SeasonInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ public class SeasonInfo
/// </summary>
public readonly List<EpisodeInfo> ExtrasList;

/// <summary>
/// A list of special episodes that come before normal episodes.
/// </summary>
public readonly IReadOnlySet<string> SpecialsBeforeEpisodes;

/// <summary>
/// A dictionary holding mappings for the previous normal episode for every special episode in a series.
/// </summary>
Expand Down Expand Up @@ -118,6 +123,7 @@ public SeasonInfo(Series series, SeriesType? customType, IEnumerable<string> ext
.Where(r => r.RelatedIDs.Shoko.HasValue)
.DistinctBy(r => r.RelatedIDs.Shoko!.Value)
.ToDictionary(r => r.RelatedIDs.Shoko!.Value.ToString(), r => r.Type);
var specialsBeforeEpisodes = new HashSet<string>();
var specialsAnchorDictionary = new Dictionary<EpisodeInfo, EpisodeInfo>();
var specialsList = new List<EpisodeInfo>();
var episodesList = new List<EpisodeInfo>();
Expand All @@ -126,7 +132,7 @@ public SeasonInfo(Series series, SeriesType? customType, IEnumerable<string> ext

// Iterate over the episodes once and store some values for later use.
int index = 0;
int lastNormalEpisode = 0;
int lastNormalEpisode = -1;
foreach (var episode in episodes) {
if (episode.Shoko.IsHidden)
continue;
Expand All @@ -147,11 +153,16 @@ public SeasonInfo(Series series, SeriesType? customType, IEnumerable<string> ext
}
else if (episode.AniDB.Type == EpisodeType.Special) {
specialsList.Add(episode);
var previousEpisode = episodes
.GetRange(lastNormalEpisode, index - lastNormalEpisode)
.FirstOrDefault(e => e.AniDB.Type == EpisodeType.Normal);
if (previousEpisode != null)
specialsAnchorDictionary[episode] = previousEpisode;
if (index == -1) {
specialsBeforeEpisodes.Add(episode.Id);
}
else {
var previousEpisode = episodes
.GetRange(lastNormalEpisode, index - lastNormalEpisode)
.FirstOrDefault(e => e.AniDB.Type == EpisodeType.Normal);
if (previousEpisode != null)
specialsAnchorDictionary[episode] = previousEpisode;
}
}
break;
}
Expand Down Expand Up @@ -191,18 +202,24 @@ public SeasonInfo(Series series, SeriesType? customType, IEnumerable<string> ext

// Re-create the special anchors because the episode list changed.
index = 0;
lastNormalEpisode = 0;
lastNormalEpisode = -1;
specialsBeforeEpisodes.Clear();
specialsAnchorDictionary.Clear();
foreach (var episode in episodes) {
if (episodesList.Contains(episode)) {
lastNormalEpisode = index;
}
else if (specialsList.Contains(episode)) {
var previousEpisode = episodes
.GetRange(lastNormalEpisode, index - lastNormalEpisode)
.FirstOrDefault(e => e.AniDB.Type == EpisodeType.Normal);
if (previousEpisode != null)
specialsAnchorDictionary[episode] = previousEpisode;
if (index == -1) {
specialsBeforeEpisodes.Add(episode.Id);
}
else {
var previousEpisode = episodes
.GetRange(lastNormalEpisode, index - lastNormalEpisode)
.FirstOrDefault(e => specialsList.Contains(e));
if (previousEpisode != null)
specialsAnchorDictionary[episode] = previousEpisode;
}
}
index++;
}
Expand Down Expand Up @@ -242,6 +259,7 @@ public SeasonInfo(Series series, SeriesType? customType, IEnumerable<string> ext
EpisodeList = episodesList;
AlternateEpisodesList = altEpisodesList;
ExtrasList = extrasList;
SpecialsBeforeEpisodes = specialsBeforeEpisodes;
SpecialsAnchors = specialsAnchorDictionary;
SpecialsList = specialsList;
Relations = relations;
Expand Down
5 changes: 5 additions & 0 deletions Shokofin/Utils/Ordering.cs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,11 @@ public static (int?, int?, int?, bool) GetSpecialPlacement(ShowInfo showInfo, Se
byAirDate:
// Reset the order if we come from `SpecialOrderType.InBetweenSeasonMixed`.
episodeNumber = null;
if (seasonInfo.SpecialsBeforeEpisodes.Contains(episodeInfo.Id)) {
airsBeforeSeasonNumber = seasonNumber;
break;
}

if (seasonInfo.SpecialsAnchors.TryGetValue(episodeInfo, out var previousEpisode))
episodeNumber = GetEpisodeNumber(showInfo, seasonInfo, previousEpisode);

Expand Down

0 comments on commit 4b92e26

Please sign in to comment.