mirror of
https://github.com/Sonarr/Sonarr.git
synced 2024-12-16 11:37:58 +02:00
Fixed: DownloadStation api client for DSM 5.x.
This commit is contained in:
parent
29419d6575
commit
5033886b90
@ -275,7 +275,7 @@ public void Setup()
|
|||||||
{ "default_destination", _defaultDestination },
|
{ "default_destination", _defaultDestination },
|
||||||
};
|
};
|
||||||
|
|
||||||
Mocker.GetMock<IDownloadStationProxy>()
|
Mocker.GetMock<IDownloadStationInfoProxy>()
|
||||||
.Setup(v => v.GetConfig(It.IsAny<DownloadStationSettings>()))
|
.Setup(v => v.GetConfig(It.IsAny<DownloadStationSettings>()))
|
||||||
.Returns(_downloadStationConfigItems);
|
.Returns(_downloadStationConfigItems);
|
||||||
}
|
}
|
||||||
@ -311,7 +311,7 @@ protected virtual void GivenTasks(List<DownloadStationTask> torrents)
|
|||||||
torrents = new List<DownloadStationTask>();
|
torrents = new List<DownloadStationTask>();
|
||||||
}
|
}
|
||||||
|
|
||||||
Mocker.GetMock<IDownloadStationProxy>()
|
Mocker.GetMock<IDownloadStationTaskProxy>()
|
||||||
.Setup(s => s.GetTasks(It.IsAny<DownloadStationSettings>()))
|
.Setup(s => s.GetTasks(It.IsAny<DownloadStationSettings>()))
|
||||||
.Returns(torrents);
|
.Returns(torrents);
|
||||||
}
|
}
|
||||||
@ -330,11 +330,11 @@ protected void GivenSuccessfulDownload()
|
|||||||
.Setup(s => s.Get(It.IsAny<HttpRequest>()))
|
.Setup(s => s.Get(It.IsAny<HttpRequest>()))
|
||||||
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), new byte[1000]));
|
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), new byte[1000]));
|
||||||
|
|
||||||
Mocker.GetMock<IDownloadStationProxy>()
|
Mocker.GetMock<IDownloadStationTaskProxy>()
|
||||||
.Setup(s => s.AddTaskFromUrl(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<DownloadStationSettings>()))
|
.Setup(s => s.AddTaskFromUrl(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<DownloadStationSettings>()))
|
||||||
.Callback(PrepareClientToReturnQueuedItem);
|
.Callback(PrepareClientToReturnQueuedItem);
|
||||||
|
|
||||||
Mocker.GetMock<IDownloadStationProxy>()
|
Mocker.GetMock<IDownloadStationTaskProxy>()
|
||||||
.Setup(s => s.AddTaskFromData(It.IsAny<byte[]>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<DownloadStationSettings>()))
|
.Setup(s => s.AddTaskFromData(It.IsAny<byte[]>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<DownloadStationSettings>()))
|
||||||
.Callback(PrepareClientToReturnQueuedItem);
|
.Callback(PrepareClientToReturnQueuedItem);
|
||||||
}
|
}
|
||||||
@ -352,7 +352,7 @@ protected int GivenAllKindOfTasks()
|
|||||||
{
|
{
|
||||||
var tasks = new List<DownloadStationTask>() { _queued, _completed, _failed, _downloading, _seeding };
|
var tasks = new List<DownloadStationTask>() { _queued, _completed, _failed, _downloading, _seeding };
|
||||||
|
|
||||||
Mocker.GetMock<IDownloadStationProxy>()
|
Mocker.GetMock<IDownloadStationTaskProxy>()
|
||||||
.Setup(d => d.GetTasks(_settings))
|
.Setup(d => d.GetTasks(_settings))
|
||||||
.Returns(tasks);
|
.Returns(tasks);
|
||||||
|
|
||||||
@ -372,7 +372,7 @@ public void Download_with_TvDirectory_should_force_directory()
|
|||||||
|
|
||||||
id.Should().NotBeNullOrEmpty();
|
id.Should().NotBeNullOrEmpty();
|
||||||
|
|
||||||
Mocker.GetMock<IDownloadStationProxy>()
|
Mocker.GetMock<IDownloadStationTaskProxy>()
|
||||||
.Verify(v => v.AddTaskFromUrl(It.IsAny<string>(), _tvDirectory, It.IsAny<DownloadStationSettings>()), Times.Once());
|
.Verify(v => v.AddTaskFromUrl(It.IsAny<string>(), _tvDirectory, It.IsAny<DownloadStationSettings>()), Times.Once());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -389,7 +389,7 @@ public void Download_with_category_should_force_directory()
|
|||||||
|
|
||||||
id.Should().NotBeNullOrEmpty();
|
id.Should().NotBeNullOrEmpty();
|
||||||
|
|
||||||
Mocker.GetMock<IDownloadStationProxy>()
|
Mocker.GetMock<IDownloadStationTaskProxy>()
|
||||||
.Verify(v => v.AddTaskFromUrl(It.IsAny<string>(), $"{_defaultDestination}/{_category}", It.IsAny<DownloadStationSettings>()), Times.Once());
|
.Verify(v => v.AddTaskFromUrl(It.IsAny<string>(), $"{_defaultDestination}/{_category}", It.IsAny<DownloadStationSettings>()), Times.Once());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -405,7 +405,7 @@ public void Download_without_TvDirectory_and_Category_should_use_default()
|
|||||||
|
|
||||||
id.Should().NotBeNullOrEmpty();
|
id.Should().NotBeNullOrEmpty();
|
||||||
|
|
||||||
Mocker.GetMock<IDownloadStationProxy>()
|
Mocker.GetMock<IDownloadStationTaskProxy>()
|
||||||
.Verify(v => v.AddTaskFromUrl(It.IsAny<string>(), null, It.IsAny<DownloadStationSettings>()), Times.Once());
|
.Verify(v => v.AddTaskFromUrl(It.IsAny<string>(), null, It.IsAny<DownloadStationSettings>()), Times.Once());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -482,7 +482,7 @@ public void Download_should_throw_and_not_add_task_if_cannot_get_serial_number()
|
|||||||
|
|
||||||
Assert.Throws(Is.InstanceOf<Exception>(), () => Subject.Download(remoteEpisode));
|
Assert.Throws(Is.InstanceOf<Exception>(), () => Subject.Download(remoteEpisode));
|
||||||
|
|
||||||
Mocker.GetMock<IDownloadStationProxy>()
|
Mocker.GetMock<IDownloadStationTaskProxy>()
|
||||||
.Verify(v => v.AddTaskFromUrl(It.IsAny<string>(), null, _settings), Times.Never());
|
.Verify(v => v.AddTaskFromUrl(It.IsAny<string>(), null, _settings), Times.Never());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ public void Setup()
|
|||||||
{ "default_destination", _defaultDestination },
|
{ "default_destination", _defaultDestination },
|
||||||
};
|
};
|
||||||
|
|
||||||
Mocker.GetMock<IDownloadStationProxy>()
|
Mocker.GetMock<IDownloadStationInfoProxy>()
|
||||||
.Setup(v => v.GetConfig(It.IsAny<DownloadStationSettings>()))
|
.Setup(v => v.GetConfig(It.IsAny<DownloadStationSettings>()))
|
||||||
.Returns(_downloadStationConfigItems);
|
.Returns(_downloadStationConfigItems);
|
||||||
}
|
}
|
||||||
@ -213,7 +213,7 @@ protected virtual void GivenTasks(List<DownloadStationTask> nzbs)
|
|||||||
nzbs = new List<DownloadStationTask>();
|
nzbs = new List<DownloadStationTask>();
|
||||||
}
|
}
|
||||||
|
|
||||||
Mocker.GetMock<IDownloadStationProxy>()
|
Mocker.GetMock<IDownloadStationTaskProxy>()
|
||||||
.Setup(s => s.GetTasks(It.IsAny<DownloadStationSettings>()))
|
.Setup(s => s.GetTasks(It.IsAny<DownloadStationSettings>()))
|
||||||
.Returns(nzbs);
|
.Returns(nzbs);
|
||||||
}
|
}
|
||||||
@ -233,7 +233,7 @@ protected void GivenSuccessfulDownload()
|
|||||||
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), new byte[1000]));
|
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), new byte[1000]));
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Mocker.GetMock<IDownloadStationProxy>()
|
Mocker.GetMock<IDownloadStationTaskProxy>()
|
||||||
.Setup(s => s.AddTaskFromData(It.IsAny<byte[]>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<DownloadStationSettings>()))
|
.Setup(s => s.AddTaskFromData(It.IsAny<byte[]>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<DownloadStationSettings>()))
|
||||||
.Callback(PrepareClientToReturnQueuedItem);
|
.Callback(PrepareClientToReturnQueuedItem);
|
||||||
}
|
}
|
||||||
@ -242,7 +242,7 @@ protected void GivenAllKindOfTasks()
|
|||||||
{
|
{
|
||||||
var tasks = new List<DownloadStationTask>() { _queued, _completed, _failed, _downloading, _seeding };
|
var tasks = new List<DownloadStationTask>() { _queued, _completed, _failed, _downloading, _seeding };
|
||||||
|
|
||||||
Mocker.GetMock<IDownloadStationProxy>()
|
Mocker.GetMock<IDownloadStationTaskProxy>()
|
||||||
.Setup(d => d.GetTasks(_settings))
|
.Setup(d => d.GetTasks(_settings))
|
||||||
.Returns(tasks);
|
.Returns(tasks);
|
||||||
}
|
}
|
||||||
@ -260,7 +260,7 @@ public void Download_with_TvDirectory_should_force_directory()
|
|||||||
|
|
||||||
id.Should().NotBeNullOrEmpty();
|
id.Should().NotBeNullOrEmpty();
|
||||||
|
|
||||||
Mocker.GetMock<IDownloadStationProxy>()
|
Mocker.GetMock<IDownloadStationTaskProxy>()
|
||||||
.Verify(v => v.AddTaskFromData(It.IsAny<byte[]>(), It.IsAny<string>(), _tvDirectory, It.IsAny<DownloadStationSettings>()), Times.Once());
|
.Verify(v => v.AddTaskFromData(It.IsAny<byte[]>(), It.IsAny<string>(), _tvDirectory, It.IsAny<DownloadStationSettings>()), Times.Once());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,7 +277,7 @@ public void Download_with_category_should_force_directory()
|
|||||||
|
|
||||||
id.Should().NotBeNullOrEmpty();
|
id.Should().NotBeNullOrEmpty();
|
||||||
|
|
||||||
Mocker.GetMock<IDownloadStationProxy>()
|
Mocker.GetMock<IDownloadStationTaskProxy>()
|
||||||
.Verify(v => v.AddTaskFromData(It.IsAny<byte[]>(), It.IsAny<string>(), $"{_defaultDestination}/{_category}", It.IsAny<DownloadStationSettings>()), Times.Once());
|
.Verify(v => v.AddTaskFromData(It.IsAny<byte[]>(), It.IsAny<string>(), $"{_defaultDestination}/{_category}", It.IsAny<DownloadStationSettings>()), Times.Once());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,7 +293,7 @@ public void Download_without_TvDirectory_and_Category_should_use_default()
|
|||||||
|
|
||||||
id.Should().NotBeNullOrEmpty();
|
id.Should().NotBeNullOrEmpty();
|
||||||
|
|
||||||
Mocker.GetMock<IDownloadStationProxy>()
|
Mocker.GetMock<IDownloadStationTaskProxy>()
|
||||||
.Verify(v => v.AddTaskFromData(It.IsAny<byte[]>(), It.IsAny<string>(), null, It.IsAny<DownloadStationSettings>()), Times.Once());
|
.Verify(v => v.AddTaskFromData(It.IsAny<byte[]>(), It.IsAny<string>(), null, It.IsAny<DownloadStationSettings>()), Times.Once());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -370,7 +370,7 @@ public void Download_should_throw_and_not_add_task_if_cannot_get_serial_number()
|
|||||||
|
|
||||||
Assert.Throws(Is.InstanceOf<Exception>(), () => Subject.Download(remoteEpisode));
|
Assert.Throws(Is.InstanceOf<Exception>(), () => Subject.Download(remoteEpisode));
|
||||||
|
|
||||||
Mocker.GetMock<IDownloadStationProxy>()
|
Mocker.GetMock<IDownloadStationTaskProxy>()
|
||||||
.Verify(v => v.AddTaskFromUrl(It.IsAny<string>(), null, _settings), Times.Never());
|
.Verify(v => v.AddTaskFromUrl(It.IsAny<string>(), null, _settings), Times.Never());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,13 +1,19 @@
|
|||||||
namespace NzbDrone.Core.Download.Clients.DownloadStation
|
namespace NzbDrone.Core.Download.Clients.DownloadStation
|
||||||
{
|
{
|
||||||
public class DiskStationApiInfo
|
public class DiskStationApiInfo
|
||||||
{
|
{
|
||||||
private string _path;
|
private string _path;
|
||||||
|
|
||||||
public int MaxVersion { get; set; }
|
public int MaxVersion { get; set; }
|
||||||
|
|
||||||
public int MinVersion { get; set; }
|
public int MinVersion { get; set; }
|
||||||
|
|
||||||
|
public DiskStationApi Type { get; set; }
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public bool NeedsAuthentication { get; set; }
|
||||||
|
|
||||||
public string Path
|
public string Path
|
||||||
{
|
{
|
||||||
get { return _path; }
|
get { return _path; }
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
using NzbDrone.Common.Cache;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Download.Clients.DownloadStation.Responses;
|
using NzbDrone.Core.Download.Clients.DownloadStation.Responses;
|
||||||
|
|
||||||
@ -13,20 +14,19 @@ public interface IDSMInfoProxy
|
|||||||
|
|
||||||
public class DSMInfoProxy : DiskStationProxyBase, IDSMInfoProxy
|
public class DSMInfoProxy : DiskStationProxyBase, IDSMInfoProxy
|
||||||
{
|
{
|
||||||
public DSMInfoProxy(IHttpClient httpClient, Logger logger) :
|
public DSMInfoProxy(IHttpClient httpClient, ICacheManager cacheManager, Logger logger) :
|
||||||
base(httpClient, logger)
|
base(DiskStationApi.DSMInfo, "SYNO.DSM.Info", httpClient, cacheManager, logger)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetSerialNumber(DownloadStationSettings settings)
|
public string GetSerialNumber(DownloadStationSettings settings)
|
||||||
{
|
{
|
||||||
var arguments = new Dictionary<string, object>() {
|
var info = GetApiInfo(settings);
|
||||||
{ "api", "SYNO.DSM.Info" },
|
|
||||||
{ "version", "2" },
|
var requestBuilder = BuildRequest(settings, "getinfo", info.MinVersion);
|
||||||
{ "method", "getinfo" }
|
|
||||||
};
|
var response = ProcessRequest<DSMInfoResponse>(requestBuilder, "get serial number", settings);
|
||||||
|
|
||||||
var response = ProcessRequest<DSMInfoResponse>(DiskStationApi.DSMInfo, arguments, settings, "get serial number");
|
|
||||||
return response.Data.SerialNumber;
|
return response.Data.SerialNumber;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,63 +1,77 @@
|
|||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
using NzbDrone.Common.Cache;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Common.Serializer;
|
using NzbDrone.Common.Serializer;
|
||||||
using NzbDrone.Core.Download.Clients.DownloadStation.Responses;
|
using NzbDrone.Core.Download.Clients.DownloadStation.Responses;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Download.Clients.DownloadStation.Proxies
|
namespace NzbDrone.Core.Download.Clients.DownloadStation.Proxies
|
||||||
{
|
{
|
||||||
public abstract class DiskStationProxyBase
|
public interface IDiskStationProxy
|
||||||
{
|
{
|
||||||
private static readonly Dictionary<DiskStationApi, string> Resources;
|
DiskStationApiInfo GetApiInfo(DownloadStationSettings settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class DiskStationProxyBase : IDiskStationProxy
|
||||||
|
{
|
||||||
|
protected readonly Logger _logger;
|
||||||
|
|
||||||
private readonly IHttpClient _httpClient;
|
private readonly IHttpClient _httpClient;
|
||||||
protected readonly Logger _logger;
|
private readonly ICached<DiskStationApiInfo> _infoCache;
|
||||||
private bool _authenticated;
|
private readonly ICached<string> _sessionCache;
|
||||||
|
private readonly DiskStationApi _apiType;
|
||||||
|
private readonly string _apiName;
|
||||||
|
|
||||||
|
private static readonly DiskStationApiInfo _apiInfo;
|
||||||
|
|
||||||
static DiskStationProxyBase()
|
static DiskStationProxyBase()
|
||||||
{
|
{
|
||||||
Resources = new Dictionary<DiskStationApi, string>
|
_apiInfo = new DiskStationApiInfo()
|
||||||
{
|
{
|
||||||
{ DiskStationApi.Info, "query.cgi" }
|
Type = DiskStationApi.Info,
|
||||||
|
Name = "SYNO.API.Info",
|
||||||
|
Path = "query.cgi",
|
||||||
|
MaxVersion = 1,
|
||||||
|
MinVersion = 1,
|
||||||
|
NeedsAuthentication = false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public DiskStationProxyBase(IHttpClient httpClient, Logger logger)
|
public DiskStationProxyBase(DiskStationApi apiType,
|
||||||
|
string apiName,
|
||||||
|
IHttpClient httpClient,
|
||||||
|
ICacheManager cacheManager,
|
||||||
|
Logger logger)
|
||||||
{
|
{
|
||||||
_httpClient = httpClient;
|
_httpClient = httpClient;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
_infoCache = cacheManager.GetCache<DiskStationApiInfo>(typeof(DiskStationProxyBase), "apiInfo");
|
||||||
|
_sessionCache = cacheManager.GetCache<string>(typeof(DiskStationProxyBase), "sessions");
|
||||||
|
_apiType = apiType;
|
||||||
|
_apiName = apiName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string GenerateSessionCacheKey(DownloadStationSettings settings)
|
||||||
protected DiskStationResponse<object> ProcessRequest(DiskStationApi api,
|
|
||||||
Dictionary<string, object> arguments,
|
|
||||||
DownloadStationSettings settings,
|
|
||||||
string operation,
|
|
||||||
HttpMethod method = HttpMethod.GET)
|
|
||||||
{
|
{
|
||||||
return ProcessRequest<object>(api, arguments, settings, operation, method);
|
return $"{settings.Username}@{settings.Host}:{settings.Port}";
|
||||||
}
|
}
|
||||||
|
|
||||||
protected DiskStationResponse<T> ProcessRequest<T>(DiskStationApi api,
|
protected DiskStationResponse<T> ProcessRequest<T>(HttpRequestBuilder requestBuilder,
|
||||||
Dictionary<string, object> arguments,
|
string operation,
|
||||||
DownloadStationSettings settings,
|
DownloadStationSettings settings) where T : new()
|
||||||
string operation,
|
|
||||||
HttpMethod method = HttpMethod.GET,
|
|
||||||
int retries = 0) where T : new()
|
|
||||||
{
|
{
|
||||||
if (retries == 5)
|
return ProcessRequest<T>(requestBuilder, operation, _apiType, settings);
|
||||||
{
|
}
|
||||||
throw new DownloadClientException("Try to process request to {0} with {1} more than 5 times", api, arguments.ToJson().ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_authenticated && api != DiskStationApi.Info && api != DiskStationApi.DSMInfo)
|
private DiskStationResponse<T> ProcessRequest<T>(HttpRequestBuilder requestBuilder,
|
||||||
{
|
string operation,
|
||||||
AuthenticateClient(settings);
|
DiskStationApi api,
|
||||||
}
|
DownloadStationSettings settings) where T : new()
|
||||||
|
{
|
||||||
var request = BuildRequest(settings, api, arguments, method);
|
var request = requestBuilder.Build();
|
||||||
var response = _httpClient.Execute(request);
|
var response = _httpClient.Execute(request);
|
||||||
|
|
||||||
_logger.Debug("Trying to {0}", operation);
|
_logger.Debug("Trying to {0}", operation);
|
||||||
@ -77,16 +91,14 @@ protected DiskStationResponse<T> ProcessRequest<T>(DiskStationApi api,
|
|||||||
|
|
||||||
if (responseContent.Error.SessionError)
|
if (responseContent.Error.SessionError)
|
||||||
{
|
{
|
||||||
_authenticated = false;
|
_sessionCache.Remove(GenerateSessionCacheKey(settings));
|
||||||
|
|
||||||
if (responseContent.Error.Code == 105)
|
if (responseContent.Error.Code == 105)
|
||||||
{
|
{
|
||||||
throw new DownloadClientAuthenticationException(msg);
|
throw new DownloadClientAuthenticationException(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ProcessRequest<T>(api, arguments, settings, operation, method, ++retries);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new DownloadClientException(msg);
|
throw new DownloadClientException(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -96,124 +108,126 @@ protected DiskStationResponse<T> ProcessRequest<T>(DiskStationApi api,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AuthenticateClient(DownloadStationSettings settings)
|
private string AuthenticateClient(DownloadStationSettings settings)
|
||||||
{
|
{
|
||||||
var arguments = new Dictionary<string, object>
|
var authInfo = GetApiInfo(DiskStationApi.Auth, settings);
|
||||||
{
|
|
||||||
{ "api", "SYNO.API.Auth" },
|
|
||||||
{ "version", "1" },
|
|
||||||
{ "method", "login" },
|
|
||||||
{ "account", settings.Username },
|
|
||||||
{ "passwd", settings.Password },
|
|
||||||
{ "format", "cookie" },
|
|
||||||
{ "session", "DownloadStation" },
|
|
||||||
};
|
|
||||||
|
|
||||||
var authLoginRequest = BuildRequest(settings, DiskStationApi.Auth, arguments, HttpMethod.GET);
|
var requestBuilder = BuildRequest(settings, authInfo, "login", 2);
|
||||||
authLoginRequest.StoreResponseCookie = true;
|
requestBuilder.AddQueryParam("account", settings.Username);
|
||||||
|
requestBuilder.AddQueryParam("passwd", settings.Password);
|
||||||
|
requestBuilder.AddQueryParam("format", "sid");
|
||||||
|
requestBuilder.AddQueryParam("session", Guid.NewGuid().ToString());
|
||||||
|
|
||||||
var response = _httpClient.Execute(authLoginRequest);
|
var authResponse = ProcessRequest<DiskStationAuthResponse>(requestBuilder, "login", DiskStationApi.Auth, settings);
|
||||||
|
|
||||||
var downloadStationResponse = Json.Deserialize<DiskStationResponse<DiskStationAuthResponse>>(response.Content);
|
return authResponse.Data.SId;
|
||||||
|
|
||||||
var authResponse = Json.Deserialize<DiskStationResponse<DiskStationAuthResponse>>(response.Content);
|
|
||||||
|
|
||||||
_authenticated = authResponse.Success;
|
|
||||||
|
|
||||||
if (!_authenticated)
|
|
||||||
{
|
|
||||||
throw new DownloadClientAuthenticationException(downloadStationResponse.Error.GetMessage(DiskStationApi.Auth));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private HttpRequest BuildRequest(DownloadStationSettings settings, DiskStationApi api, Dictionary<string, object> arguments, HttpMethod method)
|
protected HttpRequestBuilder BuildRequest(DownloadStationSettings settings, string methodName, int apiVersion, HttpMethod httpVerb = HttpMethod.GET)
|
||||||
{
|
{
|
||||||
if (!Resources.ContainsKey(api))
|
var info = GetApiInfo(_apiType, settings);
|
||||||
{
|
|
||||||
GetApiVersion(settings, api);
|
|
||||||
}
|
|
||||||
|
|
||||||
var requestBuilder = new HttpRequestBuilder(settings.UseSsl, settings.Host, settings.Port).Resource($"webapi/{Resources[api]}");
|
return BuildRequest(settings, info, methodName, apiVersion, httpVerb);
|
||||||
requestBuilder.Method = method;
|
}
|
||||||
|
|
||||||
|
private HttpRequestBuilder BuildRequest(DownloadStationSettings settings, DiskStationApiInfo apiInfo, string methodName, int apiVersion, HttpMethod httpVerb = HttpMethod.GET)
|
||||||
|
{
|
||||||
|
var requestBuilder = new HttpRequestBuilder(settings.UseSsl, settings.Host, settings.Port).Resource($"webapi/{apiInfo.Path}");
|
||||||
|
requestBuilder.Method = httpVerb;
|
||||||
requestBuilder.LogResponseContent = true;
|
requestBuilder.LogResponseContent = true;
|
||||||
requestBuilder.SuppressHttpError = true;
|
requestBuilder.SuppressHttpError = true;
|
||||||
requestBuilder.AllowAutoRedirect = false;
|
requestBuilder.AllowAutoRedirect = false;
|
||||||
|
requestBuilder.Headers.ContentType = "application/json";
|
||||||
|
|
||||||
if (requestBuilder.Method == HttpMethod.POST)
|
if (apiVersion < apiInfo.MinVersion || apiVersion > apiInfo.MaxVersion)
|
||||||
{
|
{
|
||||||
if (api == DiskStationApi.DownloadStationTask && arguments.ContainsKey("file"))
|
throw new ArgumentOutOfRangeException(nameof(apiVersion));
|
||||||
{
|
}
|
||||||
requestBuilder.Headers.ContentType = "multipart/form-data";
|
|
||||||
|
|
||||||
foreach (var arg in arguments)
|
if (httpVerb == HttpMethod.POST)
|
||||||
{
|
{
|
||||||
if (arg.Key == "file")
|
if (apiInfo.NeedsAuthentication)
|
||||||
{
|
|
||||||
Dictionary<string, object> file = (Dictionary<string, object>)arg.Value;
|
|
||||||
requestBuilder.AddFormUpload(arg.Key, file["name"].ToString(), (byte[])file["data"]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
requestBuilder.AddFormParameter(arg.Key, arg.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
requestBuilder.Headers.ContentType = "application/json";
|
requestBuilder.AddFormParameter("_sid", _sessionCache.Get(GenerateSessionCacheKey(settings), () => AuthenticateClient(settings), TimeSpan.FromHours(6)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
requestBuilder.AddFormParameter("api", apiInfo.Name);
|
||||||
|
requestBuilder.AddFormParameter("version", apiVersion);
|
||||||
|
requestBuilder.AddFormParameter("method", methodName);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
foreach (var arg in arguments)
|
if (apiInfo.NeedsAuthentication)
|
||||||
{
|
{
|
||||||
requestBuilder.AddQueryParam(arg.Key, arg.Value);
|
requestBuilder.AddQueryParam("_sid", _sessionCache.Get(GenerateSessionCacheKey(settings), () => AuthenticateClient(settings), TimeSpan.FromHours(6)));
|
||||||
|
}
|
||||||
|
|
||||||
|
requestBuilder.AddQueryParam("api", apiInfo.Name);
|
||||||
|
requestBuilder.AddQueryParam("version", apiVersion);
|
||||||
|
requestBuilder.AddQueryParam("method", methodName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return requestBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GenerateInfoCacheKey(DownloadStationSettings settings, DiskStationApi api)
|
||||||
|
{
|
||||||
|
return $"{settings.Host}:{settings.Port}->{api}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateApiInfo(DownloadStationSettings settings)
|
||||||
|
{
|
||||||
|
var apis = new Dictionary<string, DiskStationApi>()
|
||||||
|
{
|
||||||
|
{ "SYNO.API.Auth", DiskStationApi.Auth },
|
||||||
|
{ _apiName, _apiType }
|
||||||
|
};
|
||||||
|
|
||||||
|
var requestBuilder = BuildRequest(settings, _apiInfo, "query", _apiInfo.MinVersion);
|
||||||
|
requestBuilder.AddQueryParam("query", string.Join(",", apis.Keys));
|
||||||
|
|
||||||
|
var infoResponse = ProcessRequest<DiskStationApiInfoResponse>(requestBuilder, "get api info", _apiInfo.Type, settings);
|
||||||
|
|
||||||
|
foreach (var data in infoResponse.Data)
|
||||||
|
{
|
||||||
|
if (apis.ContainsKey(data.Key))
|
||||||
|
{
|
||||||
|
data.Value.Name = data.Key;
|
||||||
|
data.Value.Type = apis[data.Key];
|
||||||
|
data.Value.NeedsAuthentication = apis[data.Key] != DiskStationApi.Auth;
|
||||||
|
|
||||||
|
_infoCache.Set(GenerateInfoCacheKey(settings, apis[data.Key]), data.Value, TimeSpan.FromHours(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private DiskStationApiInfo GetApiInfo(DiskStationApi api, DownloadStationSettings settings)
|
||||||
|
{
|
||||||
|
if (api == DiskStationApi.Info)
|
||||||
|
{
|
||||||
|
return _apiInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
var key = GenerateInfoCacheKey(settings, api);
|
||||||
|
var info = _infoCache.Find(key);
|
||||||
|
|
||||||
|
if (info == null)
|
||||||
|
{
|
||||||
|
UpdateApiInfo(settings);
|
||||||
|
info = _infoCache.Find(key);
|
||||||
|
|
||||||
|
if (info == null)
|
||||||
|
{
|
||||||
|
throw new DownloadClientException("Info of {0} not found on {1}:{2}", api, settings.Host, settings.Port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return requestBuilder.Build();
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected IEnumerable<int> GetApiVersion(DownloadStationSettings settings, DiskStationApi api)
|
public DiskStationApiInfo GetApiInfo(DownloadStationSettings settings)
|
||||||
{
|
{
|
||||||
var arguments = new Dictionary<string, object>
|
return GetApiInfo(_apiType, settings);
|
||||||
{
|
|
||||||
{ "api", "SYNO.API.Info" },
|
|
||||||
{ "version", "1" },
|
|
||||||
{ "method", "query" },
|
|
||||||
{ "query", "SYNO.API.Auth, SYNO.DownloadStation.Info, SYNO.DownloadStation.Task, SYNO.FileStation.List, SYNO.DSM.Info" },
|
|
||||||
};
|
|
||||||
|
|
||||||
var infoResponse = ProcessRequest<DiskStationApiInfoResponse>(DiskStationApi.Info, arguments, settings, "Get api version");
|
|
||||||
|
|
||||||
//TODO: Refactor this into more elegant code
|
|
||||||
var infoResponeDSAuth = infoResponse.Data["SYNO.API.Auth"];
|
|
||||||
var infoResponeDSInfo = infoResponse.Data["SYNO.DownloadStation.Info"];
|
|
||||||
var infoResponeDSTask = infoResponse.Data["SYNO.DownloadStation.Task"];
|
|
||||||
var infoResponseFSList = infoResponse.Data["SYNO.FileStation.List"];
|
|
||||||
var infoResponseDSMInfo = infoResponse.Data["SYNO.DSM.Info"];
|
|
||||||
|
|
||||||
Resources[DiskStationApi.Auth] = infoResponeDSAuth.Path;
|
|
||||||
Resources[DiskStationApi.DownloadStationInfo] = infoResponeDSInfo.Path;
|
|
||||||
Resources[DiskStationApi.DownloadStationTask] = infoResponeDSTask.Path;
|
|
||||||
Resources[DiskStationApi.FileStationList] = infoResponseFSList.Path;
|
|
||||||
Resources[DiskStationApi.DSMInfo] = infoResponseDSMInfo.Path;
|
|
||||||
|
|
||||||
switch (api)
|
|
||||||
{
|
|
||||||
case DiskStationApi.Auth:
|
|
||||||
return Enumerable.Range(infoResponeDSAuth.MinVersion, infoResponeDSAuth.MaxVersion - infoResponeDSAuth.MinVersion + 1);
|
|
||||||
case DiskStationApi.DownloadStationInfo:
|
|
||||||
return Enumerable.Range(infoResponeDSInfo.MinVersion, infoResponeDSInfo.MaxVersion - infoResponeDSInfo.MinVersion + 1);
|
|
||||||
case DiskStationApi.DownloadStationTask:
|
|
||||||
return Enumerable.Range(infoResponeDSTask.MinVersion, infoResponeDSTask.MaxVersion - infoResponeDSTask.MinVersion + 1);
|
|
||||||
case DiskStationApi.FileStationList:
|
|
||||||
return Enumerable.Range(infoResponseFSList.MinVersion, infoResponseFSList.MaxVersion - infoResponseFSList.MinVersion + 1);
|
|
||||||
case DiskStationApi.DSMInfo:
|
|
||||||
return Enumerable.Range(infoResponseDSMInfo.MinVersion, infoResponseDSMInfo.MaxVersion - infoResponseDSMInfo.MinVersion + 1);
|
|
||||||
default:
|
|
||||||
throw new DownloadClientException("Api not implemented");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
using NLog;
|
||||||
|
using NzbDrone.Common.Http;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using NzbDrone.Common.Cache;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Download.Clients.DownloadStation.Proxies
|
||||||
|
{
|
||||||
|
public interface IDownloadStationInfoProxy : IDiskStationProxy
|
||||||
|
{
|
||||||
|
Dictionary<string, object> GetConfig(DownloadStationSettings settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DownloadStationInfoProxy : DiskStationProxyBase, IDownloadStationInfoProxy
|
||||||
|
{
|
||||||
|
public DownloadStationInfoProxy(IHttpClient httpClient, ICacheManager cacheManager, Logger logger) :
|
||||||
|
base(DiskStationApi.DownloadStationInfo, "SYNO.DownloadStation.Info", httpClient, cacheManager, logger)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dictionary<string, object> GetConfig(DownloadStationSettings settings)
|
||||||
|
{
|
||||||
|
var requestBuilder = BuildRequest(settings, "getConfig", 1);
|
||||||
|
|
||||||
|
var response = ProcessRequest<Dictionary<string, object>>(requestBuilder, "get config", settings);
|
||||||
|
|
||||||
|
return response.Data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,121 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using NLog;
|
|
||||||
using NzbDrone.Common.Extensions;
|
|
||||||
using NzbDrone.Common.Http;
|
|
||||||
using NzbDrone.Core.Download.Clients.DownloadStation.Responses;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Download.Clients.DownloadStation.Proxies
|
|
||||||
{
|
|
||||||
public interface IDownloadStationProxy
|
|
||||||
{
|
|
||||||
IEnumerable<DownloadStationTask> GetTasks(DownloadStationSettings settings);
|
|
||||||
Dictionary<string, object> GetConfig(DownloadStationSettings settings);
|
|
||||||
void RemoveTask(string downloadId, DownloadStationSettings settings);
|
|
||||||
void AddTaskFromUrl(string url, string downloadDirectory, DownloadStationSettings settings);
|
|
||||||
void AddTaskFromData(byte[] data, string filename, string downloadDirectory, DownloadStationSettings settings);
|
|
||||||
IEnumerable<int> GetApiVersion(DownloadStationSettings settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class DownloadStationProxy : DiskStationProxyBase, IDownloadStationProxy
|
|
||||||
{
|
|
||||||
public DownloadStationProxy(IHttpClient httpClient, Logger logger)
|
|
||||||
: base(httpClient, logger)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddTaskFromData(byte[] data, string filename, string downloadDirectory, DownloadStationSettings settings)
|
|
||||||
{
|
|
||||||
var arguments = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
{ "api", "SYNO.DownloadStation.Task" },
|
|
||||||
{ "version", "2" },
|
|
||||||
{ "method", "create" }
|
|
||||||
};
|
|
||||||
|
|
||||||
if (downloadDirectory.IsNotNullOrWhiteSpace())
|
|
||||||
{
|
|
||||||
arguments.Add("destination", downloadDirectory);
|
|
||||||
}
|
|
||||||
|
|
||||||
arguments.Add("file", new Dictionary<string, object>() { { "name", filename }, { "data", data } });
|
|
||||||
|
|
||||||
var response = ProcessRequest(DiskStationApi.DownloadStationTask, arguments, settings, $"add task from data {filename}", HttpMethod.POST);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddTaskFromUrl(string url, string downloadDirectory, DownloadStationSettings settings)
|
|
||||||
{
|
|
||||||
var arguments = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
{ "api", "SYNO.DownloadStation.Task" },
|
|
||||||
{ "version", "3" },
|
|
||||||
{ "method", "create" },
|
|
||||||
{ "uri", url }
|
|
||||||
};
|
|
||||||
|
|
||||||
if (downloadDirectory.IsNotNullOrWhiteSpace())
|
|
||||||
{
|
|
||||||
arguments.Add("destination", downloadDirectory);
|
|
||||||
}
|
|
||||||
|
|
||||||
var response = ProcessRequest(DiskStationApi.DownloadStationTask, arguments, settings, $"add task from url {url}");
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<DownloadStationTask> GetTasks(DownloadStationSettings settings)
|
|
||||||
{
|
|
||||||
var arguments = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
{ "api", "SYNO.DownloadStation.Task" },
|
|
||||||
{ "version", "1" },
|
|
||||||
{ "method", "list" },
|
|
||||||
{ "additional", "detail,transfer" }
|
|
||||||
};
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var response = ProcessRequest<DownloadStationTaskInfoResponse>(DiskStationApi.DownloadStationTask, arguments, settings, "get tasks");
|
|
||||||
|
|
||||||
return response.Data.Tasks;
|
|
||||||
}
|
|
||||||
catch (DownloadClientException e)
|
|
||||||
{
|
|
||||||
_logger.Error(e);
|
|
||||||
return new List<DownloadStationTask>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Dictionary<string, object> GetConfig(DownloadStationSettings settings)
|
|
||||||
{
|
|
||||||
var arguments = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
{ "api", "SYNO.DownloadStation.Info" },
|
|
||||||
{ "version", "1" },
|
|
||||||
{ "method", "getconfig" }
|
|
||||||
};
|
|
||||||
|
|
||||||
var response = ProcessRequest<Dictionary<string, object>>(DiskStationApi.DownloadStationInfo, arguments, settings, "get config");
|
|
||||||
|
|
||||||
return response.Data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveTask(string downloadId, DownloadStationSettings settings)
|
|
||||||
{
|
|
||||||
var arguments = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
{ "api", "SYNO.DownloadStation.Task" },
|
|
||||||
{ "version", "1" },
|
|
||||||
{ "method", "delete" },
|
|
||||||
{ "id", downloadId },
|
|
||||||
{ "force_complete", false }
|
|
||||||
};
|
|
||||||
|
|
||||||
var response = ProcessRequest(DiskStationApi.DownloadStationTask, arguments, settings, $"remove item {downloadId}");
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<int> GetApiVersion(DownloadStationSettings settings)
|
|
||||||
{
|
|
||||||
return base.GetApiVersion(settings, DiskStationApi.DownloadStationInfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,79 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Common.Cache;
|
||||||
|
using NzbDrone.Common.Extensions;
|
||||||
|
using NzbDrone.Common.Http;
|
||||||
|
using NzbDrone.Core.Download.Clients.DownloadStation.Responses;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Download.Clients.DownloadStation.Proxies
|
||||||
|
{
|
||||||
|
public interface IDownloadStationTaskProxy : IDiskStationProxy
|
||||||
|
{
|
||||||
|
IEnumerable<DownloadStationTask> GetTasks(DownloadStationSettings settings);
|
||||||
|
void RemoveTask(string downloadId, DownloadStationSettings settings);
|
||||||
|
void AddTaskFromUrl(string url, string downloadDirectory, DownloadStationSettings settings);
|
||||||
|
void AddTaskFromData(byte[] data, string filename, string downloadDirectory, DownloadStationSettings settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DownloadStationTaskProxy : DiskStationProxyBase, IDownloadStationTaskProxy
|
||||||
|
{
|
||||||
|
public DownloadStationTaskProxy(IHttpClient httpClient, ICacheManager cacheManager, Logger logger)
|
||||||
|
: base(DiskStationApi.DownloadStationTask, "SYNO.DownloadStation.Task", httpClient, cacheManager, logger)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddTaskFromData(byte[] data, string filename, string downloadDirectory, DownloadStationSettings settings)
|
||||||
|
{
|
||||||
|
var requestBuilder = BuildRequest(settings, "create", 2, HttpMethod.POST);
|
||||||
|
|
||||||
|
if (downloadDirectory.IsNotNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
requestBuilder.AddFormParameter("destination", downloadDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
|
requestBuilder.AddFormUpload("file", filename, data);
|
||||||
|
|
||||||
|
var response = ProcessRequest<object>(requestBuilder, $"add task from data {filename}", settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddTaskFromUrl(string url, string downloadDirectory, DownloadStationSettings settings)
|
||||||
|
{
|
||||||
|
var requestBuilder = BuildRequest(settings, "create", 3);
|
||||||
|
requestBuilder.AddQueryParam("uri", url);
|
||||||
|
|
||||||
|
if (downloadDirectory.IsNotNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
requestBuilder.AddQueryParam("destination", downloadDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
|
var response = ProcessRequest<object>(requestBuilder, $"add task from url {url}", settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<DownloadStationTask> GetTasks(DownloadStationSettings settings)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var requestBuilder = BuildRequest(settings, "list", 1);
|
||||||
|
requestBuilder.AddQueryParam("additional", "detail,transfer");
|
||||||
|
|
||||||
|
var response = ProcessRequest<DownloadStationTaskInfoResponse>(requestBuilder, "get tasks", settings);
|
||||||
|
|
||||||
|
return response.Data.Tasks;
|
||||||
|
}
|
||||||
|
catch (DownloadClientException e)
|
||||||
|
{
|
||||||
|
_logger.Error(e);
|
||||||
|
return new List<DownloadStationTask>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveTask(string downloadId, DownloadStationSettings settings)
|
||||||
|
{
|
||||||
|
var requestBuilder = BuildRequest(settings, "delete", 1);
|
||||||
|
requestBuilder.AddQueryParam("id", downloadId);
|
||||||
|
requestBuilder.AddQueryParam("force_complete", false);
|
||||||
|
|
||||||
|
var response = ProcessRequest<object>(requestBuilder, $"remove item {downloadId}", settings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,31 +2,27 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
using NzbDrone.Common.Cache;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Common.Serializer;
|
using NzbDrone.Common.Serializer;
|
||||||
using NzbDrone.Core.Download.Clients.DownloadStation.Responses;
|
using NzbDrone.Core.Download.Clients.DownloadStation.Responses;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Download.Clients.DownloadStation.Proxies
|
namespace NzbDrone.Core.Download.Clients.DownloadStation.Proxies
|
||||||
{
|
{
|
||||||
public interface IFileStationProxy
|
public interface IFileStationProxy : IDiskStationProxy
|
||||||
{
|
{
|
||||||
SharedFolderMapping GetSharedFolderMapping(string sharedFolder, DownloadStationSettings settings);
|
SharedFolderMapping GetSharedFolderMapping(string sharedFolder, DownloadStationSettings settings);
|
||||||
IEnumerable<int> GetApiVersion(DownloadStationSettings settings);
|
|
||||||
FileStationListFileInfoResponse GetInfoFileOrDirectory(string path, DownloadStationSettings settings);
|
FileStationListFileInfoResponse GetInfoFileOrDirectory(string path, DownloadStationSettings settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class FileStationProxy : DiskStationProxyBase, IFileStationProxy
|
public class FileStationProxy : DiskStationProxyBase, IFileStationProxy
|
||||||
{
|
{
|
||||||
public FileStationProxy(IHttpClient httpClient, Logger logger)
|
public FileStationProxy(IHttpClient httpClient, ICacheManager cacheManager, Logger logger)
|
||||||
: base(httpClient, logger)
|
: base(DiskStationApi.FileStationList, "SYNO.FileStation.List", httpClient, cacheManager, logger)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<int> GetApiVersion(DownloadStationSettings settings)
|
|
||||||
{
|
|
||||||
return base.GetApiVersion(settings, DiskStationApi.FileStationList);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SharedFolderMapping GetSharedFolderMapping(string sharedFolder, DownloadStationSettings settings)
|
public SharedFolderMapping GetSharedFolderMapping(string sharedFolder, DownloadStationSettings settings)
|
||||||
{
|
{
|
||||||
var info = GetInfoFileOrDirectory(sharedFolder, settings);
|
var info = GetInfoFileOrDirectory(sharedFolder, settings);
|
||||||
@ -38,16 +34,11 @@ public SharedFolderMapping GetSharedFolderMapping(string sharedFolder, DownloadS
|
|||||||
|
|
||||||
public FileStationListFileInfoResponse GetInfoFileOrDirectory(string path, DownloadStationSettings settings)
|
public FileStationListFileInfoResponse GetInfoFileOrDirectory(string path, DownloadStationSettings settings)
|
||||||
{
|
{
|
||||||
var arguments = new Dictionary<string, object>
|
var requestBuilder = BuildRequest(settings, "getinfo", 2);
|
||||||
{
|
requestBuilder.AddQueryParam("path", new[] { path }.ToJson());
|
||||||
{ "api", "SYNO.FileStation.List" },
|
requestBuilder.AddQueryParam("additional", "[\"real_path\"]");
|
||||||
{ "version", "2" },
|
|
||||||
{ "method", "getinfo" },
|
|
||||||
{ "path", new [] { path }.ToJson() },
|
|
||||||
{ "additional", $"[\"real_path\"]" }
|
|
||||||
};
|
|
||||||
|
|
||||||
var response = ProcessRequest<FileStationListResponse>(DiskStationApi.FileStationList, arguments, settings, $"get info of {path}");
|
var response = ProcessRequest<FileStationListResponse>(requestBuilder, $"get info of {path}", settings);
|
||||||
|
|
||||||
return response.Data.Files.First();
|
return response.Data.Files.First();
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Cache;
|
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
@ -20,7 +19,8 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
|
|||||||
{
|
{
|
||||||
public class TorrentDownloadStation : TorrentClientBase<DownloadStationSettings>
|
public class TorrentDownloadStation : TorrentClientBase<DownloadStationSettings>
|
||||||
{
|
{
|
||||||
protected readonly IDownloadStationProxy _proxy;
|
protected readonly IDownloadStationInfoProxy _dsInfoProxy;
|
||||||
|
protected readonly IDownloadStationTaskProxy _dsTaskProxy;
|
||||||
protected readonly ISharedFolderResolver _sharedFolderResolver;
|
protected readonly ISharedFolderResolver _sharedFolderResolver;
|
||||||
protected readonly ISerialNumberProvider _serialNumberProvider;
|
protected readonly ISerialNumberProvider _serialNumberProvider;
|
||||||
protected readonly IFileStationProxy _fileStationProxy;
|
protected readonly IFileStationProxy _fileStationProxy;
|
||||||
@ -28,7 +28,8 @@ public class TorrentDownloadStation : TorrentClientBase<DownloadStationSettings>
|
|||||||
public TorrentDownloadStation(ISharedFolderResolver sharedFolderResolver,
|
public TorrentDownloadStation(ISharedFolderResolver sharedFolderResolver,
|
||||||
ISerialNumberProvider serialNumberProvider,
|
ISerialNumberProvider serialNumberProvider,
|
||||||
IFileStationProxy fileStationProxy,
|
IFileStationProxy fileStationProxy,
|
||||||
IDownloadStationProxy proxy,
|
IDownloadStationInfoProxy dsInfoProxy,
|
||||||
|
IDownloadStationTaskProxy dsTaskProxy,
|
||||||
ITorrentFileInfoReader torrentFileInfoReader,
|
ITorrentFileInfoReader torrentFileInfoReader,
|
||||||
IHttpClient httpClient,
|
IHttpClient httpClient,
|
||||||
IConfigService configService,
|
IConfigService configService,
|
||||||
@ -37,7 +38,8 @@ public TorrentDownloadStation(ISharedFolderResolver sharedFolderResolver,
|
|||||||
Logger logger)
|
Logger logger)
|
||||||
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger)
|
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger)
|
||||||
{
|
{
|
||||||
_proxy = proxy;
|
_dsInfoProxy = dsInfoProxy;
|
||||||
|
_dsTaskProxy = dsTaskProxy;
|
||||||
_fileStationProxy = fileStationProxy;
|
_fileStationProxy = fileStationProxy;
|
||||||
_sharedFolderResolver = sharedFolderResolver;
|
_sharedFolderResolver = sharedFolderResolver;
|
||||||
_serialNumberProvider = serialNumberProvider;
|
_serialNumberProvider = serialNumberProvider;
|
||||||
@ -47,7 +49,7 @@ public TorrentDownloadStation(ISharedFolderResolver sharedFolderResolver,
|
|||||||
|
|
||||||
protected IEnumerable<DownloadStationTask> GetTasks()
|
protected IEnumerable<DownloadStationTask> GetTasks()
|
||||||
{
|
{
|
||||||
return _proxy.GetTasks(Settings).Where(v => v.Type.ToLower() == DownloadStationTaskType.BT.ToString().ToLower());
|
return _dsTaskProxy.GetTasks(Settings).Where(v => v.Type.ToLower() == DownloadStationTaskType.BT.ToString().ToLower());
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<DownloadClientItem> GetItems()
|
public override IEnumerable<DownloadClientItem> GetItems()
|
||||||
@ -129,7 +131,7 @@ public override void RemoveItem(string downloadId, bool deleteData)
|
|||||||
DeleteItemData(downloadId);
|
DeleteItemData(downloadId);
|
||||||
}
|
}
|
||||||
|
|
||||||
_proxy.RemoveTask(ParseDownloadId(downloadId), Settings);
|
_dsTaskProxy.RemoveTask(ParseDownloadId(downloadId), Settings);
|
||||||
_logger.Debug("{0} removed correctly", downloadId);
|
_logger.Debug("{0} removed correctly", downloadId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,7 +150,7 @@ protected override string AddFromMagnetLink(RemoteEpisode remoteEpisode, string
|
|||||||
{
|
{
|
||||||
var hashedSerialNumber = _serialNumberProvider.GetSerialNumber(Settings);
|
var hashedSerialNumber = _serialNumberProvider.GetSerialNumber(Settings);
|
||||||
|
|
||||||
_proxy.AddTaskFromUrl(magnetLink, GetDownloadDirectory(), Settings);
|
_dsTaskProxy.AddTaskFromUrl(magnetLink, GetDownloadDirectory(), Settings);
|
||||||
|
|
||||||
var item = GetTasks().SingleOrDefault(t => t.Additional.Detail["uri"] == magnetLink);
|
var item = GetTasks().SingleOrDefault(t => t.Additional.Detail["uri"] == magnetLink);
|
||||||
|
|
||||||
@ -167,7 +169,7 @@ protected override string AddFromTorrentFile(RemoteEpisode remoteEpisode, string
|
|||||||
{
|
{
|
||||||
var hashedSerialNumber = _serialNumberProvider.GetSerialNumber(Settings);
|
var hashedSerialNumber = _serialNumberProvider.GetSerialNumber(Settings);
|
||||||
|
|
||||||
_proxy.AddTaskFromData(fileContent, filename, GetDownloadDirectory(), Settings);
|
_dsTaskProxy.AddTaskFromData(fileContent, filename, GetDownloadDirectory(), Settings);
|
||||||
|
|
||||||
var items = GetTasks().Where(t => t.Additional.Detail["uri"] == Path.GetFileNameWithoutExtension(filename));
|
var items = GetTasks().Where(t => t.Additional.Detail["uri"] == Path.GetFileNameWithoutExtension(filename));
|
||||||
|
|
||||||
@ -358,13 +360,13 @@ protected ValidationFailure TestConnection()
|
|||||||
|
|
||||||
protected ValidationFailure ValidateVersion()
|
protected ValidationFailure ValidateVersion()
|
||||||
{
|
{
|
||||||
var versionRange = _proxy.GetApiVersion(Settings);
|
var info = _dsTaskProxy.GetApiInfo(Settings);
|
||||||
|
|
||||||
_logger.Debug("Download Station api version information: Min {0} - Max {1}", versionRange.Min(), versionRange.Max());
|
_logger.Debug("Download Station api version information: Min {0} - Max {1}", info.MinVersion, info.MaxVersion);
|
||||||
|
|
||||||
if (!versionRange.Contains(2))
|
if (info.MinVersion > 2 || info.MaxVersion < 2)
|
||||||
{
|
{
|
||||||
return new ValidationFailure(string.Empty, $"Download Station API version not supported, should be at least 2. It supports from {versionRange.Min()} to {versionRange.Max()}");
|
return new ValidationFailure(string.Empty, $"Download Station API version not supported, should be at least 2. It supports from {info.MinVersion} to {info.MaxVersion}");
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@ -395,7 +397,7 @@ protected string CreateDownloadId(string id, string hashedSerialNumber)
|
|||||||
|
|
||||||
protected string GetDefaultDir()
|
protected string GetDefaultDir()
|
||||||
{
|
{
|
||||||
var config = _proxy.GetConfig(Settings);
|
var config = _dsInfoProxy.GetConfig(Settings);
|
||||||
|
|
||||||
var path = config["default_destination"] as string;
|
var path = config["default_destination"] as string;
|
||||||
|
|
||||||
|
@ -17,7 +17,8 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
|
|||||||
{
|
{
|
||||||
public class UsenetDownloadStation : UsenetClientBase<DownloadStationSettings>
|
public class UsenetDownloadStation : UsenetClientBase<DownloadStationSettings>
|
||||||
{
|
{
|
||||||
protected readonly IDownloadStationProxy _proxy;
|
protected readonly IDownloadStationInfoProxy _dsInfoProxy;
|
||||||
|
protected readonly IDownloadStationTaskProxy _dsTaskProxy;
|
||||||
protected readonly ISharedFolderResolver _sharedFolderResolver;
|
protected readonly ISharedFolderResolver _sharedFolderResolver;
|
||||||
protected readonly ISerialNumberProvider _serialNumberProvider;
|
protected readonly ISerialNumberProvider _serialNumberProvider;
|
||||||
protected readonly IFileStationProxy _fileStationProxy;
|
protected readonly IFileStationProxy _fileStationProxy;
|
||||||
@ -25,7 +26,8 @@ public class UsenetDownloadStation : UsenetClientBase<DownloadStationSettings>
|
|||||||
public UsenetDownloadStation(ISharedFolderResolver sharedFolderResolver,
|
public UsenetDownloadStation(ISharedFolderResolver sharedFolderResolver,
|
||||||
ISerialNumberProvider serialNumberProvider,
|
ISerialNumberProvider serialNumberProvider,
|
||||||
IFileStationProxy fileStationProxy,
|
IFileStationProxy fileStationProxy,
|
||||||
IDownloadStationProxy proxy,
|
IDownloadStationInfoProxy dsInfoProxy,
|
||||||
|
IDownloadStationTaskProxy dsTaskProxy,
|
||||||
IHttpClient httpClient,
|
IHttpClient httpClient,
|
||||||
IConfigService configService,
|
IConfigService configService,
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
@ -34,7 +36,8 @@ Logger logger
|
|||||||
)
|
)
|
||||||
: base(httpClient, configService, diskProvider, remotePathMappingService, logger)
|
: base(httpClient, configService, diskProvider, remotePathMappingService, logger)
|
||||||
{
|
{
|
||||||
_proxy = proxy;
|
_dsInfoProxy = dsInfoProxy;
|
||||||
|
_dsTaskProxy = dsTaskProxy;
|
||||||
_fileStationProxy = fileStationProxy;
|
_fileStationProxy = fileStationProxy;
|
||||||
_sharedFolderResolver = sharedFolderResolver;
|
_sharedFolderResolver = sharedFolderResolver;
|
||||||
_serialNumberProvider = serialNumberProvider;
|
_serialNumberProvider = serialNumberProvider;
|
||||||
@ -44,7 +47,7 @@ Logger logger
|
|||||||
|
|
||||||
protected IEnumerable<DownloadStationTask> GetTasks()
|
protected IEnumerable<DownloadStationTask> GetTasks()
|
||||||
{
|
{
|
||||||
return _proxy.GetTasks(Settings).Where(v => v.Type.ToLower() == DownloadStationTaskType.NZB.ToString().ToLower());
|
return _dsTaskProxy.GetTasks(Settings).Where(v => v.Type.ToLower() == DownloadStationTaskType.NZB.ToString().ToLower());
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<DownloadClientItem> GetItems()
|
public override IEnumerable<DownloadClientItem> GetItems()
|
||||||
@ -153,7 +156,7 @@ public override void RemoveItem(string downloadId, bool deleteData)
|
|||||||
DeleteItemData(downloadId);
|
DeleteItemData(downloadId);
|
||||||
}
|
}
|
||||||
|
|
||||||
_proxy.RemoveTask(ParseDownloadId(downloadId), Settings);
|
_dsTaskProxy.RemoveTask(ParseDownloadId(downloadId), Settings);
|
||||||
_logger.Debug("{0} removed correctly", downloadId);
|
_logger.Debug("{0} removed correctly", downloadId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,7 +164,7 @@ protected override string AddFromNzbFile(RemoteEpisode remoteEpisode, string fil
|
|||||||
{
|
{
|
||||||
var hashedSerialNumber = _serialNumberProvider.GetSerialNumber(Settings);
|
var hashedSerialNumber = _serialNumberProvider.GetSerialNumber(Settings);
|
||||||
|
|
||||||
_proxy.AddTaskFromData(fileContent, filename, GetDownloadDirectory(), Settings);
|
_dsTaskProxy.AddTaskFromData(fileContent, filename, GetDownloadDirectory(), Settings);
|
||||||
|
|
||||||
var items = GetTasks().Where(t => t.Additional.Detail["uri"] == filename);
|
var items = GetTasks().Where(t => t.Additional.Detail["uri"] == filename);
|
||||||
|
|
||||||
@ -276,13 +279,13 @@ protected ValidationFailure TestConnection()
|
|||||||
|
|
||||||
protected ValidationFailure ValidateVersion()
|
protected ValidationFailure ValidateVersion()
|
||||||
{
|
{
|
||||||
var versionRange = _proxy.GetApiVersion(Settings);
|
var info = _dsTaskProxy.GetApiInfo(Settings);
|
||||||
|
|
||||||
_logger.Debug("Download Station api version information: Min {0} - Max {1}", versionRange.Min(), versionRange.Max());
|
_logger.Debug("Download Station api version information: Min {0} - Max {1}", info.MinVersion, info.MaxVersion);
|
||||||
|
|
||||||
if (!versionRange.Contains(2))
|
if (info.MinVersion > 2 || info.MaxVersion < 2)
|
||||||
{
|
{
|
||||||
return new ValidationFailure(string.Empty, $"Download Station API version not supported, should be at least 2. It supports from {versionRange.Min()} to {versionRange.Max()}");
|
return new ValidationFailure(string.Empty, $"Download Station API version not supported, should be at least 2. It supports from {info.MinVersion} to {info.MaxVersion}");
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@ -394,7 +397,7 @@ protected string CreateDownloadId(string id, string hashedSerialNumber)
|
|||||||
|
|
||||||
protected string GetDefaultDir()
|
protected string GetDefaultDir()
|
||||||
{
|
{
|
||||||
var config = _proxy.GetConfig(Settings);
|
var config = _dsInfoProxy.GetConfig(Settings);
|
||||||
|
|
||||||
var path = config["default_destination"] as string;
|
var path = config["default_destination"] as string;
|
||||||
|
|
||||||
|
@ -355,8 +355,9 @@
|
|||||||
<Compile Include="Download\Clients\Deluge\DelugeUpdateUIResult.cs" />
|
<Compile Include="Download\Clients\Deluge\DelugeUpdateUIResult.cs" />
|
||||||
<Compile Include="Download\Clients\DownloadClientAuthenticationException.cs" />
|
<Compile Include="Download\Clients\DownloadClientAuthenticationException.cs" />
|
||||||
<Compile Include="Download\Clients\DownloadClientException.cs" />
|
<Compile Include="Download\Clients\DownloadClientException.cs" />
|
||||||
|
<Compile Include="Download\Clients\DownloadStation\Proxies\DownloadStationInfoProxy.cs" />
|
||||||
<Compile Include="Download\Clients\DownloadStation\TorrentDownloadStation.cs" />
|
<Compile Include="Download\Clients\DownloadStation\TorrentDownloadStation.cs" />
|
||||||
<Compile Include="Download\Clients\DownloadStation\Proxies\DownloadStationProxy.cs" />
|
<Compile Include="Download\Clients\DownloadStation\Proxies\DownloadStationTaskProxy.cs" />
|
||||||
<Compile Include="Download\Clients\DownloadStation\DownloadStationSettings.cs" />
|
<Compile Include="Download\Clients\DownloadStation\DownloadStationSettings.cs" />
|
||||||
<Compile Include="Download\Clients\DownloadStation\DownloadStationTask.cs" />
|
<Compile Include="Download\Clients\DownloadStation\DownloadStationTask.cs" />
|
||||||
<Compile Include="Download\Clients\DownloadStation\DownloadStationTaskAdditional.cs" />
|
<Compile Include="Download\Clients\DownloadStation\DownloadStationTaskAdditional.cs" />
|
||||||
|
Loading…
Reference in New Issue
Block a user