Use new pagination interface for user playlists
This commit is contained in:
@@ -5,7 +5,6 @@ use std::path::PathBuf;
|
|||||||
use std::sync::{Arc, RwLock, RwLockReadGuard};
|
use std::sync::{Arc, RwLock, RwLockReadGuard};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
use rspotify::model::playlist::SimplifiedPlaylist;
|
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
@@ -100,7 +99,7 @@ impl Library {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn needs_download(&self, remote: &SimplifiedPlaylist) -> bool {
|
fn needs_download(&self, remote: &Playlist) -> bool {
|
||||||
self.playlists()
|
self.playlists()
|
||||||
.iter()
|
.iter()
|
||||||
.find(|local| local.id == remote.id)
|
.find(|local| local.id == remote.id)
|
||||||
@@ -255,9 +254,10 @@ impl Library {
|
|||||||
let mut stale_lists = self.playlists.read().unwrap().clone();
|
let mut stale_lists = self.playlists.read().unwrap().clone();
|
||||||
let mut list_order = Vec::new();
|
let mut list_order = Vec::new();
|
||||||
|
|
||||||
let mut lists_result = self.spotify.current_user_playlist(50, 0);
|
let lists_page = self.spotify.current_user_playlist();
|
||||||
while let Some(ref lists) = lists_result.clone() {
|
let mut lists_batch = Some(lists_page.items.read().unwrap().clone());
|
||||||
for (index, remote) in lists.items.iter().enumerate() {
|
while let Some(lists) = &lists_batch {
|
||||||
|
for (index, remote) in lists.iter().enumerate() {
|
||||||
list_order.push(remote.id.clone());
|
list_order.push(remote.id.clone());
|
||||||
|
|
||||||
// remove from stale playlists so we won't prune it later on
|
// remove from stale playlists so we won't prune it later on
|
||||||
@@ -267,7 +267,7 @@ impl Library {
|
|||||||
|
|
||||||
if self.needs_download(remote) {
|
if self.needs_download(remote) {
|
||||||
info!("updating playlist {} (index: {})", remote.name, index);
|
info!("updating playlist {} (index: {})", remote.name, index);
|
||||||
let mut playlist: Playlist = remote.into();
|
let mut playlist: Playlist = remote.clone();
|
||||||
playlist.tracks = None;
|
playlist.tracks = None;
|
||||||
playlist.load_tracks(self.spotify.clone());
|
playlist.load_tracks(self.spotify.clone());
|
||||||
self.append_or_update(&playlist);
|
self.append_or_update(&playlist);
|
||||||
@@ -275,16 +275,7 @@ impl Library {
|
|||||||
self.ev.trigger();
|
self.ev.trigger();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lists_batch = lists_page.next();
|
||||||
// load next batch if necessary
|
|
||||||
lists_result = match lists.next {
|
|
||||||
Some(_) => {
|
|
||||||
debug!("requesting playlists again..");
|
|
||||||
self.spotify
|
|
||||||
.current_user_playlist(50, lists.offset + lists.items.len() as u32)
|
|
||||||
}
|
|
||||||
None => None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove stale playlists
|
// remove stale playlists
|
||||||
|
|||||||
@@ -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, SimplifiedPlaylist};
|
use rspotify::model::playlist::{FullPlaylist, PlaylistTrack};
|
||||||
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;
|
||||||
@@ -50,6 +50,7 @@ use crate::spotify_worker::{Worker, WorkerCommand};
|
|||||||
use crate::track::Track;
|
use crate::track::Track;
|
||||||
|
|
||||||
use crate::album::Album;
|
use crate::album::Album;
|
||||||
|
use crate::playlist::Playlist;
|
||||||
use crate::ui::pagination::{ApiPage, ApiResult};
|
use crate::ui::pagination::{ApiPage, ApiResult};
|
||||||
use rspotify::model::recommend::Recommendations;
|
use rspotify::model::recommend::Recommendations;
|
||||||
use rspotify::model::show::{FullEpisode, FullShow, Show, SimplifiedEpisode};
|
use rspotify::model::show::{FullEpisode, FullShow, Show, SimplifiedEpisode};
|
||||||
@@ -532,12 +533,21 @@ impl Spotify {
|
|||||||
.take()
|
.take()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn current_user_playlist(
|
pub fn current_user_playlist(&self) -> ApiResult<Playlist> {
|
||||||
&self,
|
const MAX_LIMIT: u32 = 50;
|
||||||
limit: u32,
|
let spotify = self.clone();
|
||||||
offset: u32,
|
let fetch_page = move |offset: u32| {
|
||||||
) -> Option<Page<SimplifiedPlaylist>> {
|
debug!("fetching user playlists, offset: {}", offset);
|
||||||
self.api_with_retry(|api| api.current_user_playlists(limit, offset))
|
spotify.api_with_retry(|api| match api.current_user_playlists(MAX_LIMIT, offset) {
|
||||||
|
Ok(page) => Ok(ApiPage {
|
||||||
|
offset: page.offset,
|
||||||
|
total: page.total,
|
||||||
|
items: page.items.iter().map(|sp| sp.into()).collect(),
|
||||||
|
}),
|
||||||
|
Err(e) => Err(e),
|
||||||
|
})
|
||||||
|
};
|
||||||
|
ApiResult::new(MAX_LIMIT, Arc::new(fetch_page))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn user_playlist_tracks(
|
pub fn user_playlist_tracks(
|
||||||
@@ -574,6 +584,7 @@ impl Spotify {
|
|||||||
let spotify = self.clone();
|
let spotify = self.clone();
|
||||||
let artist_id = artist_id.to_string();
|
let artist_id = artist_id.to_string();
|
||||||
let fetch_page = move |offset: u32| {
|
let fetch_page = move |offset: u32| {
|
||||||
|
debug!("fetching artist {} albums, offset: {}", artist_id, offset);
|
||||||
spotify.api_with_retry(|api| {
|
spotify.api_with_retry(|api| {
|
||||||
match api.artist_albums(
|
match api.artist_albums(
|
||||||
&artist_id,
|
&artist_id,
|
||||||
@@ -583,11 +594,8 @@ impl Spotify {
|
|||||||
Some(offset),
|
Some(offset),
|
||||||
) {
|
) {
|
||||||
Ok(page) => {
|
Ok(page) => {
|
||||||
let mut albums: Vec<Album> = page
|
let mut albums: Vec<Album> =
|
||||||
.items
|
page.items.iter().map(|sa| sa.into()).collect();
|
||||||
.iter()
|
|
||||||
.map(|sa| sa.into())
|
|
||||||
.collect();
|
|
||||||
albums.sort_by(|a, b| b.year.cmp(&a.year));
|
albums.sort_by(|a, b| b.year.cmp(&a.year));
|
||||||
Ok(ApiPage {
|
Ok(ApiPage {
|
||||||
offset: page.offset,
|
offset: page.offset,
|
||||||
|
|||||||
Reference in New Issue
Block a user