Compare commits
2 commits
dbbc99dab7
...
7a4385b9cd
Author | SHA1 | Date | |
---|---|---|---|
7a4385b9cd | |||
d876b1f3b4 |
3 changed files with 111 additions and 86 deletions
|
@ -1,7 +1,7 @@
|
||||||
import { Client, EmbedBuilder } from "npm:discord.js";
|
import { Client, EmbedBuilder } from "npm:discord.js";
|
||||||
|
|
||||||
import { fetch_feed_channel, format_devoir_title } from "./lib.ts";
|
import { fetch_feed_channel, format_devoir_title } from "./lib.ts";
|
||||||
import { Storage } from "./storage.ts";
|
import { Devoir, Feed, Storage } from "./storage.ts";
|
||||||
import { Channel, collect, log_from } from "./utils.ts";
|
import { Channel, collect, log_from } from "./utils.ts";
|
||||||
|
|
||||||
const log = log_from(import.meta);
|
const log = log_from(import.meta);
|
||||||
|
@ -9,19 +9,32 @@ const log = log_from(import.meta);
|
||||||
export async function update_loop(bot: Client, storage: Storage, update_display: Channel) {
|
export async function update_loop(bot: Client, storage: Storage, update_display: Channel) {
|
||||||
log("Waiting for updates.");
|
log("Waiting for updates.");
|
||||||
while (true) {
|
while (true) {
|
||||||
const _trigger = await update_display.receive();
|
await update_display.receive();
|
||||||
log("Updating board.");
|
log("Updating board.");
|
||||||
for await (const [_, feed] of storage.feeds.list()) {
|
const sorted_devoirs = await get_devoirs_sorted(storage);
|
||||||
const feed_channel = await fetch_feed_channel(bot, feed);
|
for await (const [_, feed] of storage.feeds.list()) await update_feed(bot, feed, sorted_devoirs);
|
||||||
const embed = new EmbedBuilder().setTitle("`📚` Devoirs")
|
|
||||||
.setFooter({ text: "Mise à jour " + Date.now() });
|
|
||||||
const sorted_devoirs = (await (collect(storage.devoirs.list())))
|
|
||||||
.map(([_, d]) => d).toSorted((a, b) => a.date > b.date ? 1 : -1);
|
|
||||||
for (const devoir of sorted_devoirs) {
|
|
||||||
embed.addFields({ name: format_devoir_title(devoir), value: devoir.description });
|
|
||||||
}
|
|
||||||
const board_message = await feed_channel.messages.fetch(feed.board_message_id);
|
|
||||||
board_message.edit({ embeds: [embed], content: "" });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function get_devoirs_sorted(storage: Storage) {
|
||||||
|
const devoirs = await collect(storage.devoirs.list());
|
||||||
|
const sorted_devoirs = devoirs
|
||||||
|
.map(([_, d]) => d)
|
||||||
|
.toSorted((a, b) => a.date > b.date ? 1 : -1);
|
||||||
|
return sorted_devoirs;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function update_feed(bot: Client<boolean>, feed: Feed, sorted_devoirs: Devoir[]) {
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle("`📚` Devoirs")
|
||||||
|
.setFooter({ text: "Mise à jour " + Date.now() });
|
||||||
|
for (const devoir of sorted_devoirs) {
|
||||||
|
embed.addFields({
|
||||||
|
name: format_devoir_title(devoir),
|
||||||
|
value: devoir.description,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const feed_channel = await fetch_feed_channel(bot, feed);
|
||||||
|
const board_message = await feed_channel.messages.fetch(feed.board_message_id);
|
||||||
|
board_message.edit({ embeds: [embed], content: "" });
|
||||||
|
}
|
||||||
|
|
|
@ -8,7 +8,15 @@ import { Storage } from "./storage.ts";
|
||||||
|
|
||||||
export async function notification_loop(bot: Client, storage: Storage) {
|
export async function notification_loop(bot: Client, storage: Storage) {
|
||||||
while (true) {
|
while (true) {
|
||||||
// get all devoirs to notify
|
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<string>();
|
const devoirs_to_notify = new Set<string>();
|
||||||
const notification_threshold = 7 * _1d;
|
const notification_threshold = 7 * _1d;
|
||||||
for await (const [devoir_id, devoir] of storage.devoirs.list()) {
|
for await (const [devoir_id, devoir] of storage.devoirs.list()) {
|
||||||
|
@ -17,22 +25,25 @@ export async function notification_loop(bot: Client, storage: Storage) {
|
||||||
if (time_left > notification_threshold) continue;
|
if (time_left > notification_threshold) continue;
|
||||||
devoirs_to_notify.add(devoir_id.id);
|
devoirs_to_notify.add(devoir_id.id);
|
||||||
}
|
}
|
||||||
|
return devoirs_to_notify;
|
||||||
|
}
|
||||||
|
|
||||||
// delete all obsolete notifications
|
async function delete_obsolete_notifications(devoirs_to_notify: Set<string>, storage: Storage, bot: Client<boolean>) {
|
||||||
for await (const [notification_id, notification] of storage.notifications.list()) {
|
for await (const [notif_id, notif] of storage.notifications.list()) {
|
||||||
if (devoirs_to_notify.has(notification.devoir_id)) continue;
|
if (devoirs_to_notify.has(notif.devoir_id)) continue;
|
||||||
const feed = await storage.feeds.get({ id: notification.feed_id });
|
const feed = await storage.feeds.get({ id: notif.feed_id });
|
||||||
if (feed === null) continue;
|
if (feed === null) continue;
|
||||||
const feed_channel = await fetch_feed_channel(bot, feed);
|
const feed_channel = await fetch_feed_channel(bot, feed);
|
||||||
try {
|
try {
|
||||||
const message = await feed_channel.messages.fetch(notification.message_id);
|
const message = await feed_channel.messages.fetch(notif.message_id);
|
||||||
await message.delete();
|
await message.delete();
|
||||||
} catch (_) { /* . */ }
|
} catch (_) { /* oki */ }
|
||||||
await storage.notifications.delete(notification_id);
|
await storage.notifications.delete(notif_id);
|
||||||
await storage.feeds.update({ id: notification.feed_id }, (f) => f.notification_ids.delete(notification_id.id));
|
await storage.feeds.update({ id: notif.feed_id }, (f) => f.notification_ids.delete(notif_id.id));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// create missing messages.
|
async function create_missing_messages(storage: Storage, bot: Client<boolean>, devoirs_to_notify: Set<string>) {
|
||||||
for await (const [feed_id, feed] of storage.feeds.list()) {
|
for await (const [feed_id, feed] of storage.feeds.list()) {
|
||||||
const feed_channel = await fetch_feed_channel(bot, feed);
|
const feed_channel = await fetch_feed_channel(bot, feed);
|
||||||
// find devoirs needing to create a notification for
|
// find devoirs needing to create a notification for
|
||||||
|
@ -58,8 +69,9 @@ export async function notification_loop(bot: Client, storage: Storage) {
|
||||||
storage.feeds.update(feed_id, (f) => f.notification_ids.add(notification_id.id));
|
storage.feeds.update(feed_id, (f) => f.notification_ids.add(notification_id.id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// for each notification, update.
|
async function update_existing_notifications(storage: Storage, bot: Client<boolean>) {
|
||||||
for await (const [_, notification] of storage.notifications.list()) {
|
for await (const [_, notification] of storage.notifications.list()) {
|
||||||
const devoir = await storage.devoirs.get({ id: notification.devoir_id });
|
const devoir = await storage.devoirs.get({ id: notification.devoir_id });
|
||||||
if (devoir === null) continue;
|
if (devoir === null) continue;
|
||||||
|
@ -78,7 +90,4 @@ export async function notification_loop(bot: Client, storage: Storage) {
|
||||||
if (days_left <= 1) embed.setColor(0xff2626);
|
if (days_left <= 1) embed.setColor(0xff2626);
|
||||||
await message.edit({ embeds: [embed], content: "" });
|
await message.edit({ embeds: [embed], content: "" });
|
||||||
}
|
}
|
||||||
|
|
||||||
await wait(15 * _1min);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,7 @@ export class Storage {
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Devoir = z.infer<Storage["devoirs"]["parser"]>;
|
export type Devoir = z.infer<Storage["devoirs"]["parser"]>;
|
||||||
|
export type Feed = z.infer<Storage["feeds"]["parser"]>;
|
||||||
|
|
||||||
class Manager<T> {
|
class Manager<T> {
|
||||||
db;
|
db;
|
||||||
|
@ -105,7 +106,7 @@ class Manager<T> {
|
||||||
assert(typeof id === "string");
|
assert(typeof id === "string");
|
||||||
const value = this.parse(entry.value);
|
const value = this.parse(entry.value);
|
||||||
if (value === null) continue;
|
if (value === null) continue;
|
||||||
yield [{ id } as Id<T>, value as T] as const;
|
yield [{ id }, value] as Entry<T>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,3 +114,5 @@ class Manager<T> {
|
||||||
for await (const _ of this.list()) _;
|
for await (const _ of this.list()) _;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Entry<T> = [id: Id<T>, value: T];
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue