From 165bfa59669ea15e779e849098a01b95b21df9fa Mon Sep 17 00:00:00 2001 From: Slendi Date: Sun, 25 Jan 2026 18:17:33 +0200 Subject: [PATCH] Get basics to work Signed-off-by: Slendi --- src/main.rs | 135 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 99 insertions(+), 36 deletions(-) diff --git a/src/main.rs b/src/main.rs index dfab1bd..7721e65 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,19 +1,28 @@ -use std::{path::PathBuf, thread::sleep, time::Duration}; +use std::{ + path::PathBuf, + thread::sleep, + time::{Duration, Instant, SystemTime, UNIX_EPOCH}, +}; use clap::Parser; -use discord_presence::{Client, models::ActivityType}; -use mpd::{Idle, Subsystem}; +use discord_presence::{ + Client, Event, + models::{ActivityTimestamps, ActivityType}, +}; +use mpd::{Idle, Song, State, Subsystem}; use serde::{Deserialize, Serialize}; #[derive(Debug, Serialize, Deserialize)] struct Config { address: String, + client_id: u64, } impl Default for Config { fn default() -> Self { Self { - address: "localhost:6600".to_string(), + address: "localhost:6600".into(), + client_id: 1464985070992363645, } } } @@ -24,6 +33,90 @@ struct Args { config: Option, } +struct Application { + mpdc: mpd::Client, + client: Client, + config: Config, +} + +impl Application { + pub fn new(config: Config) -> Self { + let mut ret = Self { + mpdc: mpd::Client::connect(config.address.clone()).unwrap(), + client: Client::new(config.client_id), + config, + }; + + let _error = ret.client.on_error(|ctx| { + eprintln!("An error occured, {:?}", ctx.event); + }); + + ret.client.start(); + ret.client.block_until_event(Event::Ready).unwrap(); + assert!(Client::is_ready()); + + ret + } + + fn tag(song: &Song, key: &str) -> Option { + song.tags + .iter() + .find(|(k, _)| k.eq_ignore_ascii_case(key)) + .map(|(_, v)| v.clone()) + } + + pub fn run_update(&mut self) { + let _ = self.mpdc.idle(&[Subsystem::Player]); + let status = self.mpdc.status().unwrap(); + + let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); + + let start_dur: Duration; + let end_dur: Duration; + if let Some((position, end)) = status.time { + start_dur = now + .checked_sub(position) + .unwrap_or_else(|| std::time::Duration::from_secs(0)); + + end_dur = start_dur + end; + } else { + start_dur = std::time::Duration::from_secs(0); + end_dur = std::time::Duration::from_secs(0); + } + + let started_ms = start_dur.as_millis() as u64; + let ends_ms = end_dur.as_millis() as u64; + + let song = self.mpdc.currentsong().unwrap(); + if let Some(song) = song { + //let cover = self.mpdc.albumart(&song); + //let mut bytes = Vec::::new(); + //if let Ok(cover) = cover { + // bytes = cover; + //} + if status.state == State::Play { + let album = Self::tag(&song, "Album"); + + let _err = self.client.set_activity(|a| { + a.state(format!( + "{} / {}", + song.artist.unwrap_or("Unknown".into()), + album.unwrap_or("Unknown".into()) + )) + .details(song.title.unwrap_or("Unknown".into())) + .activity_type(ActivityType::Listening) + .timestamps(|_| ActivityTimestamps::new().start(started_ms).end(ends_ms)) + }); + } else { + let _err = self.client.clear_activity(); + } + } else { + let _err = self.client.clear_activity(); + } + sleep(Duration::from_secs(1)); + } +} + fn main() { let args = Args::parse(); let config = args @@ -32,39 +125,9 @@ fn main() { .and_then(|t| toml::from_str::(&t).ok()) .unwrap_or_default(); - let mut mpdc = mpd::Client::connect("localhost:6600").unwrap(); - println!("Status: {:?}", mpdc.status()); - mpdc.idle(&[Subsystem::Player]); - - let mut client = Client::new(1464985070992363645); - - client.start(); - - { - let ready = client.on_ready({ - let client = client.clone(); - move |_ctx| { - let mut client = client.clone(); - println!("READY!"); - - client - .set_activity(|a| { - a.state("Rust") - .details("Programming") - .activity_type(ActivityType::Listening) - }) - .unwrap(); - } - }); - - std::mem::forget(ready); - } - - let _error = client.on_error(|ctx| { - eprintln!("An error occured, {:?}", ctx.event); - }); + let mut app = Application::new(config); loop { - sleep(Duration::from_secs(100)); + app.run_update(); } }