importScript( 'User:JJPMaster/d-batch/links.js' ); // Backlink: [[User:JJPMaster/d-batch/links.js]]
importScript( 'User:JJPMaster/d-batch/cat.js' ); // Backlink: [[User:JJPMaster/d-batch/cat.js]]
importScript( 'User:JJPMaster/d-batch/prefix.js' ); // Backlink: [[User:JJPMaster/d-batch/prefix.js]]
async function getSubpages(page) {
var params = {
action: 'query',
list: 'allpages',
apprefix: `${new mw.Title(page).getMain()}/`,
apnamespace: new mw.Title(page).getNamespaceId(),
aplimit: 'max',
format: 'json'
},
api = new mw.Api();
try {
const data = await api.get(params);
return data.query.allpages.map(i => i.title);
}
catch {
console.log("No subpages of " + page);
return [];
}
}
async function getRedirects(page) {
var params = {
action: 'query',
prop: 'redirects',
titles: page,
rdprop: 'title',
rdlimit: 'max',
format: 'json'
},
api = new mw.Api();
try {
const data = await api.get(params);
return Object.values(data.query.pages)[0].redirects.map(i => i.title);
}
catch {
console.log("No subpages of " + page);
return [];
}
}
async function deleteBatch(arr) {
let newList = arr.map(item => `<li><a href="/wiki/${item.replace(/ /g, "_")}">${item}</a></li>`);
if (newList.length == 0) {
alert("Luna: There are no pages to delete.");
return;
}
$("#bodyContent").append(`
<div id="dBatchDialog">
You are about to delete the following ${newList.length} pages:\n<ol>${newList.join("\n")}</ol>Are you sure you want to do this?<br/>
<textarea id="dBatchReason" name="dBatchReason" placeholder="Reason for deletion ('$title' will be replaced by the respective page's title)"></textarea>
<input type="checkbox" id="deleteTalk" name="deleteTalk" /><label for="deleteTalk">Delete associated talk pages</label><br/>
<input type="checkbox" id="deleteSubs" name="deleteSubs" /><label for="deleteSubs">Delete subpages</label><br/>
<input type="checkbox" id="deleteReds" name="deleteReds" /><label for="deleteReds">Delete redirects</label><br/>
<button type="button" id="dBatchConfirm">Delete all pages</button>
</div>`);
$("#dBatchDialog").dialog({ title: "Batch delete", width: "auto", height: "auto" });
$("#dBatchConfirm").click(async () => {
let reason = document.getElementById("dBatchReason").value;
if (!reason) {
alert("You must provide a reason.");
return;
}
let deletePromises = [];
for (const p of arr) {
let params = {
action: 'delete',
deletetalk: $("#deleteTalk").prop("checked"),
title: p,
reason: reason.replace(/\$[Tt]itle/gm, p),
tags: "Luna",
format: 'json'
};
let api = new mw.Api();
console.log(`Deleting page: ${p}`);
deletePromises.push(api.postWithToken('csrf', params));
// Handle subpages
if ($("#deleteSubs").prop("checked")) {
try {
let subpages = await getSubpages(p);
console.log(`Found ${subpages.length} subpages for ${p}:`, subpages);
for (const i of subpages) {
let subParams = {
action: 'delete',
deletetalk: $("#deleteTalk").prop("checked"),
title: i,
reason: "Deleted together with the parent page with reason: " + reason.replace(/\$[Tt]itle/gm, p),
tags: "Luna",
format: 'json'
};
let subApi = new mw.Api();
console.log(`Deleting subpage: ${i}`);
deletePromises.push(subApi.postWithToken('csrf', subParams));
}
} catch (e) {
console.log("There are no subpages of " + p);
}
}
// Handle redirects
if ($("#deleteReds").prop("checked")) {
try {
let redirects = await getRedirects(p);
console.log(`Found ${redirects.length} redirects to ${p}:`, redirects);
for (const i of redirects) {
let redirParams = {
action: 'delete',
deletetalk: $("#deleteTalk").prop("checked"),
title: i,
reason: "Deleted together with the redirect target with reason: " + reason.replace(/\$[Tt]itle/gm, p),
tags: "Luna",
format: 'json'
};
let redirApi = new mw.Api();
console.log(`Deleting redirect: ${i}`);
deletePromises.push(redirApi.postWithToken('csrf', redirParams));
}
} catch (e) {
console.log("There are no redirects to " + p);
}
}
}
console.log(deletePromises);
await Promise.all(deletePromises);
mw.notify("Luna:\nThe batch deletion has been completed.");
console.log("All deletions completed.");
setTimeout(() => window.location.reload(), 2000);
});
}