mirror of
https://github.com/lidarr/Lidarr
synced 2024-12-26 01:27:00 +00:00
Download clients: New client rTorrent
This commit is contained in:
parent
944a775625
commit
4b9664d82a
9 changed files with 657 additions and 1 deletions
|
@ -0,0 +1,124 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.Download.Clients.RTorrent;
|
||||
using NzbDrone.Test.Common;
|
||||
|
||||
namespace NzbDrone.Core.Test.Download.DownloadClientTests.RTorrentTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class RTorrentFixture : DownloadClientFixtureBase<RTorrent>
|
||||
{
|
||||
protected RTorrentTorrent _downloading;
|
||||
protected RTorrentTorrent _completed;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
Subject.Definition = new DownloadClientDefinition();
|
||||
Subject.Definition.Settings = new RTorrentSettings()
|
||||
{
|
||||
TvCategory = null
|
||||
};
|
||||
|
||||
_downloading = new RTorrentTorrent
|
||||
{
|
||||
Hash = "HASH",
|
||||
IsFinished = false,
|
||||
IsOpen = true,
|
||||
IsActive = true,
|
||||
Name = _title,
|
||||
TotalSize = 1000,
|
||||
RemainingSize = 500,
|
||||
Path = "somepath"
|
||||
};
|
||||
|
||||
_completed = new RTorrentTorrent
|
||||
{
|
||||
Hash = "HASH",
|
||||
IsFinished = true,
|
||||
Name = _title,
|
||||
TotalSize = 1000,
|
||||
RemainingSize = 0,
|
||||
Path = "somepath"
|
||||
};
|
||||
|
||||
Mocker.GetMock<ITorrentFileInfoReader>()
|
||||
.Setup(s => s.GetHashFromTorrentFile(It.IsAny<Byte[]>()))
|
||||
.Returns("CBC2F069FE8BB2F544EAE707D75BCD3DE9DCF951");
|
||||
}
|
||||
|
||||
protected void GivenSuccessfulDownload()
|
||||
{
|
||||
Mocker.GetMock<IRTorrentProxy>()
|
||||
.Setup(s => s.AddTorrentFromUrl(It.IsAny<String>(), It.IsAny<RTorrentSettings>()))
|
||||
.Callback(PrepareClientToReturnCompletedItem);
|
||||
|
||||
Mocker.GetMock<IRTorrentProxy>()
|
||||
.Setup(s => s.AddTorrentFromFile(It.IsAny<String>(), It.IsAny<Byte[]>(), It.IsAny<RTorrentSettings>()))
|
||||
.Callback(PrepareClientToReturnCompletedItem);
|
||||
}
|
||||
|
||||
protected virtual void GivenTorrents(List<RTorrentTorrent> torrents)
|
||||
{
|
||||
if (torrents == null)
|
||||
{
|
||||
torrents = new List<RTorrentTorrent>();
|
||||
}
|
||||
|
||||
Mocker.GetMock<IRTorrentProxy>()
|
||||
.Setup(s => s.GetTorrents(It.IsAny<RTorrentSettings>()))
|
||||
.Returns(torrents);
|
||||
}
|
||||
|
||||
protected void PrepareClientToReturnDownloadingItem()
|
||||
{
|
||||
GivenTorrents(new List<RTorrentTorrent>
|
||||
{
|
||||
_downloading
|
||||
});
|
||||
}
|
||||
|
||||
protected void PrepareClientToReturnCompletedItem()
|
||||
{
|
||||
GivenTorrents(new List<RTorrentTorrent>
|
||||
{
|
||||
_completed
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void downloading_item_should_have_required_properties()
|
||||
{
|
||||
PrepareClientToReturnDownloadingItem();
|
||||
var item = Subject.GetItems().Single();
|
||||
VerifyDownloading(item);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void completed_download_should_have_required_properties()
|
||||
{
|
||||
PrepareClientToReturnCompletedItem();
|
||||
var item = Subject.GetItems().Single();
|
||||
VerifyCompleted(item);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_should_return_unique_id()
|
||||
{
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteEpisode = CreateRemoteEpisode();
|
||||
|
||||
var id = Subject.Download(remoteEpisode);
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -157,6 +157,7 @@
|
|||
<Compile Include="Download\DownloadClientTests\DownloadClientFixtureBase.cs" />
|
||||
<Compile Include="Download\DownloadClientTests\NzbgetTests\NzbgetFixture.cs" />
|
||||
<Compile Include="Download\DownloadClientTests\PneumaticProviderFixture.cs" />
|
||||
<Compile Include="Download\DownloadClientTests\RTorrentTests\RTorrentFixture.cs" />
|
||||
<Compile Include="Download\DownloadClientTests\SabnzbdTests\SabnzbdFixture.cs" />
|
||||
<Compile Include="Download\DownloadClientTests\TransmissionTests\TransmissionFixture.cs" />
|
||||
<Compile Include="Download\DownloadClientTests\UTorrentTests\UTorrentFixture.cs" />
|
||||
|
@ -513,4 +514,4 @@
|
|||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
214
src/NzbDrone.Core/Download/Clients/rTorrent/RTorrent.cs
Normal file
214
src/NzbDrone.Core/Download/Clients/rTorrent/RTorrent.cs
Normal file
|
@ -0,0 +1,214 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||
using NLog;
|
||||
using NzbDrone.Core.Validation;
|
||||
using FluentValidation.Results;
|
||||
using System.Net;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.RemotePathMappings;
|
||||
|
||||
namespace NzbDrone.Core.Download.Clients.RTorrent
|
||||
{
|
||||
public class RTorrent : TorrentClientBase<RTorrentSettings>
|
||||
{
|
||||
private readonly IRTorrentProxy _proxy;
|
||||
|
||||
public RTorrent(IRTorrentProxy proxy,
|
||||
ITorrentFileInfoReader torrentFileInfoReader,
|
||||
IHttpClient httpClient,
|
||||
IConfigService configService,
|
||||
IDiskProvider diskProvider,
|
||||
IRemotePathMappingService remotePathMappingService,
|
||||
Logger logger)
|
||||
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger)
|
||||
{
|
||||
_proxy = proxy;
|
||||
}
|
||||
|
||||
protected override string AddFromMagnetLink(RemoteEpisode remoteEpisode, string hash, string magnetLink)
|
||||
{
|
||||
_proxy.AddTorrentFromUrl(magnetLink, Settings);
|
||||
|
||||
// Wait until url has been resolved before returning
|
||||
var TRIES = 5;
|
||||
var RETRY_DELAY = 500; //ms
|
||||
var ready = false;
|
||||
for (var i = 0; i < TRIES; i++)
|
||||
{
|
||||
ready = _proxy.HasHashTorrent(hash, Settings);
|
||||
if (ready)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Thread.Sleep(RETRY_DELAY);
|
||||
}
|
||||
|
||||
if (ready)
|
||||
{
|
||||
_proxy.SetTorrentLabel(hash, Settings.TvCategory, Settings);
|
||||
|
||||
var priority = (RTorrentPriority)(remoteEpisode.IsRecentEpisode() ?
|
||||
Settings.RecentTvPriority : Settings.OlderTvPriority);
|
||||
_proxy.SetTorrentPriority(hash, Settings, priority);
|
||||
|
||||
return hash;
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Debug("Magnet {0} could not be resolved in {1} tries at {2} ms intervals.", magnetLink, TRIES, RETRY_DELAY);
|
||||
// Remove from client, since it is discarded
|
||||
RemoveItem(hash, true);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return "rTorrent";
|
||||
}
|
||||
}
|
||||
|
||||
public override IEnumerable<DownloadClientItem> GetItems()
|
||||
{
|
||||
try
|
||||
{
|
||||
var torrents = _proxy.GetTorrents(Settings);
|
||||
|
||||
_logger.Debug("Retrieved metadata of {0} torrents in client", torrents.Count);
|
||||
|
||||
var items = new List<DownloadClientItem>();
|
||||
foreach (RTorrentTorrent torrent in torrents)
|
||||
{
|
||||
// Don't concern ourselves with categories other than specified
|
||||
if (torrent.Category != Settings.TvCategory) continue;
|
||||
|
||||
if (torrent.Path.StartsWith("."))
|
||||
{
|
||||
throw new DownloadClientException("Download paths paths must be absolute. Please specify variable \"directory\" in rTorrent.");
|
||||
}
|
||||
|
||||
var item = new DownloadClientItem();
|
||||
item.DownloadClient = Definition.Name;
|
||||
item.Title = torrent.Name;
|
||||
item.DownloadId = torrent.Hash;
|
||||
item.OutputPath = _remotePathMappingService.RemapRemoteToLocal(Settings.Host, new OsPath(torrent.Path));
|
||||
item.TotalSize = torrent.TotalSize;
|
||||
item.RemainingSize = torrent.RemainingSize;
|
||||
item.Category = torrent.Category;
|
||||
|
||||
if (torrent.DownRate > 0) {
|
||||
var secondsLeft = torrent.RemainingSize / torrent.DownRate;
|
||||
item.RemainingTime = TimeSpan.FromSeconds(secondsLeft);
|
||||
} else {
|
||||
item.RemainingTime = TimeSpan.Zero;
|
||||
}
|
||||
|
||||
if (torrent.IsFinished) item.Status = DownloadItemStatus.Completed;
|
||||
else if (torrent.IsActive) item.Status = DownloadItemStatus.Downloading;
|
||||
else if (!torrent.IsActive) item.Status = DownloadItemStatus.Paused;
|
||||
|
||||
// Since we do not know the user's intent, do not let Sonarr to remove the torrent
|
||||
item.IsReadOnly = true;
|
||||
|
||||
items.Add(item);
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
catch (DownloadClientException ex)
|
||||
{
|
||||
_logger.ErrorException(ex.Message, ex);
|
||||
return Enumerable.Empty<DownloadClientItem>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override void RemoveItem(string downloadId, bool deleteData)
|
||||
{
|
||||
if (deleteData)
|
||||
{
|
||||
DeleteItemData(downloadId);
|
||||
}
|
||||
|
||||
_proxy.RemoveTorrent(downloadId, Settings);
|
||||
}
|
||||
|
||||
public override DownloadClientStatus GetStatus()
|
||||
{
|
||||
// XXX: This function's correctness has not been considered
|
||||
|
||||
var status = new DownloadClientStatus
|
||||
{
|
||||
IsLocalhost = Settings.Host == "127.0.0.1" || Settings.Host == "localhost"
|
||||
};
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
protected override void Test(List<ValidationFailure> failures)
|
||||
{
|
||||
failures.AddIfNotNull(TestConnection());
|
||||
if (failures.Any()) return;
|
||||
failures.AddIfNotNull(TestGetTorrents());
|
||||
}
|
||||
|
||||
private ValidationFailure TestConnection()
|
||||
{
|
||||
try
|
||||
{
|
||||
var version = _proxy.GetVersion(Settings);
|
||||
|
||||
if (new Version(version) < new Version("0.9.0"))
|
||||
{
|
||||
return new ValidationFailure(string.Empty, "rTorrent version should be at least 0.9.0. Version reported is {0}", version);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException(ex.Message, ex);
|
||||
return new NzbDroneValidationFailure(string.Empty, "Unknown exception: " + ex.Message);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private ValidationFailure TestGetTorrents()
|
||||
{
|
||||
try
|
||||
{
|
||||
_proxy.GetTorrents(Settings);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException(ex.Message, ex);
|
||||
return new NzbDroneValidationFailure(string.Empty, "Failed to get the list of torrents: " + ex.Message);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
namespace NzbDrone.Core.Download.Clients.RTorrent
|
||||
{
|
||||
public enum RTorrentPriority
|
||||
{
|
||||
DoNotDownload = 0,
|
||||
Low = 1,
|
||||
Normal = 2,
|
||||
High = 3
|
||||
}
|
||||
}
|
214
src/NzbDrone.Core/Download/Clients/rTorrent/RTorrentProxy.cs
Normal file
214
src/NzbDrone.Core/Download/Clients/rTorrent/RTorrentProxy.cs
Normal file
|
@ -0,0 +1,214 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using CookComputing.XmlRpc;
|
||||
|
||||
namespace NzbDrone.Core.Download.Clients.RTorrent
|
||||
{
|
||||
public interface IRTorrentProxy
|
||||
{
|
||||
string GetVersion(RTorrentSettings settings);
|
||||
List<RTorrentTorrent> GetTorrents(RTorrentSettings settings);
|
||||
|
||||
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 SetTorrentLabel(string hash, string label, RTorrentSettings settings);
|
||||
bool HasHashTorrent(string hash, RTorrentSettings settings);
|
||||
}
|
||||
|
||||
public interface IRTorrent : IXmlRpcProxy
|
||||
{
|
||||
[XmlRpcMethod("d.multicall")]
|
||||
object[] TorrentMulticall(params string[] parameters);
|
||||
|
||||
[XmlRpcMethod("load_start")]
|
||||
int LoadURL(string data);
|
||||
|
||||
[XmlRpcMethod("load_raw_start")]
|
||||
int LoadBinary(byte[] data);
|
||||
|
||||
[XmlRpcMethod("d.erase")]
|
||||
int Remove(string hash);
|
||||
|
||||
[XmlRpcMethod("d.set_custom1")]
|
||||
string SetLabel(string hash, string label);
|
||||
|
||||
[XmlRpcMethod("d.set_priority")]
|
||||
int SetPriority(string hash, long priority);
|
||||
|
||||
[XmlRpcMethod("d.get_name")]
|
||||
string GetName(string hash);
|
||||
|
||||
[XmlRpcMethod("system.client_version")]
|
||||
string GetVersion();
|
||||
}
|
||||
|
||||
public class RTorrentProxy : IRTorrentProxy
|
||||
{
|
||||
private readonly Logger _logger;
|
||||
|
||||
public RTorrentProxy(Logger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public string GetVersion(RTorrentSettings settings)
|
||||
{
|
||||
_logger.Debug("Executing remote method: system.client_version");
|
||||
|
||||
var client = BuildClient(settings);
|
||||
|
||||
var version = client.GetVersion();
|
||||
|
||||
return version;
|
||||
}
|
||||
|
||||
public List<RTorrentTorrent> GetTorrents(RTorrentSettings settings)
|
||||
{
|
||||
_logger.Debug("Executing remote method: d.multicall");
|
||||
|
||||
var client = BuildClient(settings);
|
||||
var ret = client.TorrentMulticall("main",
|
||||
"d.get_name=", // string
|
||||
"d.get_hash=", // string
|
||||
"d.get_base_path=", // string
|
||||
"d.get_custom1=", // string (label)
|
||||
"d.get_size_bytes=", // long
|
||||
"d.get_left_bytes=", // long
|
||||
"d.get_down_rate=", // long (in bytes / s)
|
||||
"d.get_ratio=", // long
|
||||
"d.is_open=", // long
|
||||
"d.is_active=", // long
|
||||
"d.get_complete="); //long
|
||||
|
||||
var items = new List<RTorrentTorrent>();
|
||||
foreach (object[] torrent in ret)
|
||||
{
|
||||
var item = new RTorrentTorrent();
|
||||
item.Name = (string) torrent[0];
|
||||
item.Hash = (string) torrent[1];
|
||||
item.Path = (string) torrent[2];
|
||||
item.Category = (string) torrent[3];
|
||||
item.TotalSize = (long) torrent[4];
|
||||
item.RemainingSize = (long) torrent[5];
|
||||
item.DownRate = (long) torrent[6];
|
||||
item.Ratio = (long) torrent[7];
|
||||
item.IsOpen = Convert.ToBoolean((long) torrent[8]);
|
||||
item.IsActive = Convert.ToBoolean((long) torrent[9]);
|
||||
item.IsFinished = Convert.ToBoolean((long) torrent[10]);
|
||||
|
||||
items.Add(item);
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
public bool HasHashTorrent(string hash, RTorrentSettings settings)
|
||||
{
|
||||
_logger.Debug("Executing remote method: d.get_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");
|
||||
|
||||
var client = BuildClient(settings);
|
||||
|
||||
var response = client.LoadURL(torrentUrl);
|
||||
if (response != 0)
|
||||
{
|
||||
throw new DownloadClientException("Could not add torrent: {0}.", torrentUrl);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddTorrentFromFile(string fileName, Byte[] fileContent, RTorrentSettings settings)
|
||||
{
|
||||
_logger.Debug("Executing remote method: load_raw_start");
|
||||
|
||||
var client = BuildClient(settings);
|
||||
|
||||
var response = client.LoadBinary(fileContent);
|
||||
if (response != 0)
|
||||
{
|
||||
throw new DownloadClientException("Could not add torrent: {0}.", fileName);
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveTorrent(string hash, RTorrentSettings settings)
|
||||
{
|
||||
_logger.Debug("Executing remote method: d.erase");
|
||||
|
||||
var client = BuildClient(settings);
|
||||
|
||||
var response = client.Remove(hash);
|
||||
if (response != 0)
|
||||
{
|
||||
throw new DownloadClientException("Could not remove torrent: {0}.", hash);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetTorrentPriority(string hash, RTorrentSettings settings, RTorrentPriority priority)
|
||||
{
|
||||
_logger.Debug("Executing remote method: d.set_priority");
|
||||
|
||||
var client = BuildClient(settings);
|
||||
|
||||
var response = client.SetPriority(hash, (long) priority);
|
||||
if (response != 0)
|
||||
{
|
||||
throw new DownloadClientException("Could not set priority on torrent: {0}.", hash);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetTorrentLabel(string hash, string label, RTorrentSettings settings)
|
||||
{
|
||||
_logger.Debug("Executing remote method: d.set_custom1");
|
||||
|
||||
var client = BuildClient(settings);
|
||||
|
||||
var satLabel = client.SetLabel(hash, label);
|
||||
if (satLabel != label)
|
||||
{
|
||||
throw new DownloadClientException("Could set label on torrent: {0}.", hash);
|
||||
}
|
||||
}
|
||||
|
||||
private IRTorrent BuildClient(RTorrentSettings settings)
|
||||
{
|
||||
var url = string.Format(@"{0}://{1}:{2}/{3}",
|
||||
settings.UseSsl ? "https" : "http",
|
||||
settings.Host,
|
||||
settings.Port,
|
||||
settings.UrlBase);
|
||||
|
||||
var client = XmlRpcProxyGen.Create<IRTorrent>();
|
||||
client.Url = url;
|
||||
|
||||
if (!settings.Username.IsNullOrWhiteSpace())
|
||||
{
|
||||
client.Credentials = new NetworkCredential(settings.Username, settings.Password);
|
||||
}
|
||||
|
||||
return client;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
using System;
|
||||
using FluentValidation;
|
||||
using FluentValidation.Results;
|
||||
using NzbDrone.Core.Annotations;
|
||||
using NzbDrone.Core.ThingiProvider;
|
||||
using NzbDrone.Core.Validation;
|
||||
|
||||
namespace NzbDrone.Core.Download.Clients.RTorrent
|
||||
{
|
||||
public class RTorrentSettingsValidator : AbstractValidator<RTorrentSettings>
|
||||
{
|
||||
public RTorrentSettingsValidator()
|
||||
{
|
||||
RuleFor(c => c.Host).NotEmpty();
|
||||
RuleFor(c => c.Port).InclusiveBetween(0, 65535);
|
||||
RuleFor(c => c.TvCategory).NotEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
public class RTorrentSettings : IProviderConfig
|
||||
{
|
||||
private static readonly RTorrentSettingsValidator Validator = new RTorrentSettingsValidator();
|
||||
|
||||
public RTorrentSettings()
|
||||
{
|
||||
Host = "localhost";
|
||||
Port = 8080;
|
||||
UrlBase = "RPC2";
|
||||
TvCategory = "tv-sonarr";
|
||||
OlderTvPriority = (int)RTorrentPriority.Normal;
|
||||
RecentTvPriority = (int)RTorrentPriority.Normal;
|
||||
}
|
||||
|
||||
[FieldDefinition(0, Label = "Host", Type = FieldType.Textbox)]
|
||||
public string Host { get; set; }
|
||||
|
||||
[FieldDefinition(1, Label = "Port", Type = FieldType.Textbox)]
|
||||
public int Port { get; set; }
|
||||
|
||||
[FieldDefinition(2, Label = "UrlBase", Type = FieldType.Textbox)]
|
||||
public string UrlBase { get; set; }
|
||||
|
||||
[FieldDefinition(3, Label = "Use SSL", Type = FieldType.Checkbox)]
|
||||
public bool UseSsl { get; set; }
|
||||
|
||||
[FieldDefinition(4, Label = "Username", Type = FieldType.Textbox)]
|
||||
public string Username { get; set; }
|
||||
|
||||
[FieldDefinition(5, Label = "Password", Type = FieldType.Password)]
|
||||
public string Password { get; set; }
|
||||
|
||||
[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")]
|
||||
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")]
|
||||
public int OlderTvPriority { get; set; }
|
||||
|
||||
public NzbDroneValidationResult Validate()
|
||||
{
|
||||
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
namespace NzbDrone.Core.Download.Clients.RTorrent
|
||||
{
|
||||
public class RTorrentTorrent
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Hash { get; set; }
|
||||
public string Path { get; set; }
|
||||
public string Category { get; set; }
|
||||
public long TotalSize { get; set; }
|
||||
public long RemainingSize { get; set; }
|
||||
public long DownRate { get; set; }
|
||||
public long Ratio { get; set; }
|
||||
public bool IsFinished { get; set; }
|
||||
public bool IsOpen { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
}
|
||||
}
|
|
@ -83,6 +83,10 @@
|
|||
<Reference Include="RestSharp, Version=105.0.1.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\RestSharp.105.0.1\lib\net4\RestSharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="CookComputing.XmlRpc, Version=2.5.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\xmlrpcnet.2.5.0\lib\net20\CookComputing.XmlRpcV2.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
|
@ -357,6 +361,11 @@
|
|||
<Compile Include="Download\Clients\TorrentBlackhole\TorrentBlackhole.cs" />
|
||||
<Compile Include="Download\Clients\TorrentBlackhole\TorrentBlackholeSettings.cs" />
|
||||
<Compile Include="Download\Clients\TorrentSeedConfiguration.cs" />
|
||||
<Compile Include="Download\Clients\rTorrent\RTorrent.cs" />
|
||||
<Compile Include="Download\Clients\rTorrent\RTorrentPriority.cs" />
|
||||
<Compile Include="Download\Clients\rTorrent\RTorrentProxy.cs" />
|
||||
<Compile Include="Download\Clients\rTorrent\RTorrentSettings.cs" />
|
||||
<Compile Include="Download\Clients\rTorrent\RTorrentTorrent.cs" />
|
||||
<Compile Include="Download\Clients\Transmission\Transmission.cs" />
|
||||
<Compile Include="Download\Clients\Transmission\TransmissionException.cs" />
|
||||
<Compile Include="Download\Clients\Transmission\TransmissionProxy.cs" />
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="xmlrpcnet" version="2.5.0" targetFramework="net40" />
|
||||
<package id="FluentMigrator" version="1.3.1.0" targetFramework="net40" />
|
||||
<package id="FluentMigrator.Runner" version="1.3.1.0" targetFramework="net40" />
|
||||
<package id="FluentValidation" version="5.5.0.0" targetFramework="net40" />
|
||||
|
|
Loading…
Reference in a new issue