private List <DownloadDecision> ProcessFailedGrabs(List <DownloadDecision> grabbed, List <DownloadDecision> failed) { var pending = new List <DownloadDecision>(); var stored = new List <DownloadDecision>(); var addQueue = new List <Tuple <DownloadDecision, PendingReleaseReason> >(); foreach (var report in failed) { // If a release was already grabbed with matching episodes we should store it as a fallback // and filter it out the next time it is processed incase a higher quality release failed to // add to the download client, but a lower quality release was sent to another client // If the release wasn't grabbed already, but was already stored, store it as a fallback, // otherwise store it as DownloadClientUnavailable. if (IsEpisodeProcessed(grabbed, report)) { addQueue.Add(Tuple.Create(report, PendingReleaseReason.Fallback)); pending.Add(report); } else if (IsEpisodeProcessed(stored, report)) { addQueue.Add(Tuple.Create(report, PendingReleaseReason.Fallback)); pending.Add(report); } else { addQueue.Add(Tuple.Create(report, PendingReleaseReason.DownloadClientUnavailable)); pending.Add(report); stored.Add(report); } } if (addQueue.Any()) { _pendingReleaseService.AddMany(addQueue); } return(pending); }
public ProcessedDecisions ProcessDecisions(List <DownloadDecision> decisions) { var qualifiedReports = GetQualifiedReports(decisions); var prioritizedDecisions = _prioritizeDownloadDecision.PrioritizeDecisions(qualifiedReports); var grabbed = new List <DownloadDecision>(); var pending = new List <DownloadDecision>(); var rejected = decisions.Where(d => d.Rejected).ToList(); var pendingAddQueue = new List <Tuple <DownloadDecision, PendingReleaseReason> >(); var usenetFailed = false; var torrentFailed = false; foreach (var report in prioritizedDecisions) { var remoteEpisode = report.RemoteEpisode; var downloadProtocol = report.RemoteEpisode.Release.DownloadProtocol; // Skip if already grabbed if (IsEpisodeProcessed(grabbed, report)) { continue; } if (report.TemporarilyRejected) { PreparePending(pendingAddQueue, grabbed, pending, report, PendingReleaseReason.Delay); continue; } if (downloadProtocol == DownloadProtocol.Usenet && usenetFailed || downloadProtocol == DownloadProtocol.Torrent && torrentFailed) { PreparePending(pendingAddQueue, grabbed, pending, report, PendingReleaseReason.DownloadClientUnavailable); continue; } try { _downloadService.DownloadReport(remoteEpisode); grabbed.Add(report); } catch (ReleaseUnavailableException) { _logger.Warn("Failed to download release from indexer, no longer available. " + remoteEpisode); rejected.Add(report); } catch (Exception ex) { if (ex is DownloadClientUnavailableException || ex is DownloadClientAuthenticationException) { _logger.Debug(ex, "Failed to send release to download client, storing until later. " + remoteEpisode); PreparePending(pendingAddQueue, grabbed, pending, report, PendingReleaseReason.DownloadClientUnavailable); if (downloadProtocol == DownloadProtocol.Usenet) { usenetFailed = true; } else if (downloadProtocol == DownloadProtocol.Torrent) { torrentFailed = true; } } else { _logger.Warn(ex, "Couldn't add report to download queue. " + remoteEpisode); } } } if (pendingAddQueue.Any()) { _pendingReleaseService.AddMany(pendingAddQueue); } return(new ProcessedDecisions(grabbed, pending, rejected)); }