sonarr-repo-only/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabCommunicationProxy.cs

131 lines
4.2 KiB
C#

using System;
using System.IO;
using NLog;
using NzbDrone.Common.Serializer;
using NzbDrone.Core.Configuration;
using RestSharp;
namespace NzbDrone.Core.Download.Clients.Sabnzbd
{
public interface ISabCommunicationProxy
{
SabAddResponse DownloadNzb(Stream nzb, string name, string category, int priority);
void RemoveFrom(string source, string id);
string ProcessRequest(IRestRequest restRequest, string action);
}
public class SabCommunicationProxy : ISabCommunicationProxy
{
private readonly IConfigService _configService;
private readonly Logger _logger;
public SabCommunicationProxy(IConfigService configService, Logger logger)
{
_configService = configService;
_logger = logger;
}
public SabAddResponse 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");
var response = Json.TryDeserialize<SabAddResponse>(ProcessRequest(request, action));
if (response == null)
{
response = new SabAddResponse();
response.Status = true;
}
return response;
}
public void RemoveFrom(string source, string id)
{
var request = new RestRequest();
var action = String.Format("mode={0}&name=delete&del_files=1&value={1}", source, id);
ProcessRequest(request, action);
}
public string ProcessRequest(IRestRequest restRequest, string action)
{
var client = BuildClient(action);
var response = client.Execute(restRequest);
_logger.Trace("Response: {0}", response.Content);
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);
_logger.Trace(url);
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.TryDeserialize<SabJsonError>(response.Content);
if (result == null)
{
//Handle plain text responses from SAB
result = new SabJsonError();
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)
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();
}
}
}
}