A decentralized music tracking and discovery platform built on AT Protocol 馃幍
at feat/pgpull 61 lines 2.0 kB view raw
1use super::types::{Album, Artist, SearchResponse}; 2use anyhow::Error; 3 4pub const BASE_URL: &str = "https://api.spotify.com/v1"; 5 6pub struct SpotifyClient { 7 token: String, 8} 9 10impl SpotifyClient { 11 pub fn new(token: &str) -> Self { 12 SpotifyClient { 13 token: token.to_string(), 14 } 15 } 16 17 pub async fn search(&self, query: &str) -> Result<SearchResponse, Error> { 18 let url = format!("{}/search", BASE_URL); 19 let client = reqwest::Client::new(); 20 let response = client 21 .get(&url) 22 .bearer_auth(&self.token) 23 .query(&[("type", "track"), ("q", query)]) 24 .send() 25 .await?; 26 let result = response.json().await?; 27 Ok(result) 28 } 29 30 pub async fn get_album(&self, id: &str) -> Result<Option<Album>, Error> { 31 let url = format!("{}/albums/{}", BASE_URL, id); 32 let client = reqwest::Client::new(); 33 let response = client.get(&url).bearer_auth(&self.token).send().await?; 34 35 let headers = response.headers().clone(); 36 let data = response.text().await?; 37 38 if data == "Too many requests" { 39 tracing::info!(retry_after = %headers.get("retry-after").unwrap().to_str().unwrap(), data = %data, "Rate limited on get_album"); 40 return Ok(None); 41 } 42 43 Ok(Some(serde_json::from_str(&data)?)) 44 } 45 46 pub async fn get_artist(&self, id: &str) -> Result<Option<Artist>, Error> { 47 let url = format!("{}/artists/{}", BASE_URL, id); 48 let client = reqwest::Client::new(); 49 let response = client.get(&url).bearer_auth(&self.token).send().await?; 50 51 let headers = response.headers().clone(); 52 let data = response.text().await?; 53 54 if data == "Too many requests" { 55 tracing::info!(retry_after = %headers.get("retry-after").unwrap().to_str().unwrap(), data = %data, "Rate limited on get_artist"); 56 return Ok(None); 57 } 58 59 Ok(Some(serde_json::from_str(&data)?)) 60 } 61}