diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/RTorrentTests/RTorrentFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/RTorrentTests/RTorrentFixture.cs index f8d137284..91fc1f0a0 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/RTorrentTests/RTorrentFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/RTorrentTests/RTorrentFixture.cs @@ -25,26 +25,26 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.RTorrentTests }; _downloading = new RTorrentTorrent - { - Hash = "HASH", - IsFinished = false, - IsOpen = true, - IsActive = true, - Name = _title, - TotalSize = 1000, - RemainingSize = 500, - Path = "somepath" - }; + { + 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" - }; + { + Hash = "HASH", + IsFinished = true, + Name = _title, + TotalSize = 1000, + RemainingSize = 0, + Path = "somepath" + }; Mocker.GetMock() .Setup(s => s.GetHashFromTorrentFile(It.IsAny())) @@ -54,11 +54,11 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.RTorrentTests protected void GivenSuccessfulDownload() { Mocker.GetMock() - .Setup(s => s.AddTorrentFromUrl(It.IsAny(), It.IsAny())) + .Setup(s => s.AddTorrentFromUrl(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) .Callback(PrepareClientToReturnCompletedItem); Mocker.GetMock() - .Setup(s => s.AddTorrentFromFile(It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(s => s.AddTorrentFromFile(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) .Callback(PrepareClientToReturnCompletedItem); @@ -116,11 +116,11 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.RTorrentTests { GivenSuccessfulDownload(); - var remoteMovie = CreateRemoteMovie(); + var remoteEpisode = CreateRemoteMovie(); - var id = Subject.Download(remoteMovie); + var id = Subject.Download(remoteEpisode); id.Should().NotBeNullOrEmpty(); } } -} +} \ No newline at end of file diff --git a/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrent.cs b/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrent.cs index e9674bca7..0a7e1b757 100644 --- a/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrent.cs +++ b/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrent.cs @@ -49,52 +49,36 @@ namespace NzbDrone.Core.Download.Clients.RTorrent protected override string AddFromMagnetLink(RemoteMovie remoteMovie, string hash, string magnetLink) { - _proxy.AddTorrentFromUrl(magnetLink, Settings); + _proxy.AddTorrentFromUrl(magnetLink, Settings.MovieCategory, RTorrentPriority.Normal, Settings.MovieDirectory, Settings); - // Download the magnet to the appropriate directory. - _proxy.SetTorrentLabel(hash, Settings.MovieCategory, Settings); - SetDownloadDirectory(hash); - _proxy.StartTorrent(hash, Settings); - - // Wait for the magnet to be resolved. var tries = 10; var retryDelay = 500; - if (WaitForTorrent(hash, tries, retryDelay)) - { - _logger.Info("Resolved magnet for {0}", remoteMovie.Movie.CleanTitle); - SetDownloadDirectory(hash); - _proxy.SetTorrentLabel(hash, Settings.MovieCategory, Settings); - _proxy.StartTorrent(hash, Settings); - return hash; - } - else + + // Wait a bit for the magnet to be resolved. + if (!WaitForTorrent(hash, tries, retryDelay)) { _logger.Warn("rTorrent could not resolve magnet within {0} seconds, download may remain stuck: {1}.", tries * retryDelay / 1000, magnetLink); return hash; } + + return hash; } protected override string AddFromTorrentFile(RemoteMovie remoteMovie, string hash, string filename, byte[] fileContent) { - _proxy.AddTorrentFromFile(filename, fileContent, Settings); + _proxy.AddTorrentFromFile(filename, fileContent, Settings.MovieCategory, RTorrentPriority.Normal, Settings.MovieDirectory, Settings); - var tries = 5; - var retryDelay = 200; - if (WaitForTorrent(hash, tries, retryDelay)) - { - _proxy.SetTorrentLabel(hash, Settings.MovieCategory, Settings); - SetDownloadDirectory(hash); - _proxy.StartTorrent(hash, Settings); - return hash; - } - else + var tries = 10; + var retryDelay = 500; + if (!WaitForTorrent(hash, tries, retryDelay)) { - _logger.Debug("rTorrent could not add file"); + _logger.Debug("rTorrent didn't add the torrent within {0} seconds: {1}.", tries * retryDelay / 1000, filename); - RemoveItem(hash, true); throw new ReleaseDownloadException(remoteMovie.Release, "Downloading torrent failed"); } + + return hash; } public override string Name => "rTorrent"; @@ -233,14 +217,6 @@ namespace NzbDrone.Core.Download.Clients.RTorrent return result.Errors.First(); } - private void SetDownloadDirectory(string hash) - { - if (Settings.MovieDirectory.IsNotNullOrWhiteSpace()) - { - _proxy.SetTorrentDownloadDirectory(hash, Settings.MovieDirectory, Settings); - } - } - private bool WaitForTorrent(string hash, int tries, int retryDelay) { for (var i = 0; i < tries; i++) diff --git a/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrentProxy.cs b/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrentProxy.cs index a94b6fb1e..dabe175a4 100644 --- a/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrentProxy.cs +++ b/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrentProxy.cs @@ -13,15 +13,10 @@ namespace NzbDrone.Core.Download.Clients.RTorrent string GetVersion(RTorrentSettings settings); List GetTorrents(RTorrentSettings settings); - void AddTorrentFromUrl(string torrentUrl, RTorrentSettings settings); - void AddTorrentFromFile(string fileName, byte[] fileContent, RTorrentSettings settings); + void AddTorrentFromUrl(string torrentUrl, string label, RTorrentPriority priority, string directory, RTorrentSettings settings); + void AddTorrentFromFile(string fileName, byte[] fileContent, string label, RTorrentPriority priority, string directory, RTorrentSettings settings); void RemoveTorrent(string hash, RTorrentSettings settings); - 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); - void SetDeferredMagnetProperties(string hash, string category, string directory, RTorrentPriority priority, RTorrentSettings settings); } public interface IRTorrent : IXmlRpcProxy @@ -29,35 +24,20 @@ namespace NzbDrone.Core.Download.Clients.RTorrent [XmlRpcMethod("d.multicall2")] object[] TorrentMulticall(params string[] parameters); - [XmlRpcMethod("load.normal")] - int LoadUrl(string target, string data); + [XmlRpcMethod("load.start")] + int LoadStart(string target, string data, params string[] commands); - [XmlRpcMethod("load.raw")] - int LoadBinary(string target, byte[] data); + [XmlRpcMethod("load.raw_start")] + int LoadRawStart(string target, byte[] data, params string[] commands); [XmlRpcMethod("d.erase")] int Remove(string hash); - [XmlRpcMethod("d.custom1.set")] - string SetLabel(string hash, string label); - - [XmlRpcMethod("d.priority.set")] - int SetPriority(string hash, long priority); - - [XmlRpcMethod("d.directory.set")] - int SetDirectory(string hash, string directory); - - [XmlRpcMethod("method.set_key")] - int SetKey(string target, string key, string cmd_key, string value); - [XmlRpcMethod("d.name")] string GetName(string hash); [XmlRpcMethod("system.client_version")] string GetVersion(); - - [XmlRpcMethod("system.multicall")] - object[] SystemMulticall(object[] parameters); } public class RTorrentProxy : IRTorrentProxy @@ -101,20 +81,20 @@ namespace NzbDrone.Core.Download.Clients.RTorrent var items = new List(); foreach (object[] torrent in ret) { - var labelDecoded = System.Web.HttpUtility.UrlDecode((string) torrent[3]); + var labelDecoded = System.Web.HttpUtility.UrlDecode((string)torrent[3]); var item = new RTorrentTorrent(); - item.Name = (string) torrent[0]; - item.Hash = (string) torrent[1]; - item.Path = (string) torrent[2]; + item.Name = (string)torrent[0]; + item.Hash = (string)torrent[1]; + item.Path = (string)torrent[2]; item.Category = labelDecoded; - 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]); + 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); } @@ -122,26 +102,26 @@ namespace NzbDrone.Core.Download.Clients.RTorrent return items; } - public void AddTorrentFromUrl(string torrentUrl, RTorrentSettings settings) + public void AddTorrentFromUrl(string torrentUrl, string label, RTorrentPriority priority, string directory, RTorrentSettings settings) { _logger.Debug("Executing remote method: load.normal"); var client = BuildClient(settings); - var response = client.LoadUrl("", torrentUrl); + var response = client.LoadStart("", torrentUrl, GetCommands(label, priority, directory)); if (response != 0) { throw new DownloadClientException("Could not add torrent: {0}.", torrentUrl); } } - public void AddTorrentFromFile(string fileName, byte[] fileContent, RTorrentSettings settings) + public void AddTorrentFromFile(string fileName, byte[] fileContent, string label, RTorrentPriority priority, string directory, RTorrentSettings settings) { _logger.Debug("Executing remote method: load.raw"); var client = BuildClient(settings); - var response = client.LoadBinary("", fileContent); + var response = client.LoadRawStart("", fileContent, GetCommands(label, priority, directory)); if (response != 0) { throw new DownloadClientException("Could not add torrent: {0}.", fileName); @@ -161,94 +141,26 @@ namespace NzbDrone.Core.Download.Clients.RTorrent } } - public void SetTorrentPriority(string hash, RTorrentPriority priority, RTorrentSettings settings) - { - _logger.Debug("Executing remote method: d.priority.set"); - - 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) + private string[] GetCommands(string label, RTorrentPriority priority, string directory) { - _logger.Debug("Executing remote method: d.custom1.set"); - - var labelEncoded = System.Web.HttpUtility.UrlEncode(label); - - var client = BuildClient(settings); + var result = new List(); - var setLabel = client.SetLabel(hash, labelEncoded); - if (setLabel != labelEncoded) + if (label.IsNotNullOrWhiteSpace()) { - throw new DownloadClientException("Could set label on torrent: {0}.", hash); + result.Add("d.custom1.set=" + label); } - } - - 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 void SetDeferredMagnetProperties(string hash, string category, string directory, RTorrentPriority priority, RTorrentSettings settings) - { - var commands = new List(); - - if (category.IsNotNullOrWhiteSpace()) + if (priority != RTorrentPriority.Normal) { - commands.Add("d.custom1.set=" + category); + result.Add("d.priority.set=" + (int)priority); } if (directory.IsNotNullOrWhiteSpace()) { - commands.Add("d.directory.set=" + directory); + result.Add("d.directory.set=" + directory); } - if (priority != RTorrentPriority.Normal) - { - commands.Add("d.priority.set=" + (long)priority); - } - - // Ensure it gets started if the user doesn't have schedule=...,start_tied= - commands.Add("d.open="); - commands.Add("d.start="); - - if (commands.Any()) - { - var key = "event.download.inserted_new"; - var cmd_key = "sonarr_deferred_" + hash; - - commands.Add(string.Format("print=\"Applying deferred properties to {0}\"", hash)); - - // Remove event handler once triggered. - commands.Add(string.Format("\"method.set_key={0},{1}\"", key, cmd_key)); - - var setKeyValue = string.Format("branch=\"equal=d.hash=,cat={0}\",{{{1}}}", hash, string.Join(",", commands)); - - _logger.Debug("Executing remote method: method.set_key = {0},{1},{2}", key, cmd_key, setKeyValue); - - var client = BuildClient(settings); - - // Commands need a target, in this case the target is an empty string - // See: https://github.com/rakshasa/rtorrent/issues/227 - var response = client.SetKey("", key, cmd_key, setKeyValue); - if (response != 0) - { - throw new DownloadClientException("Could set properties for torrent: {0}.", hash); - } - } + return result.ToArray(); } public bool HasHashTorrent(string hash, RTorrentSettings settings) @@ -270,32 +182,6 @@ namespace NzbDrone.Core.Download.Clients.RTorrent } } - 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)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(); @@ -316,4 +202,4 @@ namespace NzbDrone.Core.Download.Clients.RTorrent return client; } } -} +} \ No newline at end of file diff --git a/src/NzbDrone.Core/Indexers/PassThePopcorn/PassThePopcornParser.cs b/src/NzbDrone.Core/Indexers/PassThePopcorn/PassThePopcornParser.cs index 3866400f0..03a20e493 100644 --- a/src/NzbDrone.Core/Indexers/PassThePopcorn/PassThePopcornParser.cs +++ b/src/NzbDrone.Core/Indexers/PassThePopcorn/PassThePopcornParser.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Net; using Newtonsoft.Json; using NzbDrone.Common.Http; @@ -41,8 +41,8 @@ namespace NzbDrone.Core.Indexers.PassThePopcorn } var jsonResponse = JsonConvert.DeserializeObject(indexerResponse.Content); - if (jsonResponse.TotalResults == "0" || - jsonResponse.TotalResults.IsNullOrWhiteSpace() || + if (jsonResponse.TotalResults == "0" || + jsonResponse.TotalResults.IsNullOrWhiteSpace() || jsonResponse.Movies == null) { throw new IndexerException(indexerResponse, "No results were found"); @@ -51,30 +51,20 @@ namespace NzbDrone.Core.Indexers.PassThePopcorn foreach (var result in jsonResponse.Movies) { - foreach (var torrent in result.Torrents) - { - var id = torrent.Id; - var title = torrent.ReleaseName; - - if (torrent.GoldenPopcorn) - { - title = $"{title} 🍿"; - } - - if (torrent.Checked) - { - title = $"{title} ✔"; - } - - var imdbId = 0; - - int.TryParse(result.ImdbId, out imdbId); + foreach (var torrent in result.Torrents) + { + var id = torrent.Id; + var title = torrent.ReleaseName; - if (imdbId == 0 && result.ImdbId.Substring(0, 2) == "tt") - { - int.TryParse(result.ImdbId.Substring(2), out imdbId); - } + if (torrent.GoldenPopcorn) + { + title = $"{title} 🍿"; + } + if (torrent.Checked) + { + title = $"{title} ✔"; + } // Only add approved torrents if (_settings.RequireApproved && torrent.Checked) @@ -92,7 +82,7 @@ namespace NzbDrone.Core.Indexers.PassThePopcorn Golden = torrent.GoldenPopcorn, Scene = torrent.Scene, Approved = torrent.Checked, - ImdbId = imdbId + ImdbId = (result.ImdbId.IsNotNullOrWhiteSpace() ? int.Parse(result.ImdbId) : 0) }); } // Add all torrents @@ -111,7 +101,7 @@ namespace NzbDrone.Core.Indexers.PassThePopcorn Golden = torrent.GoldenPopcorn, Scene = torrent.Scene, Approved = torrent.Checked, - ImdbId = imdbId + ImdbId = (result.ImdbId.IsNotNullOrWhiteSpace() ? int.Parse(result.ImdbId) : 0) }); } // Don't add any torrents @@ -130,10 +120,10 @@ namespace NzbDrone.Core.Indexers.PassThePopcorn return torrentInfos.OrderByDescending(o => o.PublishDate) .ThenBy(o => ((dynamic)o).Golden ? 0 : 1) - .ThenBy(o => ((dynamic) o).Scene ? 0 : 1) + .ThenBy(o => ((dynamic)o).Scene ? 0 : 1) .ToArray(); } - return + return torrentInfos.OrderByDescending(o => o.PublishDate) .ThenBy(o => ((dynamic)o).Golden ? 0 : 1) .ToArray(); @@ -142,14 +132,14 @@ namespace NzbDrone.Core.Indexers.PassThePopcorn // prefer scene if (_settings.Scene) { - return + return torrentInfos.OrderByDescending(o => o.PublishDate) .ThenBy(o => ((dynamic)o).Scene ? 0 : 1) .ToArray(); } // order by date - return + return torrentInfos .OrderByDescending(o => o.PublishDate) .ToArray();