From 26b02b5ad702c834f2a577ad0e3cf77a9d9d42f0 Mon Sep 17 00:00:00 2001 From: reivilibre Date: Fri, 2 Feb 2024 08:40:17 +0000 Subject: [PATCH] Add `schedule debug` command (#223) * ScheduleCommand: extract printUpcomingTasks * ScheduleCommand: add `debug` subcommand that also shows completed task IDs * Document status, refresh, schedule view, schedule debug, schedule reset commands in help command * Add more info to reset command --------- Co-authored-by: Will Hunt --- src/Scheduler.ts | 8 ++++ src/commands/HelpCommand.ts | 4 ++ src/commands/ScheduleCommand.ts | 66 +++++++++++++++++++++++---------- 3 files changed, 59 insertions(+), 19 deletions(-) diff --git a/src/Scheduler.ts b/src/Scheduler.ts index eca3122..4f82c01 100644 --- a/src/Scheduler.ts +++ b/src/Scheduler.ts @@ -185,6 +185,14 @@ export class Scheduler { return Object.values(this.pending); } + /** + * Return a list of completed task IDs. + */ + public inspectCompleted(): string[] { + // slice() is just to clone the array to prevent mutations + return this.completedIds.slice(); + } + private async persistProgress() { const completedIds = this.completedIds.slice().reverse().slice(0, KEEP_LAST_TASKS).reverse(); await this.client.setAccountData(ACD_SCHEDULER, { diff --git a/src/commands/HelpCommand.ts b/src/commands/HelpCommand.ts index ac93f29..703d82b 100644 --- a/src/commands/HelpCommand.ts +++ b/src/commands/HelpCommand.ts @@ -42,6 +42,10 @@ export class HelpCommand implements ICommand { "!conference run <aud> - Runs the schedule in the given auditorium. If 'all' is used,\n" + " then all auditoriums will be run.\n" + "!conference stop - Halts all scheduling, resetting the bot back to no watched auditoriums.\n" + + "!conference status|refresh - Refreshes the schedule source and then displays the status of the conference. MAY NOT REFRESH THE SCHEDULER, BEWARE.\n" + + "!conference schedule view - Shows upcoming scheduler tasks.\n" + + "!conference schedule debug - Shows upcoming scheduler tasks as well as a list of stored completed task IDs.\n" + + "!conference schedule reset - Resets the scheduler which will clear all completed tasks. Some tasks may run again.\n" + "" + "

People management:

" + "
" +
diff --git a/src/commands/ScheduleCommand.ts b/src/commands/ScheduleCommand.ts
index d9c126f..e88522f 100644
--- a/src/commands/ScheduleCommand.ts
+++ b/src/commands/ScheduleCommand.ts
@@ -30,25 +30,10 @@ export class ScheduleCommand implements ICommand {
             await this.scheduler.reset();
             await this.client.sendNotice(roomId, "Schedule processing has been reset.");
         } else if (args[0] === 'view') {
-            const upcoming = sortTasks(this.scheduler.inspect());
-            let html = "Upcoming tasks:
    "; - for (const task of upcoming) { - const hasTalkRoom = this.conference.getTalk(task.talk.id) !== undefined; - const taskStart = moment(getStartTime(task)); - const formattedTimestamp = taskStart.format("YYYY-MM-DD HH:mm:ss [UTC]ZZ"); - - if (html.length > 20000) { - // chunk up the message so we don't fail to send one very large event. - html += "
"; - await this.client.sendHtmlNotice(roomId, html); - html = "…
    "; - } - - const hasRoomIndicator = hasTalkRoom ? 'has talk room' : 'no talk room'; - html += `
  • ${formattedTimestamp}: ${task.type} on ${task.talk.title} (${task.id}, ${hasRoomIndicator}) ${taskStart.fromNow()}
  • `; - } - html += "
"; - await this.client.sendHtmlNotice(roomId, html); + await this.printUpcomingTasks(roomId); + } else if (args[0] === 'debug') { + await this.printUpcomingTasks(roomId); + await this.printCompletedTasks(roomId); } else if (args[0] === 'execute') { await this.scheduler.execute(args[1]); await this.client.unstableApis.addReactionToEvent(roomId, event['event_id'], '✅'); @@ -56,4 +41,47 @@ export class ScheduleCommand implements ICommand { await this.client.sendNotice(roomId, "Unknown schedule command."); } } + + private async printUpcomingTasks(roomId: string) { + const upcoming = sortTasks(this.scheduler.inspect()); + let html = "Upcoming tasks:
    "; + for (const task of upcoming) { + const hasTalkRoom = this.conference.getTalk(task.talk.id) !== undefined; + const taskStart = moment(getStartTime(task)); + const formattedTimestamp = taskStart.format("YYYY-MM-DD HH:mm:ss [UTC]ZZ"); + + if (html.length > 20000) { + // chunk up the message so we don't fail to send one very large event. + html += "
"; + await this.client.sendHtmlNotice(roomId, html); + html = "…
    "; + } + + const hasRoomIndicator = hasTalkRoom ? 'has talk room' : 'no talk room'; + html += `
  • ${formattedTimestamp}: ${task.type} on ${task.talk.title} (${task.id}, ${hasRoomIndicator}) ${taskStart.fromNow()}
  • `; + } + html += "
"; + await this.client.sendHtmlNotice(roomId, html); + } + + private async printCompletedTasks(roomId: string) { + const completed = this.scheduler.inspectCompleted(); + let html = "Completed tasks:
    "; + completed.sort(); + + for (const taskId of completed) { + if (html.length > 20000) { + // chunk up the message so we don't fail to send one very large event. + html += "
"; + await this.client.sendHtmlNotice(roomId, html); + html = "…
    "; + } + + html += `
  • ${taskId}
  • `; + } + + html += "
"; + + await this.client.sendHtmlNotice(roomId, html); + } }