use std::time::Duration;
use reqwest::{Error, Response};
use url::Url;
pub struct ConnectionInfo {
pub url: Url,
pub token: String,
}
impl ConnectionInfo {
#[must_use]
pub fn new(url: Url, token: String) -> Self {
Self { url, token }
}
}
const TOKEN_PARAM_NAME: &str = "token";
const API_PATH: &str = "api/v1";
const TOTAL_REQUEST_TIMEOUT_IN_SECS: u64 = 5;
pub struct Client {
pub connection_info: ConnectionInfo,
api_base_url: Url,
client: reqwest::Client,
token_param: [(String, String); 1],
}
impl Client {
pub fn new(connection_info: ConnectionInfo) -> Result<Self, Error> {
let api_base_url = connection_info.url.join(API_PATH).expect("valid URL API path");
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(TOTAL_REQUEST_TIMEOUT_IN_SECS))
.build()?;
let token_param = [(TOKEN_PARAM_NAME.to_string(), connection_info.token.to_string())];
Ok(Self {
connection_info,
api_base_url,
client,
token_param,
})
}
pub async fn whitelist_torrent(&self, info_hash: &str) -> Result<Response, Error> {
let request_url = format!("{}/whitelist/{}", self.api_base_url, info_hash);
self.client.post(request_url).query(&self.token_param).send().await
}
pub async fn remove_torrent_from_whitelist(&self, info_hash: &str) -> Result<Response, Error> {
let request_url = format!("{}/whitelist/{}", self.api_base_url, info_hash);
self.client.delete(request_url).query(&self.token_param).send().await
}
pub async fn retrieve_new_tracker_key(&self, token_valid_seconds: u64) -> Result<Response, Error> {
let request_url = format!("{}/key/{}", self.api_base_url, token_valid_seconds);
self.client.post(request_url).query(&self.token_param).send().await
}
pub async fn get_torrent_info(&self, info_hash: &str) -> Result<Response, Error> {
let request_url = format!("{}/torrent/{}", self.api_base_url, info_hash);
self.client.get(request_url).query(&self.token_param).send().await
}
pub async fn get_torrents_info(&self, info_hashes: &[String]) -> Result<Response, Error> {
let request_url = format!("{}/torrents", self.api_base_url);
let mut query_params: Vec<(String, String)> = Vec::with_capacity(info_hashes.len() + 1);
query_params.push((TOKEN_PARAM_NAME.to_string(), self.connection_info.token.clone()));
for info_hash in info_hashes {
query_params.push(("info_hash".to_string(), info_hash.clone()));
}
self.client.get(request_url).query(&query_params).send().await
}
}