use anyhow::Result; use jellycommon::NodePublic; use reqwest::{ header::{HeaderMap, HeaderValue}, Client, }; use serde_json::json; use std::time::Duration; #[derive(Debug, Clone)] pub struct Instance { pub host: String, pub tls: bool, } impl Instance { pub fn new(host: String, tls: bool) -> Self { Self { host, tls } } pub fn base(&self) -> String { format!( "{}://{}", if self.tls { "https" } else { "http" }, self.host ) } pub async fn login( self, username: String, password: String, expire: Duration, ) -> anyhow::Result { let session_token = Client::builder() .build()? .post(format!("{}/api/create_session", self.base())) .json(&json!({ "expire": expire.as_secs(), "password": password, "username": username, })) .send() .await? .json() .await?; let mut headers = HeaderMap::new(); headers.insert( "Cookie", HeaderValue::from_str(&format!("session={session_token}")).unwrap(), ); headers.insert("Accept", HeaderValue::from_static("application/json")); Ok(Session { instance: self, session_token, client: Client::builder().default_headers(headers).build().unwrap(), }) } } pub struct Session { client: Client, instance: Instance, session_token: String, } impl Session { fn session_param(&self) -> String { format!("session={}", self.session_token) } pub async fn node(&self, id: &str) -> Result { Ok(self .client .get(format!("{}/n/{id}", self.instance.base())) .send() .await? .json() .await?) } // pub async fn node_asset(&self, id: &str, role: AssetRole) -> Result { // Ok(self // .client // .get(format!("/n/{id}")) // .send() // .await? // .bytes() // .await?) // } pub fn stream(&self, id: &str, tracks: &[usize], webm: bool) -> String { format!( "{}/n/{}/stream?tracks={}&webm={}&{}", self.instance.base(), id, tracks .iter() .map(|v| format!("{v}")) .collect::>() .join(","), if webm { "1" } else { "0" }, self.session_param() ) } }