135
src/main.rs
135
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 clap::Parser;
|
||||||
use discord_presence::{Client, models::ActivityType};
|
use discord_presence::{
|
||||||
use mpd::{Idle, Subsystem};
|
Client, Event,
|
||||||
|
models::{ActivityTimestamps, ActivityType},
|
||||||
|
};
|
||||||
|
use mpd::{Idle, Song, State, Subsystem};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
struct Config {
|
struct Config {
|
||||||
address: String,
|
address: String,
|
||||||
|
client_id: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Config {
|
impl Default for Config {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
address: "localhost:6600".to_string(),
|
address: "localhost:6600".into(),
|
||||||
|
client_id: 1464985070992363645,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,6 +33,90 @@ struct Args {
|
|||||||
config: Option<PathBuf>,
|
config: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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<String> {
|
||||||
|
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::<u8>::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() {
|
fn main() {
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
let config = args
|
let config = args
|
||||||
@@ -32,39 +125,9 @@ fn main() {
|
|||||||
.and_then(|t| toml::from_str::<Config>(&t).ok())
|
.and_then(|t| toml::from_str::<Config>(&t).ok())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
let mut mpdc = mpd::Client::connect("localhost:6600").unwrap();
|
let mut app = Application::new(config);
|
||||||
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);
|
|
||||||
});
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
sleep(Duration::from_secs(100));
|
app.run_update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user