~thecatster/spotsync-devel

Add playlist comparison v1 APPLIED

Daniel Rose: 1
 Add playlist comparison

 2 files changed, 42 insertions(+), 7 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~thecatster/spotsync-devel/patches/24140/mbox | git am -3
Learn more about email & git

[PATCH] Add playlist comparison Export this patch

Signed-off-by: Daniel Rose <danielrose@member.fsf.org>
---
 Cargo.toml  |  3 ++-
 src/main.rs | 46 ++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 42 insertions(+), 7 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index 2d188be..d6ccb93 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,4 +13,5 @@ fern = { version = "0.5" }
chrono = { version = "0.4" }
tokio = { version = "1", features = ["full"] }
ron = { version = "0.6" }
serde = { version = "1" }
\ No newline at end of file
serde = { version = "1" }
itertools = { version = "0.10" }
\ No newline at end of file
diff --git a/src/main.rs b/src/main.rs
index cad40ba..0618e28 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,4 +1,4 @@
#![feature(string_remove_matches)]
#![feature(string_remove_matches, slice_partition_dedup)]
use aspotify::{authorization_url, Client, ClientCredentials, PlaylistSimplified, Scope};

use fern::{log_file, Dispatch};
@@ -9,11 +9,14 @@ use ron::{
    ser::{to_string_pretty, PrettyConfig},
};
use serde::{Deserialize, Serialize};
use itertools::Itertools;

use std::{
    env,
    fs::{self, write, File},
    io::{self, Write},
    cmp::Ordering,
    hash::Hash,
};

mod tests;
@@ -24,13 +27,33 @@ struct PlaylistConfig {
    songs: Vec<Song>,
}

#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug, Serialize, Deserialize, Clone, Hash)]
struct Song {
    title: String,
    artists: Vec<String>,
    album: String,
}

impl PartialEq for Song {
    fn eq(&self, other: &Self) -> bool {
        self.title == other.title && self.album == other.album && self.artists == other.artists
    }
}

impl Eq for Song {}

impl PartialOrd for Song {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl Ord for Song {
    fn cmp(&self, other: &Self) -> Ordering {
        self.title.cmp(&other.title)
    }
}

#[tokio::main]
async fn main() {
    Dispatch::new()
@@ -58,10 +81,21 @@ async fn main() {
    // Main logic
    for playlist in &spotify_playlists {
        local_playlist_make_if_not_exists(playlist);
        let _local_songs = local_playlist_read_songs(&client, playlist).await;
        let _spotify_songs = spotify_playlist_read_songs(&client, playlist).await;
        // let needed_songs: Vec<String> = compare_playlists();
        // download_songs_and_update_ron();
        let local_songs = local_playlist_read_songs(&client, playlist).await;
        let spotify_songs = spotify_playlist_read_songs(&client, playlist).await;
        let needed_songs: Vec<Song> = compare_playlists(&local_songs, &spotify_songs, &playlist.name).await;
        if !needed_songs.is_empty() {
            // download_songs_and_update_ron(&needed_songs).await;
        }
    }
}

async fn compare_playlists(local: &[Song], remote: &[Song], playlist_title: &str) -> Vec<Song> {
    println!("{}: {:?}", playlist_title, local == remote);
    if local == remote {
        vec![]
    } else {
        [local, remote].concat().iter().unique().map(|s| s.to_owned()).collect::<Vec<_>>()
    }
}

-- 
2.32.0