|
|
@ -4,9 +4,10 @@ using System.Linq;
|
|
|
|
using System.Net;
|
|
|
|
using System.Net;
|
|
|
|
using Newtonsoft.Json.Linq;
|
|
|
|
using Newtonsoft.Json.Linq;
|
|
|
|
using NLog;
|
|
|
|
using NLog;
|
|
|
|
|
|
|
|
using NzbDrone.Common.Cache;
|
|
|
|
using NzbDrone.Common.Extensions;
|
|
|
|
using NzbDrone.Common.Extensions;
|
|
|
|
using NzbDrone.Core.Rest;
|
|
|
|
using NzbDrone.Common.Http;
|
|
|
|
using RestSharp;
|
|
|
|
using NzbDrone.Common.Serializer;
|
|
|
|
|
|
|
|
|
|
|
|
namespace NzbDrone.Core.Download.Clients.Deluge
|
|
|
|
namespace NzbDrone.Core.Download.Clients.Deluge
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -33,30 +34,31 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
|
|
|
{
|
|
|
|
{
|
|
|
|
private static readonly string[] requiredProperties = new string[] { "hash", "name", "state", "progress", "eta", "message", "is_finished", "save_path", "total_size", "total_done", "time_added", "active_time", "ratio", "is_auto_managed", "stop_at_ratio", "remove_at_ratio", "stop_ratio" };
|
|
|
|
private static readonly string[] requiredProperties = new string[] { "hash", "name", "state", "progress", "eta", "message", "is_finished", "save_path", "total_size", "total_done", "time_added", "active_time", "ratio", "is_auto_managed", "stop_at_ratio", "remove_at_ratio", "stop_ratio" };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private readonly IHttpClient _httpClient;
|
|
|
|
private readonly Logger _logger;
|
|
|
|
private readonly Logger _logger;
|
|
|
|
|
|
|
|
|
|
|
|
private string _authPassword;
|
|
|
|
private readonly ICached<Dictionary<string, string>> _authCookieCache;
|
|
|
|
private CookieContainer _authCookieContainer;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static int _callId;
|
|
|
|
public DelugeProxy(ICacheManager cacheManager, IHttpClient httpClient, Logger logger)
|
|
|
|
|
|
|
|
|
|
|
|
public DelugeProxy(Logger logger)
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
_httpClient = httpClient;
|
|
|
|
_logger = logger;
|
|
|
|
_logger = logger;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_authCookieCache = cacheManager.GetCache<Dictionary<string, string>>(GetType(), "authCookies");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public string GetVersion(DelugeSettings settings)
|
|
|
|
public string GetVersion(DelugeSettings settings)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var response = ProcessRequest<string>(settings, "daemon.info");
|
|
|
|
var response = ProcessRequest<string>(settings, "daemon.info");
|
|
|
|
|
|
|
|
|
|
|
|
return response.Result;
|
|
|
|
return response;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public Dictionary<string, object> GetConfig(DelugeSettings settings)
|
|
|
|
public Dictionary<string, object> GetConfig(DelugeSettings settings)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var response = ProcessRequest<Dictionary<string, object>>(settings, "core.get_config");
|
|
|
|
var response = ProcessRequest<Dictionary<string, object>>(settings, "core.get_config");
|
|
|
|
|
|
|
|
|
|
|
|
return response.Result;
|
|
|
|
return response;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public DelugeTorrent[] GetTorrents(DelugeSettings settings)
|
|
|
|
public DelugeTorrent[] GetTorrents(DelugeSettings settings)
|
|
|
@ -67,7 +69,7 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
|
|
|
//var response = ProcessRequest<Dictionary<String, DelugeTorrent>>(settings, "core.get_torrents_status", filter, new String[0]);
|
|
|
|
//var response = ProcessRequest<Dictionary<String, DelugeTorrent>>(settings, "core.get_torrents_status", filter, new String[0]);
|
|
|
|
var response = ProcessRequest<DelugeUpdateUIResult>(settings, "web.update_ui", requiredProperties, filter);
|
|
|
|
var response = ProcessRequest<DelugeUpdateUIResult>(settings, "web.update_ui", requiredProperties, filter);
|
|
|
|
|
|
|
|
|
|
|
|
return GetTorrents(response.Result);
|
|
|
|
return GetTorrents(response);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public DelugeTorrent[] GetTorrentsByLabel(string label, DelugeSettings settings)
|
|
|
|
public DelugeTorrent[] GetTorrentsByLabel(string label, DelugeSettings settings)
|
|
|
@ -78,28 +80,28 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
|
|
|
//var response = ProcessRequest<Dictionary<String, DelugeTorrent>>(settings, "core.get_torrents_status", filter, new String[0]);
|
|
|
|
//var response = ProcessRequest<Dictionary<String, DelugeTorrent>>(settings, "core.get_torrents_status", filter, new String[0]);
|
|
|
|
var response = ProcessRequest<DelugeUpdateUIResult>(settings, "web.update_ui", requiredProperties, filter);
|
|
|
|
var response = ProcessRequest<DelugeUpdateUIResult>(settings, "web.update_ui", requiredProperties, filter);
|
|
|
|
|
|
|
|
|
|
|
|
return GetTorrents(response.Result);
|
|
|
|
return GetTorrents(response);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public string AddTorrentFromMagnet(string magnetLink, DelugeSettings settings)
|
|
|
|
public string AddTorrentFromMagnet(string magnetLink, DelugeSettings settings)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var response = ProcessRequest<string>(settings, "core.add_torrent_magnet", magnetLink, new JObject());
|
|
|
|
var response = ProcessRequest<string>(settings, "core.add_torrent_magnet", magnetLink, new JObject());
|
|
|
|
|
|
|
|
|
|
|
|
return response.Result;
|
|
|
|
return response;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public string AddTorrentFromFile(string filename, byte[] fileContent, DelugeSettings settings)
|
|
|
|
public string AddTorrentFromFile(string filename, byte[] fileContent, DelugeSettings settings)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var response = ProcessRequest<string>(settings, "core.add_torrent_file", filename, Convert.ToBase64String(fileContent), new JObject());
|
|
|
|
var response = ProcessRequest<string>(settings, "core.add_torrent_file", filename, Convert.ToBase64String(fileContent), new JObject());
|
|
|
|
|
|
|
|
|
|
|
|
return response.Result;
|
|
|
|
return response;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public bool RemoveTorrent(string hashString, bool removeData, DelugeSettings settings)
|
|
|
|
public bool RemoveTorrent(string hashString, bool removeData, DelugeSettings settings)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var response = ProcessRequest<bool>(settings, "core.remove_torrent", hashString, removeData);
|
|
|
|
var response = ProcessRequest<bool>(settings, "core.remove_torrent", hashString, removeData);
|
|
|
|
|
|
|
|
|
|
|
|
return response.Result;
|
|
|
|
return response;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void MoveTorrentToTopInQueue(string hash, DelugeSettings settings)
|
|
|
|
public void MoveTorrentToTopInQueue(string hash, DelugeSettings settings)
|
|
|
@ -111,21 +113,21 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var response = ProcessRequest<string[]>(settings, "core.get_available_plugins");
|
|
|
|
var response = ProcessRequest<string[]>(settings, "core.get_available_plugins");
|
|
|
|
|
|
|
|
|
|
|
|
return response.Result;
|
|
|
|
return response;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public string[] GetEnabledPlugins(DelugeSettings settings)
|
|
|
|
public string[] GetEnabledPlugins(DelugeSettings settings)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var response = ProcessRequest<string[]>(settings, "core.get_enabled_plugins");
|
|
|
|
var response = ProcessRequest<string[]>(settings, "core.get_enabled_plugins");
|
|
|
|
|
|
|
|
|
|
|
|
return response.Result;
|
|
|
|
return response;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public string[] GetAvailableLabels(DelugeSettings settings)
|
|
|
|
public string[] GetAvailableLabels(DelugeSettings settings)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var response = ProcessRequest<string[]>(settings, "label.get_labels");
|
|
|
|
var response = ProcessRequest<string[]>(settings, "label.get_labels");
|
|
|
|
|
|
|
|
|
|
|
|
return response.Result;
|
|
|
|
return response;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void SetTorrentConfiguration(string hash, string key, object value, DelugeSettings settings)
|
|
|
|
public void SetTorrentConfiguration(string hash, string key, object value, DelugeSettings settings)
|
|
|
@ -143,7 +145,7 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
|
|
|
var ratioArguments = new Dictionary<string, object>();
|
|
|
|
var ratioArguments = new Dictionary<string, object>();
|
|
|
|
ratioArguments.Add("stop_ratio", seedConfiguration.Ratio.Value);
|
|
|
|
ratioArguments.Add("stop_ratio", seedConfiguration.Ratio.Value);
|
|
|
|
|
|
|
|
|
|
|
|
ProcessRequest<object>(settings, "core.set_torrent_options", new string[]{hash}, ratioArguments);
|
|
|
|
ProcessRequest<object>(settings, "core.set_torrent_options", new string[] { hash }, ratioArguments);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -157,134 +159,122 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
|
|
|
ProcessRequest<object>(settings, "label.set_torrent", hash, label);
|
|
|
|
ProcessRequest<object>(settings, "label.set_torrent", hash, label);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
protected DelugeResponse<TResult> ProcessRequest<TResult>(DelugeSettings settings, string action, params object[] arguments)
|
|
|
|
private JsonRpcRequestBuilder BuildRequest(DelugeSettings settings)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var client = BuildClient(settings);
|
|
|
|
string url = HttpRequestBuilder.BuildBaseUrl(settings.UseSsl, settings.Host, settings.Port, settings.UrlBase);
|
|
|
|
|
|
|
|
|
|
|
|
DelugeResponse<TResult> response;
|
|
|
|
var builder = new JsonRpcRequestBuilder(url);
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
builder.Resource("json");
|
|
|
|
{
|
|
|
|
builder.PostProcess += r => r.RequestTimeout = TimeSpan.FromSeconds(15);
|
|
|
|
response = ProcessRequest<TResult>(client, action, arguments);
|
|
|
|
|
|
|
|
}
|
|
|
|
AuthenticateClient(builder, settings);
|
|
|
|
catch (WebException ex)
|
|
|
|
|
|
|
|
{
|
|
|
|
return builder;
|
|
|
|
if (ex.Status == WebExceptionStatus.Timeout)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
_logger.Debug("Deluge timeout during request, daemon connection may have been broken. Attempting to reconnect.");
|
|
|
|
|
|
|
|
response = new DelugeResponse<TResult>();
|
|
|
|
|
|
|
|
response.Error = new DelugeError();
|
|
|
|
|
|
|
|
response.Error.Code = 2;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
|
|
|
|
|
|
|
|
protected TResult ProcessRequest<TResult>(DelugeSettings settings, string method, params object[] arguments)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
throw;
|
|
|
|
var requestBuilder = BuildRequest(settings);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
var response = ProcessRequest<TResult>(requestBuilder, method, arguments);
|
|
|
|
|
|
|
|
|
|
|
|
if (response.Error != null)
|
|
|
|
if (response.Error != null)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (response.Error.Code == 1 || response.Error.Code == 2)
|
|
|
|
var error = response.Error.ToObject<DelugeError>();
|
|
|
|
|
|
|
|
if (error.Code == 1 || error.Code == 2)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
AuthenticateClient(client);
|
|
|
|
AuthenticateClient(requestBuilder, settings, true);
|
|
|
|
|
|
|
|
|
|
|
|
response = ProcessRequest<TResult>(client, action, arguments);
|
|
|
|
response = ProcessRequest<TResult>(requestBuilder, method, arguments);
|
|
|
|
|
|
|
|
|
|
|
|
if (response.Error == null)
|
|
|
|
if (response.Error == null)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return response;
|
|
|
|
return response.Result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
error = response.Error.ToObject<DelugeError>();
|
|
|
|
|
|
|
|
|
|
|
|
throw new DownloadClientAuthenticationException(response.Error.Message);
|
|
|
|
throw new DownloadClientAuthenticationException(error.Message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
throw new DelugeException(response.Error.Message, response.Error.Code);
|
|
|
|
throw new DelugeException(error.Message, error.Code);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return response;
|
|
|
|
return response.Result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private DelugeResponse<TResult> ProcessRequest<TResult>(IRestClient client, string action, object[] arguments)
|
|
|
|
private JsonRpcResponse<TResult> ProcessRequest<TResult>(JsonRpcRequestBuilder requestBuilder, string method, params object[] arguments)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var request = new RestRequest(Method.POST);
|
|
|
|
var request = requestBuilder.Call(method, arguments).Build();
|
|
|
|
request.Resource = "json";
|
|
|
|
|
|
|
|
request.RequestFormat = DataFormat.Json;
|
|
|
|
|
|
|
|
request.AddHeader("Accept-Encoding", "gzip,deflate");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var data = new Dictionary<string, object>();
|
|
|
|
|
|
|
|
data.Add("id", GetCallId());
|
|
|
|
|
|
|
|
data.Add("method", action);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (arguments != null)
|
|
|
|
HttpResponse response;
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
{
|
|
|
|
data.Add("params", arguments);
|
|
|
|
response = _httpClient.Execute(request);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
request.AddBody(data);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_logger.Debug("Url: {0} Action: {1}", client.BuildUri(request), action);
|
|
|
|
|
|
|
|
var response = client.ExecuteAndValidate<DelugeResponse<TResult>>(request);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return response;
|
|
|
|
return Json.Deserialize<JsonRpcResponse<TResult>>(response.Content);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
catch (HttpException ex)
|
|
|
|
private IRestClient BuildClient(DelugeSettings settings)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
var protocol = settings.UseSsl ? "https" : "http";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
string url;
|
|
|
|
|
|
|
|
if (!settings.UrlBase.IsNullOrWhiteSpace())
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
url = string.Format(@"{0}://{1}:{2}/{3}", protocol, settings.Host, settings.Port, settings.UrlBase.Trim('/'));
|
|
|
|
if (ex.Response.StatusCode == HttpStatusCode.RequestTimeout)
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
url = string.Format(@"{0}://{1}:{2}", protocol, settings.Host, settings.Port);
|
|
|
|
_logger.Debug("Deluge timeout during request, daemon connection may have been broken. Attempting to reconnect.");
|
|
|
|
}
|
|
|
|
return new JsonRpcResponse<TResult>()
|
|
|
|
|
|
|
|
|
|
|
|
var restClient = RestClientFactory.BuildClient(url);
|
|
|
|
|
|
|
|
restClient.Timeout = 15000;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (_authPassword != settings.Password || _authCookieContainer == null)
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
_authPassword = settings.Password;
|
|
|
|
Error = JToken.Parse("{ Code = 2 }")
|
|
|
|
AuthenticateClient(restClient);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
restClient.CookieContainer = _authCookieContainer;
|
|
|
|
throw new DownloadClientException("Unable to connect to Deluge, please check your settings", ex);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return restClient;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void AuthenticateClient(IRestClient restClient)
|
|
|
|
private void AuthenticateClient(JsonRpcRequestBuilder requestBuilder, DelugeSettings settings, bool reauthenticate = false)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
restClient.CookieContainer = new CookieContainer();
|
|
|
|
var authKey = string.Format("{0}:{1}", requestBuilder.BaseUrl, settings.Password);
|
|
|
|
|
|
|
|
|
|
|
|
var result = ProcessRequest<bool>(restClient, "auth.login", new object[] { _authPassword });
|
|
|
|
var cookies = _authCookieCache.Find(authKey);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (cookies == null || reauthenticate)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
_authCookieCache.Remove(authKey);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var authLoginRequest = requestBuilder.Call("auth.login", settings.Password).Build();
|
|
|
|
|
|
|
|
var response = _httpClient.Execute(authLoginRequest);
|
|
|
|
|
|
|
|
var result = Json.Deserialize<JsonRpcResponse<bool>>(response.Content);
|
|
|
|
if (!result.Result)
|
|
|
|
if (!result.Result)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
_logger.Debug("Deluge authentication failed.");
|
|
|
|
_logger.Debug("Deluge authentication failed.");
|
|
|
|
throw new DownloadClientAuthenticationException("Failed to authenticate with Deluge.");
|
|
|
|
throw new DownloadClientAuthenticationException("Failed to authenticate with Deluge.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_logger.Debug("Deluge authentication succeeded.");
|
|
|
|
_logger.Debug("Deluge authentication succeeded.");
|
|
|
|
_authCookieContainer = restClient.CookieContainer;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ConnectDaemon(restClient);
|
|
|
|
cookies = response.GetCookies();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_authCookieCache.Set(authKey, cookies);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
requestBuilder.SetCookies(cookies);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ConnectDaemon(requestBuilder);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
requestBuilder.SetCookies(cookies);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void ConnectDaemon(IRestClient restClient)
|
|
|
|
private void ConnectDaemon(JsonRpcRequestBuilder requestBuilder)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var resultConnected = ProcessRequest<bool>(restClient, "web.connected", new object[0]);
|
|
|
|
var resultConnected = ProcessRequest<bool>(requestBuilder, "web.connected");
|
|
|
|
|
|
|
|
|
|
|
|
if (resultConnected.Result)
|
|
|
|
if (resultConnected.Result)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var resultHosts = ProcessRequest<List<object[]>>(restClient, "web.get_hosts", new object[0]);
|
|
|
|
var resultHosts = ProcessRequest<List<object[]>>(requestBuilder, "web.get_hosts");
|
|
|
|
|
|
|
|
|
|
|
|
if (resultHosts.Result != null)
|
|
|
|
if (resultHosts.Result != null)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -293,7 +283,7 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
|
|
|
|
|
|
|
|
|
|
|
if (connection != null)
|
|
|
|
if (connection != null)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
ProcessRequest<object>(restClient, "web.connect", new object[] { connection[0] });
|
|
|
|
ProcessRequest<object>(requestBuilder, "web.connect", new object[] { connection[0] });
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -302,11 +292,6 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private int GetCallId()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return System.Threading.Interlocked.Increment(ref _callId);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private DelugeTorrent[] GetTorrents(DelugeUpdateUIResult result)
|
|
|
|
private DelugeTorrent[] GetTorrents(DelugeUpdateUIResult result)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (result.Torrents == null)
|
|
|
|
if (result.Torrents == null)
|
|
|
|