Skip to content

Commit

Permalink
Add a "--from-song" option
Browse files Browse the repository at this point in the history
  • Loading branch information
Polochon-street committed Jun 14, 2024
1 parent 6e909db commit 6f2714c
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 19 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Changelog

## blissify 0.4.0
* Add a "--dry-run" option to some of the flags.
* Add a "--from-song" option to select a specific song from the command-line.
* Default to deduplicating songs when making playlist; add a "--no-deduplication" option.

## blissify 0.3.12
Expand Down
127 changes: 108 additions & 19 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,9 +305,8 @@ impl MPDLibrary {
}

/// Make a playlist from the album that's currently playing.
fn queue_from_current_album(&self, number_albums: usize) -> Result<()> {
fn queue_from_current_album(&self, number_albums: usize, dry_run: bool) -> Result<()> {
let mut mpd_conn = self.mpd_conn.lock().unwrap();
mpd_conn.random(false)?;
let mpd_song = match mpd_conn.currentsong()? {
Some(s) => s,
None => bail!("No song is currently playing. Add a song to start the playlist from, and try again."),
Expand All @@ -324,36 +323,47 @@ impl MPDLibrary {
let playlist = self
.library
.album_playlist_from::<()>(current_album, number_albums)?;
let current_pos = mpd_song.place.unwrap().pos;
mpd_conn.delete(0..current_pos)?;
if mpd_conn.queue()?.len() > 1 {
mpd_conn.delete(1..)?;
}

let mut index: usize = 1;
if let Some(track_number) = &current_song.bliss_song.track_number {
if let Ok(track_number) = track_number.parse::<usize>() {
index = track_number;
}
}

if dry_run {
for song in &playlist[index..] {
println!("{}", song.bliss_song.path.to_string_lossy());
}
return Ok(());
}

mpd_conn.random(false)?;
let current_pos = mpd_song.place.unwrap().pos;
mpd_conn.delete(0..current_pos)?;
if mpd_conn.queue()?.len() > 1 {
mpd_conn.delete(1..)?;
}
for song in &playlist[index..] {
let mpd_song = self.bliss_song_to_mpd(song)?;
mpd_conn.push(mpd_song)?;
}
Ok(())
}

/// TODO do not remove the rest of the songs when you make the playlist
fn queue_from_current_song_custom<F>(
&self,
number_songs: usize,
distance: &dyn DistanceMetricBuilder,
mut sort_by: F,
dedup: bool,
dry_run: bool,
) -> Result<()>
where
F: FnMut(&[LibrarySong<()>], &mut [LibrarySong<()>], &dyn DistanceMetricBuilder),
{
let mut mpd_conn = self.mpd_conn.lock().unwrap();
mpd_conn.random(false)?;
let mpd_song = match mpd_conn.currentsong()? {
Some(s) => s,
None => bail!("No song is currently playing. Add a song to start the playlist from, and try again."),
Expand All @@ -367,12 +377,64 @@ impl MPDLibrary {
&mut sort_by,
dedup,
)?;

if dry_run {
for song in &playlist[1..] {
println!("{}", song.bliss_song.path.to_string_lossy());
}
return Ok(());
}

mpd_conn.random(false)?;
let current_pos = mpd_song.place.unwrap().pos;
mpd_conn.delete(0..current_pos)?;
if mpd_conn.queue()?.len() > 1 {
mpd_conn.delete(1..)?;
}
for song in &playlist[1..] {
let mpd_song = self.bliss_song_to_mpd(song)?;
mpd_conn.push(mpd_song)?;
}
Ok(())
}

/// Make a playlist from a given song, queuing the songs founds.
/// Does not do any "stop random, empty playlist", etc magic.
///
/// song_path can be either a path relative to the MPD folder or the full path.
fn queue_from_song_custom<F>(
&self,
song_path: String,
number_songs: usize,
distance: &dyn DistanceMetricBuilder,
mut sort_by: F,
dedup: bool,
dry_run: bool,
) -> Result<()>
where
F: FnMut(&[LibrarySong<()>], &mut [LibrarySong<()>], &dyn DistanceMetricBuilder),
{
let mut mpd_conn = self.mpd_conn.lock().unwrap();
let path =
if song_path.contains(self.library.config.mpd_base_path.to_string_lossy().as_ref()) {
PathBuf::from(song_path)
} else {
self.library.config.mpd_base_path.join(song_path)
};
let playlist = self.library.playlist_from_custom(
&[&path.to_string_lossy().clone()],
number_songs,
distance,
&mut sort_by,
dedup,
)?;

if dry_run {
for song in &playlist[1..] {
println!("{}", song.bliss_song.path.to_string_lossy());
}
return Ok(());
}
for song in &playlist[1..] {
let mpd_song = self.bliss_song_to_mpd(song)?;
mpd_conn.push(mpd_song)?;
Expand Down Expand Up @@ -683,6 +745,11 @@ Useful to avoid a too heavy load on a machine.")
)
.default_value("euclidean")
)
.arg(Arg::with_name("from-song")
.long("from-song")
.value_name("song path")
.help("Instead of making a playlist from the current playing song, make a playlist from 'song path', and adds the corresponding songs to the queue.")
)
.arg(Arg::with_name("seed")
.long("seed-song")
.help(
Expand All @@ -697,6 +764,13 @@ Useful to avoid a too heavy load on a machine.")
)
.takes_value(false)
)
.arg(Arg::with_name("dry-run")
.long("dry-run")
.help(
"Doesn't actually make any changes to the playlist, but just print songs that would have been added on stdout."
)
.takes_value(false)
)
.arg(Arg::with_name("album")
.long("album-playlist")
.help("Make a playlist of similar albums from the current album.")
Expand Down Expand Up @@ -784,8 +858,10 @@ Defaults to 3, cannot be more than 9."
};

let library = MPDLibrary::from_config_path(config_path)?;
let dry_run = sub_m.is_present("dry-run");

if sub_m.is_present("album") {
library.queue_from_current_album(number_songs)?;
library.queue_from_current_album(number_songs, dry_run)?;
} else {
let distance_metric = if let Some(m) = sub_m.value_of("distance") {
match m {
Expand All @@ -802,12 +878,24 @@ Defaults to 3, cannot be more than 9."
true => song_to_song,
};
let no_dedup = sub_m.is_present("no-dedup");
library.queue_from_current_song_custom(
number_songs,
&distance_metric,
sort,
!no_dedup,
)?;
if let Some(song_path) = sub_m.value_of("from-song") {
library.queue_from_song_custom(
song_path.to_string(),
number_songs,
&distance_metric,
sort,
!no_dedup,
dry_run,
)?;
} else {
library.queue_from_current_song_custom(
number_songs,
&distance_metric,
sort,
!no_dedup,
dry_run,
)?;
}
}
} else if let Some(sub_m) = matches.subcommand_matches("interactive-playlist") {
let number_choices: usize = sub_m.value_of("choices").unwrap_or("3").parse()?;
Expand Down Expand Up @@ -1014,7 +1102,7 @@ mod test {
.unwrap();
}
assert_eq!(
library.queue_from_current_song_custom(20, &euclidean_distance, closest_to_songs, true).unwrap_err().to_string(),
library.queue_from_current_song_custom(20, &euclidean_distance, closest_to_songs, true, false).unwrap_err().to_string(),
String::from("No song is currently playing. Add a song to start the playlist from, and try again."),
);
}
Expand Down Expand Up @@ -1055,7 +1143,8 @@ mod test {
20,
&euclidean_distance,
closest_to_songs,
true
true,
false,
)
.unwrap_err()
.to_string(),
Expand Down Expand Up @@ -1177,7 +1266,7 @@ mod test {
.unwrap();
}
library
.queue_from_current_song_custom(20, &euclidean_distance, closest_to_songs, false)
.queue_from_current_song_custom(20, &euclidean_distance, closest_to_songs, false, false)
.unwrap();

let playlist = library
Expand Down Expand Up @@ -1221,7 +1310,7 @@ mod test {
},
];

library.queue_from_current_album(20).unwrap();
library.queue_from_current_album(20, false).unwrap();

let playlist = library
.mpd_conn
Expand Down

0 comments on commit 6f2714c

Please sign in to comment.