mirror of
https://github.com/Sonarr/Sonarr.git
synced 2024-12-16 11:37:58 +02:00
Merge pull request #674 from Sonarr/rtorrent-directory
Choose download folder for rTorrent
This commit is contained in:
commit
346d7f3cf4
@ -10,6 +10,7 @@
|
||||
using NLog;
|
||||
using NzbDrone.Core.Validation;
|
||||
using FluentValidation.Results;
|
||||
using NzbDrone.Core.Download.Clients.rTorrent;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.RemotePathMappings;
|
||||
using NzbDrone.Core.ThingiProvider;
|
||||
@ -19,6 +20,7 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
|
||||
public class RTorrent : TorrentClientBase<RTorrentSettings>
|
||||
{
|
||||
private readonly IRTorrentProxy _proxy;
|
||||
private readonly IRTorrentDirectoryValidator _rTorrentDirectoryValidator;
|
||||
|
||||
public RTorrent(IRTorrentProxy proxy,
|
||||
ITorrentFileInfoReader torrentFileInfoReader,
|
||||
@ -26,10 +28,12 @@ public RTorrent(IRTorrentProxy proxy,
|
||||
IConfigService configService,
|
||||
IDiskProvider diskProvider,
|
||||
IRemotePathMappingService remotePathMappingService,
|
||||
IRTorrentDirectoryValidator rTorrentDirectoryValidator,
|
||||
Logger logger)
|
||||
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger)
|
||||
{
|
||||
_proxy = proxy;
|
||||
_rTorrentDirectoryValidator = rTorrentDirectoryValidator;
|
||||
}
|
||||
|
||||
protected override string AddFromMagnetLink(RemoteEpisode remoteEpisode, string hash, string magnetLink)
|
||||
@ -40,6 +44,7 @@ protected override string AddFromMagnetLink(RemoteEpisode remoteEpisode, string
|
||||
var TRIES = 5;
|
||||
var RETRY_DELAY = 500; //ms
|
||||
var ready = false;
|
||||
|
||||
for (var i = 0; i < TRIES; i++)
|
||||
{
|
||||
ready = _proxy.HasHashTorrent(hash, Settings);
|
||||
@ -55,9 +60,10 @@ protected override string AddFromMagnetLink(RemoteEpisode remoteEpisode, string
|
||||
{
|
||||
_proxy.SetTorrentLabel(hash, Settings.TvCategory, Settings);
|
||||
|
||||
var priority = (RTorrentPriority)(remoteEpisode.IsRecentEpisode() ?
|
||||
Settings.RecentTvPriority : Settings.OlderTvPriority);
|
||||
_proxy.SetTorrentPriority(hash, Settings, priority);
|
||||
SetPriority(remoteEpisode, hash);
|
||||
SetDownloadDirectory(hash);
|
||||
|
||||
_proxy.StartTorrent(hash, Settings);
|
||||
|
||||
return hash;
|
||||
}
|
||||
@ -74,12 +80,12 @@ protected override string AddFromMagnetLink(RemoteEpisode remoteEpisode, string
|
||||
protected override string AddFromTorrentFile(RemoteEpisode remoteEpisode, string hash, string filename, byte[] fileContent)
|
||||
{
|
||||
_proxy.AddTorrentFromFile(filename, fileContent, Settings);
|
||||
|
||||
_proxy.SetTorrentLabel(hash, Settings.TvCategory, Settings);
|
||||
|
||||
var priority = (RTorrentPriority)(remoteEpisode.IsRecentEpisode() ?
|
||||
Settings.RecentTvPriority : Settings.OlderTvPriority);
|
||||
_proxy.SetTorrentPriority(hash, Settings, priority);
|
||||
SetPriority(remoteEpisode, hash);
|
||||
SetDownloadDirectory(hash);
|
||||
|
||||
_proxy.StartTorrent(hash, Settings);
|
||||
|
||||
return hash;
|
||||
}
|
||||
@ -182,6 +188,7 @@ protected override void Test(List<ValidationFailure> failures)
|
||||
failures.AddIfNotNull(TestConnection());
|
||||
if (failures.Any()) return;
|
||||
failures.AddIfNotNull(TestGetTorrents());
|
||||
failures.AddIfNotNull(TestDirectory());
|
||||
}
|
||||
|
||||
private ValidationFailure TestConnection()
|
||||
@ -218,5 +225,31 @@ private ValidationFailure TestGetTorrents()
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private ValidationFailure TestDirectory()
|
||||
{
|
||||
var result = _rTorrentDirectoryValidator.Validate(Settings);
|
||||
|
||||
if (result.IsValid)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return result.Errors.First();
|
||||
}
|
||||
|
||||
private void SetPriority(RemoteEpisode remoteEpisode, string hash)
|
||||
{
|
||||
var priority = (RTorrentPriority)(remoteEpisode.IsRecentEpisode() ? Settings.RecentTvPriority : Settings.OlderTvPriority);
|
||||
_proxy.SetTorrentPriority(hash, priority, Settings);
|
||||
}
|
||||
|
||||
private void SetDownloadDirectory(string hash)
|
||||
{
|
||||
if (Settings.TvDirectory.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
_proxy.SetTorrentDownloadDirectory(hash, Settings.TvDirectory, Settings);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,29 @@
|
||||
using FluentValidation;
|
||||
using FluentValidation.Results;
|
||||
using NzbDrone.Core.Download.Clients.RTorrent;
|
||||
using NzbDrone.Core.Validation.Paths;
|
||||
|
||||
namespace NzbDrone.Core.Download.Clients.rTorrent
|
||||
{
|
||||
public interface IRTorrentDirectoryValidator
|
||||
{
|
||||
ValidationResult Validate(RTorrentSettings instance);
|
||||
}
|
||||
|
||||
public class RTorrentDirectoryValidator : AbstractValidator<RTorrentSettings>, IRTorrentDirectoryValidator
|
||||
{
|
||||
public RTorrentDirectoryValidator(RootFolderValidator rootFolderValidator,
|
||||
PathExistsValidator pathExistsValidator,
|
||||
DroneFactoryValidator droneFactoryValidator,
|
||||
MappedNetworkDriveValidator mappedNetworkDriveValidator)
|
||||
{
|
||||
RuleFor(c => c.TvDirectory).Cascade(CascadeMode.StopOnFirstFailure)
|
||||
.IsValidPath()
|
||||
.SetValidator(rootFolderValidator)
|
||||
.SetValidator(droneFactoryValidator)
|
||||
.SetValidator(mappedNetworkDriveValidator)
|
||||
.SetValidator(pathExistsValidator)
|
||||
.When(c => c.Host == "localhost" || c.Host == "127.0.0.1");
|
||||
}
|
||||
}
|
||||
}
|
@ -16,9 +16,11 @@ public interface IRTorrentProxy
|
||||
void AddTorrentFromUrl(string torrentUrl, RTorrentSettings settings);
|
||||
void AddTorrentFromFile(string fileName, byte[] fileContent, RTorrentSettings settings);
|
||||
void RemoveTorrent(string hash, RTorrentSettings settings);
|
||||
void SetTorrentPriority(string hash, RTorrentSettings settings, RTorrentPriority priority);
|
||||
void SetTorrentPriority(string hash, RTorrentPriority priority, RTorrentSettings settings);
|
||||
void SetTorrentLabel(string hash, string label, RTorrentSettings settings);
|
||||
void SetTorrentDownloadDirectory(string hash, string directory, RTorrentSettings settings);
|
||||
bool HasHashTorrent(string hash, RTorrentSettings settings);
|
||||
void StartTorrent(string hash, RTorrentSettings settings);
|
||||
}
|
||||
|
||||
public interface IRTorrent : IXmlRpcProxy
|
||||
@ -26,10 +28,10 @@ public interface IRTorrent : IXmlRpcProxy
|
||||
[XmlRpcMethod("d.multicall2")]
|
||||
object[] TorrentMulticall(params string[] parameters);
|
||||
|
||||
[XmlRpcMethod("load.start")]
|
||||
int LoadURL(string target, string data);
|
||||
[XmlRpcMethod("load.normal")]
|
||||
int LoadUrl(string target, string data);
|
||||
|
||||
[XmlRpcMethod("load.raw_start")]
|
||||
[XmlRpcMethod("load.raw")]
|
||||
int LoadBinary(string target, byte[] data);
|
||||
|
||||
[XmlRpcMethod("d.erase")]
|
||||
@ -41,11 +43,17 @@ public interface IRTorrent : IXmlRpcProxy
|
||||
[XmlRpcMethod("d.priority.set")]
|
||||
int SetPriority(string hash, long priority);
|
||||
|
||||
[XmlRpcMethod("d.directory.set")]
|
||||
int SetDirectory(string hash, string directory);
|
||||
|
||||
[XmlRpcMethod("d.name")]
|
||||
string GetName(string hash);
|
||||
|
||||
[XmlRpcMethod("system.client_version")]
|
||||
string GetVersion();
|
||||
|
||||
[XmlRpcMethod("system.multicall")]
|
||||
object[] SystemMulticall(object[] parameters);
|
||||
}
|
||||
|
||||
public class RTorrentProxy : IRTorrentProxy
|
||||
@ -108,32 +116,13 @@ public List<RTorrentTorrent> GetTorrents(RTorrentSettings settings)
|
||||
return items;
|
||||
}
|
||||
|
||||
public bool HasHashTorrent(string hash, RTorrentSettings settings)
|
||||
{
|
||||
_logger.Debug("Executing remote method: d.name");
|
||||
|
||||
var client = BuildClient(settings);
|
||||
|
||||
try
|
||||
{
|
||||
var name = client.GetName(hash);
|
||||
if (name.IsNullOrWhiteSpace()) return false;
|
||||
bool metaTorrent = name == (hash + ".meta");
|
||||
return !metaTorrent;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddTorrentFromUrl(string torrentUrl, RTorrentSettings settings)
|
||||
{
|
||||
_logger.Debug("Executing remote method: load.start");
|
||||
_logger.Debug("Executing remote method: load.normal");
|
||||
|
||||
var client = BuildClient(settings);
|
||||
|
||||
var response = client.LoadURL("", torrentUrl);
|
||||
var response = client.LoadUrl("", torrentUrl);
|
||||
if (response != 0)
|
||||
{
|
||||
throw new DownloadClientException("Could not add torrent: {0}.", torrentUrl);
|
||||
@ -142,7 +131,7 @@ public void AddTorrentFromUrl(string torrentUrl, RTorrentSettings settings)
|
||||
|
||||
public void AddTorrentFromFile(string fileName, Byte[] fileContent, RTorrentSettings settings)
|
||||
{
|
||||
_logger.Debug("Executing remote method: load.raw_start");
|
||||
_logger.Debug("Executing remote method: load.raw");
|
||||
|
||||
var client = BuildClient(settings);
|
||||
|
||||
@ -166,7 +155,7 @@ public void RemoveTorrent(string hash, RTorrentSettings settings)
|
||||
}
|
||||
}
|
||||
|
||||
public void SetTorrentPriority(string hash, RTorrentSettings settings, RTorrentPriority priority)
|
||||
public void SetTorrentPriority(string hash, RTorrentPriority priority, RTorrentSettings settings)
|
||||
{
|
||||
_logger.Debug("Executing remote method: d.priority.set");
|
||||
|
||||
@ -185,13 +174,71 @@ public void SetTorrentLabel(string hash, string label, RTorrentSettings settings
|
||||
|
||||
var client = BuildClient(settings);
|
||||
|
||||
var satLabel = client.SetLabel(hash, label);
|
||||
if (satLabel != label)
|
||||
var setLabel = client.SetLabel(hash, label);
|
||||
if (setLabel != label)
|
||||
{
|
||||
throw new DownloadClientException("Could set label on torrent: {0}.", hash);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetTorrentDownloadDirectory(string hash, string directory, RTorrentSettings settings)
|
||||
{
|
||||
_logger.Debug("Executing remote method: d.directory.set");
|
||||
|
||||
var client = BuildClient(settings);
|
||||
|
||||
var response = client.SetDirectory(hash, directory);
|
||||
if (response != 0)
|
||||
{
|
||||
throw new DownloadClientException("Could not set directory for torrent: {0}.", hash);
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasHashTorrent(string hash, RTorrentSettings settings)
|
||||
{
|
||||
_logger.Debug("Executing remote method: d.name");
|
||||
|
||||
var client = BuildClient(settings);
|
||||
|
||||
try
|
||||
{
|
||||
var name = client.GetName(hash);
|
||||
if (name.IsNullOrWhiteSpace()) return false;
|
||||
bool metaTorrent = name == (hash + ".meta");
|
||||
return !metaTorrent;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void StartTorrent(string hash, RTorrentSettings settings)
|
||||
{
|
||||
_logger.Debug("Executing remote methods: d.open and d.start");
|
||||
|
||||
var client = BuildClient(settings);
|
||||
|
||||
var multicallResponse = client.SystemMulticall(new[]
|
||||
{
|
||||
new
|
||||
{
|
||||
methodName = "d.open",
|
||||
@params = new[] { hash }
|
||||
},
|
||||
new
|
||||
{
|
||||
methodName = "d.start",
|
||||
@params = new[] { hash }
|
||||
},
|
||||
}).SelectMany(c => ((IEnumerable<int>)c));
|
||||
|
||||
if (multicallResponse.Any(r => r != 0))
|
||||
{
|
||||
throw new DownloadClientException("Could not start torrent: {0}.", hash);
|
||||
}
|
||||
}
|
||||
|
||||
private IRTorrent BuildClient(RTorrentSettings settings)
|
||||
{
|
||||
var client = XmlRpcProxyGen.Create<IRTorrent>();
|
||||
|
@ -1,6 +1,4 @@
|
||||
using System;
|
||||
using FluentValidation;
|
||||
using FluentValidation.Results;
|
||||
using FluentValidation;
|
||||
using NzbDrone.Core.Annotations;
|
||||
using NzbDrone.Core.ThingiProvider;
|
||||
using NzbDrone.Core.Validation;
|
||||
@ -52,10 +50,13 @@ public RTorrentSettings()
|
||||
[FieldDefinition(6, Label = "Category", Type = FieldType.Textbox, HelpText = "Adding a category specific to Sonarr avoids conflicts with unrelated downloads, but it's optional.")]
|
||||
public string TvCategory { get; set; }
|
||||
|
||||
[FieldDefinition(7, Label = "Recent Priority", Type = FieldType.Select, SelectOptions = typeof(RTorrentPriority), HelpText = "Priority to use when grabbing episodes that aired within the last 14 days")]
|
||||
[FieldDefinition(7, Label = "Directory", Type = FieldType.Textbox, Advanced = true, HelpText = "Optional location to put downloads in, leave blank to use the default rTorrent location")]
|
||||
public string TvDirectory { get; set; }
|
||||
|
||||
[FieldDefinition(8, Label = "Recent Priority", Type = FieldType.Select, SelectOptions = typeof(RTorrentPriority), HelpText = "Priority to use when grabbing episodes that aired within the last 14 days")]
|
||||
public int RecentTvPriority { get; set; }
|
||||
|
||||
[FieldDefinition(8, Label = "Older Priority", Type = FieldType.Select, SelectOptions = typeof(RTorrentPriority), HelpText = "Priority to use when grabbing episodes that aired over 14 days ago")]
|
||||
[FieldDefinition(9, Label = "Older Priority", Type = FieldType.Select, SelectOptions = typeof(RTorrentPriority), HelpText = "Priority to use when grabbing episodes that aired over 14 days ago")]
|
||||
public int OlderTvPriority { get; set; }
|
||||
|
||||
public NzbDroneValidationResult Validate()
|
||||
|
@ -347,6 +347,7 @@
|
||||
<Compile Include="Download\Clients\Nzbget\NzbgetSettings.cs" />
|
||||
<Compile Include="Download\Clients\Pneumatic\Pneumatic.cs" />
|
||||
<Compile Include="Download\Clients\Pneumatic\PneumaticSettings.cs" />
|
||||
<Compile Include="Download\Clients\rTorrent\RTorrentDirectoryValidator.cs" />
|
||||
<Compile Include="Download\Clients\Sabnzbd\JsonConverters\SabnzbdPriorityTypeConverter.cs" />
|
||||
<Compile Include="Download\Clients\Sabnzbd\JsonConverters\SabnzbdQueueTimeConverter.cs" />
|
||||
<Compile Include="Download\Clients\Sabnzbd\Responses\SabnzbdRetryResponse.cs" />
|
||||
|
Loading…
Reference in New Issue
Block a user