|
|
|
@ -14,6 +14,7 @@ namespace NzbDrone.Core.Download
|
|
|
|
|
public interface IProcessDownloadDecisions
|
|
|
|
|
{
|
|
|
|
|
Task<ProcessedDecisions> ProcessDecisions(List<DownloadDecision> decisions);
|
|
|
|
|
Task<ProcessedDecisionResult> ProcessDecision(DownloadDecision decision, int? downloadClientId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class ProcessDownloadDecisions : IProcessDownloadDecisions
|
|
|
|
@ -49,7 +50,6 @@ namespace NzbDrone.Core.Download
|
|
|
|
|
|
|
|
|
|
foreach (var report in prioritizedDecisions)
|
|
|
|
|
{
|
|
|
|
|
var remoteEpisode = report.RemoteEpisode;
|
|
|
|
|
var downloadProtocol = report.RemoteEpisode.Release.DownloadProtocol;
|
|
|
|
|
|
|
|
|
|
// Skip if already grabbed
|
|
|
|
@ -71,37 +71,48 @@ namespace NzbDrone.Core.Download
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
_logger.Trace("Grabbing from Indexer {0} at priority {1}.", remoteEpisode.Release.Indexer, remoteEpisode.Release.IndexerPriority);
|
|
|
|
|
await _downloadService.DownloadReport(remoteEpisode, null);
|
|
|
|
|
grabbed.Add(report);
|
|
|
|
|
}
|
|
|
|
|
catch (ReleaseUnavailableException)
|
|
|
|
|
{
|
|
|
|
|
_logger.Warn("Failed to download release from indexer, no longer available. " + remoteEpisode);
|
|
|
|
|
rejected.Add(report);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
var result = await ProcessDecisionInternal(report);
|
|
|
|
|
|
|
|
|
|
switch (result)
|
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
case ProcessedDecisionResult.Grabbed:
|
|
|
|
|
{
|
|
|
|
|
grabbed.Add(report);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case ProcessedDecisionResult.Pending:
|
|
|
|
|
{
|
|
|
|
|
PreparePending(pendingAddQueue, grabbed, pending, report, PendingReleaseReason.Delay);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case ProcessedDecisionResult.Rejected:
|
|
|
|
|
{
|
|
|
|
|
rejected.Add(report);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (downloadProtocol == DownloadProtocol.Usenet)
|
|
|
|
|
case ProcessedDecisionResult.Failed:
|
|
|
|
|
{
|
|
|
|
|
usenetFailed = true;
|
|
|
|
|
PreparePending(pendingAddQueue, grabbed, pending, report, PendingReleaseReason.DownloadClientUnavailable);
|
|
|
|
|
|
|
|
|
|
if (downloadProtocol == DownloadProtocol.Usenet)
|
|
|
|
|
{
|
|
|
|
|
usenetFailed = true;
|
|
|
|
|
}
|
|
|
|
|
else if (downloadProtocol == DownloadProtocol.Torrent)
|
|
|
|
|
{
|
|
|
|
|
torrentFailed = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else if (downloadProtocol == DownloadProtocol.Torrent)
|
|
|
|
|
|
|
|
|
|
case ProcessedDecisionResult.Skipped:
|
|
|
|
|
{
|
|
|
|
|
torrentFailed = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_logger.Warn(ex, "Couldn't add report to download queue. " + remoteEpisode);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -113,6 +124,30 @@ namespace NzbDrone.Core.Download
|
|
|
|
|
return new ProcessedDecisions(grabbed, pending, rejected);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task<ProcessedDecisionResult> ProcessDecision(DownloadDecision decision, int? downloadClientId)
|
|
|
|
|
{
|
|
|
|
|
if (decision == null)
|
|
|
|
|
{
|
|
|
|
|
return ProcessedDecisionResult.Skipped;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (decision.TemporarilyRejected)
|
|
|
|
|
{
|
|
|
|
|
_pendingReleaseService.Add(decision, PendingReleaseReason.Delay);
|
|
|
|
|
|
|
|
|
|
return ProcessedDecisionResult.Pending;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var result = await ProcessDecisionInternal(decision, downloadClientId);
|
|
|
|
|
|
|
|
|
|
if (result == ProcessedDecisionResult.Failed)
|
|
|
|
|
{
|
|
|
|
|
_pendingReleaseService.Add(decision, PendingReleaseReason.DownloadClientUnavailable);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal List<DownloadDecision> GetQualifiedReports(IEnumerable<DownloadDecision> decisions)
|
|
|
|
|
{
|
|
|
|
|
// Process both approved and temporarily rejected
|
|
|
|
@ -147,5 +182,38 @@ namespace NzbDrone.Core.Download
|
|
|
|
|
queue.Add(Tuple.Create(report, reason));
|
|
|
|
|
pending.Add(report);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async Task<ProcessedDecisionResult> ProcessDecisionInternal(DownloadDecision decision, int? downloadClientId = null)
|
|
|
|
|
{
|
|
|
|
|
var remoteEpisode = decision.RemoteEpisode;
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
_logger.Trace("Grabbing from Indexer {0} at priority {1}.", remoteEpisode.Release.Indexer, remoteEpisode.Release.IndexerPriority);
|
|
|
|
|
await _downloadService.DownloadReport(remoteEpisode, downloadClientId);
|
|
|
|
|
|
|
|
|
|
return ProcessedDecisionResult.Grabbed;
|
|
|
|
|
}
|
|
|
|
|
catch (ReleaseUnavailableException)
|
|
|
|
|
{
|
|
|
|
|
_logger.Warn("Failed to download release from indexer, no longer available. " + remoteEpisode);
|
|
|
|
|
return ProcessedDecisionResult.Rejected;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
if (ex is DownloadClientUnavailableException || ex is DownloadClientAuthenticationException)
|
|
|
|
|
{
|
|
|
|
|
_logger.Debug(ex,
|
|
|
|
|
"Failed to send release to download client, storing until later. " + remoteEpisode);
|
|
|
|
|
|
|
|
|
|
return ProcessedDecisionResult.Failed;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_logger.Warn(ex, "Couldn't add report to download queue. " + remoteEpisode);
|
|
|
|
|
return ProcessedDecisionResult.Skipped;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|