Authentication-Results: mail-b.sr.ht; dkim=none Received: from mout02.posteo.de (mout02.posteo.de [185.67.36.142]) by mail-b.sr.ht (Postfix) with ESMTPS id 93BF411EE9A for <~thecatster/spotsync-devel@lists.sr.ht>; Sun, 1 Aug 2021 21:40:44 +0000 (UTC) Received: from submission (posteo.de [89.146.220.130]) by mout02.posteo.de (Postfix) with ESMTPS id 39548240103 for <~thecatster/spotsync-devel@lists.sr.ht>; Sun, 1 Aug 2021 23:40:43 +0200 (CEST) Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4GdF1P6TF8z6tmF; Sun, 1 Aug 2021 23:40:41 +0200 (CEST) From: Daniel Rose To: ~thecatster/spotsync-devel@lists.sr.ht Cc: Daniel Rose Subject: [PATCH] Clean up imports and rework local playlist reading Date: Sun, 1 Aug 2021 21:40:08 +0000 Message-Id: <20210801214008.135733-1-danielrose@member.fsf.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Rose --- src/main.rs | 99 +++++++++++++++++++++++++++------------------------- src/tests.rs | 4 +-- 2 files changed, 53 insertions(+), 50 deletions(-) diff --git a/src/main.rs b/src/main.rs index ae55a8c..cad40ba 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,29 +1,30 @@ #![feature(string_remove_matches)] -use aspotify::{ - authorization_url, Client, ClientCredentials, PlaylistSimplified, Scope, TwoWayCursorPage, -}; -use chrono::Local; +use aspotify::{authorization_url, Client, ClientCredentials, PlaylistSimplified, Scope}; + use fern::{log_file, Dispatch}; -use log::{debug, error, info, log_enabled, Level}; -use ron::de; -use std::process::Command; +use log::{info, LevelFilter}; + +use ron::{ + de::from_reader, + ser::{to_string_pretty, PrettyConfig}, +}; +use serde::{Deserialize, Serialize}; + use std::{ - env, fs, + env, + fs::{self, write, File}, io::{self, Write}, }; -use ron::de::from_reader; -use serde::Deserialize; -use std::{collections::HashMap, fs::File}; mod tests; -#[derive(Debug, Deserialize)] -struct Playlist { +#[derive(Debug, Serialize, Deserialize)] +struct PlaylistConfig { title: String, songs: Vec, } -#[derive(Debug, Deserialize)] +#[derive(Debug, Serialize, Deserialize)] struct Song { title: String, artists: Vec, @@ -32,7 +33,7 @@ struct Song { #[tokio::main] async fn main() { - fern::Dispatch::new() + Dispatch::new() .format(|out, message, record| { out.finish(format_args!( "{}[{}][{}] {}", @@ -42,12 +43,9 @@ async fn main() { message )) }) - .level(log::LevelFilter::Error) - .chain(std::io::stdout()) - .chain( - fern::log_file("spotsync.log") - .expect("No permission to write to the current directory."), - ) + .level(LevelFilter::Error) + .chain(io::stdout()) + .chain(log_file("spotsync.log").expect("No permission to write to the current directory.")) .apply() .expect("Failed to dispatch Fern logger!"); @@ -106,8 +104,8 @@ async fn authenticate_spotify() -> Client { Scope::UserFollowRead, Scope::UserFollowModify, ] - .iter() - .copied(), + .iter() + .copied(), false, "http://localhost:8888/callback", ); @@ -121,24 +119,21 @@ async fn authenticate_spotify() -> Client { client.redirected(&redirect, &state).await.unwrap(); - fs::write( + write( ".refresh_token", client .refresh_token() .await .expect("Could not obtain refresh token from Spotify!"), ) - .expect("Unable to write to refresh token file, possibly no permission?"); + .expect("Unable to write to refresh token file, possibly no permission?"); client } } } -async fn spotify_playlist_read_songs( - client: &Client, - playlist: &PlaylistSimplified, -) -> Vec { +async fn spotify_playlist_read_songs(client: &Client, playlist: &PlaylistSimplified) -> Vec { // Why is this so ugly!? There has to be a better way. client .playlists() @@ -156,7 +151,11 @@ async fn spotify_playlist_read_songs( }; let song_artists = match playlist_item.item.as_ref().expect("No such playlist item!") { - aspotify::PlaylistItemType::Track(track) => track.artists.iter().map(|x| x.name.to_string()).collect::>(), + aspotify::PlaylistItemType::Track(track) => track + .artists + .iter() + .map(|x| x.name.to_string()) + .collect::>(), _ => vec!["Artists not found".to_string()], }; @@ -193,7 +192,6 @@ fn local_playlist_make_if_not_exists(playlist: &PlaylistSimplified) { path.push(format!("./music/{}", &playlist.name)); let metadata = fs::metadata(path); if metadata.is_err() { - println!("Creating playlist directory!"); let mut path = env::current_dir().expect("Could not read current directory!"); let playlist_dir = format!("./music/{}", &playlist.name); path.push(playlist_dir); @@ -205,7 +203,6 @@ fn local_playlist_make_if_not_exists(playlist: &PlaylistSimplified) { path.push("data/playlists/"); let metadata = fs::metadata(path); if metadata.is_err() { - println!("Creating playlist directory!"); let mut path = env::current_dir().expect("Could not read current directory!"); path.push("data/playlists/"); std::fs::create_dir_all(path).unwrap(); @@ -216,32 +213,40 @@ fn local_playlist_make_if_not_exists(playlist: &PlaylistSimplified) { path.push(format!("data/playlists/\"{}\".ron", &playlist.name)); let metadata = fs::metadata(path); if metadata.is_err() { - println!("Creating playlist RON file!"); let mut path = env::current_dir().expect("Could not read current directory!"); let playlist_ron = format!("data/playlists/\"{}\".ron", &playlist.name); path.push(playlist_ron); - println!("{:?}", &path); - std::fs::File::create(path).unwrap(); + File::create(path).unwrap(); }; } -async fn local_playlist_read_songs(client: &Client, playlist: &PlaylistSimplified) { +async fn local_playlist_read_songs(client: &Client, playlist: &PlaylistSimplified) -> Vec { let input_path = format!("data/playlists/\"{}\".ron", &playlist.name); let f = File::open(&input_path).expect("Failed opening file"); - let config: Playlist = match from_reader(f) { - Ok(x) => x, - Err(e) => { - create_playlist_ron(&client, &playlist).await; - println!("Failed to load config: {}", e); - - std::process::exit(1); - } + let playlist_ron: Result = from_reader(f); + let playlist_struct: Vec = match playlist_ron { + Ok(x) => x.songs, + Err(_) => create_playlist_ron(client, playlist).await.songs, }; - println!("Config: {:?}", &config); + playlist_struct } -async fn create_playlist_ron(client: &Client, playlist: &PlaylistSimplified) { +async fn create_playlist_ron(client: &Client, playlist: &PlaylistSimplified) -> PlaylistConfig { let songs: Vec = spotify_playlist_read_songs(client, playlist).await; - println!("{:?}", songs); + let playlist_struct = PlaylistConfig { + title: playlist.name.to_string(), + songs, + }; + + let pretty = PrettyConfig::new() + .with_depth_limit(4) + .with_separate_tuple_members(true) + .with_enumerate_arrays(true); + let playlist_ron = to_string_pretty(&playlist_struct, pretty).expect("Serialization failed"); + + let playlist_file = format!("data/playlists/\"{}\".ron", &playlist.name); + write(playlist_file, playlist_ron).unwrap(); + + playlist_struct } diff --git a/src/tests.rs b/src/tests.rs index 7d3e1bb..f8fe0f3 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1,5 +1,3 @@ -use super::*; - #[test] fn read_refresh_token() { let _file = std::fs::read_to_string(".refresh_token"); @@ -7,5 +5,5 @@ fn read_refresh_token() { #[test] fn get_authenticated_user() { - let _client = authenticate_spotify(); + let _client = super::authenticate_spotify(); } -- 2.32.0