64 lines
1.9 KiB
Rust
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 {}
|