diff --git a/bin/add-edb-ids b/bin/add-edb-ids
index 7ed04e7..f48a2ff 100755
--- a/bin/add-edb-ids
+++ b/bin/add-edb-ids
@@ -1,6 +1,6 @@
#!/usr/bin/env node
-import {findItemEDBID} from '../lib/api/lodestone.js';
+import {findEDBEntryID} from '../lib/api/lodestone.js';
import {getMediawikiClient} from '../lib/config.js';
import {diff} from '../lib/util/diff.js';
import {
@@ -34,22 +34,29 @@ function insertInfoboxEDBID (pageContent, edbID) {
const mw = await getMediawikiClient();
// Get pages in the "Missing EDB ID" category from the main article namespace
-const itemPagesWithoutEDBIDs = await mw.listCategoryPages('Category:Missing EDB ID', [0], +process.env.LIMIT || 500);
+const [itemPagesWithoutEDBIDs, questPagesWithoutEDBIDs] = await Promise.all([
+ mw.listCategoryPages('Category:Missing EDB ID', [0], +process.env.LIMIT || 500),
+ mw.listCategoryPages('Category:Missing quest EDB ID', [0], +process.env.LIMIT || 500),
+]);
console.log('Processing', itemPagesWithoutEDBIDs.length, 'item pages from [[Category:Missing EDB ID]]\n');
+console.log('Processing', questPagesWithoutEDBIDs.length, 'item pages from [[Category:Missing quest EDB ID]]\n');
-for (const {title} of itemPagesWithoutEDBIDs) {
+for (const {title, type} of [
+ ...itemPagesWithoutEDBIDs.map(({title}) => ({title, type: 'item'})),
+ ...questPagesWithoutEDBIDs.map(({title}) => ({title, type: 'quest'})),
+]) {
// 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 findItemEDBID(title);
+ const edbID = await findEDBEntryID(type, title);
if (!edbID) {
- console.log('No EDB ID found for this item, skipping');
+ console.log(`No EDB ID found for this ${type}, skipping`);
continue;
}
- console.log('EDB ID:', edbID, `(https://na.finalfantasyxiv.com/lodestone/playguide/db/item/${encodeURIComponent(edbID)})`);
+ console.log('EDB ID:', edbID, `(https://na.finalfantasyxiv.com/lodestone/playguide/db/${encodeURIComponent(type)}/${encodeURIComponent(edbID)})`);
let originalText;
try {
@@ -75,7 +82,7 @@ for (const {title} of itemPagesWithoutEDBIDs) {
// write the new stuff back to the wiki
try {
- await mw.editPage(title, updatedText, "Add EDB item ID", true);
+ 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');
diff --git a/lib/api/lodestone.js b/lib/api/lodestone.js
index fcd2738..9e970f2 100644
--- a/lib/api/lodestone.js
+++ b/lib/api/lodestone.js
@@ -3,25 +3,28 @@
import {regExpEscape} from '../util/regexp.js';
/**
- * Creates a regular expression that matches a link to the named item and
- * captures its EDB ID from the matched link's `href` attribute.
+ * Creates a regular expression that matches a link to the database entry of the
+ * given type and name, and captures its EDB ID from the matched link's `href`
+ * attribute.
+ * @param {'item' | 'quest'} type
* @param {string} name
* @returns {RegExp}
*/
-const itemLinkRegExp = name => new RegExp(`]*>(?${regExpEscape(name)})`, 'i');
+const edbEntryLinkRegExp = (type, name) => new RegExp(`]*>(?${regExpEscape(name)})`, 'i');
/**
- * Gets the ID of the named item in Eorzea Database.
+ * Gets the ID of the Eorzea Database entry with the given type and name.
+ * @param {'item' | 'quest'} type
* @param {string} name
* @returns {Promise}
*/
-export async function findItemEDBID (name) {
- // execute a search for the item's name
- const searchURL = `https://na.finalfantasyxiv.com/lodestone/playguide/db/item/?q=${encodeURIComponent(name.replace(/\([^)]+\)|[&-]/g, ' '))}`;
+export async function findEDBEntryID (type, name) {
+ // execute a search for the entry's name and type
+ const searchURL = `https://na.finalfantasyxiv.com/lodestone/playguide/db/${type}/?q=${encodeURIComponent(name.replace(/\([^)]+\)|[&-]/g, ' '))}`;
const response = await fetch(searchURL);
const body = await response.text();
// find an `` in the HTML response whose text exactly matches the name
- const match = body.match(itemLinkRegExp(name));
+ const match = body.match(edbEntryLinkRegExp(type, name));
// return the ID parsed from the URL in the `href` attribute
return match?.groups.id;
}