Add killpage support

This commit is contained in:
ewin 2025-08-20 00:02:44 -06:00
parent 79a833133c
commit 37129d3833
Signed by: erin
SSH key fingerprint: SHA256:swjoHhREbZPbWe+gyJNi24d4NAxJSyUIm3fpZj4z3wc
3 changed files with 34 additions and 2 deletions

View file

@ -1,3 +1,4 @@
MW_SCRIPTPATH="https://ffxiv.consolegameswiki.com/mediawiki" MW_SCRIPTPATH="https://ffxiv.consolegameswiki.com/mediawiki"
MW_USERNAME="Wind-up Umbreon" MW_USERNAME="Wind-up Umbreon"
MW_PASSWORD="..." MW_PASSWORD="..."
MW_KILLPAGE="User talk:Wind-up Umbreon"

View file

@ -18,9 +18,15 @@ export class MediaWikiClient {
* @param {string} wikiURL Target wiki's MediaWiki path (i.e. the path that * @param {string} wikiURL Target wiki's MediaWiki path (i.e. the path that
* contains `index.php` and `api.php`) without a trailing slash. For example * contains `index.php` and `api.php`) without a trailing slash. For example
* for English Wikipedia this would be `'https://en.wikipedia.org/w'`. * for English Wikipedia this would be `'https://en.wikipedia.org/w'`.
* @param {object} options
* @param {string} [options.killPage] Name of a page that, if provided, will
* be read periodically. If the page ever contains text, the process will be
* killed. This is a safety measure allowing other editors to kill an
* unattended script if it misbehaves.
*/ */
constructor (wikiURL) { constructor (wikiURL, {killPage}) {
this.wikiURL = wikiURL; this.wikiURL = wikiURL;
this.killPage = killPage;
this.fetch = makeFetchCookie(fetch); this.fetch = makeFetchCookie(fetch);
} }
@ -122,6 +128,20 @@ export class MediaWikiClient {
if (body.login.result === 'Failed') { if (body.login.result === 'Failed') {
throw new Error(body.login.reason); throw new Error(body.login.reason);
} }
if (this.killPage) {
// start the kill page check loop as soon as we're logged in
const checkKillPage = async () => {
let content = await this.readPage(this.killPage);
if (content.trim()) {
console.error('*** Kill page is not empty; stopping ***\n');
console.error(content);
process.exit(1);
}
setTimeout(checkKillPage, 30 * 1000); // every 30 seconds
};
checkKillPage();
}
} }
/** /**

View file

@ -1,12 +1,23 @@
import {MediaWikiClient} from './api/mediawiki.js'; import {MediaWikiClient} from './api/mediawiki.js';
/**
* Creates a mediawiki client with config pulled from environment variables.
* @param {object} options
* @param {stromg} [options.unattended] If provided, the page specified by the
* `MW_KILLPAGE` environment variable will be checked periodically, and the
* script will be killed if the page contains text. This is a safety measure
* allowing other editors to kill an unattended script if it misbehaves.
* @returns {Promise<MediaWikiClient>}
*/
export async function getMediawikiClient () { export async function getMediawikiClient () {
if (!process.env.MW_USERNAME || !process.env.MW_PASSWORD) { if (!process.env.MW_USERNAME || !process.env.MW_PASSWORD) {
throw new Error('Environment variables `MW_USERNAME` and `MW_PASSWORD` are required.'); throw new Error('Environment variables `MW_USERNAME` and `MW_PASSWORD` are required.');
} }
// Log into our wiki client // Log into our wiki client
const mw = new MediaWikiClient('https://ffxiv.consolegameswiki.com/mediawiki'); const mw = new MediaWikiClient('https://ffxiv.consolegameswiki.com/mediawiki', {
killPage: process.env.MW_KILLPAGE || undefined,
});
await mw.login(process.env.MW_USERNAME, process.env.MW_PASSWORD); await mw.login(process.env.MW_USERNAME, process.env.MW_PASSWORD);
return mw; return mw;
} }