diff --git a/src/NzbDrone.Core.Test/Download/DownloadServiceFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadServiceFixture.cs index 44057879f..e3bd72eb1 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadServiceFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadServiceFixture.cs @@ -31,7 +31,7 @@ namespace NzbDrone.Core.Test.Download .Returns(_downloadClients); Mocker.GetMock<IProvideDownloadClient>() - .Setup(v => v.GetDownloadClient(It.IsAny<DownloadProtocol>(), It.IsAny<int>())) + .Setup(v => v.GetDownloadClient(It.IsAny<DownloadProtocol>(), It.IsAny<int>(), It.IsAny<bool>())) .Returns<DownloadProtocol, int>((v, i) => _downloadClients.FirstOrDefault(d => d.Protocol == v)); var episodes = Builder<Album>.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<IDownloadClient> GetDownloadClients(bool filterBlockedClients = false); IDownloadClient Get(int id); } @@ -35,8 +35,9 @@ namespace NzbDrone.Core.Download _lastUsedDownloadClient = cacheManager.GetCache<int>(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<int>(_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<int>(_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 b038cc01e..21853f88a 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; @@ -54,7 +55,8 @@ namespace NzbDrone.Core.Download Ensure.That(remoteAlbum.Albums, () => remoteAlbum.Albums).HasItems(); var downloadTitle = remoteAlbum.Release.Title; - var downloadClient = _downloadClientProvider.GetDownloadClient(remoteAlbum.Release.DownloadProtocol, remoteAlbum.Release.IndexerId); + var filterBlockedClients = remoteAlbum.Release.PendingReleaseReason == PendingReleaseReason.DownloadClientUnavailable; + var downloadClient = _downloadClientProvider.GetDownloadClient(remoteAlbum.Release.DownloadProtocol, remoteAlbum.Release.IndexerId, filterBlockedClients); if (downloadClient == null) { diff --git a/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs b/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs index 5828664d0..128fc94ed 100644 --- a/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs +++ b/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs @@ -146,7 +146,14 @@ namespace NzbDrone.Core.Download.Pending public List<ReleaseInfo> 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 1d56b893e..fbd5f34b8 100644 --- a/src/NzbDrone.Core/Parser/Model/ReleaseInfo.cs +++ b/src/NzbDrone.Core/Parser/Model/ReleaseInfo.cs @@ -1,5 +1,7 @@ using System; using System.Text; +using Newtonsoft.Json; +using NzbDrone.Core.Download.Pending; using NzbDrone.Core.Indexers; namespace NzbDrone.Core.Parser.Model @@ -26,6 +28,10 @@ namespace NzbDrone.Core.Parser.Model public string Codec { get; set; } public string Resolution { get; set; } + // Used to track pending releases that are being reprocessed + [JsonIgnore] + public PendingReleaseReason? PendingReleaseReason { get; set; } + public int Age { get { return DateTime.UtcNow.Subtract(PublishDate).Days; }