2014-02-14 05:31:49 +00:00
|
|
|
|
using System;
|
|
|
|
|
using Newtonsoft.Json.Linq;
|
|
|
|
|
using NLog;
|
2014-03-20 07:08:15 +00:00
|
|
|
|
using NzbDrone.Common.Extensions;
|
2014-02-14 05:31:49 +00:00
|
|
|
|
using NzbDrone.Common.Serializer;
|
|
|
|
|
using NzbDrone.Core.Download.Clients.Sabnzbd.Responses;
|
2016-02-28 16:34:24 +00:00
|
|
|
|
using NzbDrone.Common.Http;
|
2016-03-17 19:53:11 +00:00
|
|
|
|
using System.Net;
|
2014-02-14 05:31:49 +00:00
|
|
|
|
|
|
|
|
|
namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
|
|
|
|
{
|
|
|
|
|
public interface ISabnzbdProxy
|
|
|
|
|
{
|
2015-10-03 17:45:26 +00:00
|
|
|
|
SabnzbdAddResponse DownloadNzb(byte[] nzbData, string filename, string category, int priority, SabnzbdSettings settings);
|
2014-12-23 01:17:48 +00:00
|
|
|
|
void RemoveFrom(string source, string id,bool deleteData, SabnzbdSettings settings);
|
2016-02-17 06:40:12 +00:00
|
|
|
|
string GetVersion(SabnzbdSettings settings);
|
2014-07-04 20:27:21 +00:00
|
|
|
|
SabnzbdConfig GetConfig(SabnzbdSettings settings);
|
2014-02-14 05:31:49 +00:00
|
|
|
|
SabnzbdQueue GetQueue(int start, int limit, SabnzbdSettings settings);
|
2016-01-20 20:34:07 +00:00
|
|
|
|
SabnzbdHistory GetHistory(int start, int limit, string category, SabnzbdSettings settings);
|
2014-12-02 06:39:27 +00:00
|
|
|
|
string RetryDownload(string id, SabnzbdSettings settings);
|
2014-02-14 05:31:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class SabnzbdProxy : ISabnzbdProxy
|
|
|
|
|
{
|
2016-02-28 16:34:24 +00:00
|
|
|
|
private readonly IHttpClient _httpClient;
|
2014-02-14 05:31:49 +00:00
|
|
|
|
private readonly Logger _logger;
|
|
|
|
|
|
2016-02-28 16:34:24 +00:00
|
|
|
|
public SabnzbdProxy(IHttpClient httpClient, Logger logger)
|
2014-02-14 05:31:49 +00:00
|
|
|
|
{
|
2016-02-28 16:34:24 +00:00
|
|
|
|
_httpClient = httpClient;
|
2014-02-14 05:31:49 +00:00
|
|
|
|
_logger = logger;
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-03 17:45:26 +00:00
|
|
|
|
public SabnzbdAddResponse DownloadNzb(byte[] nzbData, string filename, string category, int priority, SabnzbdSettings settings)
|
2014-02-14 05:31:49 +00:00
|
|
|
|
{
|
2016-02-28 16:34:24 +00:00
|
|
|
|
var request = BuildRequest("addfile", settings).Post();
|
2014-02-14 05:31:49 +00:00
|
|
|
|
|
2016-02-28 16:34:24 +00:00
|
|
|
|
request.AddQueryParam("cat", category);
|
|
|
|
|
request.AddQueryParam("priority", priority);
|
|
|
|
|
|
|
|
|
|
request.AddFormUpload("name", filename, nzbData, "application/x-nzb");
|
2014-02-14 05:31:49 +00:00
|
|
|
|
|
|
|
|
|
SabnzbdAddResponse response;
|
|
|
|
|
|
2016-02-28 16:34:24 +00:00
|
|
|
|
if (!Json.TryDeserialize<SabnzbdAddResponse>(ProcessRequest(request, settings), out response))
|
2014-02-14 05:31:49 +00:00
|
|
|
|
{
|
|
|
|
|
response = new SabnzbdAddResponse();
|
|
|
|
|
response.Status = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return response;
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-23 01:17:48 +00:00
|
|
|
|
public void RemoveFrom(string source, string id, bool deleteData, SabnzbdSettings settings)
|
2014-02-14 05:31:49 +00:00
|
|
|
|
{
|
2016-02-28 16:34:24 +00:00
|
|
|
|
var request = BuildRequest(source, settings);
|
|
|
|
|
request.AddQueryParam("name", "delete");
|
|
|
|
|
request.AddQueryParam("del_files", deleteData ? 1 : 0);
|
|
|
|
|
request.AddQueryParam("value", id);
|
2014-12-23 01:17:48 +00:00
|
|
|
|
|
2016-02-28 16:34:24 +00:00
|
|
|
|
ProcessRequest(request, settings);
|
2014-02-14 05:31:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
2016-02-17 06:40:12 +00:00
|
|
|
|
public string GetVersion(SabnzbdSettings settings)
|
2014-02-14 05:31:49 +00:00
|
|
|
|
{
|
2016-02-28 16:34:24 +00:00
|
|
|
|
var request = BuildRequest("version", settings);
|
2014-02-14 05:31:49 +00:00
|
|
|
|
|
|
|
|
|
SabnzbdVersionResponse response;
|
|
|
|
|
|
2016-02-28 16:34:24 +00:00
|
|
|
|
if (!Json.TryDeserialize<SabnzbdVersionResponse>(ProcessRequest(request, settings), out response))
|
2014-02-14 05:31:49 +00:00
|
|
|
|
{
|
|
|
|
|
response = new SabnzbdVersionResponse();
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-17 06:40:12 +00:00
|
|
|
|
return response.Version;
|
2014-02-14 05:31:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-07-04 20:27:21 +00:00
|
|
|
|
public SabnzbdConfig GetConfig(SabnzbdSettings settings)
|
2014-02-14 05:31:49 +00:00
|
|
|
|
{
|
2016-02-28 16:34:24 +00:00
|
|
|
|
var request = BuildRequest("get_config", settings);
|
2014-02-14 05:31:49 +00:00
|
|
|
|
|
2016-02-28 16:34:24 +00:00
|
|
|
|
var response = Json.Deserialize<SabnzbdConfigResponse>(ProcessRequest(request, settings));
|
2014-02-14 05:31:49 +00:00
|
|
|
|
|
2014-07-04 20:27:21 +00:00
|
|
|
|
return response.Config;
|
2014-02-14 05:31:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public SabnzbdQueue GetQueue(int start, int limit, SabnzbdSettings settings)
|
|
|
|
|
{
|
2016-02-28 16:34:24 +00:00
|
|
|
|
var request = BuildRequest("queue", settings);
|
|
|
|
|
request.AddQueryParam("start", start);
|
|
|
|
|
request.AddQueryParam("limit", limit);
|
|
|
|
|
|
|
|
|
|
var response = ProcessRequest(request, settings);
|
2014-02-14 05:31:49 +00:00
|
|
|
|
|
|
|
|
|
return Json.Deserialize<SabnzbdQueue>(JObject.Parse(response).SelectToken("queue").ToString());
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-20 20:34:07 +00:00
|
|
|
|
public SabnzbdHistory GetHistory(int start, int limit, string category, SabnzbdSettings settings)
|
2014-02-14 05:31:49 +00:00
|
|
|
|
{
|
2016-02-28 16:34:24 +00:00
|
|
|
|
var request = BuildRequest("history", settings);
|
|
|
|
|
request.AddQueryParam("start", start);
|
|
|
|
|
request.AddQueryParam("limit", limit);
|
2014-02-14 05:31:49 +00:00
|
|
|
|
|
2016-01-20 20:34:07 +00:00
|
|
|
|
if (category.IsNotNullOrWhiteSpace())
|
|
|
|
|
{
|
2016-02-28 16:34:24 +00:00
|
|
|
|
request.AddQueryParam("category", category);
|
2016-01-20 20:34:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
2016-02-28 16:34:24 +00:00
|
|
|
|
var response = ProcessRequest(request, settings);
|
|
|
|
|
|
2014-02-14 05:31:49 +00:00
|
|
|
|
return Json.Deserialize<SabnzbdHistory>(JObject.Parse(response).SelectToken("history").ToString());
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-02 06:39:27 +00:00
|
|
|
|
public string RetryDownload(string id, SabnzbdSettings settings)
|
2014-04-01 20:07:41 +00:00
|
|
|
|
{
|
2016-02-28 16:34:24 +00:00
|
|
|
|
var request = BuildRequest("retry", settings);
|
|
|
|
|
request.AddQueryParam("value", id);
|
2014-04-01 20:07:41 +00:00
|
|
|
|
|
2014-12-02 06:39:27 +00:00
|
|
|
|
SabnzbdRetryResponse response;
|
|
|
|
|
|
2016-02-28 16:34:24 +00:00
|
|
|
|
if (!Json.TryDeserialize<SabnzbdRetryResponse>(ProcessRequest(request, settings), out response))
|
2014-12-02 06:39:27 +00:00
|
|
|
|
{
|
|
|
|
|
response = new SabnzbdRetryResponse();
|
|
|
|
|
response.Status = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return response.Id;
|
2014-04-01 20:07:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
2016-02-28 16:34:24 +00:00
|
|
|
|
private HttpRequestBuilder BuildRequest(string mode, SabnzbdSettings settings)
|
2014-02-14 05:31:49 +00:00
|
|
|
|
{
|
2016-02-28 16:34:24 +00:00
|
|
|
|
var baseUrl = string.Format(@"{0}://{1}:{2}/api",
|
|
|
|
|
settings.UseSsl ? "https" : "http",
|
|
|
|
|
settings.Host,
|
|
|
|
|
settings.Port);
|
2014-03-07 06:28:06 +00:00
|
|
|
|
|
2016-02-28 16:34:24 +00:00
|
|
|
|
var requestBuilder = new HttpRequestBuilder(baseUrl)
|
|
|
|
|
.Accept(HttpAccept.Json)
|
|
|
|
|
.AddQueryParam("mode", mode);
|
2014-02-14 05:31:49 +00:00
|
|
|
|
|
2016-04-06 20:53:14 +00:00
|
|
|
|
requestBuilder.LogResponseContent = true;
|
|
|
|
|
|
2016-02-28 16:34:24 +00:00
|
|
|
|
if (settings.ApiKey.IsNotNullOrWhiteSpace())
|
|
|
|
|
{
|
|
|
|
|
requestBuilder.AddSuffixQueryParam("apikey", settings.ApiKey);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
requestBuilder.AddSuffixQueryParam("ma_username", settings.Username);
|
|
|
|
|
requestBuilder.AddSuffixQueryParam("ma_password", settings.Password);
|
|
|
|
|
}
|
|
|
|
|
requestBuilder.AddSuffixQueryParam("output", "json");
|
2014-02-14 05:31:49 +00:00
|
|
|
|
|
2016-02-28 16:34:24 +00:00
|
|
|
|
return requestBuilder;
|
2014-02-14 05:31:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
2016-02-28 16:34:24 +00:00
|
|
|
|
private string ProcessRequest(HttpRequestBuilder requestBuilder, SabnzbdSettings settings)
|
2014-02-14 05:31:49 +00:00
|
|
|
|
{
|
2016-02-28 16:34:24 +00:00
|
|
|
|
var httpRequest = requestBuilder.Build();
|
|
|
|
|
|
|
|
|
|
HttpResponse response;
|
|
|
|
|
|
|
|
|
|
_logger.Debug("Url: {0}", httpRequest.Url);
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
response = _httpClient.Execute(httpRequest);
|
|
|
|
|
}
|
|
|
|
|
catch (HttpException ex)
|
2014-02-14 05:31:49 +00:00
|
|
|
|
{
|
2016-02-28 16:34:24 +00:00
|
|
|
|
throw new DownloadClientException("Unable to connect to SABnzbd, please check your settings", ex);
|
2014-02-14 05:31:49 +00:00
|
|
|
|
}
|
2016-03-17 19:53:11 +00:00
|
|
|
|
catch (WebException ex)
|
|
|
|
|
{
|
|
|
|
|
throw new DownloadClientException("Unable to connect to SABnzbd, please check your settings", ex);
|
|
|
|
|
}
|
2014-02-14 05:31:49 +00:00
|
|
|
|
|
2016-02-28 16:34:24 +00:00
|
|
|
|
CheckForError(response);
|
|
|
|
|
|
|
|
|
|
return response.Content;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void CheckForError(HttpResponse response)
|
|
|
|
|
{
|
2014-02-14 05:31:49 +00:00
|
|
|
|
SabnzbdJsonError result;
|
|
|
|
|
|
|
|
|
|
if (!Json.TryDeserialize<SabnzbdJsonError>(response.Content, out result))
|
|
|
|
|
{
|
|
|
|
|
//Handle plain text responses from SAB
|
|
|
|
|
result = new SabnzbdJsonError();
|
|
|
|
|
|
|
|
|
|
if (response.Content.StartsWith("error", StringComparison.InvariantCultureIgnoreCase))
|
|
|
|
|
{
|
|
|
|
|
result.Status = "false";
|
|
|
|
|
result.Error = response.Content.Replace("error: ", "");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
result.Status = "true";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result.Error = response.Content.Replace("error: ", "");
|
|
|
|
|
}
|
2014-04-19 15:09:22 +00:00
|
|
|
|
|
2014-02-14 05:31:49 +00:00
|
|
|
|
if (result.Failed)
|
2016-02-28 16:34:24 +00:00
|
|
|
|
{
|
2014-02-27 06:06:24 +00:00
|
|
|
|
throw new DownloadClientException("Error response received from SABnzbd: {0}", result.Error);
|
2016-02-28 16:34:24 +00:00
|
|
|
|
}
|
2014-02-14 05:31:49 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|