diff --git a/src/NzbDrone.Core.Test/Download/DownloadApprovedReportsTests/DownloadApprovedFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadApprovedReportsTests/DownloadApprovedFixture.cs index 588e65c0f..7fa234327 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadApprovedReportsTests/DownloadApprovedFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadApprovedReportsTests/DownloadApprovedFixture.cs @@ -68,7 +68,7 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests decisions.Add(new DownloadDecision(remoteBook)); await Subject.ProcessDecisions(decisions); - Mocker.GetMock().Verify(v => v.DownloadReport(It.IsAny()), Times.Once()); + Mocker.GetMock().Verify(v => v.DownloadReport(It.IsAny(), null), Times.Once()); } [Test] @@ -82,7 +82,7 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests decisions.Add(new DownloadDecision(remoteBook)); await Subject.ProcessDecisions(decisions); - Mocker.GetMock().Verify(v => v.DownloadReport(It.IsAny()), Times.Once()); + Mocker.GetMock().Verify(v => v.DownloadReport(It.IsAny(), null), Times.Once()); } [Test] @@ -101,7 +101,7 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests decisions.Add(new DownloadDecision(remoteBook2)); await Subject.ProcessDecisions(decisions); - Mocker.GetMock().Verify(v => v.DownloadReport(It.IsAny()), Times.Once()); + Mocker.GetMock().Verify(v => v.DownloadReport(It.IsAny(), null), Times.Once()); } [Test] @@ -172,7 +172,7 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests var decisions = new List(); decisions.Add(new DownloadDecision(remoteBook)); - Mocker.GetMock().Setup(s => s.DownloadReport(It.IsAny())).Throws(new Exception()); + Mocker.GetMock().Setup(s => s.DownloadReport(It.IsAny(), null)).Throws(new Exception()); var result = await Subject.ProcessDecisions(decisions); @@ -201,7 +201,7 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests decisions.Add(new DownloadDecision(remoteBook, new Rejection("Failure!", RejectionType.Temporary))); await Subject.ProcessDecisions(decisions); - Mocker.GetMock().Verify(v => v.DownloadReport(It.IsAny()), Times.Never()); + Mocker.GetMock().Verify(v => v.DownloadReport(It.IsAny(), null), Times.Never()); } [Test] @@ -242,11 +242,11 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests decisions.Add(new DownloadDecision(remoteBook)); decisions.Add(new DownloadDecision(remoteBook)); - Mocker.GetMock().Setup(s => s.DownloadReport(It.IsAny())) + Mocker.GetMock().Setup(s => s.DownloadReport(It.IsAny(), null)) .Throws(new DownloadClientUnavailableException("Download client failed")); await Subject.ProcessDecisions(decisions); - Mocker.GetMock().Verify(v => v.DownloadReport(It.IsAny()), Times.Once()); + Mocker.GetMock().Verify(v => v.DownloadReport(It.IsAny(), null), Times.Once()); } [Test] @@ -260,12 +260,12 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests decisions.Add(new DownloadDecision(remoteBook)); decisions.Add(new DownloadDecision(remoteBook2)); - Mocker.GetMock().Setup(s => s.DownloadReport(It.Is(r => r.Release.DownloadProtocol == DownloadProtocol.Usenet))) + Mocker.GetMock().Setup(s => s.DownloadReport(It.Is(r => r.Release.DownloadProtocol == DownloadProtocol.Usenet), null)) .Throws(new DownloadClientUnavailableException("Download client failed")); await Subject.ProcessDecisions(decisions); - Mocker.GetMock().Verify(v => v.DownloadReport(It.Is(r => r.Release.DownloadProtocol == DownloadProtocol.Usenet)), Times.Once()); - Mocker.GetMock().Verify(v => v.DownloadReport(It.Is(r => r.Release.DownloadProtocol == DownloadProtocol.Torrent)), Times.Once()); + Mocker.GetMock().Verify(v => v.DownloadReport(It.Is(r => r.Release.DownloadProtocol == DownloadProtocol.Usenet), null), Times.Once()); + Mocker.GetMock().Verify(v => v.DownloadReport(It.Is(r => r.Release.DownloadProtocol == DownloadProtocol.Torrent), null), Times.Once()); } [Test] @@ -278,7 +278,7 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests decisions.Add(new DownloadDecision(remoteBook)); Mocker.GetMock() - .Setup(s => s.DownloadReport(It.IsAny())) + .Setup(s => s.DownloadReport(It.IsAny(), null)) .Throws(new ReleaseUnavailableException(remoteBook.Release, "That 404 Error is not just a Quirk")); var result = await Subject.ProcessDecisions(decisions); diff --git a/src/NzbDrone.Core.Test/Download/DownloadServiceFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadServiceFixture.cs index 39af065f1..f036fbb90 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadServiceFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadServiceFixture.cs @@ -83,7 +83,7 @@ namespace NzbDrone.Core.Test.Download var mock = WithUsenetClient(); mock.Setup(s => s.Download(It.IsAny(), It.IsAny())); - await Subject.DownloadReport(_parseResult); + await Subject.DownloadReport(_parseResult, null); VerifyEventPublished(); } @@ -94,7 +94,7 @@ namespace NzbDrone.Core.Test.Download var mock = WithUsenetClient(); mock.Setup(s => s.Download(It.IsAny(), It.IsAny())); - await Subject.DownloadReport(_parseResult); + await Subject.DownloadReport(_parseResult, null); mock.Verify(s => s.Download(It.IsAny(), It.IsAny()), Times.Once()); } @@ -106,7 +106,7 @@ namespace NzbDrone.Core.Test.Download mock.Setup(s => s.Download(It.IsAny(), It.IsAny())) .Throws(new WebException()); - Assert.ThrowsAsync(async () => await Subject.DownloadReport(_parseResult)); + Assert.ThrowsAsync(async () => await Subject.DownloadReport(_parseResult, null)); VerifyEventNotPublished(); } @@ -121,7 +121,7 @@ namespace NzbDrone.Core.Test.Download throw new ReleaseDownloadException(v.Release, "Error", new WebException()); }); - Assert.ThrowsAsync(async () => await Subject.DownloadReport(_parseResult)); + Assert.ThrowsAsync(async () => await Subject.DownloadReport(_parseResult, null)); Mocker.GetMock() .Verify(v => v.RecordFailure(It.IsAny(), It.IsAny()), Times.Once()); @@ -141,7 +141,7 @@ namespace NzbDrone.Core.Test.Download throw new ReleaseDownloadException(v.Release, "Error", new TooManyRequestsException(request, response)); }); - Assert.ThrowsAsync(async () => await Subject.DownloadReport(_parseResult)); + Assert.ThrowsAsync(async () => await Subject.DownloadReport(_parseResult, null)); Mocker.GetMock() .Verify(v => v.RecordFailure(It.IsAny(), TimeSpan.FromMinutes(5.0)), Times.Once()); @@ -161,7 +161,7 @@ namespace NzbDrone.Core.Test.Download throw new ReleaseDownloadException(v.Release, "Error", new TooManyRequestsException(request, response)); }); - Assert.ThrowsAsync(async () => await Subject.DownloadReport(_parseResult)); + Assert.ThrowsAsync(async () => await Subject.DownloadReport(_parseResult, null)); Mocker.GetMock() .Verify(v => v.RecordFailure(It.IsAny(), @@ -175,7 +175,7 @@ namespace NzbDrone.Core.Test.Download mock.Setup(s => s.Download(It.IsAny(), It.IsAny())) .Throws(new DownloadClientException("Some Error")); - Assert.ThrowsAsync(async () => await Subject.DownloadReport(_parseResult)); + Assert.ThrowsAsync(async () => await Subject.DownloadReport(_parseResult, null)); Mocker.GetMock() .Verify(v => v.RecordFailure(It.IsAny(), It.IsAny()), Times.Never()); @@ -191,7 +191,7 @@ namespace NzbDrone.Core.Test.Download throw new ReleaseUnavailableException(v.Release, "Error", new WebException()); }); - Assert.ThrowsAsync(async () => await Subject.DownloadReport(_parseResult)); + Assert.ThrowsAsync(async () => await Subject.DownloadReport(_parseResult, null)); Mocker.GetMock() .Verify(v => v.RecordFailure(It.IsAny(), It.IsAny()), Times.Never()); @@ -200,7 +200,7 @@ namespace NzbDrone.Core.Test.Download [Test] public void should_not_attempt_download_if_client_isnt_configured() { - Assert.ThrowsAsync(async () => await Subject.DownloadReport(_parseResult)); + Assert.ThrowsAsync(async () => await Subject.DownloadReport(_parseResult, null)); Mocker.GetMock().Verify(c => c.Download(It.IsAny(), It.IsAny()), Times.Never()); VerifyEventNotPublished(); @@ -222,7 +222,7 @@ namespace NzbDrone.Core.Test.Download } }); - await Subject.DownloadReport(_parseResult); + await Subject.DownloadReport(_parseResult, null); Mocker.GetMock().Verify(c => c.GetBlockedProviders(), Times.Never()); mockUsenet.Verify(c => c.Download(It.IsAny(), It.IsAny()), Times.Once()); @@ -235,7 +235,7 @@ namespace NzbDrone.Core.Test.Download var mockTorrent = WithTorrentClient(); var mockUsenet = WithUsenetClient(); - await Subject.DownloadReport(_parseResult); + await Subject.DownloadReport(_parseResult, null); mockTorrent.Verify(c => c.Download(It.IsAny(), It.IsAny()), Times.Never()); mockUsenet.Verify(c => c.Download(It.IsAny(), It.IsAny()), Times.Once()); @@ -249,7 +249,7 @@ namespace NzbDrone.Core.Test.Download _parseResult.Release.DownloadProtocol = DownloadProtocol.Torrent; - await Subject.DownloadReport(_parseResult); + await Subject.DownloadReport(_parseResult, null); mockTorrent.Verify(c => c.Download(It.IsAny(), It.IsAny()), Times.Once()); mockUsenet.Verify(c => c.Download(It.IsAny(), It.IsAny()), Times.Never()); diff --git a/src/NzbDrone.Core/Download/DownloadService.cs b/src/NzbDrone.Core/Download/DownloadService.cs index 1436e6957..da27d66d3 100644 --- a/src/NzbDrone.Core/Download/DownloadService.cs +++ b/src/NzbDrone.Core/Download/DownloadService.cs @@ -17,7 +17,7 @@ namespace NzbDrone.Core.Download { public interface IDownloadService { - Task DownloadReport(RemoteBook remoteBook); + Task DownloadReport(RemoteBook remoteBook, int? downloadClientId); } public class DownloadService : IDownloadService @@ -50,13 +50,15 @@ namespace NzbDrone.Core.Download _logger = logger; } - public async Task DownloadReport(RemoteBook remoteBook) + public async Task DownloadReport(RemoteBook remoteBook, int? downloadClientId) { var filterBlockedClients = remoteBook.Release.PendingReleaseReason == PendingReleaseReason.DownloadClientUnavailable; var tags = remoteBook.Author?.Tags; - var downloadClient = _downloadClientProvider.GetDownloadClient(remoteBook.Release.DownloadProtocol, remoteBook.Release.IndexerId, filterBlockedClients, tags); + var downloadClient = downloadClientId.HasValue + ? _downloadClientProvider.Get(downloadClientId.Value) + : _downloadClientProvider.GetDownloadClient(remoteBook.Release.DownloadProtocol, remoteBook.Release.IndexerId, filterBlockedClients, tags); await DownloadReport(remoteBook, downloadClient); } diff --git a/src/NzbDrone.Core/Download/ProcessDownloadDecisions.cs b/src/NzbDrone.Core/Download/ProcessDownloadDecisions.cs index 24228a357..41f8797bf 100644 --- a/src/NzbDrone.Core/Download/ProcessDownloadDecisions.cs +++ b/src/NzbDrone.Core/Download/ProcessDownloadDecisions.cs @@ -76,7 +76,7 @@ namespace NzbDrone.Core.Download try { _logger.Trace("Grabbing from Indexer {0} at priority {1}.", remoteBook.Release.Indexer, remoteBook.Release.IndexerPriority); - await _downloadService.DownloadReport(remoteBook); + await _downloadService.DownloadReport(remoteBook, null); grabbed.Add(report); } catch (ReleaseUnavailableException) diff --git a/src/Readarr.Api.V1/Indexers/ReleaseController.cs b/src/Readarr.Api.V1/Indexers/ReleaseController.cs index 0671b0ef8..293ed54e0 100644 --- a/src/Readarr.Api.V1/Indexers/ReleaseController.cs +++ b/src/Readarr.Api.V1/Indexers/ReleaseController.cs @@ -124,7 +124,7 @@ namespace Readarr.Api.V1.Indexers throw new NzbDroneClientException(HttpStatusCode.NotFound, "Unable to parse books in the release"); } - await _downloadService.DownloadReport(remoteBook); + await _downloadService.DownloadReport(remoteBook, release.DownloadClientId); } catch (ReleaseDownloadException ex) { diff --git a/src/Readarr.Api.V1/Indexers/ReleaseResource.cs b/src/Readarr.Api.V1/Indexers/ReleaseResource.cs index 6aa84fe4d..e2453d34d 100644 --- a/src/Readarr.Api.V1/Indexers/ReleaseResource.cs +++ b/src/Readarr.Api.V1/Indexers/ReleaseResource.cs @@ -56,6 +56,9 @@ namespace Readarr.Api.V1.Indexers [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] public int? BookId { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public int? DownloadClientId { get; set; } } public static class ReleaseResourceMapper diff --git a/src/Readarr.Api.V1/Queue/QueueActionController.cs b/src/Readarr.Api.V1/Queue/QueueActionController.cs index 52bcdcd11..e7398509c 100644 --- a/src/Readarr.Api.V1/Queue/QueueActionController.cs +++ b/src/Readarr.Api.V1/Queue/QueueActionController.cs @@ -30,7 +30,7 @@ namespace Readarr.Api.V1.Queue throw new NotFoundException(); } - await _downloadService.DownloadReport(pendingRelease.RemoteBook); + await _downloadService.DownloadReport(pendingRelease.RemoteBook, null); return new { }; } @@ -48,7 +48,7 @@ namespace Readarr.Api.V1.Queue throw new NotFoundException(); } - await _downloadService.DownloadReport(pendingRelease.RemoteBook); + await _downloadService.DownloadReport(pendingRelease.RemoteBook, null); } return new { };