mirror of
https://github.com/lidarr/lidarr.git
synced 2025-07-05 20:42:19 -07:00
New: Labels support for Transmission 4.0
(cherry picked from commit 675e3cd38a14ea33c27f2d66a4be2bf802e17d88)
This commit is contained in:
parent
166f87ae68
commit
7255126af5
8 changed files with 201 additions and 68 deletions
|
@ -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",
|
||||||
|
MusicCategory = ""
|
||||||
};
|
};
|
||||||
|
|
||||||
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,8 +1,10 @@
|
||||||
using System;
|
using System;
|
||||||
|
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;
|
||||||
|
@ -13,6 +15,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,
|
||||||
|
@ -25,9 +30,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.MusicImportedCategory.IsNotNullOrWhiteSpace() &&
|
||||||
|
Settings.MusicImportedCategory != Settings.MusicCategory)
|
||||||
|
{
|
||||||
|
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.MusicImportedCategory);
|
||||||
|
|
||||||
|
if (Settings.MusicCategory.IsNotNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
labels.Remove(Settings.MusicCategory);
|
||||||
|
}
|
||||||
|
|
||||||
|
_proxy.SetTorrentLabels(hash, labels, Settings);
|
||||||
|
}
|
||||||
|
catch (DownloadClientException ex)
|
||||||
|
{
|
||||||
|
_logger.Warn(ex, "Failed to set post-import torrent label \"{0}\" for {1} in Transmission.", Settings.MusicImportedCategory, 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);
|
||||||
|
|
||||||
|
@ -41,7 +85,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;
|
||||||
|
@ -17,6 +18,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,
|
||||||
|
@ -35,7 +38,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>();
|
||||||
|
|
||||||
|
@ -43,36 +46,45 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
{
|
{
|
||||||
var outputPath = new OsPath(torrent.DownloadDir);
|
var outputPath = new OsPath(torrent.DownloadDir);
|
||||||
|
|
||||||
if (Settings.MusicDirectory.IsNotNullOrWhiteSpace())
|
if (Settings.MusicCategory.IsNotNullOrWhiteSpace() && SupportsLabels && torrent.Labels is { Count: > 0 })
|
||||||
{
|
{
|
||||||
if (!new OsPath(Settings.MusicDirectory).Contains(outputPath))
|
if (!torrent.Labels.Contains(Settings.MusicCategory, StringComparer.InvariantCultureIgnoreCase))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Settings.MusicCategory.IsNotNullOrWhiteSpace())
|
else
|
||||||
{
|
{
|
||||||
var directories = outputPath.FullPath.Split('\\', '/');
|
if (Settings.MusicDirectory.IsNotNullOrWhiteSpace())
|
||||||
if (!directories.Contains(Settings.MusicCategory))
|
|
||||||
{
|
{
|
||||||
continue;
|
if (!new OsPath(Settings.MusicDirectory).Contains(outputPath))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Settings.MusicCategory.IsNotNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
var directories = outputPath.FullPath.Split('\\', '/');
|
||||||
|
if (!directories.Contains(Settings.MusicCategory))
|
||||||
|
{
|
||||||
|
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.MusicCategory;
|
DownloadId = torrent.HashString.ToUpper(),
|
||||||
item.Title = torrent.Name;
|
Category = Settings.MusicCategory,
|
||||||
|
Title = torrent.Name,
|
||||||
item.DownloadClientInfo = DownloadClientItemClientInfo.FromDownloadClient(this, false);
|
DownloadClientInfo = DownloadClientItemClientInfo.FromDownloadClient(this, Settings.MusicImportedCategory.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)
|
||||||
{
|
{
|
||||||
|
@ -297,7 +309,7 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_proxy.GetTorrents(Settings);
|
_proxy.GetTorrents(null, Settings);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -307,5 +319,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.MusicCategory.IsNotNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
arguments.Add("labels", new List<string> { settings.MusicCategory });
|
||||||
|
}
|
||||||
|
|
||||||
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.MusicCategory.IsNotNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
arguments.Add("labels", new List<string> { settings.MusicCategory });
|
||||||
|
}
|
||||||
|
|
||||||
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.
|
||||||
|
@ -150,14 +198,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?
|
||||||
|
@ -177,11 +220,14 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
"seedRatioMode",
|
"seedRatioMode",
|
||||||
"seedIdleLimit",
|
"seedIdleLimit",
|
||||||
"seedIdleMode",
|
"seedIdleMode",
|
||||||
"fileCount"
|
"fileCount",
|
||||||
|
"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)
|
||||||
{
|
{
|
||||||
|
@ -193,9 +239,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);
|
||||||
|
|
||||||
|
@ -210,11 +261,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;
|
||||||
|
@ -242,7 +293,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);
|
||||||
|
|
|
@ -33,6 +33,7 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
Host = "localhost";
|
Host = "localhost";
|
||||||
Port = 9091;
|
Port = 9091;
|
||||||
UrlBase = "/transmission/";
|
UrlBase = "/transmission/";
|
||||||
|
MusicCategory = "lidarr";
|
||||||
}
|
}
|
||||||
|
|
||||||
[FieldDefinition(0, Label = "Host", Type = FieldType.Textbox)]
|
[FieldDefinition(0, Label = "Host", Type = FieldType.Textbox)]
|
||||||
|
@ -56,16 +57,19 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
[FieldDefinition(6, Label = "Category", Type = FieldType.Textbox, HelpText = "Adding a category specific to Lidarr avoids conflicts with unrelated downloads, but it's optional. Creates a [category] subdirectory in the output directory.")]
|
[FieldDefinition(6, Label = "Category", Type = FieldType.Textbox, HelpText = "Adding a category specific to Lidarr avoids conflicts with unrelated downloads, but it's optional. Creates a [category] subdirectory in the output directory.")]
|
||||||
public string MusicCategory { get; set; }
|
public string MusicCategory { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(7, Label = "Directory", Type = FieldType.Textbox, Advanced = true, HelpText = "Optional location to put downloads in, leave blank to use the default Transmission location")]
|
[FieldDefinition(7, Label = "PostImportCategory", Type = FieldType.Textbox, Advanced = true, HelpText = "DownloadClientSettingsPostImportCategoryHelpText")]
|
||||||
|
public string MusicImportedCategory { get; set; }
|
||||||
|
|
||||||
|
[FieldDefinition(8, Label = "Directory", Type = FieldType.Textbox, Advanced = true, HelpText = "Optional location to put downloads in, leave blank to use the default Transmission location")]
|
||||||
public string MusicDirectory { get; set; }
|
public string MusicDirectory { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(8, Label = "Recent Priority", Type = FieldType.Select, SelectOptions = typeof(TransmissionPriority), HelpText = "Priority to use when grabbing albums released within the last 14 days")]
|
[FieldDefinition(9, Label = "Recent Priority", Type = FieldType.Select, SelectOptions = typeof(TransmissionPriority), HelpText = "Priority to use when grabbing albums released within the last 14 days")]
|
||||||
public int RecentMusicPriority { get; set; }
|
public int RecentMusicPriority { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(9, Label = "Older Priority", Type = FieldType.Select, SelectOptions = typeof(TransmissionPriority), HelpText = "Priority to use when grabbing albums released over 14 days ago")]
|
[FieldDefinition(10, Label = "Older Priority", Type = FieldType.Select, SelectOptions = typeof(TransmissionPriority), HelpText = "Priority to use when grabbing albums released over 14 days ago")]
|
||||||
public int OlderMusicPriority { get; set; }
|
public int OlderMusicPriority { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(10, Label = "Add Paused", Type = FieldType.Checkbox)]
|
[FieldDefinition(11, Label = "Add Paused", Type = FieldType.Checkbox)]
|
||||||
public bool AddPaused { get; set; }
|
public bool AddPaused { get; set; }
|
||||||
|
|
||||||
public NzbDroneValidationResult Validate()
|
public NzbDroneValidationResult Validate()
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Download.Clients.Transmission
|
namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
{
|
{
|
||||||
public class TransmissionTorrent
|
public class TransmissionTorrent
|
||||||
|
@ -9,6 +12,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; }
|
||||||
|
|
|
@ -14,6 +14,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,
|
||||||
|
@ -65,7 +68,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