User:Splarka/ajaxbatchundelete.js
Appearance
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
![]() | Documentation for this user script can be added at User:Splarka/ajaxbatchundelete. |
/* Ajax batch undelete thingy, version [0.0.1]
Originally from: http://en.wikipedia.org/wiki/User:Splarka/ajaxbatchundelete.js
Notes:
* It is a bit verbose, after debugging perhaps some output should be removed.
* It waits 1 second after every undelete before starting the next.
* Can be aborted by simply deleting the contents of the textarea, or leaving the page.
* Stops when it hits a blank line.
* Nonfatal errors (skip to next line):
** Bad character or malformed line
** Bad token
** Unexpected response
* Pauses in execution can be added with a blank line.
To do:
* Cache the token if two the same?
** Please note the delete token is not guaranteed to be static, but currently it always is.
*/
addOnloadHook(function() {
mw.util.addPortletLink('p-tb','/wiki/Special:BlankPage?blankspecial=ajaxbu','Batch Undelete');
});
if(mw.config.get('wgCanonicalSpecialPageName') && mw.config.get('wgCanonicalSpecialPageName').toLowerCase() == 'blankpage' && queryString('blankspecial') == 'ajaxbu') {
document.title = 'Ajax Batch Undeletion';
addOnloadHook(abuForm);
}
function abuForm() {
mw.util.addPortletLink('p-tb','/wiki/Special:Log/delete?user=' + encodeURIComponent(mw.config.get('wgUserName')),'My delete log');
//subvert this Special: page to our own needs.
var con = document.getElementById('content') || document.getElementById('mw_content');
var bcon = document.getElementById('bodyContent') || document.getElementById('mw_contentholder');
var fh = getElementsByClassName(con,'h1','firstHeading')[0];
while(fh.firstChild) fh.removeChild(fh.firstChild)
fh.appendChild(document.createTextNode('Ajax Batch Undeletion'));
for(var i=0;i<bcon.childNodes.length;i++) {
bcur = bcon.childNodes[i];
if(bcur.id != 'siteSub' && bcur.id != 'contentSub' && bcur.className != 'visualClear') {
while(bcur.firstChild) bcur.removeChild(bcur.firstChild)
if(bcur.nodeType == 3) bcur.nodeValue = '';
}
}
//generate content
var form = document.createElement('form');
form.appendChild(document.createTextNode('List of pages to undelete:'));
form.appendChild(document.createElement('p'));
form.setAttribute('action','javascript:void(0);');
var txt = document.createElement('textarea');
txt.style.height = '20em';
txt.style.width = '50%';
txt.setAttribute('id','abu-textarea');
form.appendChild(txt);
form.appendChild(document.createElement('p'));
var lab1 = document.createElement('label');
lab1.setAttribute('for','abu-reason')
lab1.appendChild(document.createTextNode('Restore reason: '));
form.appendChild(lab1);
var inp1 = document.createElement('input');
inp1.style.width = '20em';
inp1.setAttribute('type','text');
inp1.setAttribute('id','abu-reason');
form.appendChild(inp1);
form.appendChild(document.createElement('p'));
var sub1 = document.createElement('input');
sub1.setAttribute('type','button');
sub1.setAttribute('id','abu-startbutton');
sub1.setAttribute('value','start');
sub1.setAttribute('onclick','abuStart()');
form.appendChild(sub1);
bcon.appendChild(form);
var pre = document.createElement('pre');
pre.setAttribute('id','abu-output');
bcon.appendChild(pre);
}
function abuStart() {
document.getElementById('abu-startbutton').setAttribute('disabled','disabled');
var out = document.getElementById('abu-output');
var txt = document.getElementById('abu-textarea');
var undeletes = txt.value.split('\n');
var page = undeletes[0];
if(page == '') {
out.appendChild(document.createTextNode('* Done! Nothing left to do, or next line is blank.\n'));
document.getElementById('abu-startbutton').removeAttribute('disabled');
} else {
var badchars = /(\#|\<|\>|\[|\]|\{|\}|\|)/;
if(badchars.test(page)) {
out.appendChild(document.createTextNode('! Illegal characters detected, skipping:' + page + '\n'));
setTimeout('abuStart()',1000);
} else {
out.appendChild(document.createTextNode('> Attempting to undelete [[' + page + ']]\n'));
abuGetToken(page);
}
}
undeletes = undeletes.slice(1,undeletes.length);
txt.value = undeletes.join('\n');
}
function abuGetToken(page) {
var out = document.getElementById('abu-output');
out.appendChild(document.createTextNode(' > Fetching undelete token for [[' + page + ']]\n'));
var url = mw.config.get('wgScriptPath') + '/api.php?action=query&list=deletedrevs&drprop=token&drlimit=1&format=json&titles=' + encodeURIComponent(page);
var req = sajax_init_object();
req.open('GET', url, true);
req.onreadystatechange = function() {
if(req.readyState == 4 && req.status == 200) {
eval("abuUndelete(" + req.responseText + ",'" + req.responseText.replace(/\'/g,"`") + "','" + page + "')");
}
}
req.send(null);
}
function abuUndelete(obj,txt,page) {
var out = document.getElementById('abu-output');
if(obj['error']) {
out.appendChild(document.createTextNode(' ! Api error: ' + obj['error']['code'] + ' - ' + obj['error']['info'] + '\n'));
return;
}
if(!obj['query'] || !obj['query']['deletedrevs'] || !obj['query']['deletedrevs'][0] || !obj['query']['deletedrevs'][0]['token']) {
out.appendChild(document.createTextNode(' ? Unexpected response: ' + txt + '\n'));
return;
}
var token = obj['query']['deletedrevs'][0]['token'];
out.appendChild(document.createTextNode(' > Token found, attempting undelete\n'));
var reason = document.getElementById('abu-reason').value;
var params = 'action=undelete&format=json&token=' + encodeURIComponent(token) + '&title=' + encodeURIComponent(page) + '&reason=' + encodeURIComponent(reason);
var url = mw.config.get('wgScriptPath') + '/api.php';
var req = sajax_init_object();
req.open('POST', url, true);
req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
req.setRequestHeader('Content-length', params.length);
req.setRequestHeader('Connection', 'close');
req.onreadystatechange = function() {
if(req.readyState == 4 && req.status == 200) {
eval("abuUndeleteAftermath(" + req.responseText + ",'" + req.responseText.replace(/\'/g,"`") + "')");
}
}
req.send(params);
}
function abuUndeleteAftermath(obj,txt) {
var out = document.getElementById('abu-output');
//{"undelete":{"title":"Test 6","revisions":3,"fileversions":0,"reason":3}}
if(obj['error']) {
out.appendChild(document.createTextNode(' ! Api error: ' + obj['error']['code'] + ' - ' + obj['error']['info'] + '\n'));
} else if(obj['undelete'] && obj['undelete']['title']) {
var details = '';
if(obj['undelete']['revisions']) details += ', ' + obj['undelete']['revisions'] + ' revisions restored'
if(obj['undelete']['fileversions']) details += ', ' + obj['undelete']['fileversions'] + ' file versions restored'
out.appendChild(document.createTextNode(' > Page [[' + obj['undelete']['title'] + ']] undeleted' + details + '\n'));
} else {
out.appendChild(document.createTextNode(' ? Unexpected response: ' + txt + '\n'));
return;
}
setTimeout('abuStart()',1000);
}
function queryString(p) {
var re = RegExp('[&?]' + p + '=([^&]*)');
var matches;
if (matches = re.exec(document.location)) {
try {
return decodeURI(matches[1]);
} catch (e) {
}
}
return null;
}