2023年政策修订增补工作正在进行中,欢迎参与!
User:AnnAngela/js/nulleditInCategory.js
< User:AnnAngela | js
注意:在保存之后,您可能需要清除浏览器缓存才能看到所作出的变更的影响。
- Firefox/Safari:按住“Shift”的同时单击“刷新”,或按“Ctrl-F5”或“Ctrl-R”(Mac为“⌘-R”)
- Google Chrome:按“Ctrl-Shift-R”(Mac为“⌘-Shift-R”)
- Internet Explorer:按住“Ctrl”的同时单击“刷新”,或按“Ctrl-F5”
- Opera:在“工具→首选项”中清除缓存
- 如果您已登录但该页面出现未登录状态,请尝试在地址栏的地址最后添加代码
?_=1
来访问最新页面。 - 添加代码后的本页地址如下:
-{R|https://moegirl.icu/User:AnnAngela/js/nulleditInCategory.js?_=1}-
/* eslint-disable no-magic-numbers */
/* global mw*/
// <pre>
"use strict";
$(function() {
if (mw.config.get("wgNamespaceNumber") !== 14 || !mw.config.get("wgUserGroups").includes("sysop")) { return; }
let globalNulleditLock = false;
(async function run() {
while (!mw || !mw.util || !mw.util.addPortletLink) {
await new Promise((res) => setTimeout(res, 1000));
}
await mw.loader.using(["oojs-ui"]);
const cmtitle = mw.config.get("wgPageName");
let runningPage = 0;
const thread = async (count, strPanel, progressBar, timer) => {
await new Promise((res) => setTimeout(res, Math.ceil(100 * Math.random())));
const api = new mw.Api();
while (window.list.length) {
const pageid = window.list.shift();
if (!pageid) continue;
runningPage++;
try {
const result = await api.postWithToken("csrf", {
action: "edit",
pageid,
text: (await $.get(`${mw.config.get("wgServer")}${mw.config.get("wgScriptPath")}/index.php?action=raw§ion=0&curid=${pageid}&_=${Math.random().toString().replace(/\D/g,"")}`)).replace(/^[ \n]+|[ \n]+$/g, ""),
// appendtext: "",
section: "0",
summary: "对「" + cmtitle + "」下的页面进行空编辑以资刷新分类表",
tags: "Automation tool",
minor: true,
bot: true,
nocreate: true,
watchlist: "nochange",
});
if (result.edit && "nochange" in result.edit) {
delete result.edit.contentmodel;
console.debug(result.edit);
} else {
console.error(pageid, result);
eList.push(pageid);
}
} catch (e) {
console.error(pageid, e);
eList.push(pageid);
}
const l = list.length + --runningPage;
const left = (count - l);
const mark = "Nulledit TimeEnd-" + left;
performance.mark(mark);
const d = performance.measure("Nulledit Timed-" + left, left > 100 ? "Nulledit TimeEnd-" + (left - 100) : "Nulledit TimeStart", mark).duration;
const dA = performance.measure("Nulledit TimedA-" + left, "Nulledit TimeStart", mark).duration;
strPanel.find("#nulleditInCategoryCount").text(`${(left * 100 / count).toFixed(2)}% ${left}`);
strPanel.find("#nulleditInCategoryTime").text((dA / 1000 / left).toFixed(2));
strPanel.find("#nulleditInCategoryError").text(eList.length);
timer.setTimeleft(d * l / Math.min(100, left));
progressBar.setProgress(left * 100 / count);
}
}
$(mw.util.addPortletLink("p-cactions", "#", "批量空编辑本分类下页面", "startNulledit", "批量空编辑本分类下页面")).attr("class", "sysop-show").on("click", function() {
if (!globalNulleditLock && confirm("你确定要批量执行空编辑吗?"))(async () => {
globalNulleditLock = true;
const dom = $("<div/>");
const strP = $("<p/>");
const strPanel = $("<ul/>");
// $('<style>.oo-ui-progressBarWidget-bar { position: relative; overflow: hidden; } .oo-ui-progressBarWidget-bar::before { content: attr(style); text-indent: -3em; display: inline-block; position: absolute; top: -.325em; right: -.2em; overflow: hidden; color: white; }</style>').appendTo("body");
const progressBar = new OO.ui.ProgressBarWidget({
progress: false
});
strP.text("正在加载分类内页面列表……");
dom.append("<hr>").append(strP).append(strPanel).append(progressBar.$element).appendTo("#mw-content-text > .mw-parser-output:first");
window.eList = [];
window.list = await (async () => {
const api = new mw.Api();
const eol = Symbol("eol");
const results = [];
let cmcontinue = undefined;
while (cmcontinue !== eol) {
const result = await api.post({
action: "query",
list: "categorymembers",
cmtitle,
cmprop: "ids",
cmnamespace: "*",
cmtype: "page|subcat",
cmlimit: "5000",
cmcontinue,
});
results.push(...result.query.categorymembers.map(({ pageid }) => pageid));
if (result.continue) {
cmcontinue = result.continue.cmcontinue;
} else {
cmcontinue = eol;
}
}
return results;
})();
const count = window.list.length;
strP.text("正在批量空编辑……");
strPanel.html(`<li>已完成页面:<span id="nulleditInCategoryCount">0</span>/${count}。</li><li>每个页面的平均用时为 <span id="nulleditInCategoryTime">--</span> s/页,预计仍需 <span id="nulleditInCategoryLeftTime">-- s</span>。</li><li>出现错误的页面有 <span id="nulleditInCategoryError">--</span> 个。</li>`);
progressBar.setProgress(0);
performance.mark("Nulledit TimeStart");
const timer = new class Timer {
constructor() {
this.dom = $("#nulleditInCategoryLeftTime");
this.time = Symbol();
setInterval(() => {
if (typeof this.time === "number") {
const timeleft = this.time - new Date().getTime();
if (timeleft > 0) {
this.dom.text(`${Math.round(timeleft / 1000)} s(${moment.duration(timeleft).humanize()}左右)`);
} else {
this.dom.text(`0 s`);
}
}
}, 30);
}
setTimeleft(t) {
this.time = new Date().getTime() + t;
}
}
await Promise.all([
thread(count, strPanel, progressBar, timer),
thread(count, strPanel, progressBar, timer),
thread(count, strPanel, progressBar, timer),
]);
performance.mark("Nulledit TimeEnd");
const duration = performance.measure("Nulledit Time", "Nulledit TimeStart", "Nulledit TimeEnd").duration / 1000;
console.info("Done. Duration:", duration.toFixed(4), "s. Average time:", (duration / count).toFixed(4), "s per page. eList's length is", eList.length);
strP.text("批量空编辑操作已结束。");
setTimeout(() => { alert(`操作已结束。\n编辑页面的总用时为 ${duration.toFixed(4)} s,每个页面的平均用时为 ${(duration / count).toFixed(4)} s/页。\n出现错误的页面有 ${eList.length} 个。`); }, 200);
})();
return false;
});
})();
});
// </pre>