Use new pagination interface for playlist tracks
This commit is contained in:
@@ -32,35 +32,13 @@ impl Playlist {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_all_tracks(&self, spotify: Spotify) -> Vec<Track> {
|
fn get_all_tracks(&self, spotify: Spotify) -> Vec<Track> {
|
||||||
let mut collected_tracks = Vec::new();
|
let tracks_result = spotify.user_playlist_tracks(&self.id);
|
||||||
|
while !tracks_result.at_end() {
|
||||||
let mut tracks_result = spotify.user_playlist_tracks(&self.id, 100, 0);
|
tracks_result.next();
|
||||||
while let Some(ref tracks) = tracks_result.clone() {
|
|
||||||
for (index, listtrack) in tracks.items.iter().enumerate() {
|
|
||||||
if let Some(track) = &listtrack.track {
|
|
||||||
let mut t: Track = track.into();
|
|
||||||
t.list_index = index;
|
|
||||||
t.added_at = Some(listtrack.added_at);
|
|
||||||
collected_tracks.push(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
debug!("got {} tracks", tracks.items.len());
|
|
||||||
|
|
||||||
// load next batch if necessary
|
|
||||||
tracks_result = match tracks.next {
|
|
||||||
Some(_) => {
|
|
||||||
debug!("requesting tracks again..");
|
|
||||||
spotify.user_playlist_tracks(
|
|
||||||
&self.id,
|
|
||||||
100,
|
|
||||||
tracks.offset + tracks.items.len() as u32,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
None => None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
collected_tracks
|
let tracks = tracks_result.items.read().unwrap();
|
||||||
|
tracks.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_track(&self, track_id: &str) -> bool {
|
pub fn has_track(&self, track_id: &str) -> bool {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ use rspotify::blocking::client::Spotify as SpotifyAPI;
|
|||||||
use rspotify::model::album::{FullAlbum, SavedAlbum};
|
use rspotify::model::album::{FullAlbum, SavedAlbum};
|
||||||
use rspotify::model::artist::FullArtist;
|
use rspotify::model::artist::FullArtist;
|
||||||
use rspotify::model::page::{CursorBasedPage, Page};
|
use rspotify::model::page::{CursorBasedPage, Page};
|
||||||
use rspotify::model::playlist::{FullPlaylist, PlaylistTrack};
|
use rspotify::model::playlist::FullPlaylist;
|
||||||
use rspotify::model::search::SearchResult;
|
use rspotify::model::search::SearchResult;
|
||||||
use rspotify::model::track::{FullTrack, SavedTrack, SimplifiedTrack};
|
use rspotify::model::track::{FullTrack, SavedTrack, SimplifiedTrack};
|
||||||
use rspotify::model::user::PrivateUser;
|
use rspotify::model::user::PrivateUser;
|
||||||
@@ -550,16 +550,46 @@ impl Spotify {
|
|||||||
ApiResult::new(MAX_LIMIT, Arc::new(fetch_page))
|
ApiResult::new(MAX_LIMIT, Arc::new(fetch_page))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn user_playlist_tracks(
|
pub fn user_playlist_tracks(&self, playlist_id: &str) -> ApiResult<Track> {
|
||||||
&self,
|
const MAX_LIMIT: u32 = 100;
|
||||||
playlist_id: &str,
|
let spotify = self.clone();
|
||||||
limit: u32,
|
let playlist_id = playlist_id.to_string();
|
||||||
offset: u32,
|
let fetch_page = move |offset: u32| {
|
||||||
) -> Option<Page<PlaylistTrack>> {
|
debug!(
|
||||||
let user = self.user.as_ref().unwrap();
|
"fetching playlist {} tracks, offset: {}",
|
||||||
self.api_with_retry(|api| {
|
playlist_id, offset
|
||||||
api.user_playlist_tracks(user, playlist_id, None, limit, offset, self.country)
|
);
|
||||||
})
|
spotify.api_with_retry(|api| {
|
||||||
|
match api.user_playlist_tracks(
|
||||||
|
spotify.user.as_ref().unwrap(),
|
||||||
|
&playlist_id,
|
||||||
|
None,
|
||||||
|
MAX_LIMIT,
|
||||||
|
offset,
|
||||||
|
spotify.country,
|
||||||
|
) {
|
||||||
|
Ok(page) => Ok(ApiPage {
|
||||||
|
offset: page.offset,
|
||||||
|
total: page.total,
|
||||||
|
items: page
|
||||||
|
.items
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.flat_map(|(index, pt)| {
|
||||||
|
pt.track.as_ref().map(|t| {
|
||||||
|
let mut track: Track = t.into();
|
||||||
|
track.added_at = Some(pt.added_at);
|
||||||
|
track.list_index = page.offset as usize + index;
|
||||||
|
track
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
}),
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
ApiResult::new(MAX_LIMIT, Arc::new(fetch_page))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn full_album(&self, album_id: &str) -> Option<FullAlbum> {
|
pub fn full_album(&self, album_id: &str) -> Option<FullAlbum> {
|
||||||
|
|||||||
Reference in New Issue
Block a user