Posting nzbs to SAB instead of sending an URL to download

This commit is contained in:
Mark McDowall 2013-10-18 22:35:34 -07:00
parent a5e08eefae
commit fa2bc76102
4 changed files with 103 additions and 58 deletions

View File

@ -1,4 +1,5 @@
using System;
using System.IO;
using System.Linq;
using System.Net;
using FizzWare.NBuilder;
@ -46,30 +47,6 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
.ToList();
}
private void WithFailResponse()
{
Mocker.GetMock<IHttpProvider>()
.Setup(s => s.DownloadString(It.IsAny<String>())).Returns("{ \"status\": false, \"error\": \"API Key Required\" }");
}
[Test]
public void add_url_should_format_request_properly()
{
Mocker.GetMock<IHttpProvider>(MockBehavior.Strict)
.Setup(s => s.DownloadString("http://192.168.5.55:2222/api?mode=addurl&name=http://www.nzbclub.com/nzb_download.aspx?mid=1950232&priority=0&pp=3&cat=tv&nzbname=My+Series+Name+-+5x2-5x3+-+My+title+%5bBluray720p%5d+%5bProper%5d&output=json&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass"))
.Returns("{ \"status\": true }");
Subject.DownloadNzb(_remoteEpisode);
}
[Test]
public void add_by_url_should_detect_and_handle_sab_errors()
{
WithFailResponse();
Assert.Throws<ApplicationException>(() => Subject.DownloadNzb(_remoteEpisode));
}
[Test]
public void should_be_able_to_get_categories_when_config_is_passed_in()
{
@ -195,15 +172,6 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
result.Should().Be("0.6.9");
}
[Test]
public void should_throw_when_WebException_is_thrown()
{
Mocker.GetMock<IHttpProvider>()
.Setup(s => s.DownloadString(It.IsAny<String>())).Throws(new WebException());
Assert.Throws<WebException>(() => Subject.DownloadNzb(_remoteEpisode));
}
[Test]
public void downloadNzb_should_use_sabRecentTvPriority_when_recentEpisode_is_true()
{
@ -211,16 +179,10 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
.SetupGet(s => s.SabRecentTvPriority)
.Returns(SabPriorityType.High);
Mocker.GetMock<IHttpProvider>()
.Setup(s => s.DownloadString("http://192.168.5.55:2222/api?mode=addurl&name=http://www.nzbclub.com/nzb_download.aspx?mid=1950232&priority=1&pp=3&cat=tv&nzbname=My+Series+Name+-+5x2-5x3+-+My+title+%5bBluray720p%5d+%5bProper%5d&output=json&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass"))
.Returns("{ \"status\": true }");
Subject.DownloadNzb(_remoteEpisode);
Mocker.GetMock<IHttpProvider>()
.Verify(v => v.DownloadString("http://192.168.5.55:2222/api?mode=addurl&name=http://www.nzbclub.com/nzb_download.aspx?mid=1950232&priority=1&pp=3&cat=tv&nzbname=My+Series+Name+-+5x2-5x3+-+My+title+%5bBluray720p%5d+%5bProper%5d&output=json&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass"), Times.Once());
Mocker.GetMock<ISabCommunicationProxy>()
.Verify(v => v.DownloadNzb(It.IsAny<Stream>(), It.IsAny<String>(), It.IsAny<String>(), (int)SabPriorityType.High), Times.Once());
}
}
}

View File

@ -0,0 +1,88 @@
using System;
using System.IO;
using NzbDrone.Common.Serializer;
using NzbDrone.Core.Configuration;
using RestSharp;
namespace NzbDrone.Core.Download.Clients.Sabnzbd
{
public interface ISabCommunicationProxy
{
string DownloadNzb(Stream nzb, string name, string category, int priority);
string ProcessRequest(IRestRequest restRequest, string action);
}
public class SabCommunicationProxy : ISabCommunicationProxy
{
private readonly IConfigService _configService;
public SabCommunicationProxy(IConfigService configService)
{
_configService = configService;
}
public string DownloadNzb(Stream nzb, string title, string category, int priority)
{
var request = new RestRequest(Method.POST);
var action = String.Format("mode=addfile&cat={0}&priority={1}", category, priority);
request.AddFile("name", ReadFully(nzb), title, "application/x-nzb");
return ProcessRequest(request, action);
}
public string ProcessRequest(IRestRequest restRequest, string action)
{
var client = BuildClient(action);
var response = client.Execute(restRequest);
CheckForError(response);
return response.Content;
}
private IRestClient BuildClient(string action)
{
var protocol = _configService.SabUseSsl ? "https" : "http";
var url = string.Format(@"{0}://{1}:{2}/api?{3}&apikey={4}&ma_username={5}&ma_password={6}&output=json",
protocol,
_configService.SabHost,
_configService.SabPort,
action,
_configService.SabApiKey,
_configService.SabUsername,
_configService.SabPassword);
return new RestClient(url);
}
private void CheckForError(IRestResponse response)
{
if (response.ResponseStatus != ResponseStatus.Completed)
{
throw new ApplicationException("Unable to connect to SABnzbd, please check your settings");
}
var result = Json.Deserialize<SabJsonError>(response.Content);
if (result.Status != null && result.Status.Equals("false", StringComparison.InvariantCultureIgnoreCase))
throw new ApplicationException(result.Error);
}
//TODO: Find a better home for this
private byte[] ReadFully(Stream input)
{
byte[] buffer = new byte[16 * 1024];
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
return ms.ToArray();
}
}
}
}

View File

@ -55,6 +55,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
private readonly IConfigService _configService;
private readonly IHttpProvider _httpProvider;
private readonly IParsingService _parsingService;
private readonly ISabCommunicationProxy _sabCommunicationProxy;
private readonly ICached<IEnumerable<QueueItem>> _queueCache;
private readonly Logger _logger;
@ -62,11 +63,13 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
IHttpProvider httpProvider,
ICacheManger cacheManger,
IParsingService parsingService,
ISabCommunicationProxy sabCommunicationProxy,
Logger logger)
{
_configService = configService;
_httpProvider = httpProvider;
_parsingService = parsingService;
_sabCommunicationProxy = sabCommunicationProxy;
_queueCache = cacheManger.GetCache<IEnumerable<QueueItem>>(GetType(), "queue");
_logger = logger;
}
@ -75,24 +78,16 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
{
var url = remoteEpisode.Release.DownloadUrl;
var title = remoteEpisode.Release.Title;
var category = _configService.SabTvCategory;
var priority = remoteEpisode.IsRecentEpisode() ? (int)_configService.SabRecentTvPriority : (int)_configService.SabOlderTvPriority;
string cat = _configService.SabTvCategory;
int priority = remoteEpisode.IsRecentEpisode() ? (int)_configService.SabRecentTvPriority : (int)_configService.SabOlderTvPriority;
string name = url.Replace("&", "%26");
string nzbName = HttpUtility.UrlEncode(title);
string action = string.Format("mode=addurl&name={0}&priority={1}&pp=3&cat={2}&nzbname={3}&output=json",
name, priority, cat, nzbName);
string request = GetSabRequest(action);
using (var nzb = _httpProvider.DownloadStream(url))
{
_logger.Info("Adding report [{0}] to the queue.", title);
var response = _httpProvider.DownloadString(request);
var response = _sabCommunicationProxy.DownloadNzb(nzb, title, category, priority);
_logger.Debug("Queue Response: [{0}]", response);
CheckForError(response);
}
}
public bool IsConfigured

View File

@ -225,6 +225,7 @@
<Compile Include="Download\Clients\Sabnzbd\JsonConverters\SabnzbdPriorityTypeConverter.cs" />
<Compile Include="Download\Clients\Sabnzbd\JsonConverters\SabnzbdQueueTimeConverter.cs" />
<Compile Include="Download\Clients\Sabnzbd\SabAutoConfigureService.cs" />
<Compile Include="Download\Clients\Sabnzbd\SabCommunicationProxy.cs" />
<Compile Include="Download\DownloadApprovedReports.cs" />
<Compile Include="Download\DownloadClientProvider.cs" />
<Compile Include="Download\DownloadClientType.cs" />
@ -627,7 +628,6 @@
</Content>
</ItemGroup>
<ItemGroup>
<Folder Include="Download\Clients\Sabnzbd\Api\" />
<Folder Include="Download\Clients\uTorrent\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />