Add one-off script for patch 7.3 stellar mission name changes
This commit is contained in:
parent
8e89e05756
commit
7b5357c050
2 changed files with 170 additions and 0 deletions
136
bin/7-3-stellar-mission-renames
Executable file
136
bin/7-3-stellar-mission-renames
Executable file
|
|
@ -0,0 +1,136 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
// Renames A-class Stellar Missions to replace A-1, A-2, A-3 difficulty
|
||||||
|
// indicators with the new empty/EX/EX+ naming used in patch 7.3.
|
||||||
|
// https://na.finalfantasyxiv.com/lodestone/topics/detail/907c6d2aa020c0e4458ed1477668521fb4a117ec#:~:text=The%20notation,adjusted%2E
|
||||||
|
|
||||||
|
import {getMediawikiClient} from '../lib/config.js';
|
||||||
|
import {diff} from '../lib/util/diff.js';
|
||||||
|
import {readExistingParameter, setExistingParameter} from '../lib/util/template-parameters.js';
|
||||||
|
|
||||||
|
const mw = await getMediawikiClient();
|
||||||
|
const missions = await mw.listCategoryPages('Category:Stellar Missions', [0], 1000);
|
||||||
|
|
||||||
|
const updateMissionTitle = title => title
|
||||||
|
// "A-1: Aetherochemical Samples I" -> "Aetherochemical Samples I"
|
||||||
|
.replace(/^A-1: /, '')
|
||||||
|
// "A-2: Aetherochemical Samples II" -> "EX: Aetherochemical Samples II"
|
||||||
|
.replace(/^A-2/, 'EX')
|
||||||
|
// "A-3: Aetherochemical Samples III" -> "EX+: Aetherochemical Samples III"
|
||||||
|
.replace(/^A-3/, 'EX+');
|
||||||
|
|
||||||
|
// Move all the mission pages we need to move
|
||||||
|
console.log('Moving pages');
|
||||||
|
await Promise.allSettled(missions.map(async ({title}) => {
|
||||||
|
// Rename this mission page if necessary
|
||||||
|
let newTitle = updateMissionTitle(title);
|
||||||
|
if (title === newTitle) return; // not an A-class mission, nothing to change
|
||||||
|
|
||||||
|
try {
|
||||||
|
await mw.movePage(title, newTitle, {
|
||||||
|
reason: 'A-rank stellar mission difficulties were renamed in patch 7.3',
|
||||||
|
redirect: true,
|
||||||
|
moveTalk: true,
|
||||||
|
moveSubpages: true,
|
||||||
|
});
|
||||||
|
console.log(title, '->', newTitle);
|
||||||
|
} catch (error) {
|
||||||
|
if (error.message.includes('[articleexists]')) {
|
||||||
|
try {
|
||||||
|
await mw.movePage(title, newTitle + ' (Stellar Mission)', {
|
||||||
|
reason: 'A-rank stellar mission difficulties were renamed in patch 7.3',
|
||||||
|
redirect: true,
|
||||||
|
moveTalk: true,
|
||||||
|
moveSubpages: true,
|
||||||
|
});
|
||||||
|
} catch (err2) {
|
||||||
|
console.error('Failed to move', title, 'to', newTitle + '(Stellar Mission)', ':', err2);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error('Failed to move', title, 'to', newTitle, ':', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
console.log('Done renaming');
|
||||||
|
|
||||||
|
// Fetch the category listing again now that a bunch of titles have changed
|
||||||
|
const movedMissions = await mw.listCategoryPages('Category:Stellar Missions', [0], 1000);
|
||||||
|
|
||||||
|
// Fix `previous`/`next` infobox parameters for sequential missions and use
|
||||||
|
// `rank = A` consistently for all A-class missions
|
||||||
|
for (const {title} of movedMissions) {
|
||||||
|
let pageContent = await mw.readPage(title);
|
||||||
|
const originalPageContent = pageContent;
|
||||||
|
|
||||||
|
for (const parameter of ['previous', 'next']) {
|
||||||
|
const oldValue = readExistingParameter(pageContent, parameter);
|
||||||
|
const newValue = updateMissionTitle(oldValue);
|
||||||
|
|
||||||
|
if (oldValue === newValue) continue; // mission title didn't change
|
||||||
|
|
||||||
|
// Update the value on the page
|
||||||
|
let updatedPageContent = setExistingParameter(pageContent, parameter, newValue);
|
||||||
|
if (updatedPageContent == null) {
|
||||||
|
// something very weird has happened, this shouldn't be able to fail
|
||||||
|
// if we already got the value of the parameter earlier
|
||||||
|
console.error('weird shit happened with', title);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
pageContent = updatedPageContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (readExistingParameter(pageContent, 'rank').match(/A-[123]/)) {
|
||||||
|
pageContent = setExistingParameter(pageContent, 'rank', 'A');
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Diff for', title);
|
||||||
|
diff(originalPageContent, pageContent);
|
||||||
|
try {
|
||||||
|
if (originalPageContent === pageContent) {
|
||||||
|
console.log('No changes');
|
||||||
|
} else {
|
||||||
|
await mw.editPage(title, pageContent, 'Update links to mission(s) renamed in 7.3');
|
||||||
|
console.log('Written.');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error writing page:', error);
|
||||||
|
console.error('writes should not fail, this seems bad, dying now');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Also update mission names for all CE item recipes
|
||||||
|
const items = await mw.listCategoryPages('Category:Cosmic Exploration Items', [0], 10000);
|
||||||
|
for (const {title} of items) {
|
||||||
|
let pageContent = await mw.readPage(title);
|
||||||
|
const originalPageContent = pageContent;
|
||||||
|
|
||||||
|
const infoboxes = pageContent.split('{{Recipe');
|
||||||
|
infoboxes.forEach((infobox, i) => {
|
||||||
|
if (i === 0) return; // ignore stuff before first recipe infobox
|
||||||
|
// console.log(infobox);
|
||||||
|
|
||||||
|
const mission = readExistingParameter(infobox, 'mission');
|
||||||
|
const updatedMission = updateMissionTitle(mission);
|
||||||
|
infoboxes[i] = setExistingParameter(infobox, 'mission', updatedMission);
|
||||||
|
});
|
||||||
|
pageContent = infoboxes.join('{{Recipe');
|
||||||
|
|
||||||
|
console.log('Diff for', title);
|
||||||
|
diff(originalPageContent, pageContent);
|
||||||
|
try {
|
||||||
|
if (originalPageContent === pageContent) {
|
||||||
|
console.log('No changes');
|
||||||
|
} else {
|
||||||
|
await mw.editPage(title, pageContent, 'Update links to mission(s) renamed in 7.3');
|
||||||
|
console.log('Written.');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error writing page:', error);
|
||||||
|
console.error('writes should not fail, this seems bad, dying now');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Done with content updates');
|
||||||
|
|
@ -162,6 +162,40 @@ export class MediaWikiClient {
|
||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {string} from The page's current name
|
||||||
|
* @param {string} to The page's new name
|
||||||
|
* @param {object} options
|
||||||
|
* @param {string} options.reason Move reason
|
||||||
|
* @param {boolean} options.redirect Whether to create a redirect from the
|
||||||
|
* old name to the new name
|
||||||
|
* @param {boolean} options.moveTalk Whether to move the page's talk page
|
||||||
|
* from the old name to the new name
|
||||||
|
* @param {boolean} options.moveSubpages Whether to move the page's subpages
|
||||||
|
* from the old name to the new name
|
||||||
|
* @returns {Promise<any>}
|
||||||
|
*/
|
||||||
|
async movePage (from, to, {
|
||||||
|
reason,
|
||||||
|
redirect = true,
|
||||||
|
moveTalk = true,
|
||||||
|
moveSubpages = true,
|
||||||
|
} = {}) {
|
||||||
|
const csrfToken = await this.getCSRFToken();
|
||||||
|
return this.fetchApiPost({
|
||||||
|
action: 'move',
|
||||||
|
from,
|
||||||
|
to,
|
||||||
|
reason,
|
||||||
|
movetalk: moveTalk,
|
||||||
|
movesubpages: moveSubpages,
|
||||||
|
noredirect: !redirect,
|
||||||
|
token: csrfToken,
|
||||||
|
format: 'json',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the list of wiki pages that belong to the given category.
|
* Gets the list of wiki pages that belong to the given category.
|
||||||
* @param {string} name Category name including the `Category:` namespace.
|
* @param {string} name Category name including the `Category:` namespace.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue