New: Added support to save .magnet to blackhole directory.

fixes #1406
This commit is contained in:
Taloth Saldono 2016-08-05 23:09:45 +02:00
parent e2272dcca3
commit 914f799f9d
4 changed files with 137 additions and 17 deletions

View File

@ -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()
{ {

View File

@ -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)

View File

@ -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()

View File

@ -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)