From 4a3c0e4118cfd8a988b0545189239e8e2541f473 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Quang=20Ng=C3=B4?= Date: Tue, 2 Nov 2021 22:31:01 +0700 Subject: [PATCH] Add session-stats. --- README.md | 2 +- examples/session-stats.rs | 26 ++++++++++++++++++++++++++ src/lib.rs | 37 +++++++++++++++++++++++++++++++++++++ src/types/mod.rs | 1 + src/types/request.rs | 7 +++++++ src/types/response.rs | 33 +++++++++++++++++++++++++++++++++ 6 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 examples/session-stats.rs diff --git a/README.md b/README.md index f789ecd..40893d2 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ spec: https://github.com/transmission/transmission/blob/master/extras/rpc-spec.t - [X] torrent-rename-path - [ ] session-set - [X] session-get -- [ ] session-stats +- [X] session-stats - [ ] blocklist-update - [ ] port-test - [ ] session-close diff --git a/examples/session-stats.rs b/examples/session-stats.rs new file mode 100644 index 0000000..c162fe7 --- /dev/null +++ b/examples/session-stats.rs @@ -0,0 +1,26 @@ +extern crate transmission_rpc; + +use dotenv::dotenv; +use std::env; +use transmission_rpc::types::{BasicAuth, Result, RpcResponse, SessionStats}; +use transmission_rpc::TransClient; + +#[tokio::main] +async fn main() -> Result<()> { + dotenv().ok(); + env_logger::init(); + let url = env::var("TURL")?; + let client; + if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) { + client = TransClient::with_auth(&url, BasicAuth {user, password}); + } else { + client = TransClient::new(&url); + } + let response: Result> = client.session_stats().await; + match response { + Ok(_) => println!("Yay!"), + Err(_) => panic!("Oh no!") + } + println!("Rpc response is ok: {}", response?.is_ok()); + Ok(()) +} diff --git a/src/lib.rs b/src/lib.rs index 68a6944..59aa74d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,6 +10,7 @@ pub mod types; use types::BasicAuth; use types::SessionGet; +use types::SessionStats; use types::TorrentAction; use types::{Id, Torrent, TorrentGetField, Torrents}; use types::{Nothing, Result, RpcRequest, RpcResponse, RpcResponseArgument, TorrentRenamePath}; @@ -111,6 +112,42 @@ impl TransClient { self.call(RpcRequest::session_get()).await } + /// Performs a session stats call + /// + /// # Errors + /// + /// Any IO Error or Deserialization error + /// + /// # Example + /// + /// ``` + /// extern crate transmission_rpc; + /// + /// use std::env; + /// use dotenv::dotenv; + /// use transmission_rpc::TransClient; + /// use transmission_rpc::types::{Result, RpcResponse, SessionStats, BasicAuth}; + /// + /// #[tokio::main] + /// async fn main() -> Result<()> { + /// dotenv().ok(); + /// env_logger::init(); + /// let url= env::var("TURL")?; + /// let basic_auth = BasicAuth{user: env::var("TUSER")?, password: env::var("TPWD")?}; + /// let client = TransClient::with_auth(&url, basic_auth); + /// let response: Result> = client.session_stats().await; + /// match response { + /// Ok(_) => println!("Yay!"), + /// Err(_) => panic!("Oh no!") + /// } + /// println!("Rpc reqsponse is ok: {}", response?.is_ok()); + /// Ok(()) + /// } + /// ``` + pub async fn session_stats(&self) -> Result> { + self.call(RpcRequest::session_stats()).await + } + /// Performs a torrent get call /// fileds - if None then ALL fields /// ids - if None then All items diff --git a/src/types/mod.rs b/src/types/mod.rs index 59e6f81..272fa90 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -21,6 +21,7 @@ pub use self::response::Nothing; pub use self::response::RpcResponse; pub(crate) use self::response::RpcResponseArgument; pub use self::response::SessionGet; +pub use self::response::SessionStats; pub use self::response::Torrent; pub use self::response::TorrentAdded; pub use self::response::Torrents; diff --git a/src/types/request.rs b/src/types/request.rs index 6714d96..dd66f4d 100644 --- a/src/types/request.rs +++ b/src/types/request.rs @@ -16,6 +16,13 @@ impl RpcRequest { } } + pub fn session_stats() -> RpcRequest { + RpcRequest { + method: String::from("session-stats"), + arguments: None, + } + } + pub fn torrent_get(fields: Option>, ids: Option>) -> RpcRequest { let string_fields = fields .unwrap_or(TorrentGetField::all()) diff --git a/src/types/response.rs b/src/types/response.rs index 950f7a8..a16292b 100644 --- a/src/types/response.rs +++ b/src/types/response.rs @@ -27,6 +27,25 @@ pub struct SessionGet { } impl RpcResponseArgument for SessionGet {} +#[derive(Deserialize, Debug, Clone)] +pub struct SessionStats { + #[serde(rename = "torrentCount")] + pub torrent_count: i32, + #[serde(rename = "activeTorrentCount")] + pub active_torrent_count: i32, + #[serde(rename = "pausedTorrentCount")] + pub paused_torrent_count: i32, + #[serde(rename = "downloadSpeed")] + pub download_speed: i64, + #[serde(rename = "uploadSpeed")] + pub upload_speed: i64, + #[serde(rename = "current-stats")] + pub current_stats: Stats, + #[serde(rename = "cumulative-stats")] + pub cumulative_stats: Stats, +} +impl RpcResponseArgument for SessionStats {} + #[derive(Deserialize, Debug, RustcEncodable, Clone)] pub struct Torrent { #[serde(rename = "addedDate")] @@ -84,6 +103,20 @@ pub struct Torrent { pub file_stats: Option>, } +#[derive(Deserialize, Debug, Clone)] +pub struct Stats { + #[serde(rename = "filesAdded")] + pub files_added: i32, + #[serde(rename = "downloadedBytes")] + pub downloaded_bytes: i64, + #[serde(rename = "uploadedBytes")] + pub uploaded_bytes: i64, + #[serde(rename = "secondsActive")] + pub seconds_active: i64, + #[serde(rename = "sessionCount")] + pub session_count: Option +} + #[derive(Deserialize, Debug, RustcEncodable)] pub struct Torrents { pub torrents: Vec,