diff --git a/src/playlists.rs b/src/playlists.rs index 748c454..f17eb02 100644 --- a/src/playlists.rs +++ b/src/playlists.rs @@ -97,7 +97,7 @@ impl Playlists { let mut collected_tracks = Vec::new(); - let mut tracks_result = spotify.user_playlist_tracks(&id, 100, 0).ok(); + let mut tracks_result = spotify.user_playlist_tracks(&id, 100, 0); while let Some(ref tracks) = tracks_result.clone() { for listtrack in &tracks.items { collected_tracks.push(Track::new(&listtrack.track)); @@ -110,7 +110,6 @@ impl Playlists { debug!("requesting tracks again.."); spotify .user_playlist_tracks(&id, 100, tracks.offset + tracks.items.len() as u32) - .ok() } None => None, } @@ -144,7 +143,7 @@ impl Playlists { pub fn fetch_playlists(&self) { debug!("loading playlists"); - let mut lists_result = self.spotify.current_user_playlist(50, 0).ok(); + let mut lists_result = self.spotify.current_user_playlist(50, 0); while let Some(ref lists) = lists_result.clone() { for remote in &lists.items { if self.needs_download(remote) { @@ -162,7 +161,6 @@ impl Playlists { debug!("requesting playlists again.."); self.spotify .current_user_playlist(50, lists.offset + lists.items.len() as u32) - .ok() } None => None, } diff --git a/src/spotify.rs b/src/spotify.rs index 68b1ba4..e21c91c 100644 --- a/src/spotify.rs +++ b/src/spotify.rs @@ -11,6 +11,7 @@ use librespot::playback::config::Bitrate; use librespot::playback::player::Player; use rspotify::spotify::client::Spotify as SpotifyAPI; +use rspotify::spotify::client::ApiError; use rspotify::spotify::model::page::Page; use rspotify::spotify::model::playlist::{PlaylistTrack, SimplifiedPlaylist}; use rspotify::spotify::model::search::SearchTracks; @@ -281,16 +282,37 @@ impl Spotify { (*since).clone() } - pub fn search(&self, query: &str, limit: u32, offset: u32) -> Result { - self.api.search_track(query, limit, offset, None) + /// retries once when rate limits are hit + fn api_with_retry(&self, cb: F) -> Option + where F: Fn(&SpotifyAPI) -> Result { + match cb(&self.api) { + Ok(v) => Some(v), + Err(e) => { + debug!("api error: {:?}", e); + if let Ok(apierror) = e.downcast::() { + if let ApiError::RateLimited(d) = apierror { + debug!("rate limit hit. waiting {:?} seconds", d); + thread::sleep(Duration::from_secs(d.unwrap_or(0) as u64)); + cb(&self.api).ok() + } + else { None } + } + else { None } + } + } + } + + pub fn search(&self, query: &str, limit: u32, offset: u32) -> Option { + //let res = self.api.search_track(query, limit, offset, None); + self.api_with_retry(|api| api.search_track(query, limit, offset, None) ) } pub fn current_user_playlist( &self, limit: u32, offset: u32, - ) -> Result, Error> { - self.api.current_user_playlists(limit, offset) + ) -> Option> { + self.api_with_retry(|api| api.current_user_playlists(limit, offset) ) } pub fn user_playlist_tracks( @@ -298,9 +320,9 @@ impl Spotify { playlist_id: &str, limit: u32, offset: u32, - ) -> Result, Error> { - self.api - .user_playlist_tracks(&self.user, playlist_id, None, limit, offset, None) + ) -> Option> { + self.api_with_retry(|api| api + .user_playlist_tracks(&self.user, playlist_id, None, limit, offset, None)) } pub fn load(&self, track: &Track) { diff --git a/src/ui/search.rs b/src/ui/search.rs index 3d69165..1b255f9 100644 --- a/src/ui/search.rs +++ b/src/ui/search.rs @@ -53,7 +53,7 @@ impl SearchView { v.set_content(q); }); - if let Ok(results) = spotify.search(&query, 50, 0) { + if let Some(results) = spotify.search(&query, 50, 0) { let tracks = results .tracks .items