#!/usr/bin/env -S node --env-file-if-exists=.env import {findEDBEntryID} from '../lib/api/lodestone.js'; import {getMediawikiClient} from '../lib/config.js'; import {diff} from '../lib/util/diff.js'; import { addParameterBesideExistingParameter, setEmptyParameter, } from '../lib/util/template-parameters.js'; /** * Inserts the `id-edb` item infobox parameter into the given page contents. * @param {string} pageContent * @param {string} edbID * @returns {string} */ function insertInfoboxEDBID (pageContent, edbID) { if (pageContent.includes(`id-edb = ${edbID}`)) { console.log('what????', pageContent); throw new Error('Page seems to already contain its own EDB ID??'); } let result = setEmptyParameter(pageContent, 'id-edb', edbID) ?? addParameterBesideExistingParameter(pageContent, 'id-edb', edbID, 'before', 'id-gt') ?? addParameterBesideExistingParameter(pageContent, 'id-edb', edbID, 'after', 'release') ?? addParameterBesideExistingParameter(pageContent, 'id-edb', edbID, 'after', 'patch'); if (result == null) { throw new Error('Dunno how to insert the parameter into this page'); } return result; } const mw = await getMediawikiClient(); const categoryTypes = { 'Category:Items with no EDB ID specified': 'item', 'Category:Minions with no EDB ID specified': 'item', 'Category:Triple Triad cards with no EDB ID specified': 'item', 'Category:Quests with no EDB ID specified': 'quest', }; const pages = (await Promise.all(Object.entries(categoryTypes).map(async ([category, type]) => { const pages = await mw.listCategoryPages(category, [0], +process.env.LIMIT || 500); return pages.map(({title}) => ({title, type})); }))).flat(); console.log('Processing', pages.length, 'items\n'); for (const {title, type} of pages) { // this runs serially with an artificial delay between requests to decrease // the chance of sqenix sending ninjas to my house await new Promise(resolve => setTimeout(resolve, 1000)); console.log('Page:', title); // look up on EDB const edbID = await findEDBEntryID(type, title); if (!edbID) { console.log(`No EDB ID found for this ${type}, skipping`); continue; } console.log('EDB ID:', edbID, `(https://na.finalfantasyxiv.com/lodestone/playguide/db/${encodeURIComponent(type)}/${encodeURIComponent(edbID)})`); let originalText; try { originalText = await mw.readPage(title); } catch (error) { console.log('Error reading page:', error); continue; } // rewrite wiki page to include id-edb infobox parameter let updatedText; try { updatedText = insertInfoboxEDBID(originalText, edbID); diff(originalText, updatedText); } catch (error) { console.log('Error inserting parameter:', error); console.group('Bad page content:'); console.log(originalText); console.groupEnd(); console.log(); continue; } // write the new stuff back to the wiki try { await mw.editPage(title, updatedText, `Add EDB ${type} ID`, true); } catch (error) { console.error(error); console.error('writes should not fail, this seems bad, dying now'); process.exit(1); } console.log('Written.'); console.log(); } console.log('done!');