mirror of
https://github.com/Readarr/Readarr.git
synced 2026-04-18 21:34:28 -04:00
New: Optional 'downloadClientId' for pushed releases
(cherry picked from commit fa5bfc3742c24c5730b77bf8178a423d98fdf50e) Closes #2934
This commit is contained in:
@@ -14,6 +14,7 @@ namespace NzbDrone.Core.Download
|
|||||||
public interface IProcessDownloadDecisions
|
public interface IProcessDownloadDecisions
|
||||||
{
|
{
|
||||||
Task<ProcessedDecisions> ProcessDecisions(List<DownloadDecision> decisions);
|
Task<ProcessedDecisions> ProcessDecisions(List<DownloadDecision> decisions);
|
||||||
|
Task<ProcessedDecisionResult> ProcessDecision(DownloadDecision decision, int? downloadClientId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ProcessDownloadDecisions : IProcessDownloadDecisions
|
public class ProcessDownloadDecisions : IProcessDownloadDecisions
|
||||||
@@ -40,8 +41,6 @@ namespace NzbDrone.Core.Download
|
|||||||
var prioritizedDecisions = _prioritizeDownloadDecision.PrioritizeDecisions(qualifiedReports);
|
var prioritizedDecisions = _prioritizeDownloadDecision.PrioritizeDecisions(qualifiedReports);
|
||||||
var grabbed = new List<DownloadDecision>();
|
var grabbed = new List<DownloadDecision>();
|
||||||
var pending = new List<DownloadDecision>();
|
var pending = new List<DownloadDecision>();
|
||||||
|
|
||||||
//var failed = new List<DownloadDecision>();
|
|
||||||
var rejected = decisions.Where(d => d.Rejected).ToList();
|
var rejected = decisions.Where(d => d.Rejected).ToList();
|
||||||
|
|
||||||
var pendingAddQueue = new List<Tuple<DownloadDecision, PendingReleaseReason>>();
|
var pendingAddQueue = new List<Tuple<DownloadDecision, PendingReleaseReason>>();
|
||||||
@@ -51,7 +50,6 @@ namespace NzbDrone.Core.Download
|
|||||||
|
|
||||||
foreach (var report in prioritizedDecisions)
|
foreach (var report in prioritizedDecisions)
|
||||||
{
|
{
|
||||||
var remoteBook = report.RemoteBook;
|
|
||||||
var downloadProtocol = report.RemoteBook.Release.DownloadProtocol;
|
var downloadProtocol = report.RemoteBook.Release.DownloadProtocol;
|
||||||
|
|
||||||
//Skip if already grabbed
|
//Skip if already grabbed
|
||||||
@@ -73,37 +71,48 @@ namespace NzbDrone.Core.Download
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
var result = await ProcessDecisionInternal(report);
|
||||||
{
|
|
||||||
_logger.Trace("Grabbing from Indexer {0} at priority {1}.", remoteBook.Release.Indexer, remoteBook.Release.IndexerPriority);
|
|
||||||
await _downloadService.DownloadReport(remoteBook, null);
|
|
||||||
grabbed.Add(report);
|
|
||||||
}
|
|
||||||
catch (ReleaseUnavailableException)
|
|
||||||
{
|
|
||||||
_logger.Warn("Failed to download release from indexer, no longer available. " + remoteBook);
|
|
||||||
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. " + remoteBook);
|
|
||||||
PreparePending(pendingAddQueue, grabbed, pending, report, PendingReleaseReason.DownloadClientUnavailable);
|
|
||||||
|
|
||||||
if (downloadProtocol == DownloadProtocol.Usenet)
|
switch (result)
|
||||||
|
{
|
||||||
|
case ProcessedDecisionResult.Grabbed:
|
||||||
{
|
{
|
||||||
usenetFailed = true;
|
grabbed.Add(report);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (downloadProtocol == DownloadProtocol.Torrent)
|
|
||||||
|
case ProcessedDecisionResult.Pending:
|
||||||
{
|
{
|
||||||
torrentFailed = true;
|
PreparePending(pendingAddQueue, grabbed, pending, report, PendingReleaseReason.Delay);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ProcessedDecisionResult.Rejected:
|
||||||
|
{
|
||||||
|
rejected.Add(report);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ProcessedDecisionResult.Failed:
|
||||||
|
{
|
||||||
|
PreparePending(pendingAddQueue, grabbed, pending, report, PendingReleaseReason.DownloadClientUnavailable);
|
||||||
|
|
||||||
|
if (downloadProtocol == DownloadProtocol.Usenet)
|
||||||
|
{
|
||||||
|
usenetFailed = true;
|
||||||
|
}
|
||||||
|
else if (downloadProtocol == DownloadProtocol.Torrent)
|
||||||
|
{
|
||||||
|
torrentFailed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ProcessedDecisionResult.Skipped:
|
||||||
|
{
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_logger.Warn(ex, "Couldn't add report to download queue. " + remoteBook);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,6 +124,30 @@ namespace NzbDrone.Core.Download
|
|||||||
return new ProcessedDecisions(grabbed, pending, rejected);
|
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)
|
internal List<DownloadDecision> GetQualifiedReports(IEnumerable<DownloadDecision> decisions)
|
||||||
{
|
{
|
||||||
//Process both approved and temporarily rejected
|
//Process both approved and temporarily rejected
|
||||||
@@ -148,5 +181,38 @@ namespace NzbDrone.Core.Download
|
|||||||
queue.Add(Tuple.Create(report, reason));
|
queue.Add(Tuple.Create(report, reason));
|
||||||
pending.Add(report);
|
pending.Add(report);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<ProcessedDecisionResult> ProcessDecisionInternal(DownloadDecision decision, int? downloadClientId = null)
|
||||||
|
{
|
||||||
|
var remoteBook = decision.RemoteBook;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_logger.Trace("Grabbing from Indexer {0} at priority {1}.", remoteBook.Release.Indexer, remoteBook.Release.IndexerPriority);
|
||||||
|
await _downloadService.DownloadReport(remoteBook, downloadClientId);
|
||||||
|
|
||||||
|
return ProcessedDecisionResult.Grabbed;
|
||||||
|
}
|
||||||
|
catch (ReleaseUnavailableException)
|
||||||
|
{
|
||||||
|
_logger.Warn("Failed to download release from indexer, no longer available. " + remoteBook);
|
||||||
|
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. " + remoteBook);
|
||||||
|
|
||||||
|
return ProcessedDecisionResult.Failed;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.Warn(ex, "Couldn't add report to download queue. " + remoteBook);
|
||||||
|
return ProcessedDecisionResult.Skipped;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
namespace NzbDrone.Core.Download
|
||||||
|
{
|
||||||
|
public enum ProcessedDecisionResult
|
||||||
|
{
|
||||||
|
Grabbed,
|
||||||
|
Pending,
|
||||||
|
Rejected,
|
||||||
|
Failed,
|
||||||
|
Skipped
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -53,22 +53,23 @@ namespace Readarr.Api.V1.Indexers
|
|||||||
|
|
||||||
ResolveIndexer(info);
|
ResolveIndexer(info);
|
||||||
|
|
||||||
List<DownloadDecision> decisions;
|
DownloadDecision decision;
|
||||||
|
|
||||||
lock (PushLock)
|
lock (PushLock)
|
||||||
{
|
{
|
||||||
decisions = _downloadDecisionMaker.GetRssDecision(new List<ReleaseInfo> { info }, true);
|
var decisions = _downloadDecisionMaker.GetRssDecision(new List<ReleaseInfo> { info }, true);
|
||||||
_downloadDecisionProcessor.ProcessDecisions(decisions).GetAwaiter().GetResult();
|
|
||||||
|
decision = decisions.FirstOrDefault();
|
||||||
|
|
||||||
|
_downloadDecisionProcessor.ProcessDecision(decision, release.DownloadClientId).GetAwaiter().GetResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
var firstDecision = decisions.FirstOrDefault();
|
if (decision?.RemoteBook.ParsedBookInfo == null)
|
||||||
|
|
||||||
if (firstDecision?.RemoteBook.ParsedBookInfo == null)
|
|
||||||
{
|
{
|
||||||
throw new ValidationException(new List<ValidationFailure> { new ValidationFailure("Title", "Unable to parse", release.Title) });
|
throw new ValidationException(new List<ValidationFailure> { new ("Title", "Unable to parse", release.Title) });
|
||||||
}
|
}
|
||||||
|
|
||||||
return MapDecisions(new[] { firstDecision }).First();
|
return MapDecisions(new[] { decision }).First();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ResolveIndexer(ReleaseInfo release)
|
private void ResolveIndexer(ReleaseInfo release)
|
||||||
|
|||||||
Reference in New Issue
Block a user