diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index e2e40a3..1b19c9c 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -18,10 +18,6 @@ jobs: - uses: actions/checkout@v2 with: submodules: recursive - - uses: actions-rs/toolchain@v1 - with: - toolchain: nightly-2021-04-01 - override: false - name: Packages run: sudo apt-get install build-essential yasm - name: Build diff --git a/Cargo.lock b/Cargo.lock index 06488ea..2d70fe6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -85,28 +85,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] -name = "bliss-audio-aubio-rs" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe01698d293ee91e334339d6436f17eac30d94bebaa668c5799c8206384dfeb1" -dependencies = [ - "bliss-audio-aubio-sys", -] - -[[package]] -name = "bliss-audio-aubio-sys" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ef9fab7b922bdd057bb06fa2a2fa79d2a93bec3dd576320511cb3dfe21e78a9" -dependencies = [ - "cc", -] - -[[package]] -name = "bliss-rs" -version = "0.1.1" +name = "bliss-audio" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61bc06a97899c07328cd5440f0337a65b8514e275fd620aa5407a9039fc9052" +checksum = "9a6165811a974c0df0002377a05fbc7283d2a6fb4da03bfb2e6c2f65112b334a" dependencies = [ "bliss-audio-aubio-rs", "crossbeam", @@ -126,11 +108,29 @@ dependencies = [ ] [[package]] -name = "blissify-rs" -version = "0.1.0" +name = "bliss-audio-aubio-rs" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe01698d293ee91e334339d6436f17eac30d94bebaa668c5799c8206384dfeb1" +dependencies = [ + "bliss-audio-aubio-sys", +] + +[[package]] +name = "bliss-audio-aubio-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ef9fab7b922bdd057bb06fa2a2fa79d2a93bec3dd576320511cb3dfe21e78a9" +dependencies = [ + "cc", +] + +[[package]] +name = "blissify" +version = "0.1.3" dependencies = [ "anyhow", - "bliss-rs", + "bliss-audio", "clap", "dirs", "env_logger", diff --git a/Cargo.toml b/Cargo.toml index aca8810..f8d7db4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] -name = "blissify-rs" -version = "0.1.0" +name = "blissify" +version = "0.1.3" authors = ["Polochon-street "] edition = "2018" license = "GPL-3.0-only" @@ -11,7 +11,7 @@ readme = "README.md" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -bliss-rs = "0.1.1" +bliss-audio = "0.1.3" mpd = "0.0.12" rusqlite = "0.25.0" dirs = "3.0.1" diff --git a/README.md b/README.md index c4d3101..935c438 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,37 @@ +[![crate](https://img.shields.io/crates/v/blissify.svg)](https://crates.io/crates/blissify) +[![build](https://github.com/Polochon-street/blissify-rs/workflows/Rust/badge.svg)](https://github.com/Polochon-street/blissify-rs/actions) + Blissify - analyze an MPD library and make smart playlists ========================================================== -Blissify is an MPD plugin for [bliss](https://crates.io/crates/bliss-rs). +Blissify is an [MPD](https://www.musicpd.org/) plugin +for [bliss](https://crates.io/crates/bliss-audio). You can use it to make playlists of songs that sound alike from an MPD library. +Note: the `blissify-rs` crate is outdated. Use this crate (`blissify`) instead. + Usage ===== Use `cargo install blissify` to install it. -Then analyze your MPD library by using `blissify --update /path/to/mpd/root` +Analyze a library +----------------- + +To analyze your MPD library, use +``` +$ blissify --update /path/to/mpd/root +``` (or `blissify --rescan /path/to/mpd/root`). -Then, when a song is playing, run `blissify --playlist 100` to make a playlist -of 100 songs similar to the current song. +Make a playlist +--------------- + +``` +$ blissify --playlist 100 +``` + +This will add 100 songs similar to the song that is currently +playing on MPD, starting with the closest possible. diff --git a/src/main.rs b/src/main.rs index 1c4ceb3..0a51602 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,12 +7,11 @@ //! Playlists can then subsequently be made from the current song using //! --playlist. use anyhow::{bail, Context, Result}; -use bliss_rs::library::Library; -use bliss_rs::{BlissError, Song}; +use bliss_audio::Library; +use bliss_audio::{BlissError, Song}; use clap::{App, Arg, ArgGroup}; #[cfg(not(test))] use dirs::data_local_dir; -use env_logger; use log::info; #[cfg(not(test))] use log::warn; @@ -88,11 +87,13 @@ impl MPDLibrary { )?; let results = stmt.query_map(params![&path.to_str().unwrap()], MPDLibrary::row_closure)?; - let mut song = Song::default(); - song.path = path - .to_str() - .with_context(|| "While getting current song path")? - .to_owned(); + let mut song = Song { + path: path + .to_str() + .with_context(|| "While getting current song path")? + .to_owned(), + ..Default::default() + }; let mut analysis = vec![]; for result in results { analysis.push(result?.1); @@ -230,14 +231,14 @@ impl Library for MPDLibrary { let mut songs_hashmap = HashMap::new(); for result in results { let result = result.map_err(|e| BlissError::ProviderError(e.to_string()))?; - let song_entry = songs_hashmap.entry(result.0).or_insert(vec![]); + let song_entry = songs_hashmap.entry(result.0).or_insert_with(Vec::new); song_entry.push(result.1); } let songs: Vec = songs_hashmap .into_iter() .map(|(path, analysis)| Song { - analysis, path, + analysis, ..Default::default() }) .collect(); @@ -445,69 +446,68 @@ mod test { } #[test] -// fn test_full_rescan() { -// let mut library = MPDLibrary::new(String::from("./data/")).unwrap(); -// let sqlite_conn = library.sqlite_conn.lock().unwrap(); -// sqlite_conn -// .execute( -// " -// insert into song (id, path, analyzed) values -// (1,'./data/s16_mono_22_5kHz.flac', true) -// ", -// [], -// ) -// .unwrap(); -// -// sqlite_conn -// .execute( -// " -// insert into feature (song_id, feature, feature_index) values -// (1, 0., 1), -// (1, 0., 2), -// (1, 0., 3) -// ", -// [], -// ) -// .unwrap(); -// drop(sqlite_conn); -// -// library.full_rescan().unwrap(); -// -// let sqlite_conn = library.sqlite_conn.lock().unwrap(); -// let mut stmt = sqlite_conn -// .prepare("select path, analyzed from song order by path") -// .unwrap(); -// let expected_songs = stmt -// .query_map([], |row| Ok((row.get(0).unwrap(), row.get(1).unwrap()))) -// .unwrap() -// .map(|x| { -// let x = x.unwrap(); -// (x.0, x.1) -// }) -// .collect::>(); -// -// assert_eq!( -// expected_songs, -// vec![ -// (String::from("foo"), false), -// (String::from("s16_mono_22_5kHz.flac"), true), -// (String::from("s16_stereo_22_5kHz.flac"), true), -// ], -// ); -// -// let mut stmt = sqlite_conn -// .prepare("select count(*) from feature group by song_id") -// .unwrap(); -// let expected_feature_count = stmt -// .query_map([], |row| row.get(0)) -// .unwrap() -// .map(|x| x.unwrap()) -// .collect::>(); -// for feature_count in expected_feature_count { -// assert!(feature_count > 1); -// } -// } - + // fn test_full_rescan() { + // let mut library = MPDLibrary::new(String::from("./data/")).unwrap(); + // let sqlite_conn = library.sqlite_conn.lock().unwrap(); + // sqlite_conn + // .execute( + // " + // insert into song (id, path, analyzed) values + // (1,'./data/s16_mono_22_5kHz.flac', true) + // ", + // [], + // ) + // .unwrap(); + // + // sqlite_conn + // .execute( + // " + // insert into feature (song_id, feature, feature_index) values + // (1, 0., 1), + // (1, 0., 2), + // (1, 0., 3) + // ", + // [], + // ) + // .unwrap(); + // drop(sqlite_conn); + // + // library.full_rescan().unwrap(); + // + // let sqlite_conn = library.sqlite_conn.lock().unwrap(); + // let mut stmt = sqlite_conn + // .prepare("select path, analyzed from song order by path") + // .unwrap(); + // let expected_songs = stmt + // .query_map([], |row| Ok((row.get(0).unwrap(), row.get(1).unwrap()))) + // .unwrap() + // .map(|x| { + // let x = x.unwrap(); + // (x.0, x.1) + // }) + // .collect::>(); + // + // assert_eq!( + // expected_songs, + // vec![ + // (String::from("foo"), false), + // (String::from("s16_mono_22_5kHz.flac"), true), + // (String::from("s16_stereo_22_5kHz.flac"), true), + // ], + // ); + // + // let mut stmt = sqlite_conn + // .prepare("select count(*) from feature group by song_id") + // .unwrap(); + // let expected_feature_count = stmt + // .query_map([], |row| row.get(0)) + // .unwrap() + // .map(|x| x.unwrap()) + // .collect::>(); + // for feature_count in expected_feature_count { + // assert!(feature_count > 1); + // } + // } #[test] fn test_playlist_no_song() { let library = MPDLibrary::new(String::from("")).unwrap();