var rTemplateNs = {};
var docPages = [];
var docContents = {};
var docCats = {};
var lastEdited = new Date().getTime();
function scanrTemplateNs(cont, gcmcont) {
var query = {
"action": "query",
"format": "json",
"prop": "revisions",
"generator": "categorymembers",
"formatversion": "2",
"rvprop": "content",
"rvslots": "main",
"gcmtitle": "Category:Redirect templates",
"gcmnamespace": "10",
"gcmtype": "page",
"gcmlimit": "50",
"continue": cont || '',
"gcmcontinue": gcmcont || ''
}
new mw.Api().get( query ).done( (result) => {
result.query.pages.forEach( (e) => {
if (e?.title && e.title.startsWith('Template:R ')) {
var pageContent = e?.revisions?.[0]?.slots?.main?.content
if (typeof pageContent === "string") {
var nsMatches = Array.from(
pageContent.matchAll(new RegExp("\\|\\s*(\\S*?) category\\s*=", "g")),
(v) => (v[1])
);
if (nsMatches.length == 0) nsMatches = ['unknown'];
rTemplateNs[e.title] = nsMatches;
}
}
} );
var keys = Object.keys(rTemplateNs);
if (result["continue"]) {
console.log("Got " + keys.length + " templates...")
scanrTemplateNs(result["continue"]["continue"], result["continue"].gcmcontinue,);
} else {
console.log("Done " + keys.length + " templates!");
keys.forEach( (e) => docPages.push(e + "/doc") );
getDocContent();
}
} ).fail( (e) => console.warn(e) );
}
function getDocContent() {
var limit = 50;
if (docPages.length > 0) {
titles = docPages.slice(0,limit).join('|');
docPages = docPages.slice(limit)
var query = {
"action": "query",
"format": "json",
"prop": "revisions",
"titles": titles,
"formatversion": "2",
"rvprop": "content",
"rvslots": "main",
}
new mw.Api().get( query ).done( (result) => {
result.query.pages.forEach( (e) => docContents[e.title.slice(0,-4)] = e?.revisions?.[0]?.slots?.main?.content );
console.log("Got contents of " + Object.keys(docContents).length + " doc pages...");
getDocContent();
} ).fail( (e) => console.warn(e) );
} else {
console.log("Done with contents of " + Object.keys(docContents).length + " doc pages!");
addCats();
}
}
function addCats() {
Object.keys(rTemplateNs).forEach( (e) => {
if (docContents[e]) {
docCats[e] = Array.from(
docContents[e].matchAll(new RegExp("\\[\\[[Cc]ategory:(.*?) namespace redirect templates", "g")),
(v) => (v[1].toLowerCase())
);
rTemplateNs[e].forEach( (f) => {
if ( !docCats[e].includes(f) ) {
var thisCat = '[[Category:' + f[0].toUpperCase() + f.substring(1) + ' namespace redirect templates]]'
var re = /(Categories(?: go)? below this line.*?--\>)(.*?)((?:\s*\n*\s*\[\[[Cc]ategory\:.*?\]\])*)\n*/
if (re.test(docContents[e])) {
docContents[e] = docContents[e].replace(
/(Categories(?: go)? below this line.*?--\>)(.*?)((?:\s*\n*\s*\[\[[Cc]ategory\:.*?\]\])*)\n*/, "$1$2$3\n"+thisCat
).replace(
new RegExp("\\n\\n" + thisCat), "\n"+thisCat
);
console.log(e + " added " + thisCat);
} else {
console.error("Category block not found in " + e);console.log(docContents[e]);
}
} else if (f == 'none') {
console.warn("Template NS for " + e + " is 'none'");
} else {
console.warn(e + " already includes " + f)
}
} );
} else {
console.warn("Could not get docContents[" + e + "]");
}
} );
writeDocs();
}
function makeEditFunc(page) {
return function () {
return $.Deferred(function (deferred) {
var options = {
"action": "edit",
"format": "json",
"title": page + "/doc",
"text": docContents[page],
"summary": "Add namespace-specific categories",
"minor": 1,
"nocreate": 1,
"watchlist": "nochange",
}
console.log(new Date().getTime() + ": Editing " + options.title);
lastEdited = new Date().getTime();
var promise = new mw.Api().postWithEditToken(options);
//var promise = $.when(() => {d = $.Deferred; return d.resolve().promise();}); //debug
promise.done( () => console.log("Edited " + options.title) );
promise.fail(function (code, obj) {
console.warn(new Date().getTime() + ": Edit failed (" + obj.error.info + ").");
});
promise.always(function () {
deferred.resolve();
});
});
};
}
function delay() {
return function() {
return $.Deferred(function (deferred) {
var interval = lastEdited + 667 - new Date().getTime();
console.log(new Date().getTime() + ': Waiting ' + interval + 'ms...');
setTimeout(function () {
console.log(new Date().getTime() + ': Done waiting.');
deferred.resolve();
}, interval);
});
};
}
function writeDocs() {
var articles = Object.keys(docContents);
var deferred = makeEditFunc(articles[0])();
for (var i = 1, len = articles.length; i < len; i++) {
deferred = deferred.then(delay(len));
deferred = deferred.then(makeEditFunc(articles[i]));
}
$.when(deferred).then( () => console.log("Edits done!") );
}
scanrTemplateNs();