mirror of
https://github.com/kristoferssolo/transmission-rpc.git
synced 2025-10-21 20:10:37 +00:00
added torrent actions
This commit is contained in:
parent
56e454915a
commit
f2420e876a
@ -4,7 +4,7 @@ version = "0.1.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"
|
||||||
license-file = "LICENSE"
|
license = "MIT"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
description = "Transmission JRPC client"
|
description = "Transmission JRPC client"
|
||||||
keywords = ["transmission", "torrent", "jrpc"]
|
keywords = ["transmission", "torrent", "jrpc"]
|
||||||
|
|||||||
10
README.md
10
README.md
@ -4,6 +4,16 @@ spec: https://github.com/transmission/transmission/blob/master/extras/rpc-spec.t
|
|||||||
|
|
||||||
Supported Methods:
|
Supported Methods:
|
||||||
|
|
||||||
|
Torrent Actions:
|
||||||
|
|
||||||
|
- [X] torrent-start
|
||||||
|
- [X] torrent-stop
|
||||||
|
- [X] torrent-start-now
|
||||||
|
- [X] torrent-verify
|
||||||
|
- [X] torrent-reannounce
|
||||||
|
|
||||||
|
Torrent modificators:
|
||||||
|
|
||||||
- [ ] torrent-set
|
- [ ] torrent-set
|
||||||
- [X] torrent-get
|
- [X] torrent-get
|
||||||
- [ ] torrent-add
|
- [ ] torrent-add
|
||||||
|
|||||||
22
examples/torrent-action.rs
Normal file
22
examples/torrent-action.rs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
extern crate transmission_rpc;
|
||||||
|
|
||||||
|
use std::env;
|
||||||
|
use dotenv::dotenv;
|
||||||
|
use transmission_rpc::TransClient;
|
||||||
|
use transmission_rpc::types::{Result, RpcResponse, BasicAuth};
|
||||||
|
use transmission_rpc::types::{TorrentAction, Nothing};
|
||||||
|
|
||||||
|
#[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 res1: RpcResponse<Nothing> = client.torrent_action(TorrentAction::Start, vec![1]).await?;
|
||||||
|
println!("Start result: {:?}", &res1.is_ok());
|
||||||
|
let res2: RpcResponse<Nothing> = client.torrent_action(TorrentAction::Stop, vec![1]).await?;
|
||||||
|
println!("Stop result: {:?}", &res2.is_ok());
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
@ -13,8 +13,8 @@ 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(vec![TorrentGetField::Id, TorrentGetField::Name]).await?;
|
||||||
let names: Vec<&String> = res.arguments.torrents.iter().map(|it| it.clone().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);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -12,9 +12,10 @@ use reqwest::header::CONTENT_TYPE;
|
|||||||
|
|
||||||
pub mod types;
|
pub mod types;
|
||||||
use types::BasicAuth;
|
use types::BasicAuth;
|
||||||
use types::{Result, RpcResponse, RpcResponseArgument, RpcRequest};
|
use types::{Result, RpcResponse, RpcResponseArgument, RpcRequest, Nothing};
|
||||||
use types::SessionGet;
|
use types::SessionGet;
|
||||||
use types::{TorrentGetField, Torrents, Torrent};
|
use types::{TorrentGetField, Torrents, Torrent};
|
||||||
|
use types::TorrentAction;
|
||||||
|
|
||||||
pub struct TransClient {
|
pub struct TransClient {
|
||||||
url: String,
|
url: String,
|
||||||
@ -73,6 +74,10 @@ impl TransClient {
|
|||||||
self.call(RpcRequest::torrent_get(fields)).await
|
self.call(RpcRequest::torrent_get(fields)).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn torrent_action(&self, action: TorrentAction, ids: Vec<i64>) -> Result<RpcResponse<Nothing>> {
|
||||||
|
self.call(RpcRequest::torrent_action(action, ids)).await
|
||||||
|
}
|
||||||
|
|
||||||
async fn call<RS> (&self, request: RpcRequest) -> Result<RpcResponse<RS>>
|
async fn call<RS> (&self, request: RpcRequest) -> Result<RpcResponse<RS>>
|
||||||
where RS : RpcResponseArgument + DeserializeOwned + std::fmt::Debug
|
where RS : RpcResponseArgument + DeserializeOwned + std::fmt::Debug
|
||||||
{
|
{
|
||||||
|
|||||||
@ -13,9 +13,11 @@ pub struct BasicAuth {
|
|||||||
pub(crate) use self::request::RpcRequest;
|
pub(crate) use self::request::RpcRequest;
|
||||||
pub use self::request::ArgumentFields;
|
pub use self::request::ArgumentFields;
|
||||||
pub use self::request::TorrentGetField;
|
pub use self::request::TorrentGetField;
|
||||||
|
pub use self::request::TorrentAction;
|
||||||
|
|
||||||
pub use self::response::RpcResponse;
|
pub use self::response::RpcResponse;
|
||||||
pub(crate) use self::response::RpcResponseArgument;
|
pub(crate) use self::response::RpcResponseArgument;
|
||||||
pub use self::response::SessionGet;
|
pub use self::response::SessionGet;
|
||||||
pub use self::response::Torrents;
|
pub use self::response::Torrents;
|
||||||
pub use self::response::Torrent;
|
pub use self::response::Torrent;
|
||||||
|
pub use self::response::Nothing;
|
||||||
@ -4,9 +4,7 @@ use serde::Serialize;
|
|||||||
pub struct RpcRequest {
|
pub struct RpcRequest {
|
||||||
method: String,
|
method: String,
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
arguments: Option<Fields<String>>,
|
arguments: Option<Args>,
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
|
||||||
ids: Option<String>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RpcRequest {
|
impl RpcRequest {
|
||||||
@ -14,7 +12,6 @@ impl RpcRequest {
|
|||||||
RpcRequest {
|
RpcRequest {
|
||||||
method: String::from("session-get"),
|
method: String::from("session-get"),
|
||||||
arguments: None,
|
arguments: None,
|
||||||
ids: None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -22,11 +19,16 @@ impl RpcRequest {
|
|||||||
let string_fields = fields.iter().map(|f| f.to_str()).collect();
|
let string_fields = fields.iter().map(|f| f.to_str()).collect();
|
||||||
RpcRequest {
|
RpcRequest {
|
||||||
method: String::from("torrent-get"),
|
method: String::from("torrent-get"),
|
||||||
arguments: Some (Fields { fields: string_fields }),
|
arguments: Some (Args { fields: Some(string_fields), ids: None }),
|
||||||
ids: None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn torrent_action(action: TorrentAction, ids: Vec<i64>) -> RpcRequest {
|
||||||
|
RpcRequest {
|
||||||
|
method: action.to_str(),
|
||||||
|
arguments: Some (Args { fields: None, ids: Some(ids) }),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -34,72 +36,95 @@ pub trait ArgumentFields {}
|
|||||||
impl ArgumentFields for TorrentGetField{}
|
impl ArgumentFields for TorrentGetField{}
|
||||||
|
|
||||||
#[derive(Serialize, Debug, RustcEncodable)]
|
#[derive(Serialize, Debug, RustcEncodable)]
|
||||||
struct Fields<T> {
|
struct Args {
|
||||||
fields: Vec<T>
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
|
fields: Option<Vec<String>>,
|
||||||
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
|
ids: Option<Vec<i64>>
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum TorrentGetField {
|
pub enum TorrentGetField {
|
||||||
ID,
|
Id,
|
||||||
ADDEDDATE,
|
Addeddate,
|
||||||
NAME,
|
Name,
|
||||||
TOTALSIZE,
|
Totalsize,
|
||||||
ERROR,
|
Error,
|
||||||
ERRORSTRING,
|
Errorstring,
|
||||||
ETA,
|
Eta,
|
||||||
ISFINISHED,
|
Isfinished,
|
||||||
ISSTALLED,
|
Isstalled,
|
||||||
LEFTUNTILDONE,
|
Leftuntildone,
|
||||||
METADATAPERCENTCOMPLETE,
|
Metadatapercentcomplete,
|
||||||
PEERSCONNECTED,
|
Peersconnected,
|
||||||
PEERSGETTINGFROMUS,
|
Peersgettingfromus,
|
||||||
PEERSSENDINGTOUS,
|
Peerssendingtous,
|
||||||
PERCENTDONE,
|
Percentdone,
|
||||||
QUEUEPOSITION,
|
Queueposition,
|
||||||
RATEDOWNLOAD,
|
Ratedownload,
|
||||||
RATEUPLOAD,
|
Rateupload,
|
||||||
RECHECKPROGRESS,
|
Recheckprogress,
|
||||||
SEEDRATIOMODE,
|
Seedratiomode,
|
||||||
SEEDRATIOLIMIT,
|
Seedratiolimit,
|
||||||
SIZEWHENDONE,
|
Sizewhendone,
|
||||||
STATUS,
|
Status,
|
||||||
TRACKERS,
|
Trackers,
|
||||||
DOWNLOADDIR,
|
Downloaddir,
|
||||||
UPLOADEDEVER,
|
Uploadedever,
|
||||||
UPLOADRATIO,
|
Uploadratio,
|
||||||
WEBSEEDSSENDINGTOUS,
|
Webseedssendingtous,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TorrentGetField {
|
impl TorrentGetField {
|
||||||
pub fn to_str(&self) -> String {
|
pub fn to_str(&self) -> String {
|
||||||
match self {
|
match self {
|
||||||
TorrentGetField::ID => "id",
|
TorrentGetField::Id => "id",
|
||||||
TorrentGetField::ADDEDDATE => "addedDate",
|
TorrentGetField::Addeddate => "addedDate",
|
||||||
TorrentGetField::NAME => "name",
|
TorrentGetField::Name => "name",
|
||||||
TorrentGetField::TOTALSIZE => "totalSize",
|
TorrentGetField::Totalsize => "totalSize",
|
||||||
TorrentGetField::ERROR => "error",
|
TorrentGetField::Error => "error",
|
||||||
TorrentGetField::ERRORSTRING => "errorString",
|
TorrentGetField::Errorstring => "errorString",
|
||||||
TorrentGetField::ETA => "eta",
|
TorrentGetField::Eta => "eta",
|
||||||
TorrentGetField::ISFINISHED => "isFinished",
|
TorrentGetField::Isfinished => "isFinished",
|
||||||
TorrentGetField::ISSTALLED => "isStalled",
|
TorrentGetField::Isstalled => "isStalled",
|
||||||
TorrentGetField::LEFTUNTILDONE => "leftUntilDone",
|
TorrentGetField::Leftuntildone => "leftUntilDone",
|
||||||
TorrentGetField::METADATAPERCENTCOMPLETE => "metadataPercentComplete",
|
TorrentGetField::Metadatapercentcomplete => "metadataPercentComplete",
|
||||||
TorrentGetField::PEERSCONNECTED => "peersConnected",
|
TorrentGetField::Peersconnected => "peersConnected",
|
||||||
TorrentGetField::PEERSGETTINGFROMUS => "peersGettingFromUs",
|
TorrentGetField::Peersgettingfromus => "peersGettingFromUs",
|
||||||
TorrentGetField::PEERSSENDINGTOUS => "peersSendingToUs",
|
TorrentGetField::Peerssendingtous => "peersSendingToUs",
|
||||||
TorrentGetField::PERCENTDONE => "percentDone",
|
TorrentGetField::Percentdone => "percentDone",
|
||||||
TorrentGetField::QUEUEPOSITION => "queuePosition",
|
TorrentGetField::Queueposition => "queuePosition",
|
||||||
TorrentGetField::RATEDOWNLOAD => "rateDownload",
|
TorrentGetField::Ratedownload => "rateDownload",
|
||||||
TorrentGetField::RATEUPLOAD => "rateUpload",
|
TorrentGetField::Rateupload => "rateUpload",
|
||||||
TorrentGetField::RECHECKPROGRESS => "recheckProgress",
|
TorrentGetField::Recheckprogress => "recheckProgress",
|
||||||
TorrentGetField::SEEDRATIOMODE => "seedRatioMode",
|
TorrentGetField::Seedratiomode => "seedRatioMode",
|
||||||
TorrentGetField::SEEDRATIOLIMIT => "seedRatioLimit",
|
TorrentGetField::Seedratiolimit => "seedRatioLimit",
|
||||||
TorrentGetField::SIZEWHENDONE => "sizeWhenDone",
|
TorrentGetField::Sizewhendone => "sizeWhenDone",
|
||||||
TorrentGetField::STATUS => "status",
|
TorrentGetField::Status => "status",
|
||||||
TorrentGetField::TRACKERS => "trackers",
|
TorrentGetField::Trackers => "trackers",
|
||||||
TorrentGetField::DOWNLOADDIR => "downloadDir",
|
TorrentGetField::Downloaddir => "downloadDir",
|
||||||
TorrentGetField::UPLOADEDEVER => "uploadedEver",
|
TorrentGetField::Uploadedever => "uploadedEver",
|
||||||
TorrentGetField::UPLOADRATIO => "uploadRatio",
|
TorrentGetField::Uploadratio => "uploadRatio",
|
||||||
TorrentGetField::WEBSEEDSSENDINGTOUS => "webseedsSendingToUs",
|
TorrentGetField::Webseedssendingtous => "webseedsSendingToUs",
|
||||||
}.to_string()
|
}.to_string()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum TorrentAction {
|
||||||
|
Start,
|
||||||
|
Stop,
|
||||||
|
StartNow,
|
||||||
|
Verify,
|
||||||
|
Reannounce,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TorrentAction {
|
||||||
|
pub fn to_str(&self) -> String {
|
||||||
|
match self {
|
||||||
|
TorrentAction::Start => "torrent-start",
|
||||||
|
TorrentAction::Stop => "torrent-stop",
|
||||||
|
TorrentAction::StartNow => "torrent-start-now",
|
||||||
|
TorrentAction::Verify => "torrent-verify",
|
||||||
|
TorrentAction::Reannounce => "torrent-reannounce",
|
||||||
|
}.to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -85,4 +85,8 @@ pub struct Torrents<T> {
|
|||||||
pub struct Trackers {
|
pub struct Trackers {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub announce: String,
|
pub announce: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug, RustcEncodable)]
|
||||||
|
pub struct Nothing{}
|
||||||
|
impl RpcResponseArgument for Nothing {}
|
||||||
Loading…
Reference in New Issue
Block a user