From b88a97860689e63231b00344b9b1d91be7b4b6d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20W=C3=B6lfer?= Date: Wed, 7 May 2025 01:43:37 +0200 Subject: [PATCH] Added watchdog mode --- main.ts | 63 +++++++++++++++++++++++++++++++++++++++++++++++--------- run.sh | 2 +- write.ts | 12 +++++++---- 3 files changed, 62 insertions(+), 15 deletions(-) diff --git a/main.ts b/main.ts index 5c19c8c..4fc87e6 100644 --- a/main.ts +++ b/main.ts @@ -1,5 +1,5 @@ -import { Mwn } from 'npm:mwn' -import process from "node:process"; +import { Mwn, RecentChange } from 'npm:mwn' +import process, { title } from "node:process"; import { parseSummary } from "./parse.ts"; import { bucketEvents, writeSection } from "./write.ts"; @@ -38,24 +38,67 @@ async function fetchPages(pages: string[], bot: Mwn): Promise v.status === "fulfilled").map(v => v.value) } +function sleep(ms: number): Promise { + return new Promise(resolve => setTimeout(resolve, ms)); +} + +async function watchdog(bot: Mwn, onChange: (paths: string[]) => Promise) { + let last_change: string | undefined = undefined; + + + while (true) { + const { last_change: l, new_file_changes } = await queryChanges(bot, last_change); + last_change = l + if (new_file_changes.length > 0) { + console.log(new_file_changes.length, "changes") + await onChange(new_file_changes.map(v => v.title)) + } + console.log(new Date(), "Heartbeat") + await sleep(30000); + } +} + +async function queryChanges(bot: Mwn, last_change: string | undefined): Promise<{ last_change: string | undefined; new_file_changes: RecentChange[]; }> { + const d = await bot.request({ + action: "query", + list: "recentchanges", + format: "json", + formatversion: 2, + rcprop: "title|timestamp|ids|user", + rctoponly: 1, + rcdir: 'older', + rcend: last_change || "2000-01-01T12:00:00Z", + }); + + const changes: RecentChange[] = d.query?.recentchanges; + + const new_file_changes = changes + .filter(v => v.title.startsWith("File:WCS ")) + .filter(v => last_change === undefined || new Date(v.timestamp) > new Date(last_change)); + + return { last_change: changes[0].timestamp, new_file_changes }; +} async function main() { const bot = new Mwn({ - apiUrl: 'https://dancing.thasky.one/api.php', + apiUrl: process.env.URL || 'https://dancing.thasky.one/api.php', username: process.env.BOTNAME, password: process.env.BOTPW, userAgent: 'mwn bot', }); + const title = 'Video Descriptions (Automated)' + try { await bot.login(); - // const relevantFiles = await getWorkshopVideos(bot) - // const d = await fetchPages(relevantFiles, bot) - // await Deno.writeTextFile("./descriptions.json", JSON.stringify(d)); - const d = JSON.parse(await Deno.readTextFile('./descriptions.json')); - const t = writeSection(bucketEvents(d)) - const response = await bot.save('Video Description (Automated)', "{{TOC|limit=3}}\n\n" + t, 'Generated descriptions'); - console.log(response) + await watchdog(bot, async (paths) => { + const relevantFiles = await getWorkshopVideos(bot) + const d = await fetchPages(relevantFiles, bot) + const t = writeSection(bucketEvents(d)) + const response = await bot.save(title, "{{TOC|limit=3}}\n\n" + t, 'Triggered by changes to ' + paths.map(v => "[[" + v + "]]").join(", ")); + console.log(response) + }) + } catch (error) { console.error('Error:', error); diff --git a/run.sh b/run.sh index ce7967b..04f2543 100644 --- a/run.sh +++ b/run.sh @@ -1 +1 @@ -deno run --env-file=.env --allow-read=./descriptions.json --allow-net=dancing.thasky.one:443 -E main.ts +deno run --env-file=.env --allow-read=./descriptions.json --allow-net=dancing.thasky.one:443 -E main.ts diff --git a/write.ts b/write.ts index 82f3741..33ec996 100644 --- a/write.ts +++ b/write.ts @@ -10,11 +10,15 @@ Level: ${video.level} [[${video.path}|left|400px|thumb|${video.title}]] +
==== Shown Patterns ==== ${video.patterns} ==== Notes ==== -${video.notes}`; +${video.notes} +
+ +
`; } export function writeSection(events: VideoDescription[][]): string { @@ -26,7 +30,7 @@ export function writeSection(events: VideoDescription[][]): string { const event_date = event_name.match(/\d{2}|20\d{2}/) ? "" : new Date(token.date).getFullYear().toString() let r = `== ${event_name} ${event_date} ==\n` - r += `${v.length} Videos\n` + r += `${v.length} Video${v.length <= 1 ? "" : "s"}\n` r += v.map(video => singleVideoDescription(video)).join("\n\n") return r }).join("\n\n\n") @@ -46,7 +50,7 @@ export function bucketEvents(events: VideoDescription[]): VideoDescription[][] { Object.values(buckets) .forEach(b => b.sort((a, b) => - new Date(b.date).getTime() - new Date(a.date).getTime())) + new Date(a.date).getTime() - new Date(b.date).getTime())) - return Object.values(buckets) + return Object.values(buckets).sort((a, b) => new Date(a[0].date).getTime() - new Date(b[0].date).getTime()) } \ No newline at end of file