summaryrefslogtreecommitdiff
path: root/src/labwatch.rs
diff options
context:
space:
mode:
authorNathan Ringo <nathan@remexre.com>2024-11-22 00:11:43 -0600
committerNathan Ringo <nathan@remexre.com>2024-11-22 00:11:43 -0600
commitdd0e6e45c35133ec8a3e2886b7b050484b388d03 (patch)
tree3ea9f5a098fc9c150473942c97e8b07833440803 /src/labwatch.rs
Initial commit
Diffstat (limited to 'src/labwatch.rs')
-rw-r--r--src/labwatch.rs67
1 files changed, 67 insertions, 0 deletions
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<HandlerConfig>, 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())
+}