diff options
| author | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2026-01-31 16:29:24 +0100 |
|---|---|---|
| committer | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2026-01-31 16:29:24 +0100 |
| commit | 9741228b51856902f3791b43012b2ae792cf3f5d (patch) | |
| tree | 4fa1b571cf9c5a9bed725249a5557563ef53d035 /pkgs/by-name/mp/mpdpopm/src/messanges/mod.rs | |
| parent | pkgs/mpdpopm: Change the default config to be the new json format (diff) | |
| download | nixos-config-9741228b51856902f3791b43012b2ae792cf3f5d.zip | |
pkgs/mpdpopm: Add a (basic) dj mode
Diffstat (limited to '')
| -rw-r--r-- | pkgs/by-name/mp/mpdpopm/src/messanges/mod.rs | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/pkgs/by-name/mp/mpdpopm/src/messanges/mod.rs b/pkgs/by-name/mp/mpdpopm/src/messanges/mod.rs new file mode 100644 index 00000000..c5320dd9 --- /dev/null +++ b/pkgs/by-name/mp/mpdpopm/src/messanges/mod.rs @@ -0,0 +1,110 @@ +use anyhow::{Context, Result, anyhow, bail, ensure}; +use clap::{Parser, Subcommand}; +use shlex::Shlex; +use tracing::info; + +use crate::{ + clients::{Client, IdleClient}, + dj::{Dj, algorithms::Discovery}, +}; + +pub const COMMAND_CHANNEL: &str = "unwoundstack.com:commands"; + +#[derive(Parser)] +struct Commands { + #[command(subcommand)] + command: SubCommand, +} + +#[derive(Parser)] +enum SubCommand { + Dj { + #[command(subcommand)] + command: DjCommand, + }, +} + +#[derive(Subcommand)] +enum DjCommand { + Start {}, + Stop {}, +} + +pub(crate) struct MessageQueue { + dj: Option<Dj<Discovery>>, +} + +impl MessageQueue { + pub(crate) fn new() -> Self { + Self { dj: None } + } + + pub(crate) async fn advance_dj(&mut self, client: &mut Client) -> Result<()> { + if let Some(dj) = self.dj.as_mut() { + dj.add_track(client).await?; + } + + Ok(()) + } + + /// Read messages off the commands channel & dispatch 'em + pub(crate) async fn check_messages( + &mut self, + client: &mut Client, + idle_client: &mut IdleClient, + ) -> Result<()> { + let m = idle_client + .get_messages() + .await + .context("Failed to `get_messages` from client")?; + + for (chan, msgs) in m { + ensure!(chan == COMMAND_CHANNEL, "Unknown channel: `{}`", chan); + + for msg in msgs { + self.process(client, msg).await?; + } + } + + Ok(()) + } + + /// Process a single command + pub(crate) async fn process(&mut self, client: &mut Client, msg: String) -> Result<()> { + let split = { + let mut shl = Shlex::new(&msg); + let res: Vec<_> = shl.by_ref().collect(); + + if shl.had_error { + bail!("Failed to parse command '{msg}'") + } + + assert_eq!(shl.line_no, 1, "A unexpected newline appeared"); + assert!(!res.is_empty()); + + let mut base = vec!["base".to_owned()]; + base.extend(res); + base + }; + + let args = Commands::parse_from(split); + + match args.command { + SubCommand::Dj { command } => match command { + DjCommand::Start {} => { + info!("Dj started"); + self.dj = Some(Dj::new(Discovery::new())); + self.advance_dj(client).await?; + } + DjCommand::Stop {} => { + self.dj + .take() + .ok_or_else(|| anyhow!("Tried to disable already disabled dj mode"))?; + info!("Dj stopped"); + } + }, + } + + Ok(()) + } +} |
