diff options
| author | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2026-01-27 18:59:49 +0100 |
|---|---|---|
| committer | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2026-01-27 18:59:49 +0100 |
| commit | 75d5979ae5b71d79490c14313f7d25ef3685a21c (patch) | |
| tree | 9872795a319fa1244d0d393d0269cf553c0c845f /pkgs/by-name/mp/mpdpopm/src/bin/mpdpopm.rs | |
| parent | pkgs/mpp-lyrics: Account for different name for lyrics key in mp3 files (diff) | |
| download | nixos-config-75d5979ae5b71d79490c14313f7d25ef3685a21c.zip | |
pkgs/mpdpopm: Remove the whole message handling code
It is easier to handle the messages before sending them. The only thing we lose is the ability to specify messages via external clients.
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 } |
