Gracefully handle tracks without IDs

As reported in #1231:

Local files in playlists have no IDs. When trying to delete them ncspot crashes
as it tries to extract a track ID.
This commit is contained in:
Henrik Friedrichsen
2023-07-22 13:39:04 +02:00
parent 2786c6ba34
commit 90b4560a2d
2 changed files with 21 additions and 12 deletions

View File

@@ -139,15 +139,17 @@ impl From<&PlayableItem> for Playable {
} }
} }
impl From<&Playable> for rspotify::prelude::PlayableId<'_> { impl From<&Playable> for Option<rspotify::prelude::PlayableId<'_>> {
fn from(p: &Playable) -> Self { fn from(p: &Playable) -> Self {
match p { match p {
Playable::Track(t) => rspotify::prelude::PlayableId::Track( Playable::Track(t) => {
rspotify::model::TrackId::from_id(t.id.clone().unwrap()).unwrap(), t.id.clone()
), .and_then(|id| rspotify::model::TrackId::from_id(id).ok())
Playable::Episode(e) => rspotify::prelude::PlayableId::Episode( .map(rspotify::prelude::PlayableId::Track)
rspotify::model::EpisodeId::from_id(e.id.clone()).unwrap(), }
), Playable::Episode(e) => rspotify::model::EpisodeId::from_id(e.id.clone())
.map(rspotify::prelude::PlayableId::Episode)
.ok(),
} }
} }
} }

View File

@@ -155,7 +155,10 @@ impl WebApi {
position: Option<i32>, position: Option<i32>,
) -> bool { ) -> bool {
self.api_with_retry(|api| { self.api_with_retry(|api| {
let trackids: Vec<PlayableId> = tracks.iter().map(|playable| playable.into()).collect(); let trackids: Vec<PlayableId> = tracks
.iter()
.filter_map(|playable| playable.into())
.collect();
api.playlist_add_items( api.playlist_add_items(
PlaylistId::from_id(playlist_id).unwrap(), PlaylistId::from_id(playlist_id).unwrap(),
trackids.iter().map(|id| id.as_ref()), trackids.iter().map(|id| id.as_ref()),
@@ -172,8 +175,10 @@ impl WebApi {
playables: &[Playable], playables: &[Playable],
) -> bool { ) -> bool {
self.api_with_retry(move |api| { self.api_with_retry(move |api| {
let playable_ids: Vec<PlayableId> = let playable_ids: Vec<PlayableId> = playables
playables.iter().map(|playable| playable.into()).collect(); .iter()
.filter_map(|playable| playable.into())
.collect();
let positions = playables let positions = playables
.iter() .iter()
.map(|playable| [playable.list_index() as u32]) .map(|playable| [playable.list_index() as u32])
@@ -207,8 +212,10 @@ impl WebApi {
}; };
if let Some(()) = self.api_with_retry(|api| { if let Some(()) = self.api_with_retry(|api| {
let playable_ids: Vec<PlayableId> = let playable_ids: Vec<PlayableId> = tracks
tracks.iter().map(|playable| playable.into()).collect(); .iter()
.filter_map(|playable| playable.into())
.collect();
api.playlist_replace_items( api.playlist_replace_items(
PlaylistId::from_id(id).unwrap(), PlaylistId::from_id(id).unwrap(),
playable_ids.iter().map(|p| p.as_ref()), playable_ids.iter().map(|p| p.as_ref()),