From dd0e6e45c35133ec8a3e2886b7b050484b388d03 Mon Sep 17 00:00:00 2001 From: Nathan Ringo Date: Fri, 22 Nov 2024 00:11:43 -0600 Subject: Initial commit --- src/labwatch.rs | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 src/labwatch.rs (limited to 'src/labwatch.rs') diff --git a/src/labwatch.rs b/src/labwatch.rs new file mode 100644 index 0000000..e2f8a7c --- /dev/null +++ b/src/labwatch.rs @@ -0,0 +1,67 @@ +use crate::HandlerConfig; +use anyhow::{anyhow, Context as _, Result}; +use serenity::all::{Context, MessageBuilder}; +use std::{sync::Arc, time::Duration}; +use time::{Date, OffsetDateTime, Weekday}; +use tokio::{ + fs::{self, create_dir_all, File}, + time::{interval, MissedTickBehavior}, +}; + +static REACTS: &[char] = &['✅', '❌', '❔']; + +pub async fn start(config: Arc, ctx: Context) { + let mut timer = interval(Duration::from_secs(1)); + timer.set_missed_tick_behavior(MissedTickBehavior::Skip); + loop { + timer.tick().await; + if let Err(err) = tick(&*config, &ctx).await { + log::error!("{err:?}"); + } + } +} + +async fn tick(config: &HandlerConfig, ctx: &Context) -> Result<()> { + let now = OffsetDateTime::now_local().context("Failed to get current time")?; + if now.weekday() != Weekday::Sunday { + // Wait to post 'till Sunday. + return Ok(()); + } + let mut now_path = config.db_dir.join("labwatch"); + create_dir_all(&now_path) + .await + .with_context(|| anyhow!("Failed to create {now_path:?}"))?; + now_path.push(date_name(now.date())); + if fs::try_exists(&now_path) + .await + .with_context(|| anyhow!("Failed to check if {now_path:?} exists"))? + { + // Already posted this week. + return Ok(()); + } + + let mut date = now.date(); + for _ in 1..=5 { + date = date.next_day().context("Reached the end of times")?; + let msg = MessageBuilder::new().push(date_name(date)).build(); + let msg = config + .labwatch_channel_id + .say(&ctx.http, &msg) + .await + .with_context(|| anyhow!("Failed to send message for {date}"))?; + for &react in REACTS { + msg.react(&ctx.http, react).await.with_context(|| { + anyhow!("Failed to react with {react} on the message for {date}") + })?; + } + } + + File::create(&now_path) + .await + .with_context(|| anyhow!("Failed to create {now_path:?}"))?; + Ok(()) +} + +fn date_name(date: Date) -> String { + format!("{}, {} {}", date.weekday(), date.month(), date.day()) +} -- cgit v1.2.3