From 7a4385b9cd946bad782dfddd5de8caa44ce456aa Mon Sep 17 00:00:00 2001 From: JOLIMAITRE Matthieu Date: Wed, 1 May 2024 18:00:22 +0200 Subject: [PATCH] refactor split notification update --- src/lib/notification.ts | 151 +++++++++++++++++++++------------------- src/lib/storage.ts | 4 +- 2 files changed, 83 insertions(+), 72 deletions(-) diff --git a/src/lib/notification.ts b/src/lib/notification.ts index e8d1b9d..66b32bd 100644 --- a/src/lib/notification.ts +++ b/src/lib/notification.ts @@ -8,77 +8,86 @@ import { Storage } from "./storage.ts"; export async function notification_loop(bot: Client, storage: Storage) { while (true) { - // get all devoirs to notify - const devoirs_to_notify = new Set(); - const notification_threshold = 7 * _1d; - for await (const [devoir_id, devoir] of storage.devoirs.list()) { - const time_left = devoir.date - Date.now(); - if (time_left < 0) continue; // TODO : delete devoir. - if (time_left > notification_threshold) continue; - devoirs_to_notify.add(devoir_id.id); - } - - // delete all obsolete notifications - for await (const [notification_id, notification] of storage.notifications.list()) { - if (devoirs_to_notify.has(notification.devoir_id)) continue; - const feed = await storage.feeds.get({ id: notification.feed_id }); - if (feed === null) continue; - const feed_channel = await fetch_feed_channel(bot, feed); - try { - const message = await feed_channel.messages.fetch(notification.message_id); - await message.delete(); - } catch (_) { /* . */ } - await storage.notifications.delete(notification_id); - await storage.feeds.update({ id: notification.feed_id }, (f) => f.notification_ids.delete(notification_id.id)); - } - - // create missing messages. - for await (const [feed_id, feed] of storage.feeds.list()) { - const feed_channel = await fetch_feed_channel(bot, feed); - // find devoirs needing to create a notification for - const devoirs_to_notify_in_feed = new Set(devoirs_to_notify.values()); - for (const existing_notification_id of feed.notification_ids.values()) { - const notification = await storage.notifications.get({ id: existing_notification_id }); - assertExists(notification); - devoirs_to_notify_in_feed.delete(notification.devoir_id); - } - // create notifications - for (const devoir_id of devoirs_to_notify_in_feed.values()) { - const devoir = await storage.devoirs.get({ id: devoir_id }); - if (devoir === null) continue; - const embed = new EmbedBuilder() - .setTitle(format_devoir_title(devoir)) - .setDescription(devoir.description); - const message = await feed_channel.send({ embeds: [embed] }); - const notification_id = await storage.notifications.add({ - devoir_id: devoir_id, - message_id: message.id, - feed_id: feed_id.id, - }); - storage.feeds.update(feed_id, (f) => f.notification_ids.add(notification_id.id)); - } - } - - // for each notification, update. - for await (const [_, notification] of storage.notifications.list()) { - const devoir = await storage.devoirs.get({ id: notification.devoir_id }); - if (devoir === null) continue; - const feed = await storage.feeds.get({ id: notification.feed_id }); - if (feed === null) continue; - const feed_channel = await fetch_feed_channel(bot, feed); - const message = await feed_channel.messages.fetch(notification.message_id); - const ms_left = devoir.date - Date.now(); - const days_left = Math.floor(ms_left / _1d); - const embed = new EmbedBuilder() - .setTitle(format_devoir_title(devoir) + ` (${days_left} jours)`) - .setDescription(devoir.description) - .setColor(0x8888ff); - if (days_left <= 5) embed.setColor(0xffd726); - if (days_left <= 3) embed.setColor(0xff8b26); - if (days_left <= 1) embed.setColor(0xff2626); - await message.edit({ embeds: [embed], content: "" }); - } - + const devoirs_to_notify = await get_devoirs_to_notify(storage); + await delete_obsolete_notifications(devoirs_to_notify, storage, bot); + await create_missing_messages(storage, bot, devoirs_to_notify); + await update_existing_notifications(storage, bot); await wait(15 * _1min); } } + +async function get_devoirs_to_notify(storage: Storage) { + const devoirs_to_notify = new Set(); + const notification_threshold = 7 * _1d; + for await (const [devoir_id, devoir] of storage.devoirs.list()) { + const time_left = devoir.date - Date.now(); + if (time_left < 0) continue; // TODO : delete devoir. + if (time_left > notification_threshold) continue; + devoirs_to_notify.add(devoir_id.id); + } + return devoirs_to_notify; +} + +async function delete_obsolete_notifications(devoirs_to_notify: Set, storage: Storage, bot: Client) { + for await (const [notif_id, notif] of storage.notifications.list()) { + if (devoirs_to_notify.has(notif.devoir_id)) continue; + const feed = await storage.feeds.get({ id: notif.feed_id }); + if (feed === null) continue; + const feed_channel = await fetch_feed_channel(bot, feed); + try { + const message = await feed_channel.messages.fetch(notif.message_id); + await message.delete(); + } catch (_) { /* oki */ } + await storage.notifications.delete(notif_id); + await storage.feeds.update({ id: notif.feed_id }, (f) => f.notification_ids.delete(notif_id.id)); + } +} + +async function create_missing_messages(storage: Storage, bot: Client, devoirs_to_notify: Set) { + for await (const [feed_id, feed] of storage.feeds.list()) { + const feed_channel = await fetch_feed_channel(bot, feed); + // find devoirs needing to create a notification for + const devoirs_to_notify_in_feed = new Set(devoirs_to_notify.values()); + for (const existing_notification_id of feed.notification_ids.values()) { + const notification = await storage.notifications.get({ id: existing_notification_id }); + assertExists(notification); + devoirs_to_notify_in_feed.delete(notification.devoir_id); + } + // create notifications + for (const devoir_id of devoirs_to_notify_in_feed.values()) { + const devoir = await storage.devoirs.get({ id: devoir_id }); + if (devoir === null) continue; + const embed = new EmbedBuilder() + .setTitle(format_devoir_title(devoir)) + .setDescription(devoir.description); + const message = await feed_channel.send({ embeds: [embed] }); + const notification_id = await storage.notifications.add({ + devoir_id: devoir_id, + message_id: message.id, + feed_id: feed_id.id, + }); + storage.feeds.update(feed_id, (f) => f.notification_ids.add(notification_id.id)); + } + } +} + +async function update_existing_notifications(storage: Storage, bot: Client) { + for await (const [_, notification] of storage.notifications.list()) { + const devoir = await storage.devoirs.get({ id: notification.devoir_id }); + if (devoir === null) continue; + const feed = await storage.feeds.get({ id: notification.feed_id }); + if (feed === null) continue; + const feed_channel = await fetch_feed_channel(bot, feed); + const message = await feed_channel.messages.fetch(notification.message_id); + const ms_left = devoir.date - Date.now(); + const days_left = Math.floor(ms_left / _1d); + const embed = new EmbedBuilder() + .setTitle(format_devoir_title(devoir) + ` (${days_left} jours)`) + .setDescription(devoir.description) + .setColor(0x8888ff); + if (days_left <= 5) embed.setColor(0xffd726); + if (days_left <= 3) embed.setColor(0xff8b26); + if (days_left <= 1) embed.setColor(0xff2626); + await message.edit({ embeds: [embed], content: "" }); + } +} diff --git a/src/lib/storage.ts b/src/lib/storage.ts index 06e5f31..caa7f7c 100644 --- a/src/lib/storage.ts +++ b/src/lib/storage.ts @@ -106,7 +106,7 @@ class Manager { assert(typeof id === "string"); const value = this.parse(entry.value); if (value === null) continue; - yield [{ id } as Id, value as T] as const; + yield [{ id }, value] as Entry; } } @@ -114,3 +114,5 @@ class Manager { for await (const _ of this.list()) _; } } + +type Entry = [id: Id, value: T];