src/Navbox/fixName.js
import { MediaWikiApi } from 'wiki-saikou';
import Parser from 'wikiparser-node';
import config from '../utils/config.js';
import splitAndJoin from '../utils/splitAndJoin.js';
Parser.config = 'moegirl';
const api = new MediaWikiApi(config.zh.api, {
headers: { 'user-agent': config.useragent },
});
async function querySearch(srsearch) {
const { data: { query: { search } } } = await api.post({
list: 'search',
srsearch,
srnamespace: '10',
srlimit: 'max',
srinfo: '',
srprop: '',
}, {
retry: 25,
});
return search;
}
(async () => {
console.log(`Start time: ${new Date().toISOString()}`);
await api.login(
config.zh.ibot.name,
config.zh.ibot.password,
undefined,
{ retry: 25, noCache: true },
).then(console.log);
const search = await Promise.all([
querySearch('hastemplate:"navbox" insource:"name" insource:"navbox"'),
querySearch('insource:"invoke:nav" insource:"name"'),
querySearch('hastemplate:"大家族" insource:"name" insource:"大家族"'),
]).then((result) => result.flat());
const ids = search
.filter(({ title }) => !/Template:(?:Navbox|大家族|沙盒|Sandbox)|\/doc/.test(title))
.map(({ pageid }) => pageid);
const idslist = splitAndJoin([...new Set(ids)], 500);
await Promise.all(idslist.map(async (pageids) => {
const { data: { query: { pages } } } = await api.post({
prop: 'revisions',
pageids,
rvprop: 'content',
}, {
retry: 25,
});
await Promise.all(pages.map(async ({ title, revisions: [{ content }] }) => {
const wikitext = Parser.parse(content, true);
const name = wikitext.querySelector('template:regex("name, /^Template:(?:Navbox(?:_with_collapsible_groups|_with_columns)?|大家族(?:模板)?)$/i"), magic-word#invoke[module=Module:Nav]')?.getValue('name')?.trim();
if (!name) {
console.log(`${title} 找不到navbox或缺失name参数。`);
return;
}
const value = `${name.charAt(0).toUpperCase()}${name.slice(1)}`;
const titleValue = title.replace('Template:', '');
if (value.replaceAll('_', ' ') !== titleValue) {
const regex = new RegExp(`(\\|\\s*name\\s*=\\s*)${name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}`);
await api.postWithToken('csrf', {
action: 'edit',
title,
text: content.replace(regex, `$1${titleValue}`),
bot: true,
tags: 'Bot',
watchlist: 'nochange',
summary: `修复Navbox模板name参数:${name} → ${titleValue}`,
}, {
retry: 50,
noCache: true,
}).then(({ data }) => console.log(JSON.stringify(data)));
}
}));
}));
console.log(`End time: ${new Date().toISOString()}`);
})();