mirror of
https://github.com/Sonarr/Sonarr.git
synced 2025-06-28 09:27:29 -04:00
parent
45a62a2e59
commit
675e3cd38a
9 changed files with 200 additions and 73 deletions
|
@ -148,10 +148,5 @@ namespace NzbDrone.Common.Extensions
|
||||||
{
|
{
|
||||||
return string.Join(separator, source.Select(predicate));
|
return string.Join(separator, source.Select(predicate));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HashSet<T> ToHashSet<T>(this IEnumerable<T> source, IEqualityComparer<T> comparer = null)
|
|
||||||
{
|
|
||||||
return new HashSet<T>(source, comparer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,14 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.TransmissionTests
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TransmissionFixture : TransmissionFixtureBase<Transmission>
|
public class TransmissionFixture : TransmissionFixtureBase<Transmission>
|
||||||
{
|
{
|
||||||
|
[SetUp]
|
||||||
|
public void Setup_Transmission()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<ITransmissionProxy>()
|
||||||
|
.Setup(v => v.GetClientVersion(It.IsAny<TransmissionSettings>(), It.IsAny<bool>()))
|
||||||
|
.Returns("4.0.6");
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void queued_item_should_have_required_properties()
|
public void queued_item_should_have_required_properties()
|
||||||
{
|
{
|
||||||
|
@ -272,7 +280,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.TransmissionTests
|
||||||
public void should_only_check_version_number(string version)
|
public void should_only_check_version_number(string version)
|
||||||
{
|
{
|
||||||
Mocker.GetMock<ITransmissionProxy>()
|
Mocker.GetMock<ITransmissionProxy>()
|
||||||
.Setup(s => s.GetClientVersion(It.IsAny<TransmissionSettings>()))
|
.Setup(s => s.GetClientVersion(It.IsAny<TransmissionSettings>(), true))
|
||||||
.Returns(version);
|
.Returns(version);
|
||||||
|
|
||||||
Subject.Test().IsValid.Should().BeTrue();
|
Subject.Test().IsValid.Should().BeTrue();
|
||||||
|
|
|
@ -29,7 +29,8 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.TransmissionTests
|
||||||
Host = "127.0.0.1",
|
Host = "127.0.0.1",
|
||||||
Port = 2222,
|
Port = 2222,
|
||||||
Username = "admin",
|
Username = "admin",
|
||||||
Password = "pass"
|
Password = "pass",
|
||||||
|
TvCategory = ""
|
||||||
};
|
};
|
||||||
|
|
||||||
Subject.Definition = new DownloadClientDefinition();
|
Subject.Definition = new DownloadClientDefinition();
|
||||||
|
@ -152,7 +153,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.TransmissionTests
|
||||||
}
|
}
|
||||||
|
|
||||||
Mocker.GetMock<ITransmissionProxy>()
|
Mocker.GetMock<ITransmissionProxy>()
|
||||||
.Setup(s => s.GetTorrents(It.IsAny<TransmissionSettings>()))
|
.Setup(s => s.GetTorrents(null, It.IsAny<TransmissionSettings>()))
|
||||||
.Returns(torrents);
|
.Returns(torrents);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Blocklisting;
|
using NzbDrone.Core.Blocklisting;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
@ -15,6 +17,9 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
{
|
{
|
||||||
public class Transmission : TransmissionBase
|
public class Transmission : TransmissionBase
|
||||||
{
|
{
|
||||||
|
public override string Name => "Transmission";
|
||||||
|
public override bool SupportsLabels => HasClientVersion(4, 0);
|
||||||
|
|
||||||
public Transmission(ITransmissionProxy proxy,
|
public Transmission(ITransmissionProxy proxy,
|
||||||
ITorrentFileInfoReader torrentFileInfoReader,
|
ITorrentFileInfoReader torrentFileInfoReader,
|
||||||
IHttpClient httpClient,
|
IHttpClient httpClient,
|
||||||
|
@ -28,9 +33,48 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void MarkItemAsImported(DownloadClientItem downloadClientItem)
|
||||||
|
{
|
||||||
|
if (!SupportsLabels)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException($"{Name} does not support marking items as imported");
|
||||||
|
}
|
||||||
|
|
||||||
|
// set post-import category
|
||||||
|
if (Settings.TvImportedCategory.IsNotNullOrWhiteSpace() &&
|
||||||
|
Settings.TvImportedCategory != Settings.TvCategory)
|
||||||
|
{
|
||||||
|
var hash = downloadClientItem.DownloadId.ToLowerInvariant();
|
||||||
|
var torrent = _proxy.GetTorrents(new[] { hash }, Settings).FirstOrDefault();
|
||||||
|
|
||||||
|
if (torrent == null)
|
||||||
|
{
|
||||||
|
_logger.Warn("Could not find torrent with hash \"{0}\" in Transmission.", hash);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var labels = torrent.Labels.ToHashSet(StringComparer.InvariantCultureIgnoreCase);
|
||||||
|
labels.Add(Settings.TvImportedCategory);
|
||||||
|
|
||||||
|
if (Settings.TvCategory.IsNotNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
labels.Remove(Settings.TvCategory);
|
||||||
|
}
|
||||||
|
|
||||||
|
_proxy.SetTorrentLabels(hash, labels, Settings);
|
||||||
|
}
|
||||||
|
catch (DownloadClientException ex)
|
||||||
|
{
|
||||||
|
_logger.Warn(ex, "Failed to set post-import torrent label \"{0}\" for {1} in Transmission.", Settings.TvImportedCategory, downloadClientItem.Title);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected override ValidationFailure ValidateVersion()
|
protected override ValidationFailure ValidateVersion()
|
||||||
{
|
{
|
||||||
var versionString = _proxy.GetClientVersion(Settings);
|
var versionString = _proxy.GetClientVersion(Settings, true);
|
||||||
|
|
||||||
_logger.Debug("Transmission version information: {0}", versionString);
|
_logger.Debug("Transmission version information: {0}", versionString);
|
||||||
|
|
||||||
|
@ -44,7 +88,5 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Name => "Transmission";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
|
@ -18,6 +19,8 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
{
|
{
|
||||||
public abstract class TransmissionBase : TorrentClientBase<TransmissionSettings>
|
public abstract class TransmissionBase : TorrentClientBase<TransmissionSettings>
|
||||||
{
|
{
|
||||||
|
public abstract bool SupportsLabels { get; }
|
||||||
|
|
||||||
protected readonly ITransmissionProxy _proxy;
|
protected readonly ITransmissionProxy _proxy;
|
||||||
|
|
||||||
public TransmissionBase(ITransmissionProxy proxy,
|
public TransmissionBase(ITransmissionProxy proxy,
|
||||||
|
@ -37,7 +40,7 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
public override IEnumerable<DownloadClientItem> GetItems()
|
public override IEnumerable<DownloadClientItem> GetItems()
|
||||||
{
|
{
|
||||||
var configFunc = new Lazy<TransmissionConfig>(() => _proxy.GetConfig(Settings));
|
var configFunc = new Lazy<TransmissionConfig>(() => _proxy.GetConfig(Settings));
|
||||||
var torrents = _proxy.GetTorrents(Settings);
|
var torrents = _proxy.GetTorrents(null, Settings);
|
||||||
|
|
||||||
var items = new List<DownloadClientItem>();
|
var items = new List<DownloadClientItem>();
|
||||||
|
|
||||||
|
@ -45,6 +48,15 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
{
|
{
|
||||||
var outputPath = new OsPath(torrent.DownloadDir);
|
var outputPath = new OsPath(torrent.DownloadDir);
|
||||||
|
|
||||||
|
if (Settings.TvCategory.IsNotNullOrWhiteSpace() && SupportsLabels && torrent.Labels is { Count: > 0 })
|
||||||
|
{
|
||||||
|
if (!torrent.Labels.Contains(Settings.TvCategory, StringComparer.InvariantCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (Settings.TvDirectory.IsNotNullOrWhiteSpace())
|
if (Settings.TvDirectory.IsNotNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
if (!new OsPath(Settings.TvDirectory).Contains(outputPath))
|
if (!new OsPath(Settings.TvDirectory).Contains(outputPath))
|
||||||
|
@ -60,21 +72,21 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
outputPath = _remotePathMappingService.RemapRemoteToLocal(Settings.Host, outputPath);
|
outputPath = _remotePathMappingService.RemapRemoteToLocal(Settings.Host, outputPath);
|
||||||
|
|
||||||
var item = new DownloadClientItem();
|
var item = new DownloadClientItem
|
||||||
item.DownloadId = torrent.HashString.ToUpper();
|
{
|
||||||
item.Category = Settings.TvCategory;
|
DownloadId = torrent.HashString.ToUpper(),
|
||||||
item.Title = torrent.Name;
|
Category = Settings.TvCategory,
|
||||||
|
Title = torrent.Name,
|
||||||
item.DownloadClientInfo = DownloadClientItemClientInfo.FromDownloadClient(this, false);
|
DownloadClientInfo = DownloadClientItemClientInfo.FromDownloadClient(this, Settings.TvImportedCategory.IsNotNullOrWhiteSpace() && SupportsLabels),
|
||||||
|
OutputPath = GetOutputPath(outputPath, torrent),
|
||||||
item.OutputPath = GetOutputPath(outputPath, torrent);
|
TotalSize = torrent.TotalSize,
|
||||||
item.TotalSize = torrent.TotalSize;
|
RemainingSize = torrent.LeftUntilDone,
|
||||||
item.RemainingSize = torrent.LeftUntilDone;
|
SeedRatio = torrent.DownloadedEver <= 0 ? 0 : (double)torrent.UploadedEver / torrent.DownloadedEver
|
||||||
item.SeedRatio = torrent.DownloadedEver <= 0 ? 0 :
|
};
|
||||||
(double)torrent.UploadedEver / torrent.DownloadedEver;
|
|
||||||
|
|
||||||
if (torrent.Eta >= 0)
|
if (torrent.Eta >= 0)
|
||||||
{
|
{
|
||||||
|
@ -300,7 +312,7 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_proxy.GetTorrents(Settings);
|
_proxy.GetTorrents(null, Settings);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -310,5 +322,15 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected bool HasClientVersion(int major, int minor)
|
||||||
|
{
|
||||||
|
var rawVersion = _proxy.GetClientVersion(Settings);
|
||||||
|
|
||||||
|
var versionResult = Regex.Match(rawVersion, @"(?<!\(|(\d|\.)+)(\d|\.)+(?!\)|(\d|\.)+)").Value;
|
||||||
|
var clientVersion = Version.Parse(versionResult);
|
||||||
|
|
||||||
|
return clientVersion >= new Version(major, minor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Immutable;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
@ -12,15 +15,16 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
{
|
{
|
||||||
public interface ITransmissionProxy
|
public interface ITransmissionProxy
|
||||||
{
|
{
|
||||||
List<TransmissionTorrent> GetTorrents(TransmissionSettings settings);
|
IReadOnlyCollection<TransmissionTorrent> GetTorrents(IReadOnlyCollection<string> hashStrings, TransmissionSettings settings);
|
||||||
void AddTorrentFromUrl(string torrentUrl, string downloadDirectory, TransmissionSettings settings);
|
void AddTorrentFromUrl(string torrentUrl, string downloadDirectory, TransmissionSettings settings);
|
||||||
void AddTorrentFromData(byte[] torrentData, string downloadDirectory, TransmissionSettings settings);
|
void AddTorrentFromData(byte[] torrentData, string downloadDirectory, TransmissionSettings settings);
|
||||||
void SetTorrentSeedingConfiguration(string hash, TorrentSeedConfiguration seedConfiguration, TransmissionSettings settings);
|
void SetTorrentSeedingConfiguration(string hash, TorrentSeedConfiguration seedConfiguration, TransmissionSettings settings);
|
||||||
TransmissionConfig GetConfig(TransmissionSettings settings);
|
TransmissionConfig GetConfig(TransmissionSettings settings);
|
||||||
string GetProtocolVersion(TransmissionSettings settings);
|
string GetProtocolVersion(TransmissionSettings settings);
|
||||||
string GetClientVersion(TransmissionSettings settings);
|
string GetClientVersion(TransmissionSettings settings, bool force = false);
|
||||||
void RemoveTorrent(string hash, bool removeData, TransmissionSettings settings);
|
void RemoveTorrent(string hash, bool removeData, TransmissionSettings settings);
|
||||||
void MoveTorrentToTopInQueue(string hashString, TransmissionSettings settings);
|
void MoveTorrentToTopInQueue(string hashString, TransmissionSettings settings);
|
||||||
|
void SetTorrentLabels(string hash, IEnumerable<string> labels, TransmissionSettings settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TransmissionProxy : ITransmissionProxy
|
public class TransmissionProxy : ITransmissionProxy
|
||||||
|
@ -28,50 +32,66 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
private readonly IHttpClient _httpClient;
|
private readonly IHttpClient _httpClient;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
private ICached<string> _authSessionIDCache;
|
private readonly ICached<string> _authSessionIdCache;
|
||||||
|
private readonly ICached<string> _versionCache;
|
||||||
|
|
||||||
public TransmissionProxy(ICacheManager cacheManager, IHttpClient httpClient, Logger logger)
|
public TransmissionProxy(ICacheManager cacheManager, IHttpClient httpClient, Logger logger)
|
||||||
{
|
{
|
||||||
_httpClient = httpClient;
|
_httpClient = httpClient;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
|
||||||
_authSessionIDCache = cacheManager.GetCache<string>(GetType(), "authSessionID");
|
_authSessionIdCache = cacheManager.GetCache<string>(GetType(), "authSessionID");
|
||||||
|
_versionCache = cacheManager.GetCache<string>(GetType(), "versions");
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<TransmissionTorrent> GetTorrents(TransmissionSettings settings)
|
public IReadOnlyCollection<TransmissionTorrent> GetTorrents(IReadOnlyCollection<string> hashStrings, TransmissionSettings settings)
|
||||||
{
|
{
|
||||||
var result = GetTorrentStatus(settings);
|
var result = GetTorrentStatus(hashStrings, settings);
|
||||||
|
|
||||||
var torrents = ((JArray)result.Arguments["torrents"]).ToObject<List<TransmissionTorrent>>();
|
var torrents = ((JArray)result.Arguments["torrents"]).ToObject<ReadOnlyCollection<TransmissionTorrent>>();
|
||||||
|
|
||||||
return torrents;
|
return torrents;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddTorrentFromUrl(string torrentUrl, string downloadDirectory, TransmissionSettings settings)
|
public void AddTorrentFromUrl(string torrentUrl, string downloadDirectory, TransmissionSettings settings)
|
||||||
{
|
{
|
||||||
var arguments = new Dictionary<string, object>();
|
var arguments = new Dictionary<string, object>
|
||||||
arguments.Add("filename", torrentUrl);
|
{
|
||||||
arguments.Add("paused", settings.AddPaused);
|
{ "filename", torrentUrl },
|
||||||
|
{ "paused", settings.AddPaused }
|
||||||
|
};
|
||||||
|
|
||||||
if (!downloadDirectory.IsNullOrWhiteSpace())
|
if (!downloadDirectory.IsNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
arguments.Add("download-dir", downloadDirectory);
|
arguments.Add("download-dir", downloadDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (settings.TvCategory.IsNotNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
arguments.Add("labels", new List<string> { settings.TvCategory });
|
||||||
|
}
|
||||||
|
|
||||||
ProcessRequest("torrent-add", arguments, settings);
|
ProcessRequest("torrent-add", arguments, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddTorrentFromData(byte[] torrentData, string downloadDirectory, TransmissionSettings settings)
|
public void AddTorrentFromData(byte[] torrentData, string downloadDirectory, TransmissionSettings settings)
|
||||||
{
|
{
|
||||||
var arguments = new Dictionary<string, object>();
|
var arguments = new Dictionary<string, object>
|
||||||
arguments.Add("metainfo", Convert.ToBase64String(torrentData));
|
{
|
||||||
arguments.Add("paused", settings.AddPaused);
|
{ "metainfo", Convert.ToBase64String(torrentData) },
|
||||||
|
{ "paused", settings.AddPaused }
|
||||||
|
};
|
||||||
|
|
||||||
if (!downloadDirectory.IsNullOrWhiteSpace())
|
if (!downloadDirectory.IsNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
arguments.Add("download-dir", downloadDirectory);
|
arguments.Add("download-dir", downloadDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (settings.TvCategory.IsNotNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
arguments.Add("labels", new List<string> { settings.TvCategory });
|
||||||
|
}
|
||||||
|
|
||||||
ProcessRequest("torrent-add", arguments, settings);
|
ProcessRequest("torrent-add", arguments, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,8 +102,10 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var arguments = new Dictionary<string, object>();
|
var arguments = new Dictionary<string, object>
|
||||||
arguments.Add("ids", new[] { hash });
|
{
|
||||||
|
{ "ids", new List<string> { hash } }
|
||||||
|
};
|
||||||
|
|
||||||
if (seedConfiguration.Ratio != null)
|
if (seedConfiguration.Ratio != null)
|
||||||
{
|
{
|
||||||
|
@ -97,6 +119,12 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
arguments.Add("seedIdleMode", 1);
|
arguments.Add("seedIdleMode", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Avoid extraneous request if no limits are to be set
|
||||||
|
if (arguments.All(arg => arg.Key == "ids"))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ProcessRequest("torrent-set", arguments, settings);
|
ProcessRequest("torrent-set", arguments, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,11 +135,16 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
return config.RpcVersion;
|
return config.RpcVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetClientVersion(TransmissionSettings settings)
|
public string GetClientVersion(TransmissionSettings settings, bool force = false)
|
||||||
{
|
{
|
||||||
var config = GetConfig(settings);
|
var cacheKey = $"version:{$"{GetBaseUrl(settings)}:{settings.Password}".SHA256Hash()}";
|
||||||
|
|
||||||
return config.Version;
|
if (force)
|
||||||
|
{
|
||||||
|
_versionCache.Remove(cacheKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _versionCache.Get(cacheKey, () => GetConfig(settings).Version, TimeSpan.FromHours(6));
|
||||||
}
|
}
|
||||||
|
|
||||||
public TransmissionConfig GetConfig(TransmissionSettings settings)
|
public TransmissionConfig GetConfig(TransmissionSettings settings)
|
||||||
|
@ -124,21 +157,36 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
|
|
||||||
public void RemoveTorrent(string hashString, bool removeData, TransmissionSettings settings)
|
public void RemoveTorrent(string hashString, bool removeData, TransmissionSettings settings)
|
||||||
{
|
{
|
||||||
var arguments = new Dictionary<string, object>();
|
var arguments = new Dictionary<string, object>
|
||||||
arguments.Add("ids", new string[] { hashString });
|
{
|
||||||
arguments.Add("delete-local-data", removeData);
|
{ "ids", new List<string> { hashString } },
|
||||||
|
{ "delete-local-data", removeData }
|
||||||
|
};
|
||||||
|
|
||||||
ProcessRequest("torrent-remove", arguments, settings);
|
ProcessRequest("torrent-remove", arguments, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void MoveTorrentToTopInQueue(string hashString, TransmissionSettings settings)
|
public void MoveTorrentToTopInQueue(string hashString, TransmissionSettings settings)
|
||||||
{
|
{
|
||||||
var arguments = new Dictionary<string, object>();
|
var arguments = new Dictionary<string, object>
|
||||||
arguments.Add("ids", new string[] { hashString });
|
{
|
||||||
|
{ "ids", new List<string> { hashString } }
|
||||||
|
};
|
||||||
|
|
||||||
ProcessRequest("queue-move-top", arguments, settings);
|
ProcessRequest("queue-move-top", arguments, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetTorrentLabels(string hash, IEnumerable<string> labels, TransmissionSettings settings)
|
||||||
|
{
|
||||||
|
var arguments = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "ids", new List<string> { hash } },
|
||||||
|
{ "labels", labels.ToImmutableHashSet() }
|
||||||
|
};
|
||||||
|
|
||||||
|
ProcessRequest("torrent-set", arguments, settings);
|
||||||
|
}
|
||||||
|
|
||||||
private TransmissionResponse GetSessionVariables(TransmissionSettings settings)
|
private TransmissionResponse GetSessionVariables(TransmissionSettings settings)
|
||||||
{
|
{
|
||||||
// Retrieve transmission information such as the default download directory, bandwidth throttling and seed ratio.
|
// Retrieve transmission information such as the default download directory, bandwidth throttling and seed ratio.
|
||||||
|
@ -151,14 +199,9 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
return ProcessRequest("session-stats", null, settings);
|
return ProcessRequest("session-stats", null, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
private TransmissionResponse GetTorrentStatus(TransmissionSettings settings)
|
|
||||||
{
|
|
||||||
return GetTorrentStatus(null, settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
private TransmissionResponse GetTorrentStatus(IEnumerable<string> hashStrings, TransmissionSettings settings)
|
private TransmissionResponse GetTorrentStatus(IEnumerable<string> hashStrings, TransmissionSettings settings)
|
||||||
{
|
{
|
||||||
var fields = new string[]
|
var fields = new List<string>
|
||||||
{
|
{
|
||||||
"id",
|
"id",
|
||||||
"hashString", // Unique torrent ID. Use this instead of the client id?
|
"hashString", // Unique torrent ID. Use this instead of the client id?
|
||||||
|
@ -179,11 +222,14 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
"seedIdleLimit",
|
"seedIdleLimit",
|
||||||
"seedIdleMode",
|
"seedIdleMode",
|
||||||
"fileCount",
|
"fileCount",
|
||||||
"file-count"
|
"file-count",
|
||||||
|
"labels"
|
||||||
};
|
};
|
||||||
|
|
||||||
var arguments = new Dictionary<string, object>();
|
var arguments = new Dictionary<string, object>
|
||||||
arguments.Add("fields", fields);
|
{
|
||||||
|
{ "fields", fields }
|
||||||
|
};
|
||||||
|
|
||||||
if (hashStrings != null)
|
if (hashStrings != null)
|
||||||
{
|
{
|
||||||
|
@ -195,9 +241,14 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string GetBaseUrl(TransmissionSettings settings)
|
||||||
|
{
|
||||||
|
return HttpRequestBuilder.BuildBaseUrl(settings.UseSsl, settings.Host, settings.Port, settings.UrlBase);
|
||||||
|
}
|
||||||
|
|
||||||
private HttpRequestBuilder BuildRequest(TransmissionSettings settings)
|
private HttpRequestBuilder BuildRequest(TransmissionSettings settings)
|
||||||
{
|
{
|
||||||
var requestBuilder = new HttpRequestBuilder(settings.UseSsl, settings.Host, settings.Port, settings.UrlBase)
|
var requestBuilder = new HttpRequestBuilder(GetBaseUrl(settings))
|
||||||
.Resource("rpc")
|
.Resource("rpc")
|
||||||
.Accept(HttpAccept.Json);
|
.Accept(HttpAccept.Json);
|
||||||
|
|
||||||
|
@ -212,11 +263,11 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
{
|
{
|
||||||
var authKey = string.Format("{0}:{1}", requestBuilder.BaseUrl, settings.Password);
|
var authKey = string.Format("{0}:{1}", requestBuilder.BaseUrl, settings.Password);
|
||||||
|
|
||||||
var sessionId = _authSessionIDCache.Find(authKey);
|
var sessionId = _authSessionIdCache.Find(authKey);
|
||||||
|
|
||||||
if (sessionId == null || reauthenticate)
|
if (sessionId == null || reauthenticate)
|
||||||
{
|
{
|
||||||
_authSessionIDCache.Remove(authKey);
|
_authSessionIdCache.Remove(authKey);
|
||||||
|
|
||||||
var authLoginRequest = BuildRequest(settings).Build();
|
var authLoginRequest = BuildRequest(settings).Build();
|
||||||
authLoginRequest.SuppressHttpError = true;
|
authLoginRequest.SuppressHttpError = true;
|
||||||
|
@ -244,7 +295,7 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
|
|
||||||
_logger.Debug("Transmission authentication succeeded.");
|
_logger.Debug("Transmission authentication succeeded.");
|
||||||
|
|
||||||
_authSessionIDCache.Set(authKey, sessionId);
|
_authSessionIdCache.Set(authKey, sessionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
requestBuilder.SetHeader("X-Transmission-Session-Id", sessionId);
|
requestBuilder.SetHeader("X-Transmission-Session-Id", sessionId);
|
||||||
|
|
|
@ -32,6 +32,7 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
Host = "localhost";
|
Host = "localhost";
|
||||||
Port = 9091;
|
Port = 9091;
|
||||||
UrlBase = "/transmission/";
|
UrlBase = "/transmission/";
|
||||||
|
TvCategory = "tv-sonarr";
|
||||||
}
|
}
|
||||||
|
|
||||||
[FieldDefinition(0, Label = "Host", Type = FieldType.Textbox)]
|
[FieldDefinition(0, Label = "Host", Type = FieldType.Textbox)]
|
||||||
|
@ -59,16 +60,19 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
[FieldDefinition(6, Label = "Category", Type = FieldType.Textbox, HelpText = "DownloadClientSettingsCategorySubFolderHelpText")]
|
[FieldDefinition(6, Label = "Category", Type = FieldType.Textbox, HelpText = "DownloadClientSettingsCategorySubFolderHelpText")]
|
||||||
public string TvCategory { get; set; }
|
public string TvCategory { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(7, Label = "Directory", Type = FieldType.Textbox, Advanced = true, HelpText = "DownloadClientTransmissionSettingsDirectoryHelpText")]
|
[FieldDefinition(7, Label = "PostImportCategory", Type = FieldType.Textbox, Advanced = true, HelpText = "DownloadClientSettingsPostImportCategoryHelpText")]
|
||||||
|
public string TvImportedCategory { get; set; }
|
||||||
|
|
||||||
|
[FieldDefinition(8, Label = "Directory", Type = FieldType.Textbox, Advanced = true, HelpText = "DownloadClientTransmissionSettingsDirectoryHelpText")]
|
||||||
public string TvDirectory { get; set; }
|
public string TvDirectory { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(8, Label = "DownloadClientSettingsRecentPriority", Type = FieldType.Select, SelectOptions = typeof(TransmissionPriority), HelpText = "DownloadClientSettingsRecentPriorityEpisodeHelpText")]
|
[FieldDefinition(9, Label = "DownloadClientSettingsRecentPriority", Type = FieldType.Select, SelectOptions = typeof(TransmissionPriority), HelpText = "DownloadClientSettingsRecentPriorityEpisodeHelpText")]
|
||||||
public int RecentTvPriority { get; set; }
|
public int RecentTvPriority { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(9, Label = "DownloadClientSettingsOlderPriority", Type = FieldType.Select, SelectOptions = typeof(TransmissionPriority), HelpText = "DownloadClientSettingsOlderPriorityEpisodeHelpText")]
|
[FieldDefinition(10, Label = "DownloadClientSettingsOlderPriority", Type = FieldType.Select, SelectOptions = typeof(TransmissionPriority), HelpText = "DownloadClientSettingsOlderPriorityEpisodeHelpText")]
|
||||||
public int OlderTvPriority { get; set; }
|
public int OlderTvPriority { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(10, Label = "DownloadClientSettingsAddPaused", Type = FieldType.Checkbox)]
|
[FieldDefinition(11, Label = "DownloadClientSettingsAddPaused", Type = FieldType.Checkbox)]
|
||||||
public bool AddPaused { get; set; }
|
public bool AddPaused { get; set; }
|
||||||
|
|
||||||
public override NzbDroneValidationResult Validate()
|
public override NzbDroneValidationResult Validate()
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Download.Clients.Transmission
|
namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
|
@ -11,6 +13,7 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
public long TotalSize { get; set; }
|
public long TotalSize { get; set; }
|
||||||
public long LeftUntilDone { get; set; }
|
public long LeftUntilDone { get; set; }
|
||||||
public bool IsFinished { get; set; }
|
public bool IsFinished { get; set; }
|
||||||
|
public IReadOnlyCollection<string> Labels { get; set; } = Array.Empty<string>();
|
||||||
public long Eta { get; set; }
|
public long Eta { get; set; }
|
||||||
public TransmissionTorrentStatus Status { get; set; }
|
public TransmissionTorrentStatus Status { get; set; }
|
||||||
public long SecondsDownloading { get; set; }
|
public long SecondsDownloading { get; set; }
|
||||||
|
|
|
@ -15,6 +15,9 @@ namespace NzbDrone.Core.Download.Clients.Vuze
|
||||||
{
|
{
|
||||||
private const int MINIMUM_SUPPORTED_PROTOCOL_VERSION = 14;
|
private const int MINIMUM_SUPPORTED_PROTOCOL_VERSION = 14;
|
||||||
|
|
||||||
|
public override string Name => "Vuze";
|
||||||
|
public override bool SupportsLabels => false;
|
||||||
|
|
||||||
public Vuze(ITransmissionProxy proxy,
|
public Vuze(ITransmissionProxy proxy,
|
||||||
ITorrentFileInfoReader torrentFileInfoReader,
|
ITorrentFileInfoReader torrentFileInfoReader,
|
||||||
IHttpClient httpClient,
|
IHttpClient httpClient,
|
||||||
|
@ -67,7 +70,5 @@ namespace NzbDrone.Core.Download.Clients.Vuze
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Name => "Vuze";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue