From 56436fea697131614b19fb5f9c1b58902be42093 Mon Sep 17 00:00:00 2001 From: Taloth Saldono Date: Sun, 7 Sep 2014 13:39:00 +0200 Subject: [PATCH] Fixed: Now shows UI notification if downloading nzb from indexer fails. --- src/NzbDrone.Api/Indexers/ReleaseModule.cs | 12 +++- .../NzbgetTests/NzbgetFixture.cs | 4 +- .../SabnzbdTests/SabnzbdFixture.cs | 8 +-- .../Download/Clients/Nzbget/Nzbget.cs | 28 ++------ .../Download/Clients/Nzbget/NzbgetProxy.cs | 6 +- .../Download/Clients/Sabnzbd/Sabnzbd.cs | 33 +++------ .../Download/Clients/Sabnzbd/SabnzbdProxy.cs | 6 +- .../Download/UsenetClientBase.cs | 72 +++++++++++++++++++ .../Exceptions/ReleaseDownloadException.cs | 34 +++++++++ src/NzbDrone.Core/NzbDrone.Core.csproj | 2 + 10 files changed, 145 insertions(+), 60 deletions(-) create mode 100644 src/NzbDrone.Core/Download/UsenetClientBase.cs create mode 100644 src/NzbDrone.Core/Exceptions/ReleaseDownloadException.cs diff --git a/src/NzbDrone.Api/Indexers/ReleaseModule.cs b/src/NzbDrone.Api/Indexers/ReleaseModule.cs index 4723d2728..3d8bf0721 100644 --- a/src/NzbDrone.Api/Indexers/ReleaseModule.cs +++ b/src/NzbDrone.Api/Indexers/ReleaseModule.cs @@ -6,6 +6,7 @@ using NLog; using NzbDrone.Api.Mapping; using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Download; +using NzbDrone.Core.Exceptions; using NzbDrone.Core.IndexerSearch; using NzbDrone.Core.Indexers; using NzbDrone.Core.Parser; @@ -16,6 +17,7 @@ using Nancy.ModelBinding; using NzbDrone.Api.Extensions; using NzbDrone.Common.Cache; using System.Threading; +using SystemNetHttpStatusCode = System.Net.HttpStatusCode; namespace NzbDrone.Api.Indexers { @@ -66,7 +68,15 @@ namespace NzbDrone.Api.Indexers return new NotFoundResponse(); } - _downloadService.DownloadReport(remoteEpisode); + try + { + _downloadService.DownloadReport(remoteEpisode); + } + catch (ReleaseDownloadException ex) + { + _logger.ErrorException(ex.Message, ex); + throw new NzbDroneClientException(SystemNetHttpStatusCode.Conflict, "Getting release from indexer failed"); + } return release.AsResponse(); } diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/NzbgetTests/NzbgetFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/NzbgetTests/NzbgetFixture.cs index be5f6e3e7..08d269339 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/NzbgetTests/NzbgetFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/NzbgetTests/NzbgetFixture.cs @@ -100,14 +100,14 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetTests protected void GivenFailedDownload() { Mocker.GetMock() - .Setup(s => s.DownloadNzb(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(s => s.DownloadNzb(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) .Returns((String)null); } protected void GivenSuccessfulDownload() { Mocker.GetMock() - .Setup(s => s.DownloadNzb(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(s => s.DownloadNzb(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) .Returns(Guid.NewGuid().ToString().Replace("-", "")); } diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/SabnzbdTests/SabnzbdFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/SabnzbdTests/SabnzbdFixture.cs index 730ec9ff2..c12623df0 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/SabnzbdTests/SabnzbdFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/SabnzbdTests/SabnzbdFixture.cs @@ -114,14 +114,14 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests protected void GivenFailedDownload() { Mocker.GetMock() - .Setup(s => s.DownloadNzb(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(s => s.DownloadNzb(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) .Returns((SabnzbdAddResponse)null); } protected void GivenSuccessfulDownload() { Mocker.GetMock() - .Setup(s => s.DownloadNzb(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(s => s.DownloadNzb(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) .Returns(new SabnzbdAddResponse() { Status = true, @@ -267,7 +267,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests public void Download_should_use_sabRecentTvPriority_when_recentEpisode_is_true() { Mocker.GetMock() - .Setup(s => s.DownloadNzb(It.IsAny(), It.IsAny(), It.IsAny(), (int)SabnzbdPriority.High, It.IsAny())) + .Setup(s => s.DownloadNzb(It.IsAny(), It.IsAny(), It.IsAny(), (int)SabnzbdPriority.High, It.IsAny())) .Returns(new SabnzbdAddResponse()); var remoteEpisode = CreateRemoteEpisode(); @@ -280,7 +280,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests Subject.Download(remoteEpisode); Mocker.GetMock() - .Verify(v => v.DownloadNzb(It.IsAny(), It.IsAny(), It.IsAny(), (int)SabnzbdPriority.High, It.IsAny()), Times.Once()); + .Verify(v => v.DownloadNzb(It.IsAny(), It.IsAny(), It.IsAny(), (int)SabnzbdPriority.High, It.IsAny()), Times.Once()); } [TestCase(@"Droned.S01E01.Pilot.1080p.WEB-DL-DRONE", @"Droned.S01E01_Pilot_1080p_WEB-DL-DRONE.mkv")] diff --git a/src/NzbDrone.Core/Download/Clients/Nzbget/Nzbget.cs b/src/NzbDrone.Core/Download/Clients/Nzbget/Nzbget.cs index 2b492e490..5ecb18beb 100644 --- a/src/NzbDrone.Core/Download/Clients/Nzbget/Nzbget.cs +++ b/src/NzbDrone.Core/Download/Clients/Nzbget/Nzbget.cs @@ -15,10 +15,9 @@ using NzbDrone.Core.Validation; namespace NzbDrone.Core.Download.Clients.Nzbget { - public class Nzbget : DownloadClientBase + public class Nzbget : UsenetClientBase { private readonly INzbgetProxy _proxy; - private readonly IHttpClient _httpClient; public Nzbget(INzbgetProxy proxy, IHttpClient httpClient, @@ -26,36 +25,19 @@ namespace NzbDrone.Core.Download.Clients.Nzbget IDiskProvider diskProvider, IParsingService parsingService, Logger logger) - : base(configService, diskProvider, parsingService, logger) + : base(httpClient, configService, diskProvider, parsingService, logger) { _proxy = proxy; - _httpClient = httpClient; } - public override DownloadProtocol Protocol + protected override string AddFromNzbFile(RemoteEpisode remoteEpisode, string filename, byte[] fileContent) { - get - { - return DownloadProtocol.Usenet; - } - } - - public override string Download(RemoteEpisode remoteEpisode) - { - var url = remoteEpisode.Release.DownloadUrl; - var title = remoteEpisode.Release.Title + ".nzb"; var category = Settings.TvCategory; var priority = remoteEpisode.IsRecentEpisode() ? Settings.RecentTvPriority : Settings.OlderTvPriority; - _logger.Info("Adding report [{0}] to the queue.", title); + var response = _proxy.DownloadNzb(fileContent, filename, category, priority, Settings); - using (var nzb = _httpClient.Get(new HttpRequest(url)).GetStream()) - { - _logger.Info("Adding report [{0}] to the queue.", title); - var response = _proxy.DownloadNzb(nzb, title, category, priority, Settings); - - return response; - } + return response; } private IEnumerable GetQueue() diff --git a/src/NzbDrone.Core/Download/Clients/Nzbget/NzbgetProxy.cs b/src/NzbDrone.Core/Download/Clients/Nzbget/NzbgetProxy.cs index 343250598..cbd4dccd9 100644 --- a/src/NzbDrone.Core/Download/Clients/Nzbget/NzbgetProxy.cs +++ b/src/NzbDrone.Core/Download/Clients/Nzbget/NzbgetProxy.cs @@ -12,7 +12,7 @@ namespace NzbDrone.Core.Download.Clients.Nzbget { public interface INzbgetProxy { - string DownloadNzb(Stream nzb, string title, string category, int priority, NzbgetSettings settings); + string DownloadNzb(Byte[] nzbData, string title, string category, int priority, NzbgetSettings settings); NzbgetGlobalStatus GetGlobalStatus(NzbgetSettings settings); List GetQueue(NzbgetSettings settings); List GetPostQueue(NzbgetSettings settings); @@ -32,9 +32,9 @@ namespace NzbDrone.Core.Download.Clients.Nzbget _logger = logger; } - public string DownloadNzb(Stream nzb, string title, string category, int priority, NzbgetSettings settings) + public string DownloadNzb(Byte[] nzbData, string title, string category, int priority, NzbgetSettings settings) { - var parameters = new object[] { title, category, priority, false, Convert.ToBase64String(nzb.ToBytes()) }; + var parameters = new object[] { title, category, priority, false, Convert.ToBase64String(nzbData) }; var request = BuildRequest(new JsonRequest("append", parameters)); var response = Json.Deserialize>(ProcessRequest(request, settings)); diff --git a/src/NzbDrone.Core/Download/Clients/Sabnzbd/Sabnzbd.cs b/src/NzbDrone.Core/Download/Clients/Sabnzbd/Sabnzbd.cs index c6bf31b6f..7dbd1a7a1 100644 --- a/src/NzbDrone.Core/Download/Clients/Sabnzbd/Sabnzbd.cs +++ b/src/NzbDrone.Core/Download/Clients/Sabnzbd/Sabnzbd.cs @@ -16,10 +16,9 @@ using NzbDrone.Core.Validation; namespace NzbDrone.Core.Download.Clients.Sabnzbd { - public class Sabnzbd : DownloadClientBase + public class Sabnzbd : UsenetClientBase { private readonly ISabnzbdProxy _proxy; - private readonly IHttpClient _httpClient; public Sabnzbd(ISabnzbdProxy proxy, IHttpClient httpClient, @@ -27,39 +26,25 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd IDiskProvider diskProvider, IParsingService parsingService, Logger logger) - : base(configService, diskProvider, parsingService, logger) + : base(httpClient, configService, diskProvider, parsingService, logger) { _proxy = proxy; - _httpClient = httpClient; } - public override DownloadProtocol Protocol + protected override string AddFromNzbFile(RemoteEpisode remoteEpisode, string filename, byte[] fileContent) { - get - { - return DownloadProtocol.Usenet; - } - } - - public override string Download(RemoteEpisode remoteEpisode) - { - var url = remoteEpisode.Release.DownloadUrl; var title = remoteEpisode.Release.Title; var category = Settings.TvCategory; var priority = remoteEpisode.IsRecentEpisode() ? Settings.RecentTvPriority : Settings.OlderTvPriority; - using (var nzb = _httpClient.Get(new HttpRequest(url)).GetStream()) + var response = _proxy.DownloadNzb(fileContent, title, category, priority, Settings); + + if (response != null && response.Ids.Any()) { - _logger.Info("Adding report [{0}] to the queue.", title); - var response = _proxy.DownloadNzb(nzb, title, category, priority, Settings); - - if (response != null && response.Ids.Any()) - { - return response.Ids.First(); - } - - return null; + return response.Ids.First(); } + + return null; } private IEnumerable GetQueue() diff --git a/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdProxy.cs b/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdProxy.cs index fb54f969c..ea1da6dcc 100644 --- a/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdProxy.cs +++ b/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdProxy.cs @@ -15,7 +15,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd { public interface ISabnzbdProxy { - SabnzbdAddResponse DownloadNzb(Stream nzb, string name, string category, int priority, SabnzbdSettings settings); + SabnzbdAddResponse DownloadNzb(Byte[] nzbData, string name, string category, int priority, SabnzbdSettings settings); void RemoveFrom(string source, string id, SabnzbdSettings settings); string ProcessRequest(IRestRequest restRequest, string action, SabnzbdSettings settings); SabnzbdVersionResponse GetVersion(SabnzbdSettings settings); @@ -34,12 +34,12 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd _logger = logger; } - public SabnzbdAddResponse DownloadNzb(Stream nzb, string title, string category, int priority, SabnzbdSettings settings) + public SabnzbdAddResponse DownloadNzb(Byte[] nzbData, string title, string category, int priority, SabnzbdSettings settings) { var request = new RestRequest(Method.POST); var action = String.Format("mode=addfile&cat={0}&priority={1}", category, priority); - request.AddFile("name", nzb.ToBytes(), title, "application/x-nzb"); + request.AddFile("name", nzbData, title, "application/x-nzb"); SabnzbdAddResponse response; diff --git a/src/NzbDrone.Core/Download/UsenetClientBase.cs b/src/NzbDrone.Core/Download/UsenetClientBase.cs new file mode 100644 index 000000000..24a79c328 --- /dev/null +++ b/src/NzbDrone.Core/Download/UsenetClientBase.cs @@ -0,0 +1,72 @@ +using System; +using System.IO; +using System.Linq; +using System.Collections.Generic; +using System.Net; +using NzbDrone.Common; +using NzbDrone.Common.Disk; +using NzbDrone.Common.Extensions; +using NzbDrone.Common.Http; +using NzbDrone.Core.Exceptions; +using NzbDrone.Core.Indexers; +using NzbDrone.Core.Organizer; +using NzbDrone.Core.Parser; +using NzbDrone.Core.Parser.Model; +using NzbDrone.Core.ThingiProvider; +using NzbDrone.Core.Configuration; +using NLog; + +namespace NzbDrone.Core.Download +{ + public abstract class UsenetClientBase : DownloadClientBase + where TSettings : IProviderConfig, new() + { + protected readonly IHttpClient _httpClient; + + protected UsenetClientBase(IHttpClient httpClient, + IConfigService configService, + IDiskProvider diskProvider, + IParsingService parsingService, + Logger logger) + : base(configService, diskProvider, parsingService, logger) + { + _httpClient = httpClient; + } + + public override DownloadProtocol Protocol + { + get + { + return DownloadProtocol.Usenet; + } + } + + protected abstract String AddFromNzbFile(RemoteEpisode remoteEpisode, String filename, Byte[] fileContent); + + public override String Download(RemoteEpisode remoteEpisode) + { + var url = remoteEpisode.Release.DownloadUrl; + var filename = FileNameBuilder.CleanFileName(remoteEpisode.Release.Title) + ".nzb"; + + Byte[] nzbData; + + try + { + using (var nzb = _httpClient.Get(new HttpRequest(url)).GetStream()) + { + nzbData = nzb.ToBytes(); + } + } + catch (WebException ex) + { + _logger.ErrorException(String.Format("Downloading nzb for episode '{0}' failed ({1})", + remoteEpisode.Release.Title, url), ex); + + throw new ReleaseDownloadException(remoteEpisode.Release, "Downloading nzb failed", ex); + } + + _logger.Info("Adding report [{0}] to the queue.", remoteEpisode.Release.Title); + return AddFromNzbFile(remoteEpisode, filename, nzbData); + } + } +} diff --git a/src/NzbDrone.Core/Exceptions/ReleaseDownloadException.cs b/src/NzbDrone.Core/Exceptions/ReleaseDownloadException.cs new file mode 100644 index 000000000..0f3f681b0 --- /dev/null +++ b/src/NzbDrone.Core/Exceptions/ReleaseDownloadException.cs @@ -0,0 +1,34 @@ +using System; +using NzbDrone.Common.Exceptions; +using NzbDrone.Core.Parser.Model; + +namespace NzbDrone.Core.Exceptions +{ + public class ReleaseDownloadException : NzbDroneException + { + public ReleaseInfo Release { get; set; } + + public ReleaseDownloadException(ReleaseInfo release, String message, params Object[] args) : base(message, args) + { + Release = release; + } + + public ReleaseDownloadException(ReleaseInfo release, String message) + : base(message) + { + Release = release; + } + + public ReleaseDownloadException(ReleaseInfo release, String message, Exception innerException, params Object[] args) + : base(message, innerException, args) + { + Release = release; + } + + public ReleaseDownloadException(ReleaseInfo release, String message, Exception innerException) + : base(message, innerException) + { + Release = release; + } + } +} diff --git a/src/NzbDrone.Core/NzbDrone.Core.csproj b/src/NzbDrone.Core/NzbDrone.Core.csproj index a2d4fac90..728c53c9a 100644 --- a/src/NzbDrone.Core/NzbDrone.Core.csproj +++ b/src/NzbDrone.Core/NzbDrone.Core.csproj @@ -314,6 +314,7 @@ + @@ -344,6 +345,7 @@ +