A decentralized music tracking and discovery platform built on AT Protocol 🎵

[scrobbler] add artist picture from spotify

+25 -2
+4
crates/scrobbler/src/scrobbler.rs
··· 175 175 track.album = album; 176 176 } 177 177 178 + if let Some(artist) = spotify_client.get_artist(&track.album.artists[0].id).await? { 179 + track.artists[0] = artist; 180 + } 181 + 178 182 rocksky::scrobble(cache, &did, track.into(), scrobble.timestamp).await?; 179 183 tokio::time::sleep(std::time::Duration::from_secs(1)).await; 180 184 continue;
+20 -1
crates/scrobbler/src/spotify/client.rs
··· 1 - use super::types::{Album, SearchResponse}; 1 + use super::types::{Album, Artist, SearchResponse}; 2 2 use anyhow::Error; 3 3 4 4 pub const BASE_URL: &str = "https://api.spotify.com/v1"; ··· 41 41 if data == "Too many requests" { 42 42 println!("> retry-after {}", headers.get("retry-after").unwrap().to_str().unwrap()); 43 43 println!("> {} [get_album]", data); 44 + return Ok(None); 45 + } 46 + 47 + Ok(Some(serde_json::from_str(&data)?)) 48 + } 49 + 50 + pub async fn get_artist(&self, id: &str) -> Result<Option<Artist>, Error> { 51 + let url = format!("{}/artists/{}", BASE_URL, id); 52 + let client = reqwest::Client::new(); 53 + let response = client.get(&url) 54 + .bearer_auth(&self.token) 55 + .send().await?; 56 + 57 + let headers = response.headers().clone(); 58 + let data = response.text().await?; 59 + 60 + if data == "Too many requests" { 61 + println!("> retry-after {}", headers.get("retry-after").unwrap().to_str().unwrap()); 62 + println!("> {} [get_artist]", data); 44 63 return Ok(None); 45 64 } 46 65
+1 -1
crates/scrobbler/src/types.rs
··· 139 139 duration: track.duration_ms as u32, 140 140 album_art: track.album.images.first().map(|image| image.url.clone()), 141 141 spotify_link: Some(track.external_urls.spotify.clone()), 142 - artist_picture: track.artists.first().and_then(|artist| { 142 + artist_picture: track.album.artists.first().and_then(|artist| { 143 143 artist 144 144 .images 145 145 .as_ref()