diff --git a/src/NzbDrone.Core.Test/Download/DownloadServiceFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadServiceFixture.cs index a5f42ab49..330235ea1 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadServiceFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadServiceFixture.cs @@ -22,6 +22,7 @@ namespace NzbDrone.Core.Test.Download { private RemoteEpisode _parseResult; private List _downloadClients; + [SetUp] public void Setup() { @@ -180,7 +181,7 @@ namespace NzbDrone.Core.Test.Download } [Test] - public void should_not_attempt_download_if_client_isnt_configure() + public void should_not_attempt_download_if_client_isnt_configured() { Assert.Throws(() => Subject.DownloadReport(_parseResult)); @@ -188,6 +189,21 @@ namespace NzbDrone.Core.Test.Download VerifyEventNotPublished(); } + [Test] + public void should_not_attempt_download_if_client_is_disabled() + { + WithUsenetClient(); + + Mocker.GetMock() + .Setup(v => v.IsDisabled(It.IsAny())) + .Returns(true); + + Assert.Throws(() => Subject.DownloadReport(_parseResult)); + + Mocker.GetMock().Verify(c => c.Download(It.IsAny()), Times.Never()); + VerifyEventNotPublished(); + } + [Test] public void should_send_download_to_correct_usenet_client() { diff --git a/src/NzbDrone.Core/Download/DownloadService.cs b/src/NzbDrone.Core/Download/DownloadService.cs index cc4b3464f..f0837b4c5 100644 --- a/src/NzbDrone.Core/Download/DownloadService.cs +++ b/src/NzbDrone.Core/Download/DownloadService.cs @@ -1,4 +1,4 @@ -using System; +using System; using NLog; using NzbDrone.Common.EnsureThat; using NzbDrone.Common.Extensions; @@ -56,6 +56,11 @@ namespace NzbDrone.Core.Download throw new DownloadClientUnavailableException($"{remoteEpisode.Release.DownloadProtocol} Download client isn't configured yet"); } + if (_downloadClientStatusService.IsDisabled(downloadClient.Definition.Id)) + { + throw new DownloadClientUnavailableException($"{downloadClient.Name} is disabled due to recent failues"); + } + // Limit grabs to 2 per second. if (remoteEpisode.Release.DownloadUrl.IsNotNullOrWhiteSpace() && !remoteEpisode.Release.DownloadUrl.StartsWith("magnet:")) { diff --git a/src/NzbDrone.Core/ThingiProvider/Status/ProviderStatusServiceBase.cs b/src/NzbDrone.Core/ThingiProvider/Status/ProviderStatusServiceBase.cs index b74153947..4de86a56a 100644 --- a/src/NzbDrone.Core/ThingiProvider/Status/ProviderStatusServiceBase.cs +++ b/src/NzbDrone.Core/ThingiProvider/Status/ProviderStatusServiceBase.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using NLog; @@ -10,6 +10,7 @@ namespace NzbDrone.Core.ThingiProvider.Status public interface IProviderStatusServiceBase where TModel : ProviderStatusBase, new() { + bool IsDisabled(int providerId); List GetBlockedProviders(); void RecordSuccess(int providerId); void RecordFailure(int providerId, TimeSpan minimumBackOff = default(TimeSpan)); @@ -36,6 +37,11 @@ namespace NzbDrone.Core.ThingiProvider.Status _logger = logger; } + public bool IsDisabled(int providerId) + { + return GetProviderStatus(providerId).IsDisabled(); + } + public virtual List GetBlockedProviders() { return _providerStatusRepository.All().Where(v => v.IsDisabled()).ToList();