Brought usenet up-to-date. Cleaning of using directives. Added compatibility for older DSM version. Tested against 5.2

This commit is contained in:
margaale 2017-08-16 22:23:33 -03:00 committed by Taloth Saldono
parent 46ff40a97e
commit 6444565bf4
16 changed files with 167 additions and 128 deletions

View File

@ -12,7 +12,7 @@ using NzbDrone.Core.Download.Clients.DownloadStation.Responses;
namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests
{
[TestFixture]
public class SerialNumberProviderFixture : CoreTest<SerialNumberProvider>
public class DSMInfoProviderFixture : CoreTest<DSMInfoProvider>
{
protected DownloadStationSettings _settings;
@ -36,6 +36,16 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests
.Throws(new DownloadClientException("Serial response invalid"));
}
[Test]
public void should_return_version(string versionExpected)
{
GivenValidResponse();
var version = Subject.GetDSMVersion(_settings);
version.Should().Be(new Version("6.0.1"));
}
[Test]
public void should_return_hashedserialnumber()
{

View File

@ -305,7 +305,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests
protected void GivenSerialNumber()
{
Mocker.GetMock<ISerialNumberProvider>()
Mocker.GetMock<IDSMInfoProvider>()
.Setup(s => s.GetSerialNumber(It.IsAny<DownloadStationSettings>()))
.Returns(_serialNumber);
}
@ -378,13 +378,13 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests
protected void GivenDSMVersion(string version)
{
Mocker.GetMock<IDSMInfoProxy>()
.Setup(d => d.GetInfo(It.IsAny<DownloadStationSettings>()))
.Returns(new DSMInfoResponse() { Version = version });
Mocker.GetMock<IDSMInfoProvider>()
.Setup(d => d.GetDSMVersion(It.IsAny<DownloadStationSettings>()))
.Returns(new Version(version));
}
[TestCase("DSM 6.0.0", 0)]
[TestCase("DSM 5.0.0", 1)]
[TestCase("6.0.0", 0)]
[TestCase("5.0.0", 1)]
public void TestConnection_should_return_validation_failure_as_expected(string version, int count)
{
GivenApiVersions();
@ -496,7 +496,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests
[Test]
public void GetItems_should_throw_if_serial_number_unavailable()
{
Mocker.GetMock<ISerialNumberProvider>()
Mocker.GetMock<IDSMInfoProvider>()
.Setup(s => s.GetSerialNumber(_settings))
.Throws(new ApplicationException("Some unknown exception, HttpException or DownloadClientException"));
@ -512,7 +512,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests
{
var remoteEpisode = CreateRemoteEpisode();
Mocker.GetMock<ISerialNumberProvider>()
Mocker.GetMock<IDSMInfoProvider>()
.Setup(s => s.GetSerialNumber(_settings))
.Throws(new ApplicationException("Some unknown exception, HttpException or DownloadClientException"));

View File

@ -191,7 +191,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests
protected void GivenSerialNumber()
{
Mocker.GetMock<ISerialNumberProvider>()
Mocker.GetMock<IDSMInfoProvider>()
.Setup(s => s.GetSerialNumber(It.IsAny<DownloadStationSettings>()))
.Returns(_serialNumber);
}
@ -348,7 +348,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests
[Test]
public void GetItems_should_throw_if_serial_number_unavailable()
{
Mocker.GetMock<ISerialNumberProvider>()
Mocker.GetMock<IDSMInfoProvider>()
.Setup(s => s.GetSerialNumber(_settings))
.Throws(new ApplicationException("Some unknown exception, HttpException or DownloadClientException"));
@ -364,7 +364,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests
{
var remoteEpisode = CreateRemoteEpisode();
Mocker.GetMock<ISerialNumberProvider>()
Mocker.GetMock<IDSMInfoProvider>()
.Setup(s => s.GetSerialNumber(_settings))
.Throws(new ApplicationException("Some unknown exception, HttpException or DownloadClientException"));

View File

@ -176,7 +176,7 @@
<Compile Include="Download\DownloadClientTests\DelugeTests\DelugeFixture.cs" />
<Compile Include="Download\DownloadClientTests\DownloadClientFixtureBase.cs" />
<Compile Include="Download\DownloadClientTests\DownloadStationTests\TorrentDownloadStationFixture.cs" />
<Compile Include="Download\DownloadClientTests\DownloadStationTests\SerialNumberProviderFixture.cs" />
<Compile Include="Download\DownloadClientTests\DownloadStationTests\DSMInfoProviderFixture.cs" />
<Compile Include="Download\DownloadClientTests\DownloadStationTests\SharedFolderResolverFixture.cs" />
<Compile Include="Download\DownloadClientTests\DownloadStationTests\UsenetDownloadStationFixture.cs" />
<Compile Include="Download\DownloadClientTests\HadoukenTests\HadoukenFixture.cs" />

View File

@ -0,0 +1,62 @@
using System;
using System.Text.RegularExpressions;
using NLog;
using NzbDrone.Common.Cache;
using NzbDrone.Common.Crypto;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Download.Clients.DownloadStation.Proxies;
using NzbDrone.Core.Download.Clients.DownloadStation.Responses;
namespace NzbDrone.Core.Download.Clients.DownloadStation
{
public interface IDSMInfoProvider
{
string GetSerialNumber(DownloadStationSettings settings);
Version GetDSMVersion(DownloadStationSettings settings);
}
public class DSMInfoProvider : IDSMInfoProvider
{
private readonly IDSMInfoProxy _proxy;
private ICached<DSMInfoResponse> _cache;
private readonly ILogger _logger;
public DSMInfoProvider(ICacheManager cacheManager,
IDSMInfoProxy proxy,
Logger logger)
{
_proxy = proxy;
_cache = cacheManager.GetCache<DSMInfoResponse>(GetType());
_logger = logger;
}
private DSMInfoResponse GetInfo(DownloadStationSettings settings)
{
return _cache.Get(settings.Host, () => _proxy.GetInfo(settings), TimeSpan.FromMinutes(5));
}
public string GetSerialNumber(DownloadStationSettings settings)
{
try
{
return HashConverter.GetHash(GetInfo(settings).SerialNumber).ToHexString();
}
catch (Exception ex)
{
_logger.Warn(ex, "Could not get the serial number from Download Station {0}:{1}", settings.Host, settings.Port);
throw;
}
}
public Version GetDSMVersion(DownloadStationSettings settings)
{
var info = GetInfo(settings);
Regex regex = new Regex(@"(\bDSM\b (?<version>[\d.]*)){1}");
var dsmVersion = regex.Match(info.Version).Groups["version"].Value;
return new Version(dsmVersion);
}
}
}

View File

@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

View File

@ -1,5 +1,5 @@
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Collections.Generic;
using Newtonsoft.Json;
namespace NzbDrone.Core.Download.Clients.DownloadStation
{

View File

@ -1,10 +1,5 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using static NzbDrone.Core.Download.Clients.DownloadStation.DownloadStationTask;
namespace NzbDrone.Core.Download.Clients.DownloadStation
{

View File

@ -1,6 +1,4 @@
using System;
using System.Collections.Generic;
using NLog;
using NLog;
using NzbDrone.Common.Cache;
using NzbDrone.Common.Http;
using NzbDrone.Core.Download.Clients.DownloadStation.Responses;

View File

@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using NLog;
using NzbDrone.Common.Cache;

View File

@ -1,7 +1,7 @@
using NLog;
using NzbDrone.Common.Http;
using System.Collections.Generic;
using System.Collections.Generic;
using NLog;
using NzbDrone.Common.Cache;
using NzbDrone.Common.Http;
namespace NzbDrone.Core.Download.Clients.DownloadStation.Proxies
{

View File

@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NzbDrone.Core.Download.Clients.DownloadStation.Proxies
namespace NzbDrone.Core.Download.Clients.DownloadStation.Proxies
{
public class ExpectedVersion
{

View File

@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NLog;
using NzbDrone.Common.Cache;
@ -18,9 +17,15 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation.Proxies
public class FileStationProxy : DiskStationProxyBase, IFileStationProxy
{
public FileStationProxy(IHttpClient httpClient, ICacheManager cacheManager, Logger logger)
private IDSMInfoProvider _dsmInfoProvider;
public FileStationProxy(IDSMInfoProvider dsmInfoProvider,
IHttpClient httpClient,
ICacheManager cacheManager,
Logger logger)
: base(DiskStationApi.FileStationList, "SYNO.FileStation.List", httpClient, cacheManager, logger)
{
_dsmInfoProvider = dsmInfoProvider;
}
public SharedFolderMapping GetSharedFolderMapping(string sharedFolder, DownloadStationSettings settings)
@ -34,13 +39,16 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation.Proxies
public FileStationListFileInfoResponse GetInfoFileOrDirectory(string path, DownloadStationSettings settings)
{
var requestBuilder = BuildRequest(settings, "getinfo", 2);
var dsmVersion = _dsmInfoProvider.GetDSMVersion(settings);
var requestBuilder = BuildRequest(settings, "getinfo", dsmVersion >= new Version(6, 0, 0) ? 2 : 1);
requestBuilder.AddQueryParam("path", new[] { path }.ToJson());
requestBuilder.AddQueryParam("additional", "[\"real_path\"]");
var response = ProcessRequest<FileStationListResponse>(requestBuilder, $"get info of {path}", settings);
return response.Data.Files.First();
}
}
}

View File

@ -1,49 +0,0 @@
using System;
using NLog;
using NzbDrone.Common.Cache;
using NzbDrone.Common.Crypto;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Download.Clients.DownloadStation.Proxies;
namespace NzbDrone.Core.Download.Clients.DownloadStation
{
public interface ISerialNumberProvider
{
string GetSerialNumber(DownloadStationSettings settings);
}
public class SerialNumberProvider : ISerialNumberProvider
{
private readonly IDSMInfoProxy _proxy;
private ICached<string> _cache;
private readonly ILogger _logger;
public SerialNumberProvider(ICacheManager cacheManager,
IDSMInfoProxy proxy,
Logger logger)
{
_proxy = proxy;
_cache = cacheManager.GetCache<string>(GetType());
_logger = logger;
}
public string GetSerialNumber(DownloadStationSettings settings)
{
try
{
return _cache.Get(settings.Host, () => GetHashedSerialNumber(settings), TimeSpan.FromMinutes(5));
}
catch (Exception ex)
{
_logger.Warn(ex, "Could not get the serial number from Download Station {0}:{1}", settings.Host, settings.Port);
throw;
}
}
private string GetHashedSerialNumber(DownloadStationSettings settings)
{
var serialNumber = _proxy.GetInfo(settings).SerialNumber;
return HashConverter.GetHash(serialNumber).ToHexString();
}
}
}

View File

@ -14,7 +14,6 @@ using NzbDrone.Core.MediaFiles.TorrentInfo;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.RemotePathMappings;
using NzbDrone.Core.Validation;
using System.Text.RegularExpressions;
namespace NzbDrone.Core.Download.Clients.DownloadStation
{
@ -23,16 +22,14 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
protected readonly IDownloadStationInfoProxy _dsInfoProxy;
protected readonly IDownloadStationTaskProxy _dsTaskProxy;
protected readonly ISharedFolderResolver _sharedFolderResolver;
protected readonly ISerialNumberProvider _serialNumberProvider;
protected readonly IDSMInfoProvider _dsmInfoProvider;
protected readonly IFileStationProxy _fileStationProxy;
protected readonly IDSMInfoProxy _dsmInfoProxy;
public TorrentDownloadStation(ISharedFolderResolver sharedFolderResolver,
ISerialNumberProvider serialNumberProvider,
IDSMInfoProvider dsmInfoProvider,
IFileStationProxy fileStationProxy,
IDownloadStationInfoProxy dsInfoProxy,
IDownloadStationTaskProxy dsTaskProxy,
IDSMInfoProxy dsmInfoProxy,
ITorrentFileInfoReader torrentFileInfoReader,
IHttpClient httpClient,
IConfigService configService,
@ -45,8 +42,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
_dsTaskProxy = dsTaskProxy;
_fileStationProxy = fileStationProxy;
_sharedFolderResolver = sharedFolderResolver;
_serialNumberProvider = serialNumberProvider;
_dsmInfoProxy = dsmInfoProxy;
_dsmInfoProvider = dsmInfoProvider;
}
public override string Name => "Download Station";
@ -59,7 +55,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
public override IEnumerable<DownloadClientItem> GetItems()
{
var torrents = GetTasks();
var serialNumber = _serialNumberProvider.GetSerialNumber(Settings);
var serialNumber = _dsmInfoProvider.GetSerialNumber(Settings);
var items = new List<DownloadClientItem>();
@ -153,7 +149,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
protected override string AddFromMagnetLink(RemoteEpisode remoteEpisode, string hash, string magnetLink)
{
var hashedSerialNumber = _serialNumberProvider.GetSerialNumber(Settings);
var hashedSerialNumber = _dsmInfoProvider.GetSerialNumber(Settings);
_dsTaskProxy.AddTaskFromUrl(magnetLink, GetDownloadDirectory(), Settings);
@ -172,7 +168,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
protected override string AddFromTorrentFile(RemoteEpisode remoteEpisode, string hash, string filename, byte[] fileContent)
{
var hashedSerialNumber = _serialNumberProvider.GetSerialNumber(Settings);
var hashedSerialNumber = _dsmInfoProvider.GetSerialNumber(Settings);
_dsTaskProxy.AddTaskFromData(fileContent, filename, GetDownloadDirectory(), Settings);
@ -308,7 +304,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
{
return new NzbDroneValidationFailure(fieldName, $"Shared folder does not exist")
{
DetailedDescription = $"The Diskstation does not have a Shared Folder with the name '{sharedFolder}', are you sure you specified it correctly?"
DetailedDescription = $"The Diskstation does not have a Shared Folder with the name '{downloadDir}', are you sure you specified it correctly?"
};
}
@ -339,7 +335,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
{
try
{
return ValidateProxiesVersion();
return TestProxiesVersions();
}
catch (DownloadClientAuthenticationException ex)
{
@ -371,23 +367,24 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
protected ValidationFailure TestDSMVersion()
{
var info = _dsmInfoProxy.GetInfo(Settings);
var dsmversion = _dsmInfoProvider.GetDSMVersion(Settings);
Regex regex = new Regex(@"(\bDSM\b (?<version>[\d.]*)){1}");
var dsmVersion = regex.Match(info.Version).Groups["version"].Value;
var version = new Version(dsmVersion);
return version < new Version(6, 0, 0) ? new NzbDroneValidationFailure(string.Empty, $"DSM Version {version} not fully supported. We recommend version 6.0.0 or above.") { IsWarning = true } : null;
if (dsmversion < new Version(6, 0, 0))
{
return new NzbDroneValidationFailure(string.Empty, $"DSM Version {dsmversion} not fully supported. We recommend version 6.0.0 or above.") { IsWarning = true };
}
protected ValidationFailure ValidateProxiesVersion()
return null;
}
protected ValidationFailure TestProxiesVersions()
{
var dsmVersion = _dsmInfoProvider.GetDSMVersion(Settings);
var expectedVersions = new List<ExpectedVersion>()
{
new ExpectedVersion { Version = 2, Proxy = _dsTaskProxy },
new ExpectedVersion { Version = 2, Proxy = _fileStationProxy },
new ExpectedVersion { Version = (dsmVersion >= new Version(6,0,0))? 2 : 1, Proxy = _fileStationProxy },
new ExpectedVersion { Version = 1, Proxy = _dsInfoProxy }
};

View File

@ -20,11 +20,11 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
protected readonly IDownloadStationInfoProxy _dsInfoProxy;
protected readonly IDownloadStationTaskProxy _dsTaskProxy;
protected readonly ISharedFolderResolver _sharedFolderResolver;
protected readonly ISerialNumberProvider _serialNumberProvider;
protected readonly IDSMInfoProvider _dsmInfoProvider;
protected readonly IFileStationProxy _fileStationProxy;
public UsenetDownloadStation(ISharedFolderResolver sharedFolderResolver,
ISerialNumberProvider serialNumberProvider,
IDSMInfoProvider dsmInfoProvider,
IFileStationProxy fileStationProxy,
IDownloadStationInfoProxy dsInfoProxy,
IDownloadStationTaskProxy dsTaskProxy,
@ -40,7 +40,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
_dsTaskProxy = dsTaskProxy;
_fileStationProxy = fileStationProxy;
_sharedFolderResolver = sharedFolderResolver;
_serialNumberProvider = serialNumberProvider;
_dsmInfoProvider = dsmInfoProvider;
}
public override string Name => "Download Station";
@ -53,7 +53,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
public override IEnumerable<DownloadClientItem> GetItems()
{
var nzbTasks = GetTasks();
var serialNumber = _serialNumberProvider.GetSerialNumber(Settings);
var serialNumber = _dsmInfoProvider.GetSerialNumber(Settings);
var items = new List<DownloadClientItem>();
@ -163,7 +163,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
protected override string AddFromNzbFile(RemoteEpisode remoteEpisode, string filename, byte[] fileContent)
{
var hashedSerialNumber = _serialNumberProvider.GetSerialNumber(Settings);
var hashedSerialNumber = _dsmInfoProvider.GetSerialNumber(Settings);
_dsTaskProxy.AddTaskFromData(fileContent, filename, GetDownloadDirectory(), Settings);
@ -186,6 +186,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
{
failures.AddIfNotNull(TestConnection());
if (failures.Any()) return;
failures.AddIfNotNull(TestDSMVersion());
failures.AddIfNotNull(TestOutputPath());
failures.AddIfNotNull(TestGetNZB());
}
@ -217,7 +218,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
{
return new NzbDroneValidationFailure(fieldName, $"Shared folder does not exist")
{
DetailedDescription = $"The Diskstation does not have a Shared Folder with the name '{sharedFolder}', are you sure you specified it correctly?"
DetailedDescription = $"The Diskstation does not have a Shared Folder with the name '{downloadDir}', are you sure you specified it correctly?"
};
}
@ -248,7 +249,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
{
try
{
return ValidateVersion();
return TestProxiesVersions();
}
catch (DownloadClientAuthenticationException ex)
{
@ -269,24 +270,48 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
DetailedDescription = "Please verify the hostname and port."
};
}
return new NzbDroneValidationFailure(string.Empty, "Unknown exception: " + ex.Message);
return new NzbDroneValidationFailure(string.Empty, $"Unknown exception: {ex.Message}");
}
catch (Exception ex)
{
_logger.Error(ex, "Error testing Torrent Download Station");
return new NzbDroneValidationFailure(string.Empty, "Unknown exception: " + ex.Message);
return new NzbDroneValidationFailure(string.Empty, $"Unknown exception: {ex.Message}");
}
}
protected ValidationFailure ValidateVersion()
protected ValidationFailure TestDSMVersion()
{
var info = _dsTaskProxy.GetApiInfo(Settings);
var dsmversion = _dsmInfoProvider.GetDSMVersion(Settings);
_logger.Debug("Download Station api version information: Min {0} - Max {1}", info.MinVersion, info.MaxVersion);
if (info.MinVersion > 2 || info.MaxVersion < 2)
if (dsmversion < new Version(6, 0, 0))
{
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 new NzbDroneValidationFailure(string.Empty, $"DSM Version {dsmversion} not fully supported. We recommend version 6.0.0 or above.") { IsWarning = true };
}
return null;
}
protected ValidationFailure TestProxiesVersions()
{
var dsmVersion = _dsmInfoProvider.GetDSMVersion(Settings);
var expectedVersions = new List<ExpectedVersion>()
{
new ExpectedVersion { Version = 2, Proxy = _dsTaskProxy },
new ExpectedVersion { Version = (dsmVersion >= new Version(6,0,0))? 2 : 1, Proxy = _fileStationProxy },
new ExpectedVersion { Version = 1, Proxy = _dsInfoProxy }
};
foreach (var expectedVersion in expectedVersions)
{
DiskStationApiInfo apiInfo = expectedVersion.Proxy.GetApiInfo(Settings);
_logger.Debug("{1} api version information: Min {1} - Max {2} - Expected {3}", apiInfo.Name, apiInfo.MinVersion, apiInfo.MaxVersion, expectedVersion.Version);
if (apiInfo.MinVersion > expectedVersion.Version || apiInfo.MaxVersion < expectedVersion.Version)
{
return new NzbDroneValidationFailure(string.Empty, $"{apiInfo.Name} API version not supported, should be at least {expectedVersion.Version}. It supports from {apiInfo.MinVersion} to {apiInfo.MaxVersion}");
}
}
return null;
@ -377,7 +402,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
}
catch (Exception ex)
{
return new NzbDroneValidationFailure(string.Empty, "Failed to get the list of NZBs: " + ex.Message);
return new NzbDroneValidationFailure(string.Empty, $"Failed to get the list of NZBs: {ex.Message}");
}
}