implement playlist update on demand + prune stale playlists

This commit is contained in:
Henrik Friedrichsen
2019-03-23 18:37:15 +01:00
parent c17e193429
commit 53255a48af
5 changed files with 55 additions and 15 deletions

View File

@@ -42,6 +42,7 @@ have them configurable.
* Tracks and playlists can be played using `Return` and queued using `Space`
* `Shift-p` toggles playback of a track
* `Shift-s` stops a track
* `Shift-r` updates the playlist cache
* `<` and `>` play the previous or next track, respectively
* `q` quits ncspot

View File

@@ -4,7 +4,7 @@ use std::sync::Arc;
use cursive::event::{Event, Key};
use cursive::Cursive;
use playlists::Playlist;
use playlists::{Playlist, Playlists};
use queue::Queue;
use spotify::Spotify;
use track::Track;
@@ -39,7 +39,12 @@ impl CommandManager {
self.commands.insert(name, cb);
}
pub fn register_all(&mut self, spotify: Arc<Spotify>, queue: Arc<Queue>) {
pub fn register_all(
&mut self,
spotify: Arc<Spotify>,
queue: Arc<Queue>,
playlists: Arc<Playlists>,
) {
self.register(
"quit",
vec!["q", "x"],
@@ -120,10 +125,17 @@ impl CommandManager {
self.register(
"playlists",
vec!["lists"],
Box::new(move |s, _args| {
s.call_on_id("main", |v: &mut Layout| {
v.set_view("playlists");
});
Box::new(move |s, args| {
if let Some(arg) = args.get(0) {
if arg == "update" {
playlists.fetch_playlists();
playlists.save_cache();
}
} else {
s.call_on_id("main", |v: &mut Layout| {
v.set_view("playlists");
});
}
Ok(None)
}),
);
@@ -342,6 +354,7 @@ impl CommandManager {
kb.insert("q".into(), "quit".into());
kb.insert("P".into(), "toggle".into());
kb.insert("R".into(), "playlists update".into());
kb.insert("S".into(), "stop".into());
kb.insert("<".into(), "previous".into());
kb.insert(">".into(), "next".into());

View File

@@ -29,7 +29,7 @@ use std::process;
use std::sync::Arc;
use std::thread;
use clap::{Arg, App};
use clap::{App, Arg};
use cursive::traits::Identifiable;
use cursive::Cursive;
@@ -80,12 +80,14 @@ fn main() {
.version("0.1.0")
.author("Henrik Friedrichsen <henrik@affekt.org>")
.about("cross-platform ncurses Spotify client")
.arg(Arg::with_name("debug")
.short("d")
.long("debug")
.value_name("FILE")
.help("Enable debug logging to the specified file")
.takes_value(true))
.arg(
Arg::with_name("debug")
.short("d")
.long("debug")
.value_name("FILE")
.help("Enable debug logging to the specified file")
.takes_value(true),
)
.get_matches();
if let Some(filename) = matches.value_of("debug") {
@@ -181,7 +183,7 @@ fn main() {
cursive.add_fullscreen_layer(layout.with_id("main"));
let mut cmd_manager = CommandManager::new();
cmd_manager.register_all(spotify.clone(), queue.clone());
cmd_manager.register_all(spotify.clone(), queue.clone(), playlists.clone());
let cmd_manager = Arc::new(cmd_manager);
CommandManager::register_keybindings(cmd_manager.clone(), &mut cursive, cfg.keybindings);

View File

@@ -12,7 +12,7 @@ use spotify::Spotify;
use track::Track;
use traits::ListItem;
#[derive(Clone, Deserialize, Serialize)]
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Playlist {
pub meta: SimplifiedPlaylist,
pub tracks: Vec<Track>,
@@ -144,9 +144,16 @@ impl Playlists {
pub fn fetch_playlists(&self) {
debug!("loading playlists");
let mut stale_lists = self.store.read().unwrap().clone();
let mut lists_result = self.spotify.current_user_playlist(50, 0);
while let Some(ref lists) = lists_result.clone() {
for remote in &lists.items {
// remove from stale playlists so we won't prune it later on
if let Some(index) = stale_lists.iter().position(|x| x.meta.id == remote.id) {
stale_lists.remove(index);
}
if self.needs_download(remote) {
info!("updating playlist {}", remote.name);
let playlist = Self::process_playlist(&remote, &self.spotify);
@@ -166,5 +173,21 @@ impl Playlists {
None => None,
}
}
// remove stale playlists
for stale in stale_lists {
let index = self
.store
.read()
.unwrap()
.iter()
.position(|x| x.meta.id == stale.meta.id);
if let Some(index) = index {
debug!("removing stale list: {:?}", stale.meta.name);
self.store.write().unwrap().remove(index);
}
}
// trigger redraw
self.ev.trigger();
}
}

View File

@@ -215,6 +215,7 @@ impl Spotify {
fn create_session(core: &mut Core, credentials: Credentials) -> Session {
let session_config = SessionConfig::default();
let handle = core.handle();
debug!("opening spotify session");
core.run(Session::connect(session_config, credentials, None, handle))
.ok()
.unwrap()