aboutsummaryrefslogtreecommitdiffstats
path: root/pkgs/by-name/mp/mpdpopm/src/bin
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/by-name/mp/mpdpopm/src/bin')
-rw-r--r--pkgs/by-name/mp/mpdpopm/src/bin/mpdpopm.rs78
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
}