From 7c6e08c5c0e7c403bc34dc1eb0f42e28f0f46bdd Mon Sep 17 00:00:00 2001 From: Rafael Calafell Cladera <rafaelillopalma@hotmail.com> Date: Tue, 29 Oct 2024 07:33:19 +0100 Subject: [PATCH 1/5] NEW! Add ListConfigs() - Model - Call - Test - Readme --- DelugeRPCClient.Net.Tests/ConfigTests.cs | 29 +++ DelugeRPCClient.Net/DelugeClient.cs | 13 + DelugeRPCClient.Net/Models/Config.cs | 287 +++++++++++++++++++++++ README.md | 7 + 4 files changed, 336 insertions(+) create mode 100644 DelugeRPCClient.Net.Tests/ConfigTests.cs create mode 100644 DelugeRPCClient.Net/Models/Config.cs diff --git a/DelugeRPCClient.Net.Tests/ConfigTests.cs b/DelugeRPCClient.Net.Tests/ConfigTests.cs new file mode 100644 index 0000000..3b3ef30 --- /dev/null +++ b/DelugeRPCClient.Net.Tests/ConfigTests.cs @@ -0,0 +1,29 @@ +using DelugeRPCClient.Net.Models; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace DelugeRPCClient.Net.Tests +{ + [TestClass] + public class ConfigTests + { + [TestMethod] + public async Task ListConfigs() + { + DelugeClient client = new DelugeClient(url: Constants.DelugeUrl, password: Constants.DelugePassword); + + bool loginResult = await client.Login(); + Assert.IsTrue(loginResult); + + Config configs = await client.ListConfigs(); + Assert.IsNotNull(configs); + + bool logoutResult = await client.Logout(); + Assert.IsTrue(logoutResult); + } + } +} diff --git a/DelugeRPCClient.Net/DelugeClient.cs b/DelugeRPCClient.Net/DelugeClient.cs index 5fe09c8..2a923a6 100644 --- a/DelugeRPCClient.Net/DelugeClient.cs +++ b/DelugeRPCClient.Net/DelugeClient.cs @@ -151,6 +151,19 @@ public async Task<bool> ResumeTorrent(string hash) #endregion + #region Config + + /// <summary> + /// List all existing labels + /// </summary> + /// <returns>list of labels</returns> + public async Task<Config> ListConfigs() + { + return await SendRequest<Config>("core.get_config"); + } + + #endregion + #region Labels /// <summary> diff --git a/DelugeRPCClient.Net/Models/Config.cs b/DelugeRPCClient.Net/Models/Config.cs new file mode 100644 index 0000000..e95a34e --- /dev/null +++ b/DelugeRPCClient.Net/Models/Config.cs @@ -0,0 +1,287 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; + +namespace DelugeRPCClient.Net.Models +{ + public class Config + { + [JsonProperty(PropertyName = "send_info")] + public bool SendInfo { get; set; } + + [JsonProperty(PropertyName = "info_sent")] + public double InfoSent { get; set; } + + [JsonProperty(PropertyName = "daemon_port")] + public int DaemonPort { get; set; } + + [JsonProperty(PropertyName = "allow_remote")] + public bool AllowRemote { get; set; } + + [JsonProperty(PropertyName = "pre_allocate_storage")] + public bool PreAllocateStorage { get; set; } + + [JsonProperty(PropertyName = "download_location")] + public string DownloadLocation { get; set; } + + [JsonProperty(PropertyName = "listen_ports")] + public List<int> ListenPorts { get; set; } + + [JsonProperty(PropertyName = "listen_interface")] + public string ListenInterface { get; set; } + + [JsonProperty(PropertyName = "outgoing_interface")] + public string OutgoingInterface { get; set; } + + [JsonProperty(PropertyName = "random_port")] + public bool RandomPort { get; set; } + + [JsonProperty(PropertyName = "listen_random_port")] + public int ListenRandomPort { get; set; } + + [JsonProperty(PropertyName = "listen_use_sys_port")] + public bool ListenUseSysPort { get; set; } + + [JsonProperty(PropertyName = "listen_reuse_port")] + public bool ListenReusePort { get; set; } + + [JsonProperty(PropertyName = "outgoing_ports")] + public List<int> OutgoingPorts { get; set; } + + [JsonProperty(PropertyName = "random_outgoing_ports")] + public bool RandomOutgoingPorts { get; set; } + + [JsonProperty(PropertyName = "copy_torrent_file")] + public bool CopyTorrentFile { get; set; } + + [JsonProperty(PropertyName = "del_copy_torrent_file")] + public bool DelCopyTorrentFile { get; set; } + + [JsonProperty(PropertyName = "torrentfiles_location")] + public string TorrentFilesLocation { get; set; } + + [JsonProperty(PropertyName = "plugins_location")] + public string PluginsLocation { get; set; } + + [JsonProperty(PropertyName = "prioritize_first_last_pieces")] + public bool PrioritizeFirstLastPieces { get; set; } + + [JsonProperty(PropertyName = "sequential_download")] + public bool SequentialDownload { get; set; } + + [JsonProperty(PropertyName = "dht")] + public bool DHT { get; set; } + + [JsonProperty(PropertyName = "upnp")] + public bool UPnP { get; set; } + + [JsonProperty(PropertyName = "natpmp")] + public bool NATPMP { get; set; } + + [JsonProperty(PropertyName = "utpex")] + public bool UTPEx { get; set; } + + [JsonProperty(PropertyName = "lsd")] + public bool LSD { get; set; } + + [JsonProperty(PropertyName = "enc_in_policy")] + public int EncInPolicy { get; set; } + + [JsonProperty(PropertyName = "enc_out_policy")] + public int EncOutPolicy { get; set; } + + [JsonProperty(PropertyName = "enc_level")] + public int EncLevel { get; set; } + + [JsonProperty(PropertyName = "max_connections_global")] + public int MaxConnectionsGlobal { get; set; } + + [JsonProperty(PropertyName = "max_upload_speed")] + public double MaxUploadSpeed { get; set; } + + [JsonProperty(PropertyName = "max_download_speed")] + public double MaxDownloadSpeed { get; set; } + + [JsonProperty(PropertyName = "max_upload_slots_global")] + public int MaxUploadSlotsGlobal { get; set; } + + [JsonProperty(PropertyName = "max_half_open_connections")] + public int MaxHalfOpenConnections { get; set; } + + [JsonProperty(PropertyName = "max_connections_per_second")] + public int MaxConnectionsPerSecond { get; set; } + + [JsonProperty(PropertyName = "ignore_limits_on_local_network")] + public bool IgnoreLimitsOnLocalNetwork { get; set; } + + [JsonProperty(PropertyName = "max_connections_per_torrent")] + public int MaxConnectionsPerTorrent { get; set; } + + [JsonProperty(PropertyName = "max_upload_slots_per_torrent")] + public int MaxUploadSlotsPerTorrent { get; set; } + + [JsonProperty(PropertyName = "max_upload_speed_per_torrent")] + public double MaxUploadSpeedPerTorrent { get; set; } + + [JsonProperty(PropertyName = "max_download_speed_per_torrent")] + public double MaxDownloadSpeedPerTorrent { get; set; } + + [JsonProperty(PropertyName = "enabled_plugins")] + public List<string> EnabledPlugins { get; set; } + + [JsonProperty(PropertyName = "add_paused")] + public bool AddPaused { get; set; } + + [JsonProperty(PropertyName = "max_active_seeding")] + public int MaxActiveSeeding { get; set; } + + [JsonProperty(PropertyName = "max_active_downloading")] + public int MaxActiveDownloading { get; set; } + + [JsonProperty(PropertyName = "max_active_limit")] + public int MaxActiveLimit { get; set; } + + [JsonProperty(PropertyName = "dont_count_slow_torrents")] + public bool DontCountSlowTorrents { get; set; } + + [JsonProperty(PropertyName = "queue_new_to_top")] + public bool QueueNewToTop { get; set; } + + [JsonProperty(PropertyName = "stop_seed_at_ratio")] + public bool StopSeedAtRatio { get; set; } + + [JsonProperty(PropertyName = "remove_seed_at_ratio")] + public bool RemoveSeedAtRatio { get; set; } + + [JsonProperty(PropertyName = "stop_seed_ratio")] + public double StopSeedRatio { get; set; } + + [JsonProperty(PropertyName = "share_ratio_limit")] + public double ShareRatioLimit { get; set; } + + [JsonProperty(PropertyName = "seed_time_ratio_limit")] + public double SeedTimeRatioLimit { get; set; } + + [JsonProperty(PropertyName = "seed_time_limit")] + public int SeedTimeLimit { get; set; } + + [JsonProperty(PropertyName = "auto_managed")] + public bool AutoManaged { get; set; } + + [JsonProperty(PropertyName = "move_completed")] + public bool MoveCompleted { get; set; } + + [JsonProperty(PropertyName = "move_completed_path")] + public string MoveCompletedPath { get; set; } + + [JsonProperty(PropertyName = "move_completed_paths_list")] + public List<string> MoveCompletedPathsList { get; set; } + + [JsonProperty(PropertyName = "download_location_paths_list")] + public List<string> DownloadLocationPathsList { get; set; } + + [JsonProperty(PropertyName = "path_chooser_show_chooser_button_on_localhost")] + public bool PathChooserShowChooserButtonOnLocalhost { get; set; } + + [JsonProperty(PropertyName = "path_chooser_auto_complete_enabled")] + public bool PathChooserAutoCompleteEnabled { get; set; } + + [JsonProperty(PropertyName = "path_chooser_accelerator_string")] + public string PathChooserAcceleratorString { get; set; } + + [JsonProperty(PropertyName = "path_chooser_max_popup_rows")] + public int PathChooserMaxPopupRows { get; set; } + + [JsonProperty(PropertyName = "path_chooser_show_hidden_files")] + public bool PathChooserShowHiddenFiles { get; set; } + + [JsonProperty(PropertyName = "new_release_check")] + public bool NewReleaseCheck { get; set; } + + [JsonProperty(PropertyName = "proxy")] + public ProxyConfig Proxy { get; set; } + + [JsonProperty(PropertyName = "peer_tos")] + public string PeerTos { get; set; } + + [JsonProperty(PropertyName = "rate_limit_ip_overhead")] + public bool RateLimitIpOverhead { get; set; } + + [JsonProperty(PropertyName = "geoip_db_location")] + public string GeoIpDbLocation { get; set; } + + [JsonProperty(PropertyName = "cache_size")] + public int CacheSize { get; set; } + + [JsonProperty(PropertyName = "cache_expiry")] + public int CacheExpiry { get; set; } + + [JsonProperty(PropertyName = "auto_manage_prefer_seeds")] + public bool AutoManagePreferSeeds { get; set; } + + [JsonProperty(PropertyName = "shared")] + public bool Shared { get; set; } + + [JsonProperty(PropertyName = "super_seeding")] + public bool SuperSeeding { get; set; } + + public bool ExistProperty(string propertyName) + { + PropertyInfo property = typeof(Config).GetProperty(propertyName); + + if (property != null) + { + return true; + } + + return false; + } + + public string GetPropertyValue(string propertyName) + { + PropertyInfo property = typeof(Config).GetProperty(propertyName); + + if (property != null) + { + return property.GetValue(this)?.ToString(); + } + + return null; + } + } + + public class ProxyConfig + { + [JsonProperty(PropertyName = "type")] + public int Type { get; set; } + + [JsonProperty(PropertyName = "hostname")] + public string Hostname { get; set; } + + [JsonProperty(PropertyName = "username")] + public string Username { get; set; } + + [JsonProperty(PropertyName = "password")] + public string Password { get; set; } + + [JsonProperty(PropertyName = "port")] + public int Port { get; set; } + + [JsonProperty(PropertyName = "proxy_hostnames")] + public bool ProxyHostnames { get; set; } + + [JsonProperty(PropertyName = "proxy_peer_connections")] + public bool ProxyPeerConnections { get; set; } + + [JsonProperty(PropertyName = "proxy_tracker_connections")] + public bool ProxyTrackerConnections { get; set; } + + [JsonProperty(PropertyName = "force_proxy")] + public bool ForceProxy { get; set; } + + [JsonProperty(PropertyName = "anonymous_mode")] + public bool AnonymousMode { get; set; } + } +} \ No newline at end of file diff --git a/README.md b/README.md index e6497b6..b9439eb 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,13 @@ Resume Torrent bool resumeResult = await client.ResumeTorrent(torrentHash); ``` +## Configs + +#### List configs +```C# +List<Config> config = await client.ListConfigs(); +``` + ## Labels #### List existing labels From 50f63d3c27ad3996fff7761d5f939f839ca8545d Mon Sep 17 00:00:00 2001 From: Rafael Calafell Cladera <rafaelillopalma@hotmail.com> Date: Tue, 29 Oct 2024 07:41:43 +0100 Subject: [PATCH 2/5] NEW! Add RecheckTorrents() - Call - Test - Readme --- DelugeRPCClient.Net.Tests/TorrentsTests.cs | 22 ++++++++++++++++++++++ DelugeRPCClient.Net/DelugeClient.cs | 10 ++++++++++ README.md | 5 +++++ 3 files changed, 37 insertions(+) diff --git a/DelugeRPCClient.Net.Tests/TorrentsTests.cs b/DelugeRPCClient.Net.Tests/TorrentsTests.cs index 9ae9696..7bedb2a 100644 --- a/DelugeRPCClient.Net.Tests/TorrentsTests.cs +++ b/DelugeRPCClient.Net.Tests/TorrentsTests.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Reflection; using System.Text; using System.Threading; @@ -104,5 +105,26 @@ public async Task PauseResumeTorrent() bool logoutResult = await client.Logout(); Assert.IsTrue(logoutResult); } + + [TestMethod] + public async Task RecheckTorrents() + { + DelugeClient client = new DelugeClient(url: Constants.DelugeUrl, password: Constants.DelugePassword); + + bool loginResult = await client.Login(); + Assert.IsTrue(loginResult); + + List<Torrent> torrents = await client.ListTorrents(); + Assert.IsNotNull(torrents); + Assert.AreNotEqual(0, torrents.Count); + + Torrent torrent = torrents[0]; + + bool? recheckResult = await client.RecheckTorrents(torrent.Hash.Split(",").ToList()); + Assert.IsNull(recheckResult); + + bool logoutResult = await client.Logout(); + Assert.IsTrue(logoutResult); + } } } diff --git a/DelugeRPCClient.Net/DelugeClient.cs b/DelugeRPCClient.Net/DelugeClient.cs index 2a923a6..5285a2f 100644 --- a/DelugeRPCClient.Net/DelugeClient.cs +++ b/DelugeRPCClient.Net/DelugeClient.cs @@ -149,6 +149,16 @@ public async Task<bool> ResumeTorrent(string hash) return result == null; } + /// <summary> + /// Recheck torrents + /// </summary> + /// <param name="hash">Hash of the target torrents</param> + /// <returns>true if the action is successfull</returns> + public async Task<bool?> RecheckTorrents(List<string> hash) + { + return await SendRequest<bool?>("core.force_recheck", hash); + } + #endregion #region Config diff --git a/README.md b/README.md index b9439eb..f83952e 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,11 @@ Resume Torrent bool resumeResult = await client.ResumeTorrent(torrentHash); ``` +#### Recheck Torrents +```C# +bool recheckTorrentResult = await client.RecheckTorrents(List<string> torrentsHash); +``` + ## Configs #### List configs From f6e920cdaad19f373404a14a61d04b3f37b3577a Mon Sep 17 00:00:00 2001 From: Rafael Calafell Cladera <rafaelillopalma@hotmail.com> Date: Tue, 29 Oct 2024 07:45:33 +0100 Subject: [PATCH 3/5] NEW! Add AddTorrentByUrl() - DelugeResponse - Call - Test - Constants - Readme --- DelugeRPCClient.Net.Tests/Constants.cs | 1 + DelugeRPCClient.Net.Tests/TorrentsTests.cs | 20 ++++++++++++++++ DelugeRPCClient.Net/Core/DelugeResponse.cs | 7 ++++++ DelugeRPCClient.Net/DelugeClient.cs | 28 +++++++++++++++++++++- README.md | 6 +++++ 5 files changed, 61 insertions(+), 1 deletion(-) diff --git a/DelugeRPCClient.Net.Tests/Constants.cs b/DelugeRPCClient.Net.Tests/Constants.cs index 4752aa4..a411622 100644 --- a/DelugeRPCClient.Net.Tests/Constants.cs +++ b/DelugeRPCClient.Net.Tests/Constants.cs @@ -11,5 +11,6 @@ internal class Constants internal const string TestLabelName = "testlabel"; internal const string TorrentMagnet = "magnet:?xt=urn:btih:30987c19cf0eae3cf47766f387c621fa78a58ab9&dn=debian-9.2.1-amd64-netinst.iso"; internal const string TestTorrentFilename = "test.torrent"; + internal const string TestTorrentUrl = "https://archive.org/download/die_siedler_2_151/die_siedler_2_151_archive.torrent"; } } diff --git a/DelugeRPCClient.Net.Tests/TorrentsTests.cs b/DelugeRPCClient.Net.Tests/TorrentsTests.cs index 7bedb2a..8b0da9e 100644 --- a/DelugeRPCClient.Net.Tests/TorrentsTests.cs +++ b/DelugeRPCClient.Net.Tests/TorrentsTests.cs @@ -73,6 +73,26 @@ public async Task AddRemoveTorrentByFile() Assert.IsTrue(logoutResult); } + [TestMethod] + public async Task AddRemoveTorrentByUrl() + { + DelugeClient client = new DelugeClient(url: Constants.DelugeUrl, password: Constants.DelugePassword); + + bool loginResult = await client.Login(); + Assert.IsTrue(loginResult); + + Torrent torrent = await client.AddTorrentByUrl(Constants.TestTorrentUrl); + Assert.IsNotNull(torrent); + + Thread.Sleep(1000); + + bool removeTorrentResult = await client.RemoveTorrent(torrent.Hash); + Assert.IsTrue(removeTorrentResult); + + bool logoutResult = await client.Logout(); + Assert.IsTrue(logoutResult); + } + [TestMethod] public async Task PauseResumeTorrent() { diff --git a/DelugeRPCClient.Net/Core/DelugeResponse.cs b/DelugeRPCClient.Net/Core/DelugeResponse.cs index a1f6975..5282b96 100644 --- a/DelugeRPCClient.Net/Core/DelugeResponse.cs +++ b/DelugeRPCClient.Net/Core/DelugeResponse.cs @@ -16,4 +16,11 @@ internal class DelugeResponsee<T> [JsonProperty(PropertyName = "error")] public DelugeError Error { get; set; } } + + internal class ResultEntry + { + public bool Success { get; set; } + public string Hash { get; set; } + + } } diff --git a/DelugeRPCClient.Net/DelugeClient.cs b/DelugeRPCClient.Net/DelugeClient.cs index 5285a2f..9daa1c6 100644 --- a/DelugeRPCClient.Net/DelugeClient.cs +++ b/DelugeRPCClient.Net/DelugeClient.cs @@ -1,4 +1,5 @@ -using DelugeRPCClient.Net.Models; +using DelugeRPCClient.Net.Core; +using DelugeRPCClient.Net.Models; using Newtonsoft.Json; using System; using System.Collections.Generic; @@ -114,6 +115,31 @@ public async Task<Torrent> AddTorrentByFile(string file, TorrentOptions options return await GetTorrent(hash); } + /// <summary> + /// Add a new torrent by .torrent url + /// </summary> + /// <param name="file">url of the .torrent file</param> + /// <param name="options">Optional torrent options</param> + /// <returns>the torrent object</returns> + /// <exception cref="ArgumentException"></exception> + public async Task<Torrent> AddTorrentByUrl(string url, TorrentOptions options = null) + { + if (String.IsNullOrWhiteSpace(url)) throw new ArgumentException(nameof(url)); + var request = CreateRequest("web.download_torrent_from_url", url, options); + request.NullValueHandling = NullValueHandling.Ignore; + string pathTemp = await SendRequest<string>(request); + + request = CreateRequest("web.add_torrents", new object[] { new object[] { new { options = new object { }, path = pathTemp } } }); + var resultAdd = await SendRequest<List<List<Object>>>(request); + return await GetTorrent(resultAdd.Select(item => + new ResultEntry + { + Success = item[0] is bool success && success, + Hash = item[1] as string + } + ).FirstOrDefault().Hash); + } + /// <summary> /// Remove a torrent from deluge /// </summary> diff --git a/README.md b/README.md index f83952e..fc962cf 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,12 @@ Add a torrent by .torrent file ```C# Torrent torrent = await client.AddTorrentByFile(torrentFilename); ``` +``` + +Add a torrent by .torrent url +```C# +Torrent torrent = await client.AddTorrentByUrl(torrentUrl); +``` #### Remove Torrent ```C# From d80ffb6b7f0977132f8dfa77bdfdf60583d02ee4 Mon Sep 17 00:00:00 2001 From: Rafael Calafell Cladera <rafaelillopalma@hotmail.com> Date: Tue, 29 Oct 2024 19:19:44 +0100 Subject: [PATCH 4/5] NEW! Add AddTorrentByUrl() - TorrentExtended - Calls - Test - Readme --- DelugeRPCClient.Net.Tests/TorrentsTests.cs | 19 +++ DelugeRPCClient.Net/DelugeClient.cs | 24 ++++ DelugeRPCClient.Net/Models/TorrentExtended.cs | 118 ++++++++++++++++++ README.md | 11 +- 4 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 DelugeRPCClient.Net/Models/TorrentExtended.cs diff --git a/DelugeRPCClient.Net.Tests/TorrentsTests.cs b/DelugeRPCClient.Net.Tests/TorrentsTests.cs index 8b0da9e..7c65c28 100644 --- a/DelugeRPCClient.Net.Tests/TorrentsTests.cs +++ b/DelugeRPCClient.Net.Tests/TorrentsTests.cs @@ -33,6 +33,25 @@ public async Task ListAndGetTorrent() Assert.IsTrue(logoutResult); } + [TestMethod] + public async Task ListAndGetTorrentExtended() + { + DelugeClient client = new DelugeClient(url: Constants.DelugeUrl, password: Constants.DelugePassword); + + bool loginResult = await client.Login(); + Assert.IsTrue(loginResult); + + List<TorrentExtended> torrents = await client.ListTorrentsExtended(); + Assert.IsNotNull(torrents); + Assert.AreNotEqual(0, torrents.Count); + + TorrentExtended torrent = await client.GetTorrentExtended(torrents[0].Hash); + Assert.IsNotNull(torrent); + + bool logoutResult = await client.Logout(); + Assert.IsTrue(logoutResult); + } + [TestMethod] public async Task AddRemoveTorrentByMagnet() { diff --git a/DelugeRPCClient.Net/DelugeClient.cs b/DelugeRPCClient.Net/DelugeClient.cs index 9daa1c6..2d46ce7 100644 --- a/DelugeRPCClient.Net/DelugeClient.cs +++ b/DelugeRPCClient.Net/DelugeClient.cs @@ -69,6 +69,19 @@ public async Task<List<Torrent>> ListTorrents(Dictionary<string, string> filters return result.Values.ToList(); } + /// <summary> + /// List all torrents with details optionnaly filtered + /// </summary> + /// <param name="filters">optional filters</param> + /// <returns>List of torrents</returns> + public async Task<List<TorrentExtended>> ListTorrentsExtended(Dictionary<string, string> filters = null) + { + filters = filters ?? new Dictionary<string, string>(); + var keys = typeof(TorrentExtended).GetAllJsonPropertyFromType(); + Dictionary<string, TorrentExtended> result = await SendRequest<Dictionary<string, TorrentExtended>>("core.get_torrents_status", filters, keys); + return result.Values.ToList(); + } + /// <summary> /// Get torrent informations by torrent hash /// </summary> @@ -80,6 +93,17 @@ public async Task<Torrent> GetTorrent(string hash) return torrents.Count > 0 ? torrents[0] : null; } + /// <summary> + /// Get torrent informations with details by torrent hash + /// </summary> + /// <param name="hash">The requested torrent hash</param> + /// <returns>the torrent object</returns> + public async Task<TorrentExtended> GetTorrentExtended(string hash) + { + List<TorrentExtended> torrents = await ListTorrentsExtended(new Dictionary<string, string>() { { "hash", hash } }); + return torrents.Count > 0 ? torrents[0] : null; + } + /// <summary> /// Add a new torrent by magnet information /// </summary> diff --git a/DelugeRPCClient.Net/Models/TorrentExtended.cs b/DelugeRPCClient.Net/Models/TorrentExtended.cs new file mode 100644 index 0000000..4cdf591 --- /dev/null +++ b/DelugeRPCClient.Net/Models/TorrentExtended.cs @@ -0,0 +1,118 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Text; + +namespace DelugeRPCClient.Net.Models +{ + public class TorrentExtended : Torrent + { + [JsonProperty(PropertyName = "total_done")] + public long TotalDone { get; set; } + + [JsonProperty(PropertyName = "total_payload_download")] + public long TotalPayloadDownload { get; set; } + + [JsonProperty(PropertyName = "total_uploaded")] + public long TotalUploaded { get; set; } + + [JsonProperty(PropertyName = "next_announce")] + public int NextAnnounce { get; set; } + + [JsonProperty(PropertyName = "tracker_status")] + public string TrackerStatus { get; set; } + + [JsonProperty(PropertyName = "num_pieces")] + public int NumPieces { get; set; } + + [JsonProperty(PropertyName = "piece_length")] + public long PieceLength { get; set; } + + [JsonProperty(PropertyName = "is_auto_managed")] + public bool IsAutoManaged { get; set; } + + [JsonProperty(PropertyName = "active_time")] + public long ActiveTime { get; set; } + + [JsonProperty(PropertyName = "seeding_time")] + public long SeedingTime { get; set; } + + [JsonProperty(PropertyName = "time_since_transfer")] + public long TimeSinceTransfer { get; set; } + + [JsonProperty(PropertyName = "seed_rank")] + public int SeedRank { get; set; } + + [JsonProperty(PropertyName = "last_seen_complete")] + public long LastSeenComplete { get; set; } + + [JsonProperty(PropertyName = "completed_time")] + public long CompletedTime { get; set; } + + [JsonProperty(PropertyName = "owner")] + public string Owner { get; set; } + + [JsonProperty(PropertyName = "public")] + public bool Public { get; set; } + + [JsonProperty(PropertyName = "shared")] + public bool Shared { get; set; } + + [JsonProperty(PropertyName = "queue")] + public int Queue { get; set; } + + [JsonProperty(PropertyName = "total_wanted")] + public long TotalWanted { get; set; } + + [JsonProperty(PropertyName = "state")] + public string State { get; set; } + + [JsonProperty(PropertyName = "progress")] + public float Progress { get; set; } + + [JsonProperty(PropertyName = "num_seeds")] + public int NumSeeds { get; set; } + + [JsonProperty(PropertyName = "total_seeds")] + public int TotalSeeds { get; set; } + + [JsonProperty(PropertyName = "num_peers")] + public int NumPeers { get; set; } + + [JsonProperty(PropertyName = "total_peers")] + public int TotalPeers { get; set; } + + [JsonProperty(PropertyName = "download_payload_rate")] + public long DownloadPayloadRate { get; set; } + + [JsonProperty(PropertyName = "upload_payload_rate")] + public long UploadPayloadRate { get; set; } + + [JsonProperty(PropertyName = "eta")] + public long Eta { get; set; } + + [JsonProperty(PropertyName = "distributed_copies")] + public float DistributedCopies { get; set; } + + [JsonProperty(PropertyName = "time_added")] + public int TimeAdded { get; set; } + + [JsonProperty(PropertyName = "tracker_host")] + public string TrackerHost { get; set; } + + [JsonProperty(PropertyName = "download_location")] + public string DownloadLocation { get; set; } + + [JsonProperty(PropertyName = "total_remaining")] + public long TotalRemaining { get; set; } + + [JsonProperty(PropertyName = "max_download_speed")] + public long MaxDownloadSpeed { get; set; } + + [JsonProperty(PropertyName = "max_upload_speed")] + public long MaxUploadSpeed { get; set; } + + [JsonProperty(PropertyName = "seeds_peers_ratio")] + public float SeedsPeersRatio { get; set; } + } +} diff --git a/README.md b/README.md index fc962cf..8b87e72 100644 --- a/README.md +++ b/README.md @@ -46,11 +46,21 @@ List torrents List<Torrent> torrents = await client.ListTorrents(); ``` +List torrents extended +```C# +List<TorrentExtended> torrents = await client.ListTorrentsExtended(); +``` + Get torrent by hash ```C# Torrent torrent = await client.GetTorrent(torrentHash); ``` +Get torrent extended by hash +```C# +TorrentExtended torrent = await client.GetTorrentExtended(torrentHash); +``` + #### Add Torrent Add a torrent by magnet uri @@ -62,7 +72,6 @@ Add a torrent by .torrent file ```C# Torrent torrent = await client.AddTorrentByFile(torrentFilename); ``` -``` Add a torrent by .torrent url ```C# From 22a457e2a049da0f89f2db16d3f74edde5442aa3 Mon Sep 17 00:00:00 2001 From: Rafael Calafell <48203251+rafacc87@users.noreply.github.com> Date: Sun, 3 Nov 2024 23:18:40 +0100 Subject: [PATCH 5/5] Reduced timeout to 3 seconds --- DelugeRPCClient.Net/Core/CoreDelugeWebClient.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/DelugeRPCClient.Net/Core/CoreDelugeWebClient.cs b/DelugeRPCClient.Net/Core/CoreDelugeWebClient.cs index 13ac59b..8d96f06 100644 --- a/DelugeRPCClient.Net/Core/CoreDelugeWebClient.cs +++ b/DelugeRPCClient.Net/Core/CoreDelugeWebClient.cs @@ -61,7 +61,9 @@ private async Task<String> PostJson(String json) StringContent content = new StringContent(json); content.Headers.ContentType = new MediaTypeWithQualityHeaderValue("application/json"); - var responseMessage = await HttpClient.PostAsync(Url, content); + var httpClient = new HttpClient(); + httpClient.Timeout = TimeSpan.FromMilliseconds(30); + var responseMessage = await httpClient.PostAsync(Url, content); responseMessage.EnsureSuccessStatusCode(); var responseJson = await responseMessage.Content.ReadAsStringAsync();