예제 #1
0
        private XDocument ExecuteRequest(RTorrentSettings settings, string methodName, params object[] args)
        {
            var requestBuilder = new XmlRpcRequestBuilder(settings.UseSsl, settings.Host, settings.Port, settings.UrlBase)
            {
                LogResponseContent = true,
            };

            if (!settings.Username.IsNullOrWhiteSpace())
            {
                requestBuilder.NetworkCredential = new NetworkCredential(settings.Username, settings.Password);
            }

            var request = requestBuilder.Call(methodName, args).Build();

            var response = _httpClient.Execute(request);

            var doc = XDocument.Parse(response.Content);

            var faultElement = doc.XPathSelectElement("./methodResponse/fault");

            if (faultElement != null)
            {
                var fault = new RTorrentFault(faultElement);

                throw new DownloadClientException($"rTorrent returned error code {fault.FaultCode}: {fault.FaultString}");
            }

            return(doc);
        }
예제 #2
0
        public List <RTorrentTorrent> GetTorrents(RTorrentSettings settings)
        {
            var document = ExecuteRequest(settings,
                                          "d.multicall2",
                                          "",
                                          "",
                                          "d.name=",                // string
                                          "d.hash=",                // string
                                          "d.base_path=",           // string
                                          "d.custom1=",             // string (label)
                                          "d.size_bytes=",          // long
                                          "d.left_bytes=",          // long
                                          "d.down.rate=",           // long (in bytes / s)
                                          "d.ratio=",               // long
                                          "d.is_open=",             // long
                                          "d.is_active=",           // long
                                          "d.complete=",            //long
                                          "d.timestamp.finished="); // long (unix timestamp)

            var torrents = document.XPathSelectElement("./methodResponse/params/param/value/array/data")
                           ?.Elements()
                           .Select(x => new RTorrentTorrent(x))
                           .ToList()
                           ?? new List <RTorrentTorrent>();

            return(torrents);
        }
예제 #3
0
        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 <int>)c));

            if (multicallResponse.Any(r => r != 0))
            {
                throw new DownloadClientException("Could not start torrent: {0}.", hash);
            }
        }
예제 #4
0
        public void PushTorrentUniqueView(string hash, string view, RTorrentSettings settings)
        {
            var response = ExecuteRequest(settings, "d.views.push_back_unique", hash, view);

            if (response.GetIntResponse() != 0)
            {
                throw new DownloadClientException("Could not push unique view {0} for torrent: {1}.", view, hash);
            }
        }
예제 #5
0
        public string GetVersion(RTorrentSettings settings)
        {
            _logger.Debug("Executing remote method: system.client_version");

            var client  = BuildClient(settings);
            var version = ExecuteRequest(() => client.GetVersion());

            return(version);
        }
예제 #6
0
        public void RemoveTorrent(string hash, RTorrentSettings settings)
        {
            var response = ExecuteRequest(settings, "d.erase", hash);

            if (response.GetIntResponse() != 0)
            {
                throw new DownloadClientException("Could not remove torrent: {0}.", hash);
            }
        }
예제 #7
0
        public void SetTorrentLabel(string hash, string label, RTorrentSettings settings)
        {
            var response = ExecuteRequest(settings, "d.custom1.set", hash, label);

            if (response.GetStringResponse() != label)
            {
                throw new DownloadClientException("Could not set label to {1} for torrent: {0}.", hash, label);
            }
        }
예제 #8
0
        public void PushTorrentUniqueView(string hash, string view, RTorrentSettings settings)
        {
            _logger.Debug("Executing remote method: d.views.push_back_unique");

            var client   = BuildClient(settings);
            var response = ExecuteRequest(() => client.PushUniqueView(hash, view));

            if (response != 0)
            {
                throw new DownloadClientException("Could not push unique view {0} for torrent: {1}.", view, hash);
            }
        }
예제 #9
0
        public void RemoveTorrent(string hash, RTorrentSettings settings)
        {
            _logger.Debug("Executing remote method: d.erase");

            var client   = BuildClient(settings);
            var response = ExecuteRequest(() => client.Remove(hash));

            if (response != 0)
            {
                throw new DownloadClientException("Could not remove torrent: {0}.", hash);
            }
        }
예제 #10
0
        public void SetTorrentLabel(string hash, string label, RTorrentSettings settings)
        {
            _logger.Debug("Executing remote method: d.custom1.set");

            var client   = BuildClient(settings);
            var response = ExecuteRequest(() => client.SetLabel(hash, label));

            if (response != label)
            {
                throw new DownloadClientException("Could not set label to {1} for torrent: {0}.", hash, label);
            }
        }
예제 #11
0
        public void SetTorrentLabel(string hash, string label, RTorrentSettings settings)
        {
            _logger.Debug("Executing remote method: d.set_custom1");

            var client = BuildClient(settings);

            var setLabel = client.SetLabel(hash, label);

            if (setLabel != label)
            {
                throw new DownloadClientException("Could set label on torrent: {0}.", hash);
            }
        }
예제 #12
0
        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);
            }
        }
예제 #13
0
        public void AddTorrentFromFile(string fileName, byte[] fileContent, RTorrentSettings settings)
        {
            _logger.Debug("Executing remote method: load.raw");

            var client = BuildClient(settings);

            var response = client.LoadBinary("", fileContent);

            if (response != 0)
            {
                throw new DownloadClientException("Could not add torrent: {0}.", fileName);
            }
        }
예제 #14
0
        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);
            }
        }
예제 #15
0
        public void AddTorrentFromUrl(string torrentUrl, RTorrentSettings settings)
        {
            _logger.Debug("Executing remote method: load.normal");

            var client = BuildClient(settings);

            var response = client.LoadUrl("", torrentUrl);

            if (response != 0)
            {
                throw new DownloadClientException("Could not add torrent: {0}.", torrentUrl);
            }
        }
예제 #16
0
        public void SetTorrentLabel(string hash, string label, RTorrentSettings settings)
        {
            _logger.Debug("Executing remote method: d.custom1.set");

            var labelEncoded = System.Web.HttpUtility.UrlEncode(label);

            var client = BuildClient(settings);

            var setLabel = client.SetLabel(hash, labelEncoded);

            if (setLabel != labelEncoded)
            {
                throw new DownloadClientException("Could set label on torrent: {0}.", hash);
            }
        }
예제 #17
0
        public List <RTorrentTorrent> GetTorrents(RTorrentSettings settings)
        {
            _logger.Debug("Executing remote method: d.multicall2");

            var client = BuildClient(settings);
            var ret    = ExecuteRequest(() => client.TorrentMulticall(
                                            "",
                                            "",
                                            "d.name=",                 // string
                                            "d.hash=",                 // string
                                            "d.base_path=",            // string
                                            "d.custom1=",              // string (label)
                                            "d.size_bytes=",           // long
                                            "d.left_bytes=",           // long
                                            "d.down.rate=",            // long (in bytes / s)
                                            "d.ratio=",                // long
                                            "d.is_open=",              // long
                                            "d.is_active=",            // long
                                            "d.complete=",             //long
                                            "d.timestamp.finished=")); // long (unix timestamp)

            _logger.Trace(ret.ToJson());

            var items = new List <RTorrentTorrent>();

            foreach (object[] torrent in ret)
            {
                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.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.FinishedTime  = (long)torrent[11];

                items.Add(item);
            }

            return(items);
        }
예제 #18
0
        private IRTorrent BuildClient(RTorrentSettings settings)
        {
            var client = XmlRpcProxyGen.Create <IRTorrent>();

            client.Url = string.Format(@"{0}://{1}:{2}/{3}",
                                       settings.UseSsl ? "https" : "http",
                                       settings.Host,
                                       settings.Port,
                                       settings.UrlBase);

            client.EnableCompression = true;

            if (!settings.Username.IsNullOrWhiteSpace())
            {
                client.Credentials = new NetworkCredential(settings.Username, settings.Password);
            }

            return(client);
        }
예제 #19
0
        public bool HasHashTorrent(string hash, RTorrentSettings settings)
        {
            _logger.Debug("Executing remote method: d.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);
            }
        }
예제 #20
0
        public bool HasHashTorrent(string hash, RTorrentSettings settings)
        {
            try
            {
                var response = ExecuteRequest(settings, "d.name", hash);
                var name     = response.GetStringResponse();

                if (name.IsNullOrWhiteSpace())
                {
                    return(false);
                }

                var metaTorrent = name == (hash + ".meta");

                return(!metaTorrent);
            }
            catch (Exception)
            {
                return(false);
            }
        }
예제 #21
0
        public List <RTorrentTorrent> GetTorrents(RTorrentSettings settings)
        {
            _logger.Debug("Executing remote method: d.multicall2");

            var client = BuildClient(settings);
            var ret    = client.TorrentMulticall("", "",
                                                 "d.name=",       // string
                                                 "d.hash=",       // string
                                                 "d.base_path=",  // string
                                                 "d.custom1=",    // string (label)
                                                 "d.size_bytes=", // long
                                                 "d.left_bytes=", // long
                                                 "d.down.rate=",  // long (in bytes / s)
                                                 "d.ratio=",      // long
                                                 "d.is_open=",    // long
                                                 "d.is_active=",  // long
                                                 "d.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);
        }
예제 #22
0
        public void SetDeferredMagnetProperties(string hash, string category, string directory, RTorrentPriority priority, RTorrentSettings settings)
        {
            var commands = new List <string>();

            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);
            }

            // 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("\"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);
                }
            }
        }
예제 #23
0
        public void AddTorrentFromUrl(string torrentUrl, string label, RTorrentPriority priority, string directory, bool doNotStart, RTorrentSettings settings)
        {
            _logger.Debug("Adding Torrent From URL");

            var client = BuildClient(settings);

            var response = -1;

            if (doNotStart)
            {
                _logger.Debug("Executing remote method load.normal");
                response = client.Load("", torrentUrl, GetCommands(label, priority, directory));
            }
            else
            {
                _logger.Debug("Executing remote method load.start");
                response = client.LoadStart("", torrentUrl, GetCommands(label, priority, directory));
            }

            if (response != 0)
            {
                throw new DownloadClientException("Could not add torrent: {0}.", torrentUrl);
            }
        }
예제 #24
0
        public void AddTorrentFromUrl(string torrentUrl, string label, RTorrentPriority priority, string directory, RTorrentSettings settings)
        {
            var args = new List <object> {
                "", torrentUrl
            };

            args.AddRange(GetCommands(label, priority, directory));

            XDocument response;

            if (settings.AddStopped)
            {
                response = ExecuteRequest(settings, "load.normal", args.ToArray());
            }
            else
            {
                response = ExecuteRequest(settings, "load.start", args.ToArray());
            }

            if (response.GetIntResponse() != 0)
            {
                throw new DownloadClientException("Could not add torrent: {0}.", torrentUrl);
            }
        }
예제 #25
0
        public void AddTorrentFromFile(string fileName, byte[] fileContent, string label, RTorrentPriority priority, string directory, RTorrentSettings settings)
        {
            var client   = BuildClient(settings);
            var response = ExecuteRequest(() =>
            {
                if (settings.AddStopped)
                {
                    _logger.Debug("Executing remote method: load.raw");
                    return(client.LoadRaw("", fileContent, GetCommands(label, priority, directory)));
                }
                else
                {
                    _logger.Debug("Executing remote method: load.raw_start");
                    return(client.LoadRawStart("", fileContent, GetCommands(label, priority, directory)));
                }
            });

            if (response != 0)
            {
                throw new DownloadClientException("Could not add torrent: {0}.", fileName);
            }
        }
예제 #26
0
        public void AddTorrentFromUrl(string torrentUrl, string label, RTorrentPriority priority, string directory, RTorrentSettings settings)
        {
            var client   = BuildClient(settings);
            var response = ExecuteRequest(() =>
            {
                if (settings.AddStopped)
                {
                    _logger.Debug("Executing remote method: load.normal");
                    return(client.LoadNormal("", torrentUrl, GetCommands(label, priority, directory)));
                }
                else
                {
                    _logger.Debug("Executing remote method: load.start");
                    return(client.LoadStart("", torrentUrl, GetCommands(label, priority, directory)));
                }
            });

            if (response != 0)
            {
                throw new DownloadClientException("Could not add torrent: {0}.", torrentUrl);
            }
        }
예제 #27
0
        public void AddTorrentFromFile(string fileName, byte[] fileContent, string label, RTorrentPriority priority, string directory, RTorrentSettings settings)
        {
            var args = new List <object> {
                "", fileContent
            };

            args.AddRange(GetCommands(label, priority, directory));

            XDocument response;

            if (settings.AddStopped)
            {
                response = ExecuteRequest(settings, "load.raw", args.ToArray());
            }
            else
            {
                response = ExecuteRequest(settings, "load.raw_start", args.ToArray());
            }

            if (response.GetIntResponse() != 0)
            {
                throw new DownloadClientException("Could not add torrent: {0}.", fileName);
            }
        }
예제 #28
0
        public string GetVersion(RTorrentSettings settings)
        {
            var document = ExecuteRequest(settings, "system.client_version");

            return(document.Descendants("string").FirstOrDefault()?.Value ?? "0.0.0");
        }
예제 #29
0
        public void AddTorrentFromFile(string fileName, byte[] fileContent, string label, RTorrentPriority priority, string directory, bool doNotStart, RTorrentSettings settings)
        {
            _logger.Debug("Loading Torrent from File");

            var client = BuildClient(settings);

            var response = -1;

            if (doNotStart)
            {
                _logger.Debug("Executing remote method load.raw");
                response = client.LoadRaw("", fileContent, GetCommands(label, priority, directory));
            }
            else
            {
                _logger.Debug("Executing remote method load.raw_start");
                response = client.LoadRawStart("", fileContent, GetCommands(label, priority, directory));
            }

            if (response != 0)
            {
                throw new DownloadClientException("Could not add torrent: {0}.", fileName);
            }
        }