jude/orphan-reminders #1
@ -1,9 +1,8 @@
|
||||
-- Drop existing constraint
|
||||
-- TODO
|
||||
ALTER TABLE `reminders` DROP CONSTRAINT `channel_id_`
|
||||
ALTER TABLE `reminders` DROP CONSTRAINT `reminders_ibfk_1`;
|
||||
|
||||
ALTER TABLE `reminders` MODIFY COLUMN `channel_id` BIGINT ;
|
||||
ALTER TABLE `reminders` ADD COLUMN `guild_id` BIGINT;
|
||||
ALTER TABLE `reminders` MODIFY COLUMN `channel_id` INT UNSIGNED;
|
||||
ALTER TABLE `reminders` ADD COLUMN `guild_id` INT UNSIGNED;
|
||||
|
||||
ALTER TABLE `reminders`
|
||||
ADD CONSTRAINT `guild_id_fk`
|
||||
@ -17,5 +16,4 @@ ALTER TABLE `reminders`
|
||||
REFERENCES `channels`(`id`)
|
||||
ON DELETE SET NULL;
|
||||
|
||||
-- TODO
|
||||
UPDATE `reminders` SET `guild_id` = (SELECT guilds.`id` FROM `channels` INNER JOIN `guilds` ON channels.guild_id = guilds.id WHERE )
|
||||
UPDATE `reminders` SET `guild_id` = (SELECT guilds.`id` FROM `channels` INNER JOIN `guilds` ON channels.guild_id = guilds.id WHERE reminders.channel_id = channels.id);
|
||||
|
@ -10,6 +10,7 @@ pub struct ChannelData {
|
||||
pub webhook_id: Option<u64>,
|
||||
pub webhook_token: Option<String>,
|
||||
pub paused: bool,
|
||||
pub db_guild_id: Option<u32>,
|
||||
pub paused_until: Option<NaiveDateTime>,
|
||||
}
|
||||
|
||||
@ -22,7 +23,7 @@ impl ChannelData {
|
||||
|
||||
if let Ok(c) = sqlx::query_as_unchecked!(
|
||||
Self,
|
||||
"SELECT id, name, nudge, blacklisted, webhook_id, webhook_token, paused, paused_until 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)
|
||||
@ -46,7 +47,7 @@ impl ChannelData {
|
||||
Ok(sqlx::query_as_unchecked!(
|
||||
Self,
|
||||
"
|
||||
SELECT id, name, nudge, blacklisted, webhook_id, webhook_token, paused, paused_until 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
|
||||
)
|
||||
|
@ -51,6 +51,7 @@ pub struct ReminderBuilder {
|
||||
pool: MySqlPool,
|
||||
uid: String,
|
||||
channel: u32,
|
||||
guild: Option<u32>,
|
||||
thread_id: Option<u64>,
|
||||
utc_time: NaiveDateTime,
|
||||
timezone: String,
|
||||
@ -86,6 +87,7 @@ impl ReminderBuilder {
|
||||
INSERT INTO reminders (
|
||||
`uid`,
|
||||
`channel_id`,
|
||||
`guild_id`,
|
||||
`utc_time`,
|
||||
`timezone`,
|
||||
`interval_seconds`,
|
||||
@ -110,11 +112,13 @@ INSERT INTO reminders (
|
||||
?,
|
||||
?,
|
||||
?,
|
||||
?,
|
||||
?
|
||||
)
|
||||
",
|
||||
self.uid,
|
||||
self.channel,
|
||||
self.guild,
|
||||
utc_time,
|
||||
self.timezone,
|
||||
self.interval_seconds,
|
||||
@ -247,10 +251,10 @@ impl<'a> MultiReminderBuilder<'a> {
|
||||
{
|
||||
Err(ReminderError::UserBlockedDm)
|
||||
} else {
|
||||
Ok(user_data.dm_channel)
|
||||
Ok((user_data.dm_channel, None))
|
||||
}
|
||||
} else {
|
||||
Ok(user_data.dm_channel)
|
||||
Ok((user_data.dm_channel, None))
|
||||
}
|
||||
} else {
|
||||
Err(ReminderError::InvalidTag)
|
||||
@ -297,13 +301,13 @@ impl<'a> MultiReminderBuilder<'a> {
|
||||
.commit_changes(&self.ctx.data().database)
|
||||
.await;
|
||||
|
||||
Ok(channel_data.id)
|
||||
Ok((channel_data.id, channel_data.db_guild_id))
|
||||
}
|
||||
|
||||
Err(e) => Err(ReminderError::DiscordError(e.to_string())),
|
||||
}
|
||||
} else {
|
||||
Ok(channel_data.id)
|
||||
Ok((channel_data.id, channel_data.db_guild_id))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -317,7 +321,8 @@ impl<'a> MultiReminderBuilder<'a> {
|
||||
let builder = ReminderBuilder {
|
||||
pool: self.ctx.data().database.clone(),
|
||||
uid: generate_uid(),
|
||||
channel: c,
|
||||
channel: c.0,
|
||||
guild: c.1,
|
||||
thread_id,
|
||||
utc_time: self.utc_time,
|
||||
timezone: self.timezone.to_string(),
|
||||
|
@ -165,6 +165,7 @@ pub async fn initialize(
|
||||
routes::dashboard::guild::get_reminders,
|
||||
routes::dashboard::guild::edit_reminder,
|
||||
routes::dashboard::guild::delete_reminder,
|
||||
routes::dashboard::guild::get_reminder_errors,
|
||||
routes::dashboard::export::export_reminders,
|
||||
routes::dashboard::export::export_reminder_templates,
|
||||
routes::dashboard::export::export_todos,
|
||||
|
@ -26,7 +26,7 @@ use crate::{
|
||||
routes::{
|
||||
dashboard::{
|
||||
create_database_channel, create_reminder, template_name_default, DeleteReminder,
|
||||
DeleteReminderTemplate, PatchReminder, Reminder, ReminderTemplate,
|
||||
DeleteReminderTemplate, PatchReminder, Reminder, ReminderError, ReminderTemplate,
|
||||
},
|
||||
JsonResult,
|
||||
},
|
||||
@ -322,72 +322,53 @@ pub async fn create_guild_reminder(
|
||||
pub async fn get_reminders(
|
||||
id: u64,
|
||||
cookies: &CookieJar<'_>,
|
||||
ctx: &State<Context>,
|
||||
serenity_context: &State<Context>,
|
||||
pool: &State<Pool<MySql>>,
|
||||
) -> JsonResult {
|
||||
check_authorization!(cookies, serenity_context.inner(), id);
|
||||
|
||||
let channels_res = GuildId(id).channels(&ctx.inner()).await;
|
||||
sqlx::query_as_unchecked!(
|
||||
Reminder,
|
||||
"SELECT
|
||||
reminders.attachment,
|
||||
reminders.attachment_name,
|
||||
reminders.avatar,
|
||||
channels.channel,
|
||||
reminders.content,
|
||||
reminders.embed_author,
|
||||
reminders.embed_author_url,
|
||||
reminders.embed_color,
|
||||
reminders.embed_description,
|
||||
reminders.embed_footer,
|
||||
reminders.embed_footer_url,
|
||||
reminders.embed_image_url,
|
||||
reminders.embed_thumbnail_url,
|
||||
reminders.embed_title,
|
||||
IFNULL(reminders.embed_fields, '[]') AS embed_fields,
|
||||
reminders.enabled,
|
||||
reminders.expires,
|
||||
reminders.interval_seconds,
|
||||
reminders.interval_days,
|
||||
reminders.interval_months,
|
||||
reminders.name,
|
||||
reminders.restartable,
|
||||
reminders.tts,
|
||||
reminders.uid,
|
||||
reminders.username,
|
||||
reminders.utc_time
|
||||
FROM reminders
|
||||
LEFT JOIN channels ON channels.id = reminders.channel_id
|
||||
WHERE `status` = 'pending' AND reminders.guild_id = (SELECT id FROM guilds WHERE guild = ?)",
|
||||
id
|
||||
)
|
||||
.fetch_all(pool.inner())
|
||||
.await
|
||||
.map(|r| Ok(json!(r)))
|
||||
.unwrap_or_else(|e| {
|
||||
warn!("Failed to complete SQL query: {:?}", e);
|
||||
|
||||
match channels_res {
|
||||
Ok(channels) => {
|
||||
let channels = channels
|
||||
.keys()
|
||||
.into_iter()
|
||||
.map(|k| k.as_u64().to_string())
|
||||
.collect::<Vec<String>>()
|
||||
.join(",");
|
||||
|
||||
sqlx::query_as_unchecked!(
|
||||
Reminder,
|
||||
"SELECT
|
||||
reminders.attachment,
|
||||
reminders.attachment_name,
|
||||
reminders.avatar,
|
||||
channels.channel,
|
||||
reminders.content,
|
||||
reminders.embed_author,
|
||||
reminders.embed_author_url,
|
||||
reminders.embed_color,
|
||||
reminders.embed_description,
|
||||
reminders.embed_footer,
|
||||
reminders.embed_footer_url,
|
||||
reminders.embed_image_url,
|
||||
reminders.embed_thumbnail_url,
|
||||
reminders.embed_title,
|
||||
IFNULL(reminders.embed_fields, '[]') AS embed_fields,
|
||||
reminders.enabled,
|
||||
reminders.expires,
|
||||
reminders.interval_seconds,
|
||||
reminders.interval_days,
|
||||
reminders.interval_months,
|
||||
reminders.name,
|
||||
reminders.restartable,
|
||||
reminders.tts,
|
||||
reminders.uid,
|
||||
reminders.username,
|
||||
reminders.utc_time
|
||||
FROM reminders
|
||||
LEFT JOIN channels ON channels.id = reminders.channel_id
|
||||
WHERE `status` = 'pending' AND FIND_IN_SET(channels.channel, ?)",
|
||||
channels
|
||||
)
|
||||
.fetch_all(pool.inner())
|
||||
.await
|
||||
.map(|r| Ok(json!(r)))
|
||||
.unwrap_or_else(|e| {
|
||||
warn!("Failed to complete SQL query: {:?}", e);
|
||||
|
||||
json_err!("Could not load reminders")
|
||||
})
|
||||
}
|
||||
Err(e) => {
|
||||
warn!("Could not fetch channels from {}: {:?}", id, e);
|
||||
|
||||
Ok(json!([]))
|
||||
}
|
||||
}
|
||||
json_err!("Could not load reminders")
|
||||
})
|
||||
}
|
||||
|
||||
#[patch("/api/guild/<id>/reminders", data = "<reminder>")]
|
||||
@ -623,3 +604,35 @@ pub async fn delete_reminder(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/api/guild/<id>/errors")]
|
||||
pub async fn get_reminder_errors(
|
||||
id: u64,
|
||||
cookies: &CookieJar<'_>,
|
||||
serenity_context: &State<Context>,
|
||||
pool: &State<Pool<MySql>>,
|
||||
) -> JsonResult {
|
||||
check_authorization!(cookies, serenity_context.inner(), id);
|
||||
|
||||
sqlx::query_as_unchecked!(
|
||||
ReminderError,
|
||||
"SELECT
|
||||
reminders.status,
|
||||
reminders.utc_time,
|
||||
reminders.name,
|
||||
reminders.uid,
|
||||
reminders.channel_id AS channel
|
||||
FROM reminders
|
||||
LEFT JOIN channels ON channels.id = reminders.channel_id
|
||||
WHERE (`status` != 'pending' OR reminders.channel_id IS NULL) AND reminders.guild_id = (SELECT id FROM guilds WHERE guild = ?)",
|
||||
id
|
||||
)
|
||||
.fetch_all(pool.inner())
|
||||
.await
|
||||
.map(|r| Ok(json!(r)))
|
||||
.unwrap_or_else(|e| {
|
||||
warn!("Failed to complete SQL query: {:?}", e);
|
||||
|
||||
json_err!("Could not load reminders")
|
||||
})
|
||||
}
|
||||
|
@ -152,6 +152,18 @@ pub struct Reminder {
|
||||
utc_time: NaiveDateTime,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct ReminderError {
|
||||
#[serde(with = "string")]
|
||||
channel: u64,
|
||||
status: String,
|
||||
#[serde(default = "name_default")]
|
||||
name: String,
|
||||
#[serde(default)]
|
||||
uid: String,
|
||||
utc_time: NaiveDateTime,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct ReminderCsv {
|
||||
#[serde(with = "base64s")]
|
||||
@ -479,6 +491,7 @@ pub async fn create_reminder(
|
||||
attachment,
|
||||
attachment_name,
|
||||
channel_id,
|
||||
guild_id,
|
||||
avatar,
|
||||
content,
|
||||
embed_author,
|
||||
@ -501,11 +514,12 @@ pub async fn create_reminder(
|
||||
tts,
|
||||
username,
|
||||
`utc_time`
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
new_uid,
|
||||
attachment_data,
|
||||
reminder.attachment_name,
|
||||
channel,
|
||||
guild_id.0,
|
||||
reminder.avatar,
|
||||
reminder.content,
|
||||
reminder.embed_author,
|
||||
|
@ -5,7 +5,7 @@ const reminderErrors = () => {
|
||||
}
|
||||
|
||||
const guildId = () => {
|
||||
let selected: HTMLElement = document.querySelector(".guildList a.is-active");
|
||||
let selected = document.querySelector(".guildList a.is-active");
|
||||
return selected.dataset["guild"];
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user