diff options
Diffstat (limited to 'pkgs/by-name/mp/mpdpopm/src/bin/mpdpopm.rs')
| -rw-r--r-- | pkgs/by-name/mp/mpdpopm/src/bin/mpdpopm.rs | 78 |
1 files changed, 37 insertions, 41 deletions
diff --git a/pkgs/by-name/mp/mpdpopm/src/bin/mpdpopm.rs b/pkgs/by-name/mp/mpdpopm/src/bin/mpdpopm.rs index d9d607d5..746088ca 100644 --- a/pkgs/by-name/mp/mpdpopm/src/bin/mpdpopm.rs +++ b/pkgs/by-name/mp/mpdpopm/src/bin/mpdpopm.rs @@ -29,6 +29,8 @@ use mpdpopm::{ clients::{Client, PlayerStatus, quote}, config::{self, Config}, + filters::ExpressionParser, + filters_ast::{FilterStickerNames, evaluate}, storage::{last_played, play_count, rating_count}, }; @@ -263,12 +265,31 @@ async fn get_playlists(client: &mut Client) -> Result<()> { } /// Add songs selected by filter to the queue -async fn findadd(client: &mut Client, chan: &str, filter: &str, case: bool) -> Result<()> { +async fn searchadd(client: &mut Client, filter: &str, case_sensitive: bool) -> Result<()> { let qfilter = quote(filter); debug!("findadd: got ``{}'', quoted to ``{}''.", filter, qfilter); - let cmd = format!("{} {}", if case { "findadd" } else { "searchadd" }, qfilter); - client.send_message(chan, &cmd).await?; - Ok(()) + + let ast = match ExpressionParser::new().parse(&qfilter) { + Ok(ast) => ast, + Err(err) => { + bail!("Failed to parse filter: `{}`", err) + } + }; + + debug!("ast: {:#?}", ast); + + let mut results = Vec::new(); + for song in evaluate(&ast, case_sensitive, client, &FilterStickerNames::default()) + .await + .context("Failed to evaluate filter")? + { + results.push(client.add(&song).await); + } + + match results.into_iter().collect::<Result<Vec<()>>>() { + Ok(_) => Ok(()), + Err(err) => Err(err), + } } /// Send an arbitrary command @@ -442,34 +463,7 @@ enum SubCommand { command: PlaylistsCommand, }, - /// search case-sensitively for songs matching matching a filter and add them to the queue - /// - /// This command extends the MPD command `findadd' (which will search the MPD database) to allow - /// searches on attributes managed by mpdpopm: rating, playcount & last played time. - /// - /// The MPD `findadd' <https://www.musicpd.org/doc/html/protocol.html#command-findadd> will search the - /// MPD database for songs that match a given filter & add them to the play queue. The filter syntax is - /// documented here <https://www.musicpd.org/doc/html/protocol.html#filter-syntax>. - /// - /// This command adds three new terms on which you can filter: rating, playcount & lastplayed. Each is - /// expressed as an unsigned integer, with zero interpreted as "not set". For instance: - /// - /// mppopm findadd "(rating > 128)" - /// - /// Will add all songs in the library with a rating sticker > 128 to the play queue. - /// - /// mppopm also introduces OR clauses (MPD only supports AND), so that: - /// - /// mppopm findadd "((rating > 128) AND (artist =~ \"pogues\"))" - /// - /// will add all songs whose artist tag matches the regexp "pogues" with a rating greater than - /// 128. - /// - /// `findadd' is case-sensitive; for case-insensitive searching see the `searchadd' command. - #[clap(verbatim_doc_comment)] - Findadd { filter: String }, - - /// search case-insensitively for songs matching matching a filter and add them to the queue + /// search for songs matching matching a filter and add them to the queue /// /// This command extends the MPD command `searchadd' (which will search the MPD database) to allow /// searches on attributes managed by mpdpopm: rating, playcount & last played time. @@ -491,10 +485,14 @@ enum SubCommand { /// /// will add all songs whose artist tag matches the regexp "pogues" with a rating greater than /// 128. - /// - /// `searchadd' is case-insensitive; for case-sensitive searching see the `findadd' command. #[clap(verbatim_doc_comment)] - Searchadd { filter: String }, + Searchadd { + filter: String, + + /// Respect the casing, when performing the filter evaluation. + #[arg(short, long, default_value_t = true)] + case_sensitive: bool, + }, /// Send a command to mpd. #[clap(verbatim_doc_comment)] @@ -584,12 +582,10 @@ async fn main() -> Result<()> { SubCommand::Playlists { command } => match command { PlaylistsCommand::Get {} => get_playlists(&mut client).await, }, - SubCommand::Findadd { filter } => { - findadd(&mut client, &config.commands_chan, &filter, true).await - } - SubCommand::Searchadd { filter } => { - findadd(&mut client, &config.commands_chan, &filter, false).await - } + SubCommand::Searchadd { + filter, + case_sensitive, + } => searchadd(&mut client, &filter, case_sensitive).await, SubCommand::SendCommand { args } => { send_command(&mut client, &config.commands_chan, args).await } |
