Skip to content

Commit

Permalink
fix: better "missing" episode removal logic
Browse files Browse the repository at this point in the history
This should hopefully fix the faulty removal logic for good… hopefully.
  • Loading branch information
revam committed Jan 20, 2025
1 parent 8cc7496 commit b31ea80
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 50 deletions.
17 changes: 10 additions & 7 deletions Shokofin/Providers/CustomEpisodeProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

namespace Shokofin.Providers;
#pragma warning disable IDE0059
#pragma warning disable IDE0290

/// <summary>
/// The custom episode provider. Responsible for de-duplicating episodes, both
Expand All @@ -25,7 +24,7 @@ namespace Shokofin.Providers;
/// about how a provider cannot also be a custom provider otherwise it won't
/// save the metadata.
/// </remarks>
public class CustomEpisodeProvider(ILogger<CustomEpisodeProvider> _logger, ILibraryManager _libraryManager, MergeVersionsManager _mergeVersionsManager) : IHasItemChangeMonitor, ICustomMetadataProvider<Episode> {
public class CustomEpisodeProvider(ILogger<CustomEpisodeProvider> _logger, ILibraryManager _libraryManager, IIdLookup _lookup, MergeVersionsManager _mergeVersionsManager) : IHasItemChangeMonitor, ICustomMetadataProvider<Episode> {
public string Name => Plugin.MetadataProviderName;

public bool HasChanged(BaseItem item, IDirectoryService directoryService) {
Expand All @@ -46,13 +45,17 @@ public async Task<ItemUpdateType> FetchAsync(Episode episode, MetadataRefreshOpt
return ItemUpdateType.None;

var itemUpdated = ItemUpdateType.None;
if (episode.TryGetProviderId(ShokoEpisodeId.Name, out var episodeId)) {
using (Plugin.Instance.Tracker.Enter($"Providing custom info for Episode \"{episode.Name}\". (Path=\"{episode.Path}\",IsMissingEpisode={episode.IsMissingEpisode})"))
if (RemoveDuplicates(_libraryManager, _logger, episodeId, episode, series.GetPresentationUniqueKey()))
itemUpdated |= ItemUpdateType.MetadataEdit;
if (_lookup.TryGetEpisodeIdsFor(episode, out var episodeIds)) {
using (Plugin.Instance.Tracker.Enter($"Providing custom info for Episode \"{episode.Name}\". (Path=\"{episode.Path}\",IsMissingEpisode={episode.IsMissingEpisode})")) {
foreach (var episodeId in episodeIds) {
if (RemoveDuplicates(_libraryManager, _logger, episodeId, episode, series.GetPresentationUniqueKey()))
itemUpdated |= ItemUpdateType.MetadataEdit;
}
}

if (Plugin.Instance.Configuration.AutoMergeVersions && !_libraryManager.IsScanRunning && options.MetadataRefreshMode != MetadataRefreshMode.ValidationOnly) {
await _mergeVersionsManager.SplitAndMergeEpisodesByEpisodeId(episodeId).ConfigureAwait(false);
foreach (var episodeId in episodeIds)
await _mergeVersionsManager.SplitAndMergeEpisodesByEpisodeId(episodeId).ConfigureAwait(false);
itemUpdated |= ItemUpdateType.MetadataEdit;
}
}
Expand Down
34 changes: 9 additions & 25 deletions Shokofin/Providers/CustomSeasonProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,22 +87,14 @@ public async Task<ItemUpdateType> FetchAsync(Season season, MetadataRefreshOptio
.ToHashSet();
var existingEpisodes = new HashSet<string>();
var toRemoveEpisodes = new List<Episode>();
foreach (var episode in season.Children.OfType<Episode>()) {
if (_lookup.TryGetEpisodeIdsFor(episode, out var episodeIds)) {
if ((string.IsNullOrEmpty(episode.Path) || episode.IsVirtualItem) && !knownEpisodeIds.Overlaps(episodeIds)) {
var orderedEpisodes = season.Children.OfType<Episode>().OrderBy(e => e.IndexNumber).ThenBy(e => e.IndexNumberEnd).ThenByDescending(e => e.IsVirtualItem).ToList();
foreach (var episode in orderedEpisodes) {
if (_lookup.TryGetEpisodeIdsFor(episode, out var episodeIds))
if ((string.IsNullOrEmpty(episode.Path) || episode.IsVirtualItem) && (!knownEpisodeIds.Overlaps(episodeIds) || existingEpisodes.Overlaps(episodeIds)))
toRemoveEpisodes.Add(episode);
}
else {
else
foreach (var episodeId in episodeIds)
existingEpisodes.Add(episodeId);
}
}
else if (_lookup.TryGetEpisodeIdFor(episode, out var episodeId)) {
if ((string.IsNullOrEmpty(episode.Path) || episode.IsVirtualItem) && !knownEpisodeIds.Contains(episodeId))
toRemoveEpisodes.Add(episode);
else
existingEpisodes.Add(episodeId);
}
}

// Remove unknown or unwanted episodes.
Expand Down Expand Up @@ -150,22 +142,14 @@ public async Task<ItemUpdateType> FetchAsync(Season season, MetadataRefreshOptio
: [];
var existingEpisodes = new HashSet<string>();
var toRemoveEpisodes = new List<Episode>();
foreach (var episode in season.Children.OfType<Episode>()) {
var orderedEpisodes = season.Children.OfType<Episode>().OrderBy(e => e.IndexNumber).ThenBy(e => e.IndexNumberEnd).ThenByDescending(e => e.IsVirtualItem).ToList();
foreach (var episode in orderedEpisodes) {
if (_lookup.TryGetEpisodeIdsFor(episode, out var episodeIds)) {
if ((string.IsNullOrEmpty(episode.Path) || episode.IsVirtualItem) && !knownEpisodeIds.Overlaps(episodeIds)) {
if ((string.IsNullOrEmpty(episode.Path) || episode.IsVirtualItem) && (!knownEpisodeIds.Overlaps(episodeIds) || existingEpisodes.Overlaps(episodeIds)))
toRemoveEpisodes.Add(episode);
}
else {
else
foreach (var episodeId in episodeIds)
existingEpisodes.Add(episodeId);
}

}
else if (_lookup.TryGetEpisodeIdFor(episode, out var episodeId)) {
if ((string.IsNullOrEmpty(episode.Path) || episode.IsVirtualItem) && !knownEpisodeIds.Contains(episodeId))
toRemoveEpisodes.Add(episode);
else
existingEpisodes.Add(episodeId);
}
}

Expand Down
27 changes: 9 additions & 18 deletions Shokofin/Providers/CustomSeriesProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public async Task<ItemUpdateType> FetchAsync(Series series, MetadataRefreshOptio
}

// Add missing seasons.
if (ShouldAddMetadata && options.MetadataRefreshMode != MetadataRefreshMode.ValidationOnly)
if (ShouldAddMetadata && options.MetadataRefreshMode != MetadataRefreshMode.ValidationOnly)
foreach (var (seasonNumber, season) in CreateMissingSeasons(showInfo, series, seasons)) {
itemUpdated |= ItemUpdateType.MetadataImport;
seasons.TryAdd(seasonNumber, season);
Expand All @@ -130,19 +130,14 @@ public async Task<ItemUpdateType> FetchAsync(Series series, MetadataRefreshOptio
.ToHashSet();
var existingEpisodes = new HashSet<string>();
var toRemoveEpisodes = new List<Episode>();
foreach (var episode in zeroSeason.Children.OfType<Episode>()) {
var orderedEpisodes = zeroSeason.Children.OfType<Episode>().OrderBy(e => e.IndexNumber).ThenBy(e => e.IndexNumberEnd).ThenByDescending(e => e.IsVirtualItem).ToList();
foreach (var episode in orderedEpisodes) {
if (_lookup.TryGetEpisodeIdsFor(episode, out var episodeIds))
if ((string.IsNullOrEmpty(episode.Path) || episode.IsVirtualItem) && !knownEpisodeIds.Overlaps(episodeIds))
if ((string.IsNullOrEmpty(episode.Path) || episode.IsVirtualItem) && (!knownEpisodeIds.Overlaps(episodeIds) || existingEpisodes.Overlaps(episodeIds)))
toRemoveEpisodes.Add(episode);
else
else
foreach (var episodeId in episodeIds)
existingEpisodes.Add(episodeId);
else if (_lookup.TryGetEpisodeIdFor(episode, out var episodeId)) {
if ((string.IsNullOrEmpty(episode.Path) || episode.IsVirtualItem) && !knownEpisodeIds.Contains(episodeId))
toRemoveEpisodes.Add(episode);
else
existingEpisodes.Add(episodeId);
}
}

// Remove unknown or unwanted episodes.
Expand Down Expand Up @@ -192,18 +187,14 @@ public async Task<ItemUpdateType> FetchAsync(Series series, MetadataRefreshOptio
var knownEpisodeIds = ShouldAddMetadata ? episodeList.Select(episodeInfo => episodeInfo.Id).ToHashSet() : [];
var existingEpisodes = new HashSet<string>();
var toRemoveEpisodes = new List<Episode>();
foreach (var episode in season.Children.OfType<Episode>()) {
if (_lookup.TryGetEpisodeIdsFor(episode, out var episodeIds))
if ((string.IsNullOrEmpty(episode.Path) || episode.IsVirtualItem) && !knownEpisodeIds.Overlaps(episodeIds))
var orderedEpisodes = season.Children.OfType<Episode>().OrderBy(e => e.IndexNumber).ThenBy(e => e.IndexNumberEnd).ThenByDescending(e => e.IsVirtualItem).ToList();
foreach (var episode in orderedEpisodes) {
if (_lookup.TryGetEpisodeIdsFor(episode, out var episodeIds)) {
if ((string.IsNullOrEmpty(episode.Path) || episode.IsVirtualItem) && (!knownEpisodeIds.Overlaps(episodeIds) || existingEpisodes.Overlaps(episodeIds)))
toRemoveEpisodes.Add(episode);
else
foreach (var episodeId in episodeIds)
existingEpisodes.Add(episodeId);
else if (_lookup.TryGetEpisodeIdFor(episode, out var episodeId)) {
if ((string.IsNullOrEmpty(episode.Path) || episode.IsVirtualItem) && !knownEpisodeIds.Contains(episodeId))
toRemoveEpisodes.Add(episode);
else
existingEpisodes.Add(episodeId);
}
}

Expand Down

0 comments on commit b31ea80

Please sign in to comment.