mirror of
https://github.com/kristoferssolo/transmission-rpc.git
synced 2025-10-21 20:10:37 +00:00
init
This commit is contained in:
parent
ac3cefea36
commit
baad21f277
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/target
|
||||
Cargo.lock
|
||||
.env
|
||||
24
Cargo.toml
Normal file
24
Cargo.toml
Normal file
@ -0,0 +1,24 @@
|
||||
[package]
|
||||
name = "transmission-rpc"
|
||||
version = "0.1.0"
|
||||
authors = ["red <red.avtovo@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
|
||||
[dependencies]
|
||||
dotenv = "0.15.0"
|
||||
reqwest = { version = "0.10.4", features = ["json", "rustls-tls"] }
|
||||
tokio = { version = "0.2", features = ["full"] }
|
||||
tokio-postgres = "0.5.2"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
futures = "0.3.3"
|
||||
serde_json = "1.0"
|
||||
ajson = "0.2"
|
||||
|
||||
log = "0.4.8"
|
||||
env_logger = "0.7.1"
|
||||
|
||||
bb8-postgres = "0.4.0"
|
||||
bb8 = "0.4.1"
|
||||
|
||||
rustc-serialize = "0.3.24"
|
||||
19
README.md
Normal file
19
README.md
Normal file
@ -0,0 +1,19 @@
|
||||
Library to communicate with transmission rpc
|
||||
|
||||
spec: https://github.com/transmission/transmission/blob/master/extras/rpc-spec.txt
|
||||
|
||||
Supported Methods:
|
||||
|
||||
- [ ] torrent-set
|
||||
- [ ] torrent-get
|
||||
- [ ] torrent-add
|
||||
- [ ] torrent-remove
|
||||
- [ ] torrent-set-location
|
||||
- [ ] torrent-rename-path
|
||||
- [ ] session-set
|
||||
- [X] session-get
|
||||
- [ ] session-stats
|
||||
- [ ] blocklist-update
|
||||
- [ ] port-test
|
||||
- [ ] session-close
|
||||
- [ ] free-space
|
||||
109
src/main.rs
Normal file
109
src/main.rs
Normal file
@ -0,0 +1,109 @@
|
||||
#[allow(unused_imports)]
|
||||
#[allow(dead_code)]
|
||||
|
||||
extern crate ajson;
|
||||
extern crate bb8;
|
||||
extern crate bb8_postgres;
|
||||
extern crate env_logger;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate reqwest;
|
||||
extern crate tokio_postgres;
|
||||
|
||||
use std::env;
|
||||
use dotenv::dotenv;
|
||||
use std::collections::HashMap;
|
||||
use reqwest::header::CONTENT_TYPE;
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct BasicAuth {
|
||||
user: String,
|
||||
password: String,
|
||||
}
|
||||
|
||||
mod models;
|
||||
use models::request::SessionGet;
|
||||
use models::response::RpcResponse;
|
||||
use models::entity::SessionInfo;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
not_main().await
|
||||
}
|
||||
|
||||
async fn not_main() -> Result<()> {
|
||||
dotenv().ok();
|
||||
env_logger::init();
|
||||
|
||||
let url= env::var("URL")?;
|
||||
let basic_auth = Some(BasicAuth{user: env::var("TUSER")?, password: env::var("TPWD")?});
|
||||
info!("Loaded auth: {:?}", &basic_auth);
|
||||
let rq: reqwest::RequestBuilder = rpc_request(url.as_ref(), &basic_auth)
|
||||
.header("X-Transmission-Session-Id", get_session_id(url.as_ref(), &basic_auth).await)
|
||||
.json(&SessionGet::default());
|
||||
debug!("Request body: {:?}", rq.try_clone().unwrap().body_string()?);
|
||||
|
||||
// let p2 = Point{ x: 34, ..Default::default() };
|
||||
|
||||
let resp: reqwest::Response = rq.send().await?;
|
||||
// print!("{:?}", resp.text().await);
|
||||
let rpc_response: RpcResponse<SessionInfo> = resp.json().await?;
|
||||
info!("{:#?}", rpc_response);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
trait BodyString {
|
||||
fn body_string(self) -> Result<String>;
|
||||
}
|
||||
|
||||
impl BodyString for reqwest::RequestBuilder {
|
||||
fn body_string(self) -> Result<String> {
|
||||
let rq = self.build()?;
|
||||
let body = rq.body().unwrap().as_bytes().unwrap();
|
||||
Ok(std::str::from_utf8(body)?.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
fn rpc_request(url: &str, basic_auth: &Option<BasicAuth>) -> reqwest::RequestBuilder {
|
||||
let client = reqwest::Client::new();
|
||||
if let Some(auth) = basic_auth {
|
||||
client.post(url.clone())
|
||||
.basic_auth(&auth.user, Some(&auth.password))
|
||||
} else {
|
||||
client.post(url.clone())
|
||||
}
|
||||
.header(CONTENT_TYPE, "application/json")
|
||||
}
|
||||
|
||||
async fn get_session_id(url: &str, basic_auth: &Option<BasicAuth>) -> String {
|
||||
let mut map = HashMap::new();
|
||||
map.insert("method", "session-get");
|
||||
info!("Requesting session id info");
|
||||
let response: reqwest::Response = rpc_request(url, basic_auth)
|
||||
.json(&map)
|
||||
.send()
|
||||
.await
|
||||
.unwrap();
|
||||
let session_id = response.headers()
|
||||
.get("x-transmission-session-id")
|
||||
.expect("Unable to get session id")
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.to_owned();
|
||||
info!("Received session id: {}", session_id);
|
||||
session_id
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::not_main;
|
||||
use crate::Result;
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_works() -> Result<()> {
|
||||
dotenv().ok();
|
||||
not_main().await
|
||||
}
|
||||
}
|
||||
14
src/models/entity.rs
Normal file
14
src/models/entity.rs
Normal file
@ -0,0 +1,14 @@
|
||||
use serde::Deserialize;
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct SessionInfo {
|
||||
#[serde(rename="blocklist-enabled")]
|
||||
blocklist_enabled: bool,
|
||||
#[serde(rename="download-dir")]
|
||||
download_dir: String,
|
||||
encryption: String,
|
||||
#[serde(rename="rpc-version")]
|
||||
rpc_version: i32,
|
||||
#[serde(rename="rpc-version-minimum")]
|
||||
rpc_version_minimum: i32,
|
||||
version: String,
|
||||
}
|
||||
4
src/models/mod.rs
Normal file
4
src/models/mod.rs
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
pub mod request;
|
||||
pub mod response;
|
||||
pub mod entity;
|
||||
12
src/models/request.rs
Normal file
12
src/models/request.rs
Normal file
@ -0,0 +1,12 @@
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Serialize, Debug, RustcEncodable)]
|
||||
pub struct SessionGet {
|
||||
method: String
|
||||
}
|
||||
|
||||
impl Default for SessionGet{
|
||||
fn default() -> SessionGet {
|
||||
SessionGet { method: String::from("session-get") }
|
||||
}
|
||||
}
|
||||
6
src/models/response.rs
Normal file
6
src/models/response.rs
Normal file
@ -0,0 +1,6 @@
|
||||
use serde::Deserialize;
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct RpcResponse<T> {
|
||||
arguments: T,
|
||||
result: String
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user