2014-02-14 05:31:49 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using Newtonsoft.Json.Linq;
|
|
|
|
|
using NLog;
|
2014-03-07 06:28:06 +00:00
|
|
|
|
using NzbDrone.Common;
|
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;
|
2014-03-13 20:12:42 +00:00
|
|
|
|
using NzbDrone.Core.Instrumentation.Extensions;
|
2014-02-14 05:31:49 +00:00
|
|
|
|
using RestSharp;
|
|
|
|
|
|
|
|
|
|
namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
|
|
|
|
{
|
|
|
|
|
public interface ISabnzbdProxy
|
|
|
|
|
{
|
|
|
|
|
SabnzbdAddResponse DownloadNzb(Stream nzb, 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);
|
|
|
|
|
SabnzbdCategoryResponse GetCategories(SabnzbdSettings settings);
|
|
|
|
|
SabnzbdQueue GetQueue(int start, int limit, SabnzbdSettings settings);
|
|
|
|
|
SabnzbdHistory GetHistory(int start, int limit, SabnzbdSettings settings);
|
2014-04-01 20:07:41 +00:00
|
|
|
|
void RetryDownload(string id, SabnzbdSettings settings);
|
2014-02-14 05:31:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class SabnzbdProxy : ISabnzbdProxy
|
|
|
|
|
{
|
|
|
|
|
private readonly Logger _logger;
|
|
|
|
|
|
|
|
|
|
public SabnzbdProxy(Logger logger)
|
|
|
|
|
{
|
|
|
|
|
_logger = logger;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public SabnzbdAddResponse DownloadNzb(Stream nzb, 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);
|
|
|
|
|
|
2014-03-20 07:08:15 +00:00
|
|
|
|
request.AddFile("name", nzb.ToBytes(), title, "application/x-nzb");
|
2014-02-14 05:31:49 +00:00
|
|
|
|
|
|
|
|
|
SabnzbdAddResponse response;
|
|
|
|
|
|
|
|
|
|
if (!Json.TryDeserialize<SabnzbdAddResponse>(ProcessRequest(request, action, settings), out response))
|
|
|
|
|
{
|
|
|
|
|
response = new SabnzbdAddResponse();
|
|
|
|
|
response.Status = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return response;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void RemoveFrom(string source, string id, SabnzbdSettings settings)
|
|
|
|
|
{
|
|
|
|
|
var request = new RestRequest();
|
|
|
|
|
var action = String.Format("mode={0}&name=delete&del_files=1&value={1}", source, id);
|
|
|
|
|
|
|
|
|
|
ProcessRequest(request, action, settings);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public string ProcessRequest(IRestRequest restRequest, string action, SabnzbdSettings settings)
|
|
|
|
|
{
|
|
|
|
|
var client = BuildClient(action, settings);
|
|
|
|
|
var response = client.Execute(restRequest);
|
|
|
|
|
_logger.Trace("Response: {0}", response.Content);
|
|
|
|
|
|
|
|
|
|
CheckForError(response);
|
|
|
|
|
|
|
|
|
|
return response.Content;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public SabnzbdVersionResponse GetVersion(SabnzbdSettings settings)
|
|
|
|
|
{
|
|
|
|
|
var request = new RestRequest();
|
|
|
|
|
var action = "mode=version";
|
|
|
|
|
|
|
|
|
|
SabnzbdVersionResponse response;
|
|
|
|
|
|
|
|
|
|
if (!Json.TryDeserialize<SabnzbdVersionResponse>(ProcessRequest(request, action, settings), out response))
|
|
|
|
|
{
|
|
|
|
|
response = new SabnzbdVersionResponse();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return response;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public SabnzbdCategoryResponse GetCategories(SabnzbdSettings settings)
|
|
|
|
|
{
|
|
|
|
|
var request = new RestRequest();
|
|
|
|
|
var action = "mode=get_cats";
|
|
|
|
|
|
2014-02-20 02:40:19 +00:00
|
|
|
|
var response = Json.Deserialize<SabnzbdCategoryResponse>(ProcessRequest(request, action, settings));
|
2014-02-14 05:31:49 +00:00
|
|
|
|
|
|
|
|
|
return response;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public SabnzbdQueue GetQueue(int start, int limit, SabnzbdSettings settings)
|
|
|
|
|
{
|
|
|
|
|
var request = new RestRequest();
|
|
|
|
|
var action = String.Format("mode=queue&start={0}&limit={1}", start, limit);
|
|
|
|
|
|
|
|
|
|
var response = ProcessRequest(request, action, settings);
|
|
|
|
|
return Json.Deserialize<SabnzbdQueue>(JObject.Parse(response).SelectToken("queue").ToString());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public SabnzbdHistory GetHistory(int start, int limit, SabnzbdSettings settings)
|
|
|
|
|
{
|
|
|
|
|
var request = new RestRequest();
|
2014-02-18 01:57:20 +00:00
|
|
|
|
var action = String.Format("mode=history&start={0}&limit={1}", start, limit);
|
2014-02-14 05:31:49 +00:00
|
|
|
|
|
|
|
|
|
var response = ProcessRequest(request, action, settings);
|
|
|
|
|
return Json.Deserialize<SabnzbdHistory>(JObject.Parse(response).SelectToken("history").ToString());
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-01 20:07:41 +00:00
|
|
|
|
public void RetryDownload(string id, SabnzbdSettings settings)
|
|
|
|
|
{
|
|
|
|
|
var request = new RestRequest();
|
|
|
|
|
var action = String.Format("mode=retry&value={0}", id);
|
|
|
|
|
|
|
|
|
|
ProcessRequest(request, action, settings);
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-14 05:31:49 +00:00
|
|
|
|
private IRestClient BuildClient(string action, SabnzbdSettings settings)
|
|
|
|
|
{
|
|
|
|
|
var protocol = settings.UseSsl ? "https" : "http";
|
|
|
|
|
|
2014-03-07 06:28:06 +00:00
|
|
|
|
var authentication = settings.ApiKey.IsNullOrWhiteSpace() ?
|
|
|
|
|
String.Format("ma_username={0}&ma_password={1}", settings.Username, settings.Password) :
|
|
|
|
|
String.Format("apikey={0}", settings.ApiKey);
|
|
|
|
|
|
|
|
|
|
var url = string.Format(@"{0}://{1}:{2}/api?{3}&{4}&output=json",
|
2014-02-14 05:31:49 +00:00
|
|
|
|
protocol,
|
|
|
|
|
settings.Host,
|
|
|
|
|
settings.Port,
|
|
|
|
|
action,
|
2014-03-07 06:28:06 +00:00
|
|
|
|
authentication);
|
2014-02-14 05:31:49 +00:00
|
|
|
|
|
2014-03-13 20:12:42 +00:00
|
|
|
|
_logger.CleansedDebug(url);
|
2014-02-14 05:31:49 +00:00
|
|
|
|
|
|
|
|
|
return new RestClient(url);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void CheckForError(IRestResponse response)
|
|
|
|
|
{
|
|
|
|
|
if (response.ResponseStatus != ResponseStatus.Completed)
|
|
|
|
|
{
|
2014-03-07 06:28:06 +00:00
|
|
|
|
throw new DownloadClientException("Unable to connect to SABnzbd, please check your settings");
|
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: ", "");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (result.Failed)
|
2014-02-27 06:06:24 +00:00
|
|
|
|
throw new DownloadClientException("Error response received from SABnzbd: {0}", result.Error);
|
2014-02-14 05:31:49 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|