parent
e2272dcca3
commit
914f799f9d
|
@ -22,6 +22,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||||
protected string _completedDownloadFolder;
|
protected string _completedDownloadFolder;
|
||||||
protected string _blackholeFolder;
|
protected string _blackholeFolder;
|
||||||
protected string _filePath;
|
protected string _filePath;
|
||||||
|
protected string _magnetFilePath;
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
|
@ -29,6 +30,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||||
_completedDownloadFolder = @"c:\blackhole\completed".AsOsAgnostic();
|
_completedDownloadFolder = @"c:\blackhole\completed".AsOsAgnostic();
|
||||||
_blackholeFolder = @"c:\blackhole\torrent".AsOsAgnostic();
|
_blackholeFolder = @"c:\blackhole\torrent".AsOsAgnostic();
|
||||||
_filePath = (@"c:\blackhole\torrent\" + _title + ".torrent").AsOsAgnostic();
|
_filePath = (@"c:\blackhole\torrent\" + _title + ".torrent").AsOsAgnostic();
|
||||||
|
_magnetFilePath = Path.ChangeExtension(_filePath, ".magnet");
|
||||||
|
|
||||||
Mocker.SetConstant<IScanWatchFolder>(Mocker.Resolve<ScanWatchFolder>());
|
Mocker.SetConstant<IScanWatchFolder>(Mocker.Resolve<ScanWatchFolder>());
|
||||||
|
|
||||||
|
@ -132,6 +134,51 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||||
Mocker.GetMock<IHttpClient>().Verify(c => c.DownloadFile(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
|
Mocker.GetMock<IHttpClient>().Verify(c => c.DownloadFile(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Download_should_save_magnet_if_enabled()
|
||||||
|
{
|
||||||
|
Subject.Definition.Settings.As<TorrentBlackholeSettings>().SaveMagnetFiles = true;
|
||||||
|
|
||||||
|
var remoteEpisode = CreateRemoteEpisode();
|
||||||
|
remoteEpisode.Release.DownloadUrl = null;
|
||||||
|
|
||||||
|
Subject.Download(remoteEpisode);
|
||||||
|
|
||||||
|
Mocker.GetMock<IHttpClient>().Verify(c => c.Get(It.Is<HttpRequest>(v => v.Url.FullUri == _downloadUrl)), Times.Never());
|
||||||
|
Mocker.GetMock<IDiskProvider>().Verify(c => c.OpenWriteStream(_filePath), Times.Never());
|
||||||
|
Mocker.GetMock<IDiskProvider>().Verify(c => c.OpenWriteStream(_magnetFilePath), Times.Once());
|
||||||
|
Mocker.GetMock<IHttpClient>().Verify(c => c.DownloadFile(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Download_should_not_save_magnet_if_disabled()
|
||||||
|
{
|
||||||
|
var remoteEpisode = CreateRemoteEpisode();
|
||||||
|
remoteEpisode.Release.DownloadUrl = null;
|
||||||
|
|
||||||
|
Assert.Throws<ReleaseDownloadException>(() => Subject.Download(remoteEpisode));
|
||||||
|
|
||||||
|
Mocker.GetMock<IHttpClient>().Verify(c => c.Get(It.Is<HttpRequest>(v => v.Url.FullUri == _downloadUrl)), Times.Never());
|
||||||
|
Mocker.GetMock<IDiskProvider>().Verify(c => c.OpenWriteStream(_filePath), Times.Never());
|
||||||
|
Mocker.GetMock<IDiskProvider>().Verify(c => c.OpenWriteStream(_magnetFilePath), Times.Never());
|
||||||
|
Mocker.GetMock<IHttpClient>().Verify(c => c.DownloadFile(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Download_should_prefer_torrent_over_magnet()
|
||||||
|
{
|
||||||
|
Subject.Definition.Settings.As<TorrentBlackholeSettings>().SaveMagnetFiles = true;
|
||||||
|
|
||||||
|
var remoteEpisode = CreateRemoteEpisode();
|
||||||
|
|
||||||
|
Subject.Download(remoteEpisode);
|
||||||
|
|
||||||
|
Mocker.GetMock<IHttpClient>().Verify(c => c.Get(It.Is<HttpRequest>(v => v.Url.FullUri == _downloadUrl)), Times.Once());
|
||||||
|
Mocker.GetMock<IDiskProvider>().Verify(c => c.OpenWriteStream(_filePath), Times.Once());
|
||||||
|
Mocker.GetMock<IDiskProvider>().Verify(c => c.OpenWriteStream(_magnetFilePath), Times.Never());
|
||||||
|
Mocker.GetMock<IHttpClient>().Verify(c => c.DownloadFile(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Download_should_replace_illegal_characters_in_title()
|
public void Download_should_replace_illegal_characters_in_title()
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
|
@ -23,6 +24,14 @@ namespace NzbDrone.Core.Download.Clients.Blackhole
|
||||||
|
|
||||||
public TimeSpan ScanGracePeriod { get; set; }
|
public TimeSpan ScanGracePeriod { get; set; }
|
||||||
|
|
||||||
|
public override bool PreferTorrentFile
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public TorrentBlackhole(IScanWatchFolder scanWatchFolder,
|
public TorrentBlackhole(IScanWatchFolder scanWatchFolder,
|
||||||
ITorrentFileInfoReader torrentFileInfoReader,
|
ITorrentFileInfoReader torrentFileInfoReader,
|
||||||
IHttpClient httpClient,
|
IHttpClient httpClient,
|
||||||
|
@ -39,7 +48,26 @@ namespace NzbDrone.Core.Download.Clients.Blackhole
|
||||||
|
|
||||||
protected override string AddFromMagnetLink(RemoteEpisode remoteEpisode, string hash, string magnetLink)
|
protected override string AddFromMagnetLink(RemoteEpisode remoteEpisode, string hash, string magnetLink)
|
||||||
{
|
{
|
||||||
throw new NotSupportedException("Blackhole does not support magnet links.");
|
if (!Settings.SaveMagnetFiles)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException("Blackhole does not support magnet links.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var title = remoteEpisode.Release.Title;
|
||||||
|
|
||||||
|
title = FileNameBuilder.CleanFileName(title);
|
||||||
|
|
||||||
|
var filepath = Path.Combine(Settings.TorrentFolder, string.Format("{0}.magnet", title));
|
||||||
|
|
||||||
|
var fileContent = Encoding.UTF8.GetBytes(magnetLink);
|
||||||
|
using (var stream = _diskProvider.OpenWriteStream(filepath))
|
||||||
|
{
|
||||||
|
stream.Write(fileContent, 0, fileContent.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.Debug("Saving magnet link succeeded, saved to: {0}", filepath);
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string AddFromTorrentFile(RemoteEpisode remoteEpisode, string hash, string filename, byte[] fileContent)
|
protected override string AddFromTorrentFile(RemoteEpisode remoteEpisode, string hash, string filename, byte[] fileContent)
|
||||||
|
|
|
@ -34,7 +34,12 @@ namespace NzbDrone.Core.Download.Clients.Blackhole
|
||||||
|
|
||||||
[DefaultValue(false)]
|
[DefaultValue(false)]
|
||||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
|
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
|
||||||
[FieldDefinition(2, Label = "Read Only", Type = FieldType.Checkbox, HelpText = "Instead of moving files this will instruct Sonarr to Copy or Hardlink (depending on settings/system configuration)")]
|
[FieldDefinition(2, Label = "Save Magnet Files", Type = FieldType.Checkbox, HelpText = "Save a .magnet file with the magnet link if no .torrent file is available (only useful if the download client supports .magnet files)")]
|
||||||
|
public bool SaveMagnetFiles { get; set; }
|
||||||
|
|
||||||
|
[DefaultValue(false)]
|
||||||
|
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
|
||||||
|
[FieldDefinition(3, Label = "Read Only", Type = FieldType.Checkbox, HelpText = "Instead of moving files this will instruct Sonarr to Copy or Hardlink (depending on settings/system configuration)")]
|
||||||
public bool ReadOnly { get; set; }
|
public bool ReadOnly { get; set; }
|
||||||
|
|
||||||
public NzbDroneValidationResult Validate()
|
public NzbDroneValidationResult Validate()
|
||||||
|
|
|
@ -42,6 +42,14 @@ namespace NzbDrone.Core.Download
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual bool PreferTorrentFile
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract string AddFromMagnetLink(RemoteEpisode remoteEpisode, string hash, string magnetLink);
|
protected abstract string AddFromMagnetLink(RemoteEpisode remoteEpisode, string hash, string magnetLink);
|
||||||
protected abstract string AddFromTorrentFile(RemoteEpisode remoteEpisode, string hash, string filename, byte[] fileContent);
|
protected abstract string AddFromTorrentFile(RemoteEpisode remoteEpisode, string hash, string filename, byte[] fileContent);
|
||||||
|
|
||||||
|
@ -65,32 +73,64 @@ namespace NzbDrone.Core.Download
|
||||||
{
|
{
|
||||||
magnetUrl = torrentInfo.MagnetUrl;
|
magnetUrl = torrentInfo.MagnetUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
string hash = null;
|
if (PreferTorrentFile)
|
||||||
|
|
||||||
if (magnetUrl.IsNotNullOrWhiteSpace())
|
|
||||||
{
|
{
|
||||||
try
|
if (torrentUrl.IsNotNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
hash = DownloadFromMagnetUrl(remoteEpisode, magnetUrl);
|
try
|
||||||
|
{
|
||||||
|
return DownloadFromWebUrl(remoteEpisode, torrentUrl);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
if (!magnetUrl.IsNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.Debug("Torrent download failed, trying magnet. ({0})", ex.Message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (NotSupportedException ex)
|
|
||||||
|
if (magnetUrl.IsNotNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
if (torrentUrl.IsNullOrWhiteSpace())
|
try
|
||||||
|
{
|
||||||
|
return DownloadFromMagnetUrl(remoteEpisode, magnetUrl);
|
||||||
|
}
|
||||||
|
catch (NotSupportedException ex)
|
||||||
{
|
{
|
||||||
throw new ReleaseDownloadException(remoteEpisode.Release, "Magnet not supported by download client. ({0})", ex.Message);
|
throw new ReleaseDownloadException(remoteEpisode.Release, "Magnet not supported by download client. ({0})", ex.Message);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (magnetUrl.IsNotNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return DownloadFromMagnetUrl(remoteEpisode, magnetUrl);
|
||||||
|
}
|
||||||
|
catch (NotSupportedException ex)
|
||||||
|
{
|
||||||
|
if (torrentUrl.IsNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
throw new ReleaseDownloadException(remoteEpisode.Release, "Magnet not supported by download client. ({0})", ex.Message);
|
||||||
|
}
|
||||||
|
|
||||||
_logger.Debug("Magnet not supported by download client, trying torrent. ({0})", ex.Message);
|
_logger.Debug("Magnet not supported by download client, trying torrent. ({0})", ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (torrentUrl.IsNotNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
return DownloadFromWebUrl(remoteEpisode, torrentUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hash == null && torrentUrl.IsNotNullOrWhiteSpace())
|
return null;
|
||||||
{
|
|
||||||
hash = DownloadFromWebUrl(remoteEpisode, torrentUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hash;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private string DownloadFromWebUrl(RemoteEpisode remoteEpisode, string torrentUrl)
|
private string DownloadFromWebUrl(RemoteEpisode remoteEpisode, string torrentUrl)
|
||||||
|
|
Loading…
Reference in New Issue