diff --git a/src/NzbDrone.Core/NzbDrone.Core.csproj b/src/NzbDrone.Core/NzbDrone.Core.csproj index 6c7875871..56c632442 100644 --- a/src/NzbDrone.Core/NzbDrone.Core.csproj +++ b/src/NzbDrone.Core/NzbDrone.Core.csproj @@ -892,6 +892,7 @@ + diff --git a/src/NzbDrone.Core/Tv/EpisodeAddedService.cs b/src/NzbDrone.Core/Tv/EpisodeAddedService.cs new file mode 100644 index 000000000..54e3d2991 --- /dev/null +++ b/src/NzbDrone.Core/Tv/EpisodeAddedService.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NLog; +using NzbDrone.Common.Cache; +using NzbDrone.Common.Extensions; +using NzbDrone.Core.IndexerSearch; +using NzbDrone.Core.Messaging.Commands; +using NzbDrone.Core.Messaging.Events; +using NzbDrone.Core.Tv.Events; + +namespace NzbDrone.Core.Tv +{ + public interface IEpisodeAddedService + { + void SearchForRecentlyAdded(int seriesId); + } + + public class EpisodeAddedService : IHandle, IEpisodeAddedService + { + private readonly IManageCommandQueue _commandQueueManager; + private readonly IEpisodeService _episodeService; + private readonly Logger _logger; + private readonly ICached> _addedEpisodesCache; + + public EpisodeAddedService(ICacheManager cacheManager, + IManageCommandQueue commandQueueManager, + IEpisodeService episodeService, + Logger logger) + { + _commandQueueManager = commandQueueManager; + _episodeService = episodeService; + _logger = logger; + _addedEpisodesCache = cacheManager.GetCache>(GetType()); + } + + public void SearchForRecentlyAdded(int seriesId) + { + var previouslyAired = _addedEpisodesCache.Find(seriesId.ToString()); + + if (previouslyAired != null && previouslyAired.Any()) + { + var missing = previouslyAired.Select(e => _episodeService.GetEpisode(e)).Where(e => !e.HasFile).ToList(); + + if (missing.Any()) + { + _commandQueueManager.Push(new EpisodeSearchCommand(missing.Select(e => e.Id).ToList())); + } + } + + _addedEpisodesCache.Remove(seriesId.ToString()); + } + + public void Handle(EpisodeInfoRefreshedEvent message) + { + if (message.Series.AddOptions == null) + { + if (!message.Series.Monitored) + { + _logger.Debug("Series is not monitored"); + return; + } + + if (message.Added.Empty()) + { + _logger.Debug("No new episodes, skipping search"); + return; + } + + if (message.Added.None(a => a.AirDateUtc.HasValue)) + { + _logger.Debug("No new episodes have an air date"); + return; + } + + var previouslyAired = message.Added.Where(a => a.AirDateUtc.HasValue && a.AirDateUtc.Value.Before(DateTime.UtcNow.AddDays(1)) && a.Monitored).ToList(); + + if (previouslyAired.Empty()) + { + _logger.Debug("Newly added episodes all air in the future"); + return; + } + + _addedEpisodesCache.Set(message.Series.Id.ToString(), previouslyAired.Select(e => e.Id).ToList()); + } + } + } +} diff --git a/src/NzbDrone.Core/Tv/SeriesScannedHandler.cs b/src/NzbDrone.Core/Tv/SeriesScannedHandler.cs index aa8d90d5a..9d208c764 100644 --- a/src/NzbDrone.Core/Tv/SeriesScannedHandler.cs +++ b/src/NzbDrone.Core/Tv/SeriesScannedHandler.cs @@ -12,17 +12,20 @@ public class SeriesScannedHandler : IHandle, private readonly IEpisodeMonitoredService _episodeMonitoredService; private readonly ISeriesService _seriesService; private readonly IManageCommandQueue _commandQueueManager; - + private readonly IEpisodeAddedService _episodeAddedService; + private readonly Logger _logger; public SeriesScannedHandler(IEpisodeMonitoredService episodeMonitoredService, ISeriesService seriesService, IManageCommandQueue commandQueueManager, + IEpisodeAddedService episodeAddedService, Logger logger) { _episodeMonitoredService = episodeMonitoredService; _seriesService = seriesService; _commandQueueManager = commandQueueManager; + _episodeAddedService = episodeAddedService; _logger = logger; } @@ -30,6 +33,7 @@ private void HandleScanEvents(Series series) { if (series.AddOptions == null) { + _episodeAddedService.SearchForRecentlyAdded(series.Id); return; }