added id filtering by id or hashstring

This commit is contained in:
red 2020-04-25 18:34:45 +02:00
parent ed530d9903
commit 64072f70b6
7 changed files with 69 additions and 22 deletions

View File

@ -1,6 +1,6 @@
[package] [package]
name = "transmission-rpc" name = "transmission-rpc"
version = "0.2.0" version = "0.2.1"
authors = ["red <red.avtovo@gmail.com>"] authors = ["red <red.avtovo@gmail.com>"]
edition = "2018" edition = "2018"
repository = "https://github.com/j0rsa/transmission-rpc" repository = "https://github.com/j0rsa/transmission-rpc"
@ -19,6 +19,7 @@ reqwest = { version = "0.10.4", features = ["json", "rustls-tls"] }
tokio = { version = "0.2", features = ["macros"] } tokio = { version = "0.2", features = ["macros"] }
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
rustc-serialize = "0.3.24" rustc-serialize = "0.3.24"
enum-iterator = "0.6.0"
dotenv = "0.15.0" dotenv = "0.15.0"
log = "0.4.8" log = "0.4.8"

View File

@ -4,7 +4,7 @@ use std::env;
use dotenv::dotenv; use dotenv::dotenv;
use transmission_rpc::TransClient; use transmission_rpc::TransClient;
use transmission_rpc::types::{Result, RpcResponse, BasicAuth}; use transmission_rpc::types::{Result, RpcResponse, BasicAuth};
use transmission_rpc::types::{TorrentAction, Nothing}; use transmission_rpc::types::{TorrentAction, Nothing, Id};
#[tokio::main] #[tokio::main]
async fn main() -> Result<()> { async fn main() -> Result<()> {
@ -13,9 +13,9 @@ async fn main() -> Result<()> {
let url= env::var("TURL")?; let url= env::var("TURL")?;
let basic_auth = BasicAuth{user: env::var("TUSER")?, password: env::var("TPWD")?}; let basic_auth = BasicAuth{user: env::var("TUSER")?, password: env::var("TPWD")?};
let client = TransClient::with_auth(&url, basic_auth); let client = TransClient::with_auth(&url, basic_auth);
let res1: RpcResponse<Nothing> = client.torrent_action(TorrentAction::Start, vec![1]).await?; let res1: RpcResponse<Nothing> = client.torrent_action(TorrentAction::Start, vec![Id::Id(1)]).await?;
println!("Start result: {:?}", &res1.is_ok()); println!("Start result: {:?}", &res1.is_ok());
let res2: RpcResponse<Nothing> = client.torrent_action(TorrentAction::Stop, vec![1]).await?; let res2: RpcResponse<Nothing> = client.torrent_action(TorrentAction::Stop, vec![Id::Id(1)]).await?;
println!("Stop result: {:?}", &res2.is_ok()); println!("Stop result: {:?}", &res2.is_ok());
Ok(()) Ok(())

View File

@ -4,7 +4,7 @@ use std::env;
use dotenv::dotenv; use dotenv::dotenv;
use transmission_rpc::TransClient; use transmission_rpc::TransClient;
use transmission_rpc::types::{Result, RpcResponse, BasicAuth}; use transmission_rpc::types::{Result, RpcResponse, BasicAuth};
use transmission_rpc::types::{Torrents, Torrent, TorrentGetField}; use transmission_rpc::types::{Torrents, Torrent, TorrentGetField, Id};
#[tokio::main] #[tokio::main]
async fn main() -> Result<()> { async fn main() -> Result<()> {
@ -13,9 +13,26 @@ async fn main() -> Result<()> {
let url= env::var("TURL")?; let url= env::var("TURL")?;
let basic_auth = BasicAuth{user: env::var("TUSER")?, password: env::var("TPWD")?}; let basic_auth = BasicAuth{user: env::var("TUSER")?, password: env::var("TPWD")?};
let client = TransClient::with_auth(&url, basic_auth); let client = TransClient::with_auth(&url, basic_auth);
let res: RpcResponse<Torrents<Torrent>> = client.torrent_get(vec![TorrentGetField::Id, TorrentGetField::Name]).await?;
let res: RpcResponse<Torrents<Torrent>> = client.torrent_get(None, None).await?;
let names: Vec<&String> = res.arguments.torrents.iter().map(|it| it.name.as_ref().unwrap()).collect(); let names: Vec<&String> = res.arguments.torrents.iter().map(|it| it.name.as_ref().unwrap()).collect();
println!("{:#?}", names); println!("{:#?}", names);
let res1: RpcResponse<Torrents<Torrent>> = client.torrent_get(Some(vec![TorrentGetField::Id, TorrentGetField::Name]), Some(vec![Id::Id(1), Id::Id(2), Id::Id(3)])).await?;
let first_three: Vec<String> = res1.arguments.torrents.iter().map(|it|
format!("{}. {}",&it.id.as_ref().unwrap(), &it.name.as_ref().unwrap())
).collect();
println!("{:#?}", first_three);
let res2: RpcResponse<Torrents<Torrent>> = client.torrent_get(Some(vec![TorrentGetField::Id, TorrentGetField::HashString, TorrentGetField::Name]), Some(vec![Id::Hash(String::from("64b0d9a53ac9cd1002dad1e15522feddb00152fe"))])).await?;
let info: Vec<String> = res2.arguments.torrents.iter().map(|it|
format!("{:5}. {:^45} {}",
&it.id.as_ref().unwrap(),
&it.hash_string.as_ref().unwrap(),
&it.name.as_ref().unwrap())
).collect();
println!("{:#?}", info);
Ok(()) Ok(())
} }

View File

@ -4,7 +4,7 @@ use std::env;
use dotenv::dotenv; use dotenv::dotenv;
use transmission_rpc::TransClient; use transmission_rpc::TransClient;
use transmission_rpc::types::{Result, RpcResponse, BasicAuth}; use transmission_rpc::types::{Result, RpcResponse, BasicAuth};
use transmission_rpc::types::{Nothing}; use transmission_rpc::types::{Nothing, Id};
#[tokio::main] #[tokio::main]
async fn main() -> Result<()> { async fn main() -> Result<()> {
@ -13,7 +13,7 @@ async fn main() -> Result<()> {
let url= env::var("TURL")?; let url= env::var("TURL")?;
let basic_auth = BasicAuth{user: env::var("TUSER")?, password: env::var("TPWD")?}; let basic_auth = BasicAuth{user: env::var("TUSER")?, password: env::var("TPWD")?};
let client = TransClient::with_auth(&url, basic_auth); let client = TransClient::with_auth(&url, basic_auth);
let res: RpcResponse<Nothing> = client.torrent_remove(vec![1], false).await?; let res: RpcResponse<Nothing> = client.torrent_remove(vec![Id::Id(1)], false).await?;
println!("Remove result: {:?}", &res.is_ok()); println!("Remove result: {:?}", &res.is_ok());
Ok(()) Ok(())

View File

@ -13,7 +13,7 @@ pub mod types;
use types::BasicAuth; use types::BasicAuth;
use types::{Result, RpcResponse, RpcResponseArgument, RpcRequest, Nothing}; use types::{Result, RpcResponse, RpcResponseArgument, RpcRequest, Nothing};
use types::SessionGet; use types::SessionGet;
use types::{TorrentGetField, Torrents, Torrent}; use types::{TorrentGetField, Torrents, Torrent, Id};
use types::TorrentAction; use types::TorrentAction;
use types::{TorrentAddArgs, TorrentAdded}; use types::{TorrentAddArgs, TorrentAdded};
@ -88,6 +88,8 @@ impl TransClient {
} }
/// Performs a torrent get call /// Performs a torrent get call
/// fileds - if None then ALL fields
/// ids - if None then All items
/// ///
/// # Errors /// # Errors
/// ///
@ -96,8 +98,8 @@ impl TransClient {
/// # Example /// # Example
/// ///
/// in examples/torrent-get.rs /// in examples/torrent-get.rs
pub async fn torrent_get(&self, fields: Vec<TorrentGetField>) -> Result<RpcResponse<Torrents<Torrent>>> { pub async fn torrent_get(&self, fields: Option<Vec<TorrentGetField>>, ids: Option<Vec<Id>>) -> Result<RpcResponse<Torrents<Torrent>>> {
self.call(RpcRequest::torrent_get(fields)).await self.call(RpcRequest::torrent_get(fields, ids)).await
} }
/// Performs a torrent action call /// Performs a torrent action call
@ -109,7 +111,7 @@ impl TransClient {
/// # Example /// # Example
/// ///
/// in examples/torrent-action.rs /// in examples/torrent-action.rs
pub async fn torrent_action(&self, action: TorrentAction, ids: Vec<i64>) -> Result<RpcResponse<Nothing>> { pub async fn torrent_action(&self, action: TorrentAction, ids: Vec<Id>) -> Result<RpcResponse<Nothing>> {
self.call(RpcRequest::torrent_action(action, ids)).await self.call(RpcRequest::torrent_action(action, ids)).await
} }
@ -122,7 +124,7 @@ impl TransClient {
/// # Example /// # Example
/// ///
/// in examples/torrent-remove.rs /// in examples/torrent-remove.rs
pub async fn torrent_remove(&self, ids: Vec<i64>, delete_local_data: bool) -> Result<RpcResponse<Nothing>> { pub async fn torrent_remove(&self, ids: Vec<Id>, delete_local_data: bool) -> Result<RpcResponse<Nothing>> {
self.call( RpcRequest::torrent_remove(ids, delete_local_data)).await self.call( RpcRequest::torrent_remove(ids, delete_local_data)).await
} }

View File

@ -16,6 +16,7 @@ pub use self::request::TorrentGetField;
pub use self::request::TorrentAction; pub use self::request::TorrentAction;
pub use self::request::TorrentAddArgs; pub use self::request::TorrentAddArgs;
pub use self::request::File; pub use self::request::File;
pub use self::request::Id;
pub use self::response::RpcResponse; pub use self::response::RpcResponse;
pub(crate) use self::response::RpcResponseArgument; pub(crate) use self::response::RpcResponseArgument;

View File

@ -1,4 +1,5 @@
use serde::Serialize; use serde::Serialize;
use enum_iterator::IntoEnumIterator;
#[derive(Serialize, Debug, RustcEncodable)] #[derive(Serialize, Debug, RustcEncodable)]
pub struct RpcRequest { pub struct RpcRequest {
@ -15,15 +16,15 @@ impl RpcRequest {
} }
} }
pub fn torrent_get(fields: Vec<TorrentGetField>) -> RpcRequest { pub fn torrent_get(fields: Option<Vec<TorrentGetField>>, ids: Option<Vec<Id>>) -> RpcRequest {
let string_fields = fields.iter().map(|f| f.to_str()).collect(); let string_fields = fields.unwrap_or(TorrentGetField::all()).iter().map(|f| f.to_str()).collect();
RpcRequest { RpcRequest {
method: String::from("torrent-get"), method: String::from("torrent-get"),
arguments: Some ( Args::TorrentGetArgs(TorrentGetArgs { fields: Some(string_fields)} )), arguments: Some ( Args::TorrentGetArgs(TorrentGetArgs { fields: Some(string_fields), ids } )),
} }
} }
pub fn torrent_remove(ids: Vec<i64>, delete_local_data: bool) -> RpcRequest { pub fn torrent_remove(ids: Vec<Id>, delete_local_data: bool) -> RpcRequest {
RpcRequest { RpcRequest {
method: String::from("torrent-remove"), method: String::from("torrent-remove"),
arguments: Some ( Args::TorrentRemoveArgs(TorrentRemoveArgs {ids, delete_local_data} ) ) arguments: Some ( Args::TorrentRemoveArgs(TorrentRemoveArgs {ids, delete_local_data} ) )
@ -37,7 +38,7 @@ impl RpcRequest {
} }
} }
pub fn torrent_action(action: TorrentAction, ids: Vec<i64>) -> RpcRequest { pub fn torrent_action(action: TorrentAction, ids: Vec<Id>) -> RpcRequest {
RpcRequest { RpcRequest {
method: action.to_str(), method: action.to_str(),
arguments: Some ( Args::TorrentActionArgs(TorrentActionArgs { ids })), arguments: Some ( Args::TorrentActionArgs(TorrentActionArgs { ids })),
@ -59,20 +60,39 @@ pub enum Args{
#[derive(Serialize, Debug, RustcEncodable, Clone)] #[derive(Serialize, Debug, RustcEncodable, Clone)]
pub struct TorrentGetArgs { pub struct TorrentGetArgs {
#[serde(skip_serializing_if="Option::is_none")] #[serde(skip_serializing_if="Option::is_none")]
fields: Option<Vec<String>> fields: Option<Vec<String>>,
#[serde(skip_serializing_if="Option::is_none")]
ids: Option<Vec<Id>>,
}
impl Default for TorrentGetArgs {
fn default() -> Self {
let all_fields = TorrentGetField::into_enum_iter().map (|it| it.to_str()).collect();
TorrentGetArgs {
fields: Some(all_fields),
ids: None
}
}
} }
#[derive(Serialize, Debug, RustcEncodable, Clone)] #[derive(Serialize, Debug, RustcEncodable, Clone)]
pub struct TorrentActionArgs { pub struct TorrentActionArgs {
ids: Vec<i64>, ids: Vec<Id>,
} }
#[derive(Serialize, Debug, RustcEncodable, Clone)] #[derive(Serialize, Debug, RustcEncodable, Clone)]
pub struct TorrentRemoveArgs { pub struct TorrentRemoveArgs {
ids: Vec<i64>, ids: Vec<Id>,
#[serde(rename="delete-local-data")] #[serde(rename="delete-local-data")]
delete_local_data: bool delete_local_data: bool
} }
#[derive(Serialize, Debug, RustcEncodable, Clone)]
#[serde(untagged)]
pub enum Id {
Id(i64),
Hash(String)
}
#[derive(Serialize, Debug, RustcEncodable, Clone)] #[derive(Serialize, Debug, RustcEncodable, Clone)]
pub struct TorrentAddArgs { pub struct TorrentAddArgs {
#[serde(skip_serializing_if="Option::is_none")] #[serde(skip_serializing_if="Option::is_none")]
@ -129,7 +149,7 @@ impl Default for TorrentAddArgs {
pub struct File { pub struct File {
//todo //todo
} }
#[derive(Clone, IntoEnumIterator)]
pub enum TorrentGetField { pub enum TorrentGetField {
Id, Id,
Addeddate, Addeddate,
@ -162,6 +182,12 @@ pub enum TorrentGetField {
Webseedssendingtous, Webseedssendingtous,
} }
impl TorrentGetField {
pub fn all() -> Vec<TorrentGetField> {
TorrentGetField::into_enum_iter().collect()
}
}
impl TorrentGetField { impl TorrentGetField {
pub fn to_str(&self) -> String { pub fn to_str(&self) -> String {
match self { match self {