211 lines
5.6 KiB
Rust
211 lines
5.6 KiB
Rust
use gloo_net::http::Request;
|
|
use thiserror::Error;
|
|
|
|
#[derive(Debug, Error)]
|
|
pub enum ApiError {
|
|
#[error("Network error")]
|
|
Network,
|
|
#[error("Server error: {status}")]
|
|
Server { status: u16 },
|
|
#[error("Login failed")]
|
|
LoginFailed,
|
|
#[error("Unauthorized")]
|
|
Unauthorized,
|
|
#[error("Too many requests")]
|
|
RateLimited,
|
|
#[error("Server function error: {0}")]
|
|
ServerFn(String),
|
|
}
|
|
|
|
fn base_url() -> String {
|
|
"/api".to_string()
|
|
}
|
|
|
|
pub mod auth {
|
|
use super::*;
|
|
|
|
#[derive(serde::Serialize)]
|
|
pub struct LoginRequest {
|
|
pub username: String,
|
|
pub password: String,
|
|
pub remember_me: bool,
|
|
}
|
|
|
|
pub async fn login(
|
|
username: &str,
|
|
password: &str,
|
|
remember_me: bool,
|
|
) -> Result<(), ApiError> {
|
|
let req = LoginRequest {
|
|
username: username.to_string(),
|
|
password: password.to_string(),
|
|
remember_me,
|
|
};
|
|
let resp = Request::post(&format!("{}/auth/login", base_url()))
|
|
.json(&req)
|
|
.map_err(|_| ApiError::Network)?
|
|
.send()
|
|
.await
|
|
.map_err(|_| ApiError::Network)?;
|
|
|
|
if resp.ok() {
|
|
Ok(())
|
|
} else if resp.status() == 429 {
|
|
Err(ApiError::RateLimited)
|
|
} else {
|
|
Err(ApiError::LoginFailed)
|
|
}
|
|
}
|
|
|
|
pub async fn logout() -> Result<(), ApiError> {
|
|
Request::post(&format!("{}/auth/logout", base_url()))
|
|
.send()
|
|
.await
|
|
.map_err(|_| ApiError::Network)?;
|
|
Ok(())
|
|
}
|
|
|
|
pub async fn check_auth() -> Result<bool, ApiError> {
|
|
let resp = Request::get(&format!("{}/auth/check", base_url()))
|
|
.send()
|
|
.await
|
|
.map_err(|_| ApiError::Network)?;
|
|
Ok(resp.ok())
|
|
}
|
|
|
|
#[derive(serde::Deserialize)]
|
|
pub struct UserResponse {
|
|
pub username: String,
|
|
}
|
|
|
|
pub async fn get_user() -> Result<UserResponse, ApiError> {
|
|
let resp = Request::get(&format!("{}/auth/check", base_url()))
|
|
.send()
|
|
.await
|
|
.map_err(|_| ApiError::Network)?;
|
|
let user = resp.json().await.map_err(|_| ApiError::Network)?;
|
|
Ok(user)
|
|
}
|
|
}
|
|
|
|
pub mod setup {
|
|
use super::*;
|
|
|
|
#[derive(serde::Serialize)]
|
|
pub struct SetupRequest {
|
|
pub username: String,
|
|
pub password: String,
|
|
}
|
|
|
|
#[derive(serde::Deserialize)]
|
|
pub struct SetupStatusResponse {
|
|
pub completed: bool,
|
|
}
|
|
|
|
pub async fn get_status() -> Result<SetupStatusResponse, ApiError> {
|
|
let resp = Request::get(&format!("{}/setup/status", base_url()))
|
|
.send()
|
|
.await
|
|
.map_err(|_| ApiError::Network)?;
|
|
let status = resp.json().await.map_err(|_| ApiError::Network)?;
|
|
Ok(status)
|
|
}
|
|
|
|
pub async fn setup(username: &str, password: &str) -> Result<(), ApiError> {
|
|
let req = SetupRequest {
|
|
username: username.to_string(),
|
|
password: password.to_string(),
|
|
};
|
|
Request::post(&format!("{}/setup", base_url()))
|
|
.json(&req)
|
|
.map_err(|_| ApiError::Network)?
|
|
.send()
|
|
.await
|
|
.map_err(|_| ApiError::Network)?;
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
pub mod settings {
|
|
use super::*;
|
|
use shared::GlobalLimitRequest;
|
|
|
|
pub async fn set_global_limits(req: &GlobalLimitRequest) -> Result<(), ApiError> {
|
|
shared::server_fns::settings::set_global_limits(
|
|
req.max_download_rate,
|
|
req.max_upload_rate,
|
|
)
|
|
.await
|
|
.map_err(|e| ApiError::ServerFn(e.to_string()))
|
|
}
|
|
}
|
|
|
|
pub mod push {
|
|
use super::*;
|
|
|
|
pub async fn get_public_key() -> Result<String, ApiError> {
|
|
shared::server_fns::push::get_public_key()
|
|
.await
|
|
.map_err(|e| ApiError::ServerFn(e.to_string()))
|
|
}
|
|
|
|
pub async fn subscribe(endpoint: &str, p256dh: &str, auth: &str) -> Result<(), ApiError> {
|
|
shared::server_fns::push::subscribe_push(
|
|
endpoint.to_string(),
|
|
p256dh.to_string(),
|
|
auth.to_string(),
|
|
)
|
|
.await
|
|
.map_err(|e| ApiError::ServerFn(e.to_string()))
|
|
}
|
|
}
|
|
|
|
pub mod torrent {
|
|
use super::*;
|
|
|
|
pub async fn add(uri: &str) -> Result<(), ApiError> {
|
|
shared::server_fns::torrent::add_torrent(uri.to_string())
|
|
.await
|
|
.map_err(|e| ApiError::ServerFn(e.to_string()))
|
|
}
|
|
|
|
pub async fn action(hash: &str, action: &str) -> Result<(), ApiError> {
|
|
shared::server_fns::torrent::torrent_action(hash.to_string(), action.to_string())
|
|
.await
|
|
.map(|_| ())
|
|
.map_err(|e| ApiError::ServerFn(e.to_string()))
|
|
}
|
|
|
|
pub async fn delete(hash: &str) -> Result<(), ApiError> {
|
|
action(hash, "delete").await
|
|
}
|
|
|
|
pub async fn delete_with_data(hash: &str) -> Result<(), ApiError> {
|
|
action(hash, "delete_with_data").await
|
|
}
|
|
|
|
pub async fn start(hash: &str) -> Result<(), ApiError> {
|
|
action(hash, "start").await
|
|
}
|
|
|
|
pub async fn stop(hash: &str) -> Result<(), ApiError> {
|
|
action(hash, "stop").await
|
|
}
|
|
|
|
pub async fn set_label(hash: &str, label: &str) -> Result<(), ApiError> {
|
|
shared::server_fns::torrent::set_label(hash.to_string(), label.to_string())
|
|
.await
|
|
.map_err(|e| ApiError::ServerFn(e.to_string()))
|
|
}
|
|
|
|
pub async fn set_priority(hash: &str, file_index: u32, priority: u8) -> Result<(), ApiError> {
|
|
shared::server_fns::torrent::set_file_priority(
|
|
hash.to_string(),
|
|
file_index,
|
|
priority,
|
|
)
|
|
.await
|
|
.map_err(|e| ApiError::ServerFn(e.to_string()))
|
|
}
|
|
}
|