qbt-rs/src/api.rs
2022-10-16 15:59:50 +02:00

64 lines
1.9 KiB
Rust

use snafu::ResultExt;
use qbittorrent_web_api::Api;
use tokio::runtime::Builder;
use crate::config::Config;
use crate::error::{Error, ApiSnafu as IOError, InternalApiSnafu as ApiError};
pub struct ApiClient {
pub rt: tokio::runtime::Runtime,
pub api: qbittorrent_web_api::api_impl::Authenticated
}
impl ApiClient {
pub fn from_config(config: &Config) -> Result<ApiClient, Error> {
Self::new(&config.format_host(), &config.qbittorrent.login, &config.qbittorrent.password)
}
pub fn new(host: &str, login: &str, password: &str) -> Result<ApiClient, Error> {
let rt = Builder::new_current_thread()
.enable_all()
.build().context(IOError)?;
// Call the asynchronous connect method using the runtime.
let api = rt.block_on(Api::login(host, &login, &password)).context(ApiError)?;
Ok(ApiClient {
rt,
api,
})
}
pub fn add(&self, magnet: &str, paused: bool) -> Result<(), Error> {
let base_call = self.api.torrent_management();
let call = if paused {
base_call.add(magnet).paused("true")
} else {
base_call.add(magnet)
};
let res = self.rt.block_on(call.send_raw()).context(ApiError)?;
if res == "Ok." {
Ok(())
} else {
Err(Error::message(res.clone()))
}
}
pub fn get(&self, hash: &str) -> Result<Option<String>, Error> {
let res = self.rt.block_on(self.api.torrent_management().properties_raw(hash)).context(ApiError)?;
if res == "" {
Ok(None)
} else {
Ok(Some(res))
}
}
pub fn list(&self) -> Result<String, Error> {
Ok(
self.rt.block_on(self.api.torrent_management().info().send_raw()).context(ApiError)?
)
}
}
// TODO: typestate builder https://www.greyblake.com/blog/builder-with-typestate-in-rust/
//struct ApiClientBuilder {}