Asked Vlams to look over it, this is the result

This commit is authored by me due to laziness
This commit is contained in:
Nox Sluijtman 2025-06-21 15:46:40 +02:00
parent 64c6487560
commit 76facd0ec2
Signed by: Egg
SSH key fingerprint: SHA256:2sG9X3C7Xvq2svGumz1/k7cm8l4G9+qAtAeugqB4J9M

View file

@ -24,23 +24,23 @@ struct Cli {
#[derive(Subcommand)] #[derive(Subcommand)]
enum Commands { enum Commands {
/// Toggle MPD stream /// Toggle MPD stream
Toggle {}, Toggle,
/// Skip to the next track /// Skip to the next track
Next {}, Next,
/// Revert to the previous track /// Revert to the previous track
Prev {}, Prev,
/// Stops playing /// Stops playing
Stop {}, Stop,
/// Play queueueu /// Play queueueu
Play { track: Option<u32> }, Play { track: Option<u32> },
/// Set or get crossfade /// Set or get crossfade
Crossfade { seconds: Option<i64> }, Crossfade { seconds: Option<i64> },
///Update still needs some work ///Update still needs some work
Update {}, Update,
/// Return currently playing song /// Return currently playing song
Current {}, Current,
/// Clear current queueueu /// Clear current queueueu
Clear {}, Clear,
/// Query database /// Query database
Search { Search {
///Search query ///Search query
@ -75,7 +75,7 @@ enum Commands {
// position: Option<u32>, // position: Option<u32>,
// }, // },
/// Shuffles the current queueue /// Shuffles the current queueue
Shuffle {}, Shuffle,
} }
fn main() { fn main() {
@ -89,15 +89,8 @@ fn main() {
None => String::from("localhost:6600"), None => String::from("localhost:6600"),
}; };
// let mut conn = Client::connect(host).unwrap();
let mut conn = Client::connect(host).expect("Connection failed"); let mut conn = Client::connect(host).expect("Connection failed");
// let mut conn = match Client::connect(host) {
// Ok(conn) => conn,
// Err(error) => panic!("yo fucked up: {}", error.to_string()),
// };
if let Some(cmd) = &cli.command { if let Some(cmd) = &cli.command {
match cmd { match cmd {
Commands::Play { track } => { Commands::Play { track } => {
@ -106,36 +99,19 @@ fn main() {
} else { } else {
conn.play().unwrap(); conn.play().unwrap();
} }
let status = get_status(conn, cli.verbose, n);
println!("{status}");
} }
Commands::Stop => {
Commands::Stop {} => {
conn.stop().unwrap(); conn.stop().unwrap();
} }
Commands::Toggle => {
Commands::Toggle {} => {
if conn.status().unwrap().state == State::Stop { if conn.status().unwrap().state == State::Stop {
conn.play().unwrap(); conn.play().unwrap();
} else { } else {
conn.toggle_pause().unwrap(); conn.toggle_pause().unwrap();
} }
let status = get_status(conn, cli.verbose, n);
println!("{status}");
} }
Commands::Next => conn.next().unwrap(),
Commands::Next {} => { Commands::Prev => conn.prev().unwrap(),
conn.next().unwrap();
let status = get_status(conn, cli.verbose, n);
println!("{status}");
}
Commands::Prev {} => {
conn.prev().unwrap();
let status = get_status(conn, cli.verbose, n);
println!("{status}");
}
Commands::List { file } => conn.queue().unwrap().iter().for_each(|x| { Commands::List { file } => conn.queue().unwrap().iter().for_each(|x| {
println!( println!(
"{:<02} {}", "{:<02} {}",
@ -147,166 +123,133 @@ fn main() {
} }
) )
}), }),
Commands::Update => {
Commands::Update {} => {
let thing = conn.update().unwrap(); let thing = conn.update().unwrap();
println!("{thing}") println!("{thing}")
} }
Commands::Current => (), // this is basically the same as having no command
Commands::Current {} => { Commands::Clear => conn.clear().unwrap(),
let status = get_status(conn, cli.verbose, n); Commands::Search { query, max } => {
println!("{status}");
}
Commands::Clear {} => {
conn.clear().unwrap();
}
Commands::Search {
query,
max,
// append,
// insert,
} => {
let mut songs: Vec<Song> = vec![];
let query = query.join(" "); let query = query.join(" ");
// I want to return all results by default let max = max.unwrap_or(conn.stats().unwrap().songs);
let window = (
0,
if let Some(n) = max {
*n
} else {
conn.stats().unwrap().songs
},
);
// let queue_length = conn.status().unwrap().queue_len;
// conn.search(&Query::new().and(Term::Any, query), window)
// .unwrap()
// .iter()
// .for_each(|x| songs.push(x.clone()));
// songs.iter().rev().for_each(|x| { conn.search(&Query::new().and(Term::Any, query), (0, max))
// conn.insert(x, usize::try_from(queue_length).unwrap())
// .unwrap();
// });
//conn.insert(, usize::try_from(queue_length).unwrap())
conn.search(&Query::new().and(Term::Any, query), window)
.unwrap() .unwrap()
.iter() .iter()
.for_each(|x| songs.push(x.clone())); .for_each(|x| println!("{}", x.file));
songs.iter().for_each(|x| println!("{}", x.file))
} }
Commands::Find { query, max, append } => { Commands::Find { query, max, append } => {
let mut songs: Vec<Song> = vec![];
let query = query.join(" "); let query = query.join(" ");
let window = ( let max = max.unwrap_or(conn.stats().unwrap().songs);
0,
if let Some(n) = max {
*n
} else {
conn.stats().unwrap().songs
},
);
if *append { if *append {
conn.findadd(&Query::new().and(Term::Any, query)).unwrap(); conn.findadd(&Query::new().and(Term::Any, query)).unwrap();
} else { } else {
conn.find(&Query::new().and(Term::Any, query), window) conn.find(&Query::new().and(Term::Any, query), (0, max))
.unwrap() .unwrap()
.iter() .iter()
.for_each(|x| songs.push(x.clone())); .for_each(|x| println!("{}", x.file));
songs.iter().for_each(|x| println!("{}", x.file))
} }
} }
Commands::Crossfade { seconds } => { Commands::Crossfade { seconds } => {
if let Some(crossfade) = seconds { if let Some(crossfade) = seconds {
conn.crossfade(*crossfade).unwrap() conn.crossfade(*crossfade).unwrap();
} else { } else {
if let Some(crossfade) = conn.status().unwrap().crossfade { println!(
println!("Crossfade: {}", crossfade.as_secs()); "Crossfade: {}",
} else { conn.status()
println!("Crossfade disabled") .unwrap()
.crossfade
.map_or("Disabled".into(), |d| d.as_secs().to_string())
);
} }
} }
} Commands::Shuffle => {
send_notification("Shuffling queueueu...", &n);
Commands::Shuffle {} => {
send_notification("Shuffling queueueu...".to_string(), n);
println!("Shuffling queueueu..."); println!("Shuffling queueueu...");
conn.shuffle(..).unwrap(); conn.shuffle(..).unwrap();
} }
} }
} else {
let status = get_status(conn, cli.verbose, n); if let Commands::Stop
println!("{}", &status); | Commands::List { .. }
libnotify::uninit(); | Commands::Update
| Commands::Clear
| Commands::Search { .. }
| Commands::Find { .. }
| Commands::Crossfade { .. }
| Commands::Shuffle = cmd
{
return;
} }
} }
println!("{}", get_status(conn, cli.verbose, n));
}
fn format_song(song: Song) -> String { fn format_song(song: Song) -> String {
format!("{} - {}", song.artist.unwrap(), song.title.unwrap()) format!("{} - {}", song.artist.unwrap(), song.title.unwrap())
} }
///Bool to String trait QuickFmt {
fn bts(b: bool) -> &'static str { fn quick_fmt(&self) -> &'static str;
b.then(|| "on").unwrap_or("off") }
impl QuickFmt for bool {
fn quick_fmt(&self) -> &'static str {
if *self {
"on"
} else {
"off"
}
}
} }
fn get_status(mut client: Client, verbose: bool, notify: Notification) -> String { fn get_status(mut client: Client, verbose: bool, notify: Notification) -> String {
let current_song = if let Some(song) = client.currentsong().unwrap() {
format_song(song)
} else {
"No song playing".into()
};
send_notification(&current_song, &notify);
if !verbose {
return current_song;
}
let mut output = Vec::with_capacity(3);
output.push(current_song);
let status = client.status().unwrap(); let status = client.status().unwrap();
let repeat = bts(status.repeat);
let single = bts(status.single);
let random = bts(status.random);
let consume = bts(status.consume);
let duration = match status.time {
Some((stamp, total)) => {
let stamp = to_mins_string(stamp);
let total = to_mins_string(total);
format!("{stamp}/{total}")
}
None => "".to_string(),
};
let mut output = vec![];
if let Some(song) = client.currentsong().unwrap() {
output.push(format_song(song))
} else {
output.push("No song playing".to_string())
}
send_notification(output.first().unwrap().clone(), notify);
if verbose {
output.push(format!( output.push(format!(
"volume: {vol:<6} repeat: {repeat:<6} random: {rnd:<6} single: {single:<6} consume: {consume:<6}", "volume: {vol:<6} repeat: {repeat:<6} random: {rnd:<6} single: {single:<6} consume: {consume:<6}",
vol = {format!("{}%", status.volume)}, vol = format!("{}%", status.volume),
repeat = repeat, repeat = status.repeat.quick_fmt(),
rnd = random, rnd = status.random.quick_fmt(),
single = single, single = status.single.quick_fmt(),
consume = consume consume = status.consume.quick_fmt()
)); ));
output.push(format!( let state = match status.state {
"[{status}] {duration}",
status = {
match client.status().unwrap().state {
State::Stop => "stopped", State::Stop => "stopped",
State::Pause => "paused", State::Pause => "paused",
State::Play => "playing", State::Play => "playing",
} };
}
)); let duration = status.time.map_or("".into(), |(stamp, total)| {
} let stamp = to_mins_string(stamp);
let total = to_mins_string(total);
format!("{stamp}/{total}")
});
output.push(format!("[{state}] {duration}"));
output.join("\n") output.join("\n")
} }
fn send_notification(body: String, notify: Notification) -> String { fn send_notification(body: &str, notify: &Notification) {
let _ = notify.update("Noise", body.as_str(), None); let _ = notify.update("Noise", body, None);
notify.show().unwrap(); notify.show().unwrap();
body
} }
fn to_mins_string(dur: Duration) -> String { fn to_mins_string(dur: Duration) -> String {