1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
pub mod data; pub mod param; pub mod services; mod errors; pub use errors::*; #[derive(Debug, serde::Deserialize)] pub struct Pager<T> { total: usize, data: Vec<T>, } #[derive(Clone)] struct Config { base_url: String, } pub struct Api { config: Config, pub accounts: services::Accounts, } impl Api { pub fn new(base_url: &str) -> Self { let config = Config { base_url: base_url.to_string(), }; Self { accounts: services::Accounts::new(&config), config, } } pub async fn auth(&self, username: &str, password: &str) -> crate::Result<data::Token> { let oauth_clients: data::OauthClient = Self::get(&self.config, "/oauth-clients/local", (), None).await?; let params = param::Auth { client_id: oauth_clients.client_id, client_secret: oauth_clients.client_secret, username: username.to_string(), password: password.to_string(), grant_type: "password".to_string(), response_type: "code".to_string(), }; Self::post(&self.config, "/users/token", ¶ms, None).await } pub(crate) async fn get<T: for<'de> serde::Deserialize<'de>, P: serde::Serialize>(config: &Config, path: &str, params: P, auth: Option<&data::Token>) -> crate::Result<T> { Self::request(reqwest::Method::GET, config, path, params, auth).await } pub(crate) async fn post<T: for<'de> serde::Deserialize<'de>, P: serde::Serialize>(config: &Config, path: &str, params: P, auth: Option<&data::Token>) -> crate::Result<T> { Self::request(reqwest::Method::POST, config, path, params, auth).await } async fn request<T: for<'de> serde::Deserialize<'de>, P: serde::Serialize>(method: reqwest::Method, config: &Config, path: &str, params: P, auth: Option<&data::Token>) -> crate::Result<T> { let url = format!("{}/api/v1{}", config.base_url, path); let client = reqwest::Client::new(); let mut request = client.request(method.clone(), &url); request = match method { reqwest::Method::GET => request.query(¶ms), _ => request.form(¶ms), }; if let Some(auth) = auth { request = request.bearer_auth(&auth.access_token); } let response = request.send() .await?; if response.status().is_success() { Ok(response.json().await?) } else { Err(crate::Error::Peertube(response.json().await?)) } } } #[cfg(test)] mod test { pub(crate) fn instance() -> String { std::env::var("INSTANCE").unwrap() } pub(crate) fn username() -> String { std::env::var("USERNAME").unwrap() } pub(crate) fn password() -> String { std::env::var("PASSWORD").unwrap() } pub(crate) fn api() -> crate::Api { env_logger::try_init().ok(); dotenv::dotenv().ok(); crate::Api::new(&instance()) } }