diff --git a/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrent.cs b/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrent.cs index e49aa064f..5c3f1c4b4 100644 --- a/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrent.cs +++ b/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrent.cs @@ -41,26 +41,30 @@ protected override string AddFromMagnetLink(RemoteEpisode remoteEpisode, string { _proxy.AddTorrentFromUrl(magnetLink, Settings); + // Download the magnet to the appropriate directory. + _proxy.SetTorrentLabel(hash, Settings.TvCategory, Settings); + SetPriority(remoteEpisode, hash); + SetDownloadDirectory(hash); + + // Once the magnet meta download finishes, rTorrent replaces it with the actual torrent download with default settings. + // Schedule an event to apply the appropriate settings when that happens. + var priority = (RTorrentPriority)(remoteEpisode.IsRecentEpisode() ? Settings.RecentTvPriority : Settings.OlderTvPriority); + _proxy.SetDeferredMagnetProperties(hash, Settings.TvCategory, Settings.TvDirectory, priority, Settings); + + _proxy.StartTorrent(hash, Settings); + + // Wait for the magnet to be resolved. var tries = 10; var retryDelay = 500; if (WaitForTorrent(hash, tries, retryDelay)) { - _proxy.SetTorrentLabel(hash, Settings.TvCategory, Settings); - - SetPriority(remoteEpisode, hash); - SetDownloadDirectory(hash); - - _proxy.StartTorrent(hash, Settings); - return hash; } else { - _logger.Debug("rTorrent could not resolve magnet {0}. Removing", magnetLink); + _logger.Warn("rTorrent could not resolve magnet within {0} seconds, download may remain stuck: {1}.", tries * retryDelay / 1000, magnetLink); - RemoveItem(hash, true); - - return null; + return hash; } } diff --git a/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrentProxy.cs b/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrentProxy.cs index b90fdb47f..c1f915ff8 100644 --- a/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrentProxy.cs +++ b/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrentProxy.cs @@ -21,6 +21,7 @@ public interface IRTorrentProxy 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 @@ -46,6 +47,9 @@ public interface IRTorrent : IXmlRpcProxy [XmlRpcMethod("d.directory.set")] int SetDirectory(string hash, string directory); + [XmlRpcMethod("system.method.set_key")] + int SetKey(string key, string cmd_key, string value); + [XmlRpcMethod("d.name")] string GetName(string hash); @@ -198,6 +202,49 @@ public void SetTorrentDownloadDirectory(string hash, string directory, RTorrentS } } + public void SetDeferredMagnetProperties(string hash, string category, string directory, RTorrentPriority priority, RTorrentSettings settings) + { + var commands = new List(); + + if (category.IsNotNullOrWhiteSpace()) + { + commands.Add("d.set_custom1=" + category); + } + + if (directory.IsNotNullOrWhiteSpace()) + { + commands.Add("d.set_directory=" + directory); + } + + if (priority != RTorrentPriority.Normal) + { + commands.Add("d.set_priority=" + (long)priority); + } + + if (commands.Any()) + { + var key = "event.download.inserted"; + 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("\"system.method.set_key={0},{1}\"", key, cmd_key)); + + var setKeyValue = string.Format("branch=\"equal=d.get_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); + + var response = client.SetKey(key, cmd_key, setKeyValue); + if (response != 0) + { + throw new DownloadClientException("Could set properties for torrent: {0}.", hash); + } + } + } + public bool HasHashTorrent(string hash, RTorrentSettings settings) { _logger.Debug("Executing remote method: d.name");