1
Fork 0
shimmeringmoon/src/bin/discord-presence/main.rs
prescientmoon ce18db3d14
Automatically run jacket processing
This commit makes it so jacket processing is automatically run if any of
it's outputs are missing from the filesystem, or if the hash of the raw
jacket directory has changes since the last recorded value.

Moreover, most assets and all fonts are now embedded in the binary!
2024-11-09 12:22:35 +01:00

71 lines
2 KiB
Rust

use std::time::Duration;
use anyhow::anyhow;
// {{{ Imports
use discord_rich_presence::activity::{Activity, Assets};
use discord_rich_presence::{DiscordIpc, DiscordIpcClient};
use shimmeringmoon::arcaea::chart::Difficulty;
use shimmeringmoon::arcaea::play::PlayWithDetails;
use shimmeringmoon::arcaea::score::ScoringSystem;
use shimmeringmoon::context::paths::get_var;
use shimmeringmoon::context::Error;
// }}}
#[tokio::main]
async fn main() -> Result<(), Error> {
let server_url = get_var("SHIMMERING_SERVER_URL")?;
let client_id = get_var("SHIMMERING_DISCORD_ID")?;
println!("Connecting to discord...");
let mut ipc = DiscordIpcClient::new(&client_id).map_err(|e| anyhow!("{}", e))?;
ipc.connect().map_err(|e| anyhow!("{}", e))?;
println!("Starting presence loop...");
loop {
println!("Getting most recent score...");
let res = reqwest::get(format!("{}/plays/latest", server_url)).await;
let res = match res.and_then(|r| r.error_for_status()) {
Ok(v) => v,
Err(e) => {
ipc.clear_activity().map_err(|e| anyhow!("{}", e))?;
println!("{e}");
tokio::time::sleep(Duration::from_secs(10)).await;
continue;
}
};
let triplet = res.json::<PlayWithDetails>().await?;
let jacket_url = format!(
"{}/jackets/by_chart_id/{}.png",
server_url, &triplet.chart.id
);
println!("Jacket url: {}", jacket_url);
let jacket_text = format!("{}{}", &triplet.song.title, &triplet.song.artist);
let assets = Assets::new()
.large_image(&jacket_url)
.large_text(&jacket_text);
let details = format!(
"{} [{} {}]",
&triplet.song.title,
Difficulty::DIFFICULTY_SHORTHANDS[triplet.chart.difficulty.to_index()],
&triplet.chart.level,
);
let state = format!("{}", &triplet.play.score(ScoringSystem::Standard));
let activity = Activity::new()
.assets(assets)
.details(&details)
.state(&state);
println!("Sending activity");
ipc.set_activity(activity).map_err(|e| anyhow!("{}", e))?;
tokio::time::sleep(Duration::from_secs(30)).await;
}
}