From f75ac43e494cfeaff567411cb777dc5964638f74 Mon Sep 17 00:00:00 2001 From: Roger Far Date: Sat, 19 Mar 2022 12:49:38 -0600 Subject: [PATCH] Add QBittorrent API sync/maindata endpoint for home assistant integration. --- client/package-lock.json | 14 +-- .../Models/QBittorrent/SyncMetaData.cs | 106 ++++++++++++++++++ .../RdtClient.Service/Services/QBittorrent.cs | 26 ++++- server/RdtClient.Service/Services/Torrents.cs | 2 +- .../Controllers/QBittorrentController.cs | 18 +++ 5 files changed, 157 insertions(+), 9 deletions(-) create mode 100644 server/RdtClient.Data/Models/QBittorrent/SyncMetaData.cs diff --git a/client/package-lock.json b/client/package-lock.json index 867dc3e..0211f88 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -35,7 +35,7 @@ "@angular/language-service": "~13.2.6", "@types/file-saver": "^2.0.5", "@types/node": "^17.0.21", - "typescript": "~4.6.2" + "typescript": "~4.5.5" } }, "node_modules/@ampproject/remapping": { @@ -10290,9 +10290,9 @@ "dev": true }, "node_modules/typescript": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz", - "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==", + "version": "4.5.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz", + "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -18520,9 +18520,9 @@ "dev": true }, "typescript": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz", - "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==", + "version": "4.5.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz", + "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==", "dev": true }, "unicode-canonical-property-names-ecmascript": { diff --git a/server/RdtClient.Data/Models/QBittorrent/SyncMetaData.cs b/server/RdtClient.Data/Models/QBittorrent/SyncMetaData.cs new file mode 100644 index 0000000..8a43502 --- /dev/null +++ b/server/RdtClient.Data/Models/QBittorrent/SyncMetaData.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; +using RdtClient.Data.Models.QBittorrent.QuickType; + +namespace RdtClient.Data.Models.QBittorrent +{ + public class SyncMetaData + { + [JsonPropertyName("categories")] + public IDictionary Categories { get; set; } + + [JsonPropertyName("full_update")] + public Boolean FullUpdate { get; set; } + + [JsonPropertyName("rid")] + public Int64 Rid { get; set; } + + [JsonPropertyName("server_state")] + public SyncMetaDataServerState ServerState { get; set; } + + [JsonPropertyName("tags")] + public IList Tags { get; set; } + + [JsonPropertyName("torrents")] + public IDictionary Torrents { get; set; } + + [JsonPropertyName("trackers")] + public IDictionary> Trackers { get; set; } + } + + public class SyncMetaDataServerState + { + [JsonPropertyName("alltime_dl")] + public Int64 AlltimeDl { get; set; } + + [JsonPropertyName("alltime_ul")] + public Int64 AlltimeUl { get; set; } + + [JsonPropertyName("average_time_queue")] + public Int64 AverageTimeQueue { get; set; } + + [JsonPropertyName("connection_status")] + public String ConnectionStatus { get; set; } + + [JsonPropertyName("dht_nodes")] + public Int64 DhtNodes { get; set; } + + [JsonPropertyName("dl_info_data")] + public Int64 DlInfoData { get; set; } + + [JsonPropertyName("dl_info_speed")] + public Int64 DlInfoSpeed { get; set; } + + [JsonPropertyName("dl_rate_limit")] + public Int64 DlRateLimit { get; set; } + + [JsonPropertyName("free_space_on_disk")] + public Int64 FreeSpaceOnDisk { get; set; } + + [JsonPropertyName("global_ratio")] + public String GlobalRatio { get; set; } + + [JsonPropertyName("queued_io_jobs")] + public Int64 QueuedIoJobs { get; set; } + + [JsonPropertyName("queueing")] + public Boolean Queueing { get; set; } + + [JsonPropertyName("read_cache_hits")] + public String ReadCacheHits { get; set; } + + [JsonPropertyName("read_cache_overload")] + public String ReadCacheOverload { get; set; } + + [JsonPropertyName("refresh_interval")] + public Int64 RefreshInterval { get; set; } + + [JsonPropertyName("total_buffers_size")] + public Int64 TotalBuffersSize { get; set; } + + [JsonPropertyName("total_peer_connections")] + public Int64 TotalPeerConnections { get; set; } + + [JsonPropertyName("total_queued_size")] + public Int64 TotalQueuedSize { get; set; } + + [JsonPropertyName("total_wasted_session")] + public Int64 TotalWastedSession { get; set; } + + [JsonPropertyName("up_info_data")] + public Int64 UpInfoData { get; set; } + + [JsonPropertyName("up_info_speed")] + public Int64 UpInfoSpeed { get; set; } + + [JsonPropertyName("up_rate_limit")] + public Int64 UpRateLimit { get; set; } + + [JsonPropertyName("use_alt_speed_limits")] + public Boolean UseAltSpeedLimits { get; set; } + + [JsonPropertyName("write_cache_overload")] + public String WriteCacheOverload { get; set; } + } +} diff --git a/server/RdtClient.Service/Services/QBittorrent.cs b/server/RdtClient.Service/Services/QBittorrent.cs index 893eb9c..24b7427 100644 --- a/server/RdtClient.Service/Services/QBittorrent.cs +++ b/server/RdtClient.Service/Services/QBittorrent.cs @@ -497,7 +497,7 @@ namespace RdtClient.Service.Services m => new TorrentCategory { Name = m, - SavePath = "" + SavePath = Path.Combine(AppDefaultSavePath(), m) }); } @@ -594,5 +594,29 @@ namespace RdtClient.Service.Services } } } + + public async Task SyncMainData() + { + var torrents = await TorrentInfo(); + + var categories = await TorrentsCategories(); + + var activeDownloads = TorrentRunner.ActiveDownloadClients.Sum(m => m.Value.Speed); + + return new SyncMetaData + { + Categories = categories, + FullUpdate = true, + Rid = 0, + Tags = null, + Trackers = new Dictionary>(), + Torrents = torrents.ToDictionary(m => m.Hash, m => m), + ServerState = new SyncMetaDataServerState + { + DlInfoSpeed = activeDownloads, + UpInfoSpeed = 0 + } + }; + } } } diff --git a/server/RdtClient.Service/Services/Torrents.cs b/server/RdtClient.Service/Services/Torrents.cs index ed9aed3..f584a3f 100644 --- a/server/RdtClient.Service/Services/Torrents.cs +++ b/server/RdtClient.Service/Services/Torrents.cs @@ -272,7 +272,7 @@ namespace RdtClient.Service.Services } } - if (deleteLocalFiles) + if (deleteLocalFiles && !String.IsNullOrWhiteSpace(torrent.RdName)) { var downloadPath = DownloadPath(torrent); downloadPath = Path.Combine(downloadPath, torrent.RdName); diff --git a/server/RdtClient.Web/Controllers/QBittorrentController.cs b/server/RdtClient.Web/Controllers/QBittorrentController.cs index 4db5c50..24127c3 100644 --- a/server/RdtClient.Web/Controllers/QBittorrentController.cs +++ b/server/RdtClient.Web/Controllers/QBittorrentController.cs @@ -421,6 +421,24 @@ namespace RdtClient.Web.Controllers { return await TorrentsTopPrio(request); } + + [Authorize] + [Route("sync/maindata")] + [HttpGet] + public async Task SyncMainData() + { + var result = await _qBittorrent.SyncMainData(); + + return Ok(result); + } + + [Authorize] + [Route("sync/maindata")] + [HttpPost] + public async Task SyncMainDataPost() + { + return await SyncMainData(); + } } public class QBAuthLoginRequest