using System; using System.Linq; using NLog; using NzbDrone.Core.History; using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Messaging.Events; namespace NzbDrone.Core.Download { public class FailedDownloadService : IExecute { private readonly IProvideDownloadClient _downloadClientProvider; private readonly IHistoryService _historyService; private readonly IEventAggregator _eventAggregator; private readonly Logger _logger; private static string DOWNLOAD_CLIENT = "downloadClient"; private static string DOWNLOAD_CLIENT_ID = "downloadClientId"; public FailedDownloadService(IProvideDownloadClient downloadClientProvider, IHistoryService historyService, IEventAggregator eventAggregator, Logger logger) { _downloadClientProvider = downloadClientProvider; _historyService = historyService; _eventAggregator = eventAggregator; _logger = logger; } private void CheckForFailedDownloads() { var downloadClient = _downloadClientProvider.GetDownloadClient(); var downloadClientHistory = downloadClient.GetHistory(0, 20).ToList(); var failedItems = downloadClientHistory.Where(h => h.Status == HistoryStatus.Failed).ToList(); if (!failedItems.Any()) { _logger.Trace("Yay! No failed downloads"); return; } var grabbedHistory = _historyService.Grabbed(); var failedHistory = _historyService.Failed(); foreach (var failedItem in failedItems) { var failedLocal = failedItem; var historyItems = grabbedHistory.Where(h => h.Data.ContainsKey(DOWNLOAD_CLIENT) && h.Data[DOWNLOAD_CLIENT_ID].Equals(failedLocal.Id)) .ToList(); if (!historyItems.Any()) { _logger.Trace("Unable to find matching history item"); continue; } if (failedHistory.Any(h => h.Data.ContainsKey(DOWNLOAD_CLIENT_ID) && h.Data[DOWNLOAD_CLIENT_ID].Equals(failedLocal.Id))) { _logger.Trace("Already added to history as failed"); continue; } var historyItem = historyItems.First(); _eventAggregator.PublishEvent(new DownloadFailedEvent { SeriesId = historyItem.SeriesId, EpisodeIds = historyItems.Select(h => h.EpisodeId).ToList(), Quality = historyItem.Quality, SourceTitle = historyItem.SourceTitle, DownloadClient = historyItem.Data[DOWNLOAD_CLIENT], DownloadClientId = historyItem.Data[DOWNLOAD_CLIENT_ID], Message = failedItem.Message }); } } public void Execute(FailedDownloadCommand message) { CheckForFailedDownloads(); } } }