diff --git a/src/lib.rs b/src/lib.rs index e2f6f29..ad069ef 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,20 +4,20 @@ extern crate log; use reqwest::{header::CONTENT_TYPE, Client, StatusCode, Url}; use serde::de::DeserializeOwned; -#[cfg(feature = "sync")] -mod sync; - #[cfg(feature = "sync")] pub use sync::SharableTransClient; - -pub mod types; use types::{ BasicAuth, BlocklistUpdate, FreeSpace, Id, Nothing, PortTest, Result, RpcRequest, RpcResponse, - RpcResponseArgument, SessionClose, SessionGet, SessionStats, Torrent, TorrentAction, - TorrentAddArgs, TorrentAddedOrDuplicate, TorrentGetField, TorrentRenamePath, TorrentSetArgs, - Torrents, + RpcResponseArgument, SessionClose, SessionGet, SessionSet, SessionSetArgs, SessionStats, + Torrent, TorrentAction, TorrentAddArgs, TorrentAddedOrDuplicate, TorrentGetField, + TorrentRenamePath, TorrentSetArgs, Torrents, }; +#[cfg(feature = "sync")] +mod sync; + +pub mod types; + const MAX_RETRIES: usize = 5; #[derive(Clone, Debug)] @@ -93,6 +93,54 @@ impl TransClient { .header(CONTENT_TYPE, "application/json") } + /// Performs a session set call + /// + /// # Errors + /// + /// Any IO Error or Deserialization error + /// + /// # Example + /// + /// ``` + /// extern crate transmission_rpc; + /// + /// use std::env; + /// + /// use dotenvy::dotenv; + /// use transmission_rpc::{ + /// types::{BasicAuth, Result, RpcResponse, SessionSet, SessionSetArgs}, + /// TransClient, + /// }; + /// + /// #[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 mut client = TransClient::with_auth(url.parse()?, basic_auth); + /// let args: SessionSetArgs = SessionSetArgs { + /// download_dir: Some( + /// "/torrent/download".to_string(), + /// ), + /// ..SessionSetArgs::default() + /// }; + /// let response: Result> = client.session_set(args).await; + /// match response { + /// Ok(_) => println!("Yay!"), + /// Err(_) => panic!("Oh no!"), + /// } + /// println!("Rpc response is ok: {}", response?.is_ok()); + /// Ok(()) + /// } + /// ``` + pub async fn session_set(&mut self, args: SessionSetArgs) -> Result> { + self.call(RpcRequest::session_set(args)).await + } + /// Performs a session get call /// /// # Errors diff --git a/src/types/mod.rs b/src/types/mod.rs index 9e35f96..557a0dc 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -11,13 +11,13 @@ pub struct BasicAuth { pub(crate) use self::request::RpcRequest; pub use self::request::{ - ArgumentFields, Id, TorrentAction, TorrentAddArgs, TorrentGetField, TorrentRenamePathArgs, - TorrentSetArgs, TrackerList, + ArgumentFields, Id, SessionSetArgs, TorrentAction, TorrentAddArgs, TorrentGetField, + TorrentRenamePathArgs, TorrentSetArgs, TrackerList, }; pub(crate) use self::response::RpcResponseArgument; pub use self::response::{ BlocklistUpdate, ErrorType, FreeSpace, Nothing, PortTest, RpcResponse, SessionClose, - SessionGet, SessionStats, Torrent, TorrentAddedOrDuplicate, TorrentRenamePath, TorrentStatus, - Torrents, + SessionGet, SessionSet, SessionStats, Torrent, TorrentAddedOrDuplicate, TorrentRenamePath, + TorrentStatus, Torrents, }; diff --git a/src/types/request.rs b/src/types/request.rs index 99d0f62..0c0a053 100644 --- a/src/types/request.rs +++ b/src/types/request.rs @@ -9,6 +9,13 @@ pub struct RpcRequest { } impl RpcRequest { + pub fn session_set(args: SessionSetArgs) -> RpcRequest { + RpcRequest { + method: String::from("session-set"), + arguments: Some(Args::SessionSet(args)), + } + } + pub fn session_get() -> RpcRequest { RpcRequest { method: String::from("session-get"), @@ -131,6 +138,7 @@ impl ArgumentFields for TorrentGetField {} #[serde(untagged)] pub enum Args { FreeSpace(FreeSpaceArgs), + SessionSet(SessionSetArgs), TorrentGet(TorrentGetArgs), TorrentAction(TorrentActionArgs), TorrentRemove(TorrentRemoveArgs), @@ -145,6 +153,222 @@ pub struct FreeSpaceArgs { path: String, } +#[derive(Serialize, Debug, Clone, Default)] +pub struct SessionSetArgs { + #[serde(skip_serializing_if = "Option::is_none", rename = "alt-speed-down")] + pub alt_speed_down: Option, + + #[serde(skip_serializing_if = "Option::is_none", rename = "alt-speed-enabled")] + pub alt_speed_enabled: Option, + + #[serde( + skip_serializing_if = "Option::is_none", + rename = "alt-speed-time-begin" + )] + pub alt_speed_time_begin: Option, + + #[serde(skip_serializing_if = "Option::is_none", rename = "alt-speed-time-day")] + pub alt_speed_time_day: Option, + + #[serde( + skip_serializing_if = "Option::is_none", + rename = "alt-speed-time-enabled" + )] + pub alt_speed_time_enabled: Option, + + #[serde(skip_serializing_if = "Option::is_none", rename = "alt-speed-time-end")] + pub alt_speed_time_end: Option, + + #[serde(skip_serializing_if = "Option::is_none", rename = "alt-speed-up")] + pub alt_speed_up: Option, + + #[serde(skip_serializing_if = "Option::is_none", rename = "blocklist-enabled")] + pub blocklist_enabled: Option, + + #[serde(skip_serializing_if = "Option::is_none", rename = "blocklist-url")] + pub blocklist_url: Option, + + #[serde(skip_serializing_if = "Option::is_none", rename = "cache-size-mb")] + pub cache_size_mb: Option, + + #[serde(skip_serializing_if = "Option::is_none", rename = "default-trackers")] + pub default_trackers: Option, + + #[serde(skip_serializing_if = "Option::is_none", rename = "dht-enabled")] + pub dht_enabled: Option, + + #[serde(skip_serializing_if = "Option::is_none", rename = "download-dir")] + pub download_dir: Option, + + #[serde( + skip_serializing_if = "Option::is_none", + rename = "download-dir-free-space" + )] + pub download_dir_free_space: Option, + + #[serde( + skip_serializing_if = "Option::is_none", + rename = "download-queue-enabled" + )] + pub download_queue_enabled: Option, + + #[serde( + skip_serializing_if = "Option::is_none", + rename = "download-queue-size" + )] + pub download_queue_size: Option, + + #[serde(skip_serializing_if = "Option::is_none")] + pub encryption: Option, + + #[serde( + skip_serializing_if = "Option::is_none", + rename = "idle-seeding-limit-enabled" + )] + pub idle_seeding_limit_enabled: Option, + + #[serde(skip_serializing_if = "Option::is_none", rename = "idle-seeding-limit")] + pub idle_seeding_limit: Option, + + #[serde( + skip_serializing_if = "Option::is_none", + rename = "incomplete-dir-enabled" + )] + pub incomplete_dir_enabled: Option, + + #[serde(skip_serializing_if = "Option::is_none", rename = "incomplete-dir")] + pub incomplete_dir: Option, + + #[serde(skip_serializing_if = "Option::is_none", rename = "lpd-enabled")] + pub lpd_enabled: Option, + + #[serde(skip_serializing_if = "Option::is_none", rename = "peer-limit-global")] + pub peer_limit_global: Option, + + #[serde( + skip_serializing_if = "Option::is_none", + rename = "peer-limit-per-torrent" + )] + pub peer_limit_per_torrent: Option, + + #[serde( + skip_serializing_if = "Option::is_none", + rename = "peer-port-random-on-start" + )] + pub peer_port_random_on_start: Option, + + #[serde(skip_serializing_if = "Option::is_none", rename = "peer-port")] + pub peer_port: Option, + + #[serde(skip_serializing_if = "Option::is_none", rename = "pex-enabled")] + pub pex_enabled: Option, + + #[serde( + skip_serializing_if = "Option::is_none", + rename = "port-forwarding-enabled" + )] + pub port_forwarding_enabled: Option, + + #[serde( + skip_serializing_if = "Option::is_none", + rename = "queue-stalled-enabled" + )] + pub queue_stalled_enabled: Option, + + #[serde( + skip_serializing_if = "Option::is_none", + rename = "queue-stalled-minutes" + )] + pub queue_stalled_minutes: Option, + + #[serde( + skip_serializing_if = "Option::is_none", + rename = "rename-partial-files" + )] + pub rename_partial_files: Option, + + #[serde( + skip_serializing_if = "Option::is_none", + rename = "script-torrent-added-enabled" + )] + pub script_torrent_added_enabled: Option, + + #[serde( + skip_serializing_if = "Option::is_none", + rename = "script-torrent-added-filename" + )] + pub script_torrent_added_filename: Option, + + #[serde( + skip_serializing_if = "Option::is_none", + rename = "script-torrent-done-enabled" + )] + pub script_torrent_done_enabled: Option, + + #[serde( + skip_serializing_if = "Option::is_none", + rename = "script-torrent-done-filename" + )] + pub script_torrent_done_filename: Option, + + #[serde( + skip_serializing_if = "Option::is_none", + rename = "script-torrent-done-seeding-enabled" + )] + pub script_torrent_done_seeding_enabled: Option, + + #[serde( + skip_serializing_if = "Option::is_none", + rename = "script-torrent-done-seeding-filename" + )] + pub script_torrent_done_seeding_filename: Option, + + #[serde(skip_serializing_if = "Option::is_none", rename = "seed-queue-enabled")] + pub seed_queue_enabled: Option, + + #[serde(skip_serializing_if = "Option::is_none", rename = "seed-queue-size")] + pub seed_queue_size: Option, + + #[serde(skip_serializing_if = "Option::is_none", rename = "seedRatioLimit")] + pub seed_ratio_limit: Option, + + #[serde(skip_serializing_if = "Option::is_none", rename = "seedRatioLimited")] + pub seed_ratio_limited: Option, + + #[serde( + skip_serializing_if = "Option::is_none", + rename = "speed-limit-down-enabled" + )] + pub speed_limit_down_enabled: Option, + + #[serde(skip_serializing_if = "Option::is_none", rename = "speed-limit-down")] + pub speed_limit_down: Option, + + #[serde( + skip_serializing_if = "Option::is_none", + rename = "speed-limit-up-enabled" + )] + pub speed_limit_up_enabled: Option, + + #[serde(skip_serializing_if = "Option::is_none", rename = "speed-limit-up")] + pub speed_limit_up: Option, + + #[serde( + skip_serializing_if = "Option::is_none", + rename = "start-added-torrents" + )] + pub start_added_torrents: Option, + + #[serde( + skip_serializing_if = "Option::is_none", + rename = "trash-original-torrent-files" + )] + pub trash_original_torrent_files: Option, + + #[serde(skip_serializing_if = "Option::is_none", rename = "utp-enabled")] + pub utp_enabled: Option, +} + #[derive(Serialize, Debug, Clone)] pub struct TorrentGetArgs { #[serde(skip_serializing_if = "Option::is_none")] diff --git a/src/types/response.rs b/src/types/response.rs index bcc4bf6..955f4f3 100644 --- a/src/types/response.rs +++ b/src/types/response.rs @@ -16,6 +16,10 @@ impl RpcResponse { } pub trait RpcResponseArgument {} +#[derive(Deserialize, Debug, Clone)] +pub struct SessionSet {} +impl RpcResponseArgument for SessionSet {} + #[derive(Deserialize, Debug, Clone)] #[serde(rename_all = "kebab-case")] pub struct SessionGet {