From 5f703e85386112f54cc3aef5dd2094a6aaba6b45 Mon Sep 17 00:00:00 2001 From: jude Date: Sat, 16 Sep 2023 17:59:03 +0100 Subject: [PATCH] Add status update time to sender --- postman/src/sender.rs | 15 ++++++++---- src/models/channel_data.rs | 30 ++++++++++++++++------- web/src/routes/dashboard/export.rs | 2 +- web/src/routes/dashboard/guild.rs | 3 ++- web/src/routes/dashboard/mod.rs | 38 ++++++++++++++++++++++++++---- web/static/js/reminder_errors.js | 4 ++++ 6 files changed, 73 insertions(+), 19 deletions(-) diff --git a/postman/src/sender.rs b/postman/src/sender.rs index da99555..9b325fe 100644 --- a/postman/src/sender.rs +++ b/postman/src/sender.rs @@ -472,10 +472,17 @@ WHERE } async fn set_sent(&self, pool: impl Executor<'_, Database = Database> + Copy) { - sqlx::query!("UPDATE reminders SET `status` = 'sent' WHERE `id` = ?", self.id) - .execute(pool) - .await - .expect(&format!("Could not delete Reminder {}", self.id)); + sqlx::query!( + " + UPDATE reminders + SET `status` = 'sent', `status_change_time` = NOW() + WHERE `id` = ? + ", + self.id + ) + .execute(pool) + .await + .expect(&format!("Could not delete Reminder {}", self.id)); } async fn set_failed( diff --git a/src/models/channel_data.rs b/src/models/channel_data.rs index e36f31c..1b29675 100644 --- a/src/models/channel_data.rs +++ b/src/models/channel_data.rs @@ -23,7 +23,11 @@ impl ChannelData { if let Ok(c) = sqlx::query_as_unchecked!( Self, - "SELECT id, name, nudge, blacklisted, webhook_id, webhook_token, paused, paused_until, guild_id AS db_guild_id FROM channels WHERE channel = ?", + " + SELECT id, name, nudge, blacklisted, webhook_id, webhook_token, paused, paused_until, + guild_id AS db_guild_id + FROM channels WHERE channel = ? + ", channel_id ) .fetch_one(pool) @@ -31,12 +35,18 @@ impl ChannelData { { Ok(c) } else { - let props = channel.to_owned().guild().map(|g| (g.guild_id.as_u64().to_owned(), g.name)); + let props = + channel.to_owned().guild().map(|g| (g.guild_id.as_u64().to_owned(), g.name)); - let (guild_id, channel_name) = if let Some((a, b)) = props { (Some(a), Some(b)) } else { (None, None) }; + let (guild_id, channel_name) = + if let Some((a, b)) = props { (Some(a), Some(b)) } else { (None, None) }; sqlx::query!( - "INSERT IGNORE INTO channels (channel, name, guild_id) VALUES (?, ?, (SELECT id FROM guilds WHERE guild = ?))", + " + INSERT IGNORE INTO channels + (channel, name, guild_id) + VALUES (?, ?, (SELECT id FROM guilds WHERE guild = ?)) + ", channel_id, channel_name, guild_id @@ -47,7 +57,10 @@ impl ChannelData { Ok(sqlx::query_as_unchecked!( Self, " -SELECT id, name, nudge, blacklisted, webhook_id, webhook_token, paused, paused_until, guild_id AS db_guild_id FROM channels WHERE channel = ? + SELECT id, name, nudge, blacklisted, webhook_id, webhook_token, paused, + paused_until, guild_id AS db_guild_id + FROM channels + WHERE channel = ? ", channel_id ) @@ -59,9 +72,10 @@ SELECT id, name, nudge, blacklisted, webhook_id, webhook_token, paused, paused_u pub async fn commit_changes(&self, pool: &MySqlPool) { sqlx::query!( " -UPDATE channels SET name = ?, nudge = ?, blacklisted = ?, webhook_id = ?, webhook_token = ?, paused = ?, paused_until \ - = ? WHERE id = ? - ", + UPDATE channels + SET name = ?, nudge = ?, blacklisted = ?, webhook_id = ?, webhook_token = ?, + paused = ?, paused_until = ? + WHERE id = ?", self.name, self.nudge, self.blacklisted, diff --git a/web/src/routes/dashboard/export.rs b/web/src/routes/dashboard/export.rs index 86cf10e..ba02886 100644 --- a/web/src/routes/dashboard/export.rs +++ b/web/src/routes/dashboard/export.rs @@ -145,7 +145,7 @@ pub async fn import_reminders( attachment: record.attachment, attachment_name: record.attachment_name, avatar: record.avatar, - channel: channel_id, + channel: Some(channel_id), content: record.content, embed_author: record.embed_author, embed_author_url: record.embed_author_url, diff --git a/web/src/routes/dashboard/guild.rs b/web/src/routes/dashboard/guild.rs index 4c33798..1adf4a8 100644 --- a/web/src/routes/dashboard/guild.rs +++ b/web/src/routes/dashboard/guild.rs @@ -332,7 +332,8 @@ pub async fn get_reminders( sqlx::query_as_unchecked!( Reminder, - "SELECT + " + SELECT reminders.attachment, reminders.attachment_name, reminders.avatar, diff --git a/web/src/routes/dashboard/mod.rs b/web/src/routes/dashboard/mod.rs index 65ff743..7a4d784 100644 --- a/web/src/routes/dashboard/mod.rs +++ b/web/src/routes/dashboard/mod.rs @@ -124,8 +124,8 @@ pub struct Reminder { attachment: Option>, attachment_name: Option, avatar: Option, - #[serde(with = "string")] - channel: u64, + #[serde(with = "string_opt")] + channel: Option, content: String, embed_author: String, embed_author_url: Option, @@ -310,6 +310,34 @@ mod string { } } +mod string_opt { + use std::{fmt::Display, str::FromStr}; + + use serde::{de, Deserialize, Deserializer, Serializer}; + + pub fn serialize(value: &Option, serializer: S) -> Result + where + T: Display, + S: Serializer, + { + match value { + Some(value) => serializer.collect_str(value), + None => serializer.serialize_none(), + } + } + + pub fn deserialize<'de, T, D>(deserializer: D) -> Result, D::Error> + where + T: FromStr, + T::Err: Display, + D: Deserializer<'de>, + { + Option::deserialize(deserializer)? + .map(|d: String| d.parse().map_err(de::Error::custom)) + .transpose() + } +} + mod base64s { use serde::{de, Deserialize, Deserializer, Serializer}; @@ -374,7 +402,7 @@ pub async fn create_reminder( } // validate channel - let channel = ChannelId(reminder.channel).to_channel_cached(&ctx); + let channel = reminder.channel.map(|c| ChannelId(c).to_channel_cached(&ctx)).flatten(); let channel_exists = channel.is_some(); let channel_matches_guild = @@ -382,14 +410,14 @@ pub async fn create_reminder( if !channel_matches_guild || !channel_exists { warn!( - "Error in `create_reminder`: channel {} not found for guild {} (channel exists: {})", + "Error in `create_reminder`: channel {:?} not found for guild {} (channel exists: {})", reminder.channel, guild_id, channel_exists ); return Err(json!({"error": "Channel not found"})); } - let channel = create_database_channel(&ctx, ChannelId(reminder.channel), pool).await; + let channel = create_database_channel(&ctx, ChannelId(reminder.channel.unwrap()), pool).await; if let Err(e) = channel { warn!("`create_database_channel` returned an error code: {:?}", e); diff --git a/web/static/js/reminder_errors.js b/web/static/js/reminder_errors.js index 4d941ac..181cf83 100644 --- a/web/static/js/reminder_errors.js +++ b/web/static/js/reminder_errors.js @@ -16,6 +16,10 @@ document.addEventListener("paneLoad", (ev) => { loadErrors() .then((res) => { + res = res + .filter((r) => r.status_change_time !== null) + .sort((a, b) => a.status_change_time < b.status_change_time); + for (const reminder of res) { const newRow = template.content.cloneNode(true);