diff --git a/src/NzbDrone.Core.Test/Download/DownloadServiceFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadServiceFixture.cs index d6185ea5e..9a1ae9719 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadServiceFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadServiceFixture.cs @@ -32,7 +32,7 @@ namespace NzbDrone.Core.Test.Download .Returns(_downloadClients); Mocker.GetMock() - .Setup(v => v.GetDownloadClient(It.IsAny(), It.IsAny())) + .Setup(v => v.GetDownloadClient(It.IsAny(), It.IsAny(), It.IsAny())) .Returns((v, i) => _downloadClients.FirstOrDefault(d => d.Protocol == v)); var episodes = Builder.CreateListOfSize(2) diff --git a/src/NzbDrone.Core/Download/DownloadClientProvider.cs b/src/NzbDrone.Core/Download/DownloadClientProvider.cs index df9249dcc..370b66dea 100644 --- a/src/NzbDrone.Core/Download/DownloadClientProvider.cs +++ b/src/NzbDrone.Core/Download/DownloadClientProvider.cs @@ -9,7 +9,7 @@ namespace NzbDrone.Core.Download { public interface IProvideDownloadClient { - IDownloadClient GetDownloadClient(DownloadProtocol downloadProtocol, int indexerId = 0); + IDownloadClient GetDownloadClient(DownloadProtocol downloadProtocol, int indexerId = 0, bool filterBlockedClients = false); IEnumerable GetDownloadClients(bool filterBlockedClients = false); IDownloadClient Get(int id); } @@ -35,8 +35,9 @@ namespace NzbDrone.Core.Download _lastUsedDownloadClient = cacheManager.GetCache(GetType(), "lastDownloadClientId"); } - public IDownloadClient GetDownloadClient(DownloadProtocol downloadProtocol, int indexerId = 0) + public IDownloadClient GetDownloadClient(DownloadProtocol downloadProtocol, int indexerId = 0, bool filterBlockedClients = false) { + var blockedProviders = new HashSet(_downloadClientStatusService.GetBlockedProviders().Select(v => v.ProviderId)); var availableProviders = _downloadClientFactory.GetAvailableProviders().Where(v => v.Protocol == downloadProtocol).ToList(); if (!availableProviders.Any()) @@ -52,12 +53,15 @@ namespace NzbDrone.Core.Download { var client = availableProviders.SingleOrDefault(d => d.Definition.Id == indexer.DownloadClientId); - return client ?? throw new DownloadClientUnavailableException($"Indexer specified download client is not available"); + if (client == null || (filterBlockedClients && blockedProviders.Contains(client.Definition.Id))) + { + throw new DownloadClientUnavailableException($"Indexer specified download client is not available"); + } + + return client; } } - var blockedProviders = new HashSet(_downloadClientStatusService.GetBlockedProviders().Select(v => v.ProviderId)); - if (blockedProviders.Any()) { var nonBlockedProviders = availableProviders.Where(v => !blockedProviders.Contains(v.Definition.Id)).ToList(); @@ -66,6 +70,10 @@ namespace NzbDrone.Core.Download { availableProviders = nonBlockedProviders; } + else if (filterBlockedClients) + { + throw new DownloadClientUnavailableException($"All download clients for {downloadProtocol} are not available"); + } else { _logger.Trace("No non-blocked Download Client available, retrying blocked one."); diff --git a/src/NzbDrone.Core/Download/DownloadService.cs b/src/NzbDrone.Core/Download/DownloadService.cs index c867d3396..be09564b7 100644 --- a/src/NzbDrone.Core/Download/DownloadService.cs +++ b/src/NzbDrone.Core/Download/DownloadService.cs @@ -6,6 +6,7 @@ using NzbDrone.Common.Http; using NzbDrone.Common.Instrumentation.Extensions; using NzbDrone.Common.TPL; using NzbDrone.Core.Download.Clients; +using NzbDrone.Core.Download.Pending; using NzbDrone.Core.Exceptions; using NzbDrone.Core.Indexers; using NzbDrone.Core.Messaging.Events; @@ -50,9 +51,11 @@ namespace NzbDrone.Core.Download public void DownloadReport(RemoteEpisode remoteEpisode, int? downloadClientId) { + var filterBlockedClients = remoteEpisode.Release.PendingReleaseReason == PendingReleaseReason.DownloadClientUnavailable; + var downloadClient = downloadClientId.HasValue ? _downloadClientProvider.Get(downloadClientId.Value) - : _downloadClientProvider.GetDownloadClient(remoteEpisode.Release.DownloadProtocol, remoteEpisode.Release.IndexerId); + : _downloadClientProvider.GetDownloadClient(remoteEpisode.Release.DownloadProtocol, remoteEpisode.Release.IndexerId, filterBlockedClients); DownloadReport(remoteEpisode, downloadClient); } diff --git a/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs b/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs index c4a34a9cc..0145d956a 100644 --- a/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs +++ b/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs @@ -139,7 +139,14 @@ namespace NzbDrone.Core.Download.Pending public List GetPending() { - var releases = _repository.All().Select(p => p.Release).ToList(); + var releases = _repository.All().Select(p => + { + var release = p.Release; + + release.PendingReleaseReason = p.Reason; + + return release; + }).ToList(); if (releases.Any()) { diff --git a/src/NzbDrone.Core/Parser/Model/ReleaseInfo.cs b/src/NzbDrone.Core/Parser/Model/ReleaseInfo.cs index 044bd11d4..8d37deea6 100644 --- a/src/NzbDrone.Core/Parser/Model/ReleaseInfo.cs +++ b/src/NzbDrone.Core/Parser/Model/ReleaseInfo.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; using System.Text; +using Newtonsoft.Json; +using NzbDrone.Core.Download.Pending; using NzbDrone.Core.Indexers; using NzbDrone.Core.Languages; @@ -37,6 +39,10 @@ namespace NzbDrone.Core.Parser.Model public List Languages { get; set; } + // Used to track pending releases that are being reprocessed + [JsonIgnore] + public PendingReleaseReason? PendingReleaseReason { get; set; } + public int Age { get