User:Ahecht/Scripts/refresh.js: Difference between revisions

Content deleted Content added
use mw.config.get("wgRelevantPageName")
var api = new mw.Api( { userAgent: 'refresh/0.0.1' } );
 
(42 intermediate revisions by the same user not shown)
Line 1:
// Add "refresh" option on category pages, template pages, and on "Special:WhatLinksHere".
// "Special:WhatLinksHere". Makes forceupdate nulledit on all pages in the category or all linked pages.
// category, all transclusing pages, or all linked pages.
// Based on [https://phabricator.wikimedia.org/T170039#3473755] and [[:he:User:IKhitron/101.js]]
 
mw.loader.using( [ 'mediawiki.util', 'mediawiki.api' ] ).then( function() {
var api = new mw.Api( { userAgent: 'refresh/0.0.1' } );
function getWait(d) {
var waitpageList =1000 [];
const reuse = ( typeof refreshReuseBubble === 'undefined' ? false : refreshReuseBubble );
if (d && d.query && d.query.userinfo && d.query.userinfo.ratelimits
&& d.query.userinfo.ratelimits.purge)
function shuffleArray(array) {
{
console.log('Shuffling array...');
if (d.query.userinfo.ratelimits.purge.user
for (let i = array.length - 1; i >= 0; i--) {
&& d.query.userinfo.ratelimits.purge.user.hits
const j = Math.floor(Math.random() * (i + 1));
&& d.query.userinfo.ratelimits.purge.user.seconds)
[array[i], array[j]] = [array[j], array[i]];
{
}
var hits = d.query.userinfo.ratelimits.purge.user.hits;
}
var seconds = d.query.userinfo.ratelimits.purge.user.seconds;
wait = Math.ceil( (seconds/hits) * 1000 );
function getWait(d, totalCount) {
} else {
var wait={edit: 8000, purge: 2100};
wait = 2000;
if (d && d?.query?.userinfo) {
var ratelimits = d.query.userinfo?.ratelimits;
if (d.query.userinfo.rights
&& d.query.userinfo.rights.includes("noratelimit")) {
wait = {edit: 1, purge: 1};
} else if (ratelimits) {
['edit', 'purge'].forEach ( (v) => {
var u = ratelimits?.[v]?.user;
if (u && u?.hits && u?.seconds) {
console.log(v + " rate limit: hits=" + u.hits + ", seconds=" + u.seconds);
if (u.hits < totalCount) {
wait[v] = Math.ceil( (u.seconds/u.hits) * 1050 );
} else {
console.log(totalCount+" items to refresh is less than "+u.hits);
wait[v] = 1;
}
}
} );
}
}
console.log("Millisecond waits between queries:");console.log(wait);
return wait;
}
function postPurge(target, count, wait, addParams) {
function doRefresh(action, count, totalCount, wait) {
step = target.gcmlimit || target.glhlimit || 1;
function postDone() {
mw.notify("Fetching " + target.generator + "...", { tag: "bubble"+count } );
if (pageList.length > 0) {
var apiParams = $.extend({
setTimeout(function() {
action: 'purge',
doRefresh(action, count, totalCount, wait);
forcelinkupdate: 1
}, wait[action]);
} else if (confirm("Done!\n\nReload page?") == true) {
document.___location.reload();
} else {
mw.notify("Done!", {type: 'success', tag: "bubble" + (reuse ? 0 : 'done')});
}
}
function postFail(code, error) {
console.error(error);
var err = error?.textStatus || code;
var errMsg;
//if (confirm("Error performing " + action + ": " + err + "!\n\nContinue?") == true) {
errMsg = "Continuing after "+err+" error...";
postDone();
//} else {
// errMsg = "Aborted due to "+err+" error!";
//}
mw.notify(errMsg, { tag: "bubble" + (reuse ? 0 : "error"), type: 'error',
autoHideSeconds: (action == 'purge') ? 'long' : 'short' } );
}
function postSuccess() {
count = count + ( (action == "purge") ? ((apiParams.titles.match(/\|/g) || []).length + 1) : 1 );
mw.notify(count + " of " + totalCount + " page(s) were " + ((action == "purge") ? "purged" : "edited"), {
tag: "bubble" + (reuse ? 0 : "count"),
autoHideSeconds: (action == 'purge') ? 'long' : 'short'
} );
postDone();
}
 
var apiParams = {action: action};
if (action == "purge") {
// 'purge' is always once every two second unless 'noratelimit',
// so give editors with higher 'edit' rate a boost.
// More than 3 at a time leads to timeouts.
var numPages = wait.edit < 1000 ? 3 : 1;
apiParams.titles = pageList.splice(0, numPages).join('|');
console.log(apiParams.titles);
apiParams.forcerecursivelinkupdate = "1";
//apiParams.forcelinkupdate = "1";
api.post(apiParams).fail(postFail).done(postSuccess);
} else {
apiParams.title = pageList.shift();
console.log(apiParams.title);
apiParams.watchlist = "nochange";
apiParams.nocreate = "1";
apiParams.appendtext = "";
api.postWithEditToken(apiParams).fail(postFail).done(postSuccess);
}
}
function getList(action, target, addParams) {
mw.notify("Fetching " + target.generator + "...", { tag: "bubble0" } );
var queryParams = $.extend({
action: 'query',
formatversion: '2',
prop: ''
},
target,
addParams);
var list = target?.list || "pages";
console.log(apiParams);
if (queryParams.cmsort && window.refreshCatSort) queryParams.cmsort = window.refreshCatSort;
new mw.Api().post(apiParams)
if (queryParams.cmdir && window.refreshCatDir) queryParams.cmdir = window.refreshCatDir;
.fail(function(e) {
if (queryParams.srsort && window.refreshSearchSort) queryParams.srsort = window.refreshSearchSort;
console.log(e);
console.log(queryParams);
alert("Fail!");
api.get(queryParams).fail(function(code, error) {
})
console.error(error);
.done(function(d) {
alert("Error fetching page titles: " + code + "!");
console.log(d);
} ).done(function(q) {
mw.notify((count + 1) + " pages were updated", { tag: "bubble"+count } );
if(q && q.warnings === undefined && q?.query?.[list] !== undefined) {
count += step;
q.query[list].forEach(page => {
if (d.warnings === undefined && d["continue"] !== undefined
if (page.title) pageList.push(page.title);
&& (d["continue"].gcmcontinue || d["continue"].glhcontinue)) {
});
setTimeout(function() {
if (q?.continue?.continue !== undefined) {
postPurge(target, count, wait, d["continue"]);
}getList(action, waittarget, q.continue);
} else {
if (window.refreshShuffle) shuffleArray(pageList);
alert("Done!");
document console.___location.reloadlog(pageList);
api.get( {
}});
meta: 'userinfo',
uiprop: 'ratelimits|rights'
} ).fail( function(e) {
console.error(e);
doRefresh(action, 0, pageList.length, {edit: 8000, purge: 2100});
} ).done( function(ui) {
var len = pageList.length;
mw.notification.autoHideLimit = len;
mw.notify('Performing '+action+' on '+len+' page(s)...', {
autoHideSeconds: (action == 'purge') ? 'long' : 'short',
tage: 'bubble0'
} );
doRefresh(action, 0, len, getWait(ui, len));
} );
}
}
} );
}
if ( (mw.config.get('wgNamespaceNumber') == 14) || (mw.config.get("wgCanonicalSpecialPageName") == "Whatlinkshere") ){
var linkshere = mw.config.get("wgCanonicalSpecialPageName") == "Whatlinkshere";
new mw.Api().get({
var sparams = new URLSearchParams(window.___location.search);
meta: 'userinfo',
var search= (mw.config.get("wgCanonicalSpecialPageName") == "Search" &&
uiprop: 'ratelimits'
sparams.get('search') && sparams.get('search') != '');
}).done( function(d) {
var if target =( (mw.config.get("wgRelevantPageName"'wgNamespaceNumber').replace(/_/g, "== "10);
if|| (mw.config.get('wgNamespaceNumber') == 14) {
|| (mw.config.get('wgNamespaceNumber') == 828)
target = {
|| linkshere || search)
generator: 'categorymembers',
{
gcmtitle: target,
var linkTitle="linking pages", toolTipText="that link to this page.";
gcmlimit: 1
var target = mw.config.get("wgRelevantPageName").replace(/_/g, " ");
};
var targetNS = mw.Title.newFromText(target).getNamespaceId();
var query = {
generator: 'linkshere',
titles: target,
glhlimit: 'max'
};
if (search) {
linkTitle = "search results";
toolTipText = "in this search result.";
query = {
list: 'search',
srsearch: sparams.get('search'),
srlimit: 'max',
srsort: 'last_edit_desc',
srprop: ''
};
nslist = [];
for(const e of sparams.entries()) {
var nsp = e[0].match(/^ns(\d+)/);
if (nsp?.[1] && e[1] == 1) nslist.push(nsp[1]);
}
if (nslist.length > 0 ) query.srnamespace = nslist.join("|");
 
} else if ( (targetNS == 10) || (targetNS == 828) ){
if ( linkshere ) {
toolTipText = "that link to this template.";
} else {
targetquery = {
generator: 'linksheretranscludedin',
titles: target,
glhlimitgtilimit: 1'max'
};
linkTitle = "transcluding pages";
toolTipText = "that transclude this template.";
}
} else if (targetNS == 14) {
$(mw.util.addPortletLink('p-cactions', '#', 'Refresh links', 'pt-refresh'))
.click(functionif ( linkshere ) {
toolTipText = "that link to this category.";
postPurge(target, 0, getWait(d));
}); else {
} query );= {
list: 'categorymembers',
cmtitle: target,
cmlimit: 'max',
cmsort: 'timestamp',
cmdir: 'desc'
};
linkTitle = "category members";
toolTipText = "in this category.";
}
}
$(mw.util.addPortletLink('p-cactions', '#', 'Purge ' + linkTitle, 'pt-refresh-purge', 'Perform a "forcelinkupdate" purge on all pages ' + toolTipText))
.click(function() {
getList("purge", query);
});
$(mw.util.addPortletLink('p-cactions', '#', 'Null edit ' + linkTitle, 'pt-refresh-null', 'Perform a null edit on all pages ' + toolTipText))
.click(function() {
getList("edit", query);
});
}
});