/**
* Script to easily make Good Article Reassessment (GAR)
* nominations.
*/
/* <nowiki> */
/* jshint maxerr: 999 */
var gar = {};
window.gar = gar;
$.when(
mw.loader.using('ext.gadget.morebits'),
$.ready
).then(function() {
if ([0, 1].indexOf(mw.config.get('wgNamespaceNumber')) !== -1) {
mw.util.addPortletLink('p-cactions', '#', 'GAR', 'gar-portlet', 'Nominate for GAR');
$('#gar-portlet').click(gar.callback);
}
});
gar.advert = ' ([[User:SD0001/GAR-helper|GAR-helper]])';
gar.callback = function garCallback(e) {
if (e) e.preventDefault();
var Window = new Morebits.simpleWindow(600, 450);
Window.setTitle( "Nominate article for GAR" );
Window.setScriptName('GAR-helper');
Window.addFooterLink('GAR instructions', 'WP:GAR');
var form = new Morebits.quickForm(gar.evaluate);
mw.util.addCSS('.quickform * { font-size: 12px; }');
var typefield = form.append({
type: 'field',
label: 'GAR type',
id: 'gartype_fieldset'
});
typefield.append({
type: 'radio',
name: 'gartype',
list: [
{
label: 'Community reassessment',
value: 'garc',
checked: true
},
{
label: 'Individual reassessment',
value: 'gari'
}
]
});
var field = form.append({
type: 'field',
label: 'Details',
name: 'details'
});
field.append({
type: 'checkbox',
list: [
{
label: 'Notify article creator',
value: 'notify',
name: 'notify',
tooltip: "A notification template will be placed on the creator's talk page if this is checked.",
checked: true
}
]
});
field.append({
type: 'textarea',
name: 'reason',
label: 'Rationale:',
style: 'height: 130px',
tooltip: 'You can expand the rationale after the page has been saved as well.'
});
form.append({ type: 'submit', label: 'Submit' });
var result = form.render();
Window.setContent(result);
Window.display();
};
gar.evaluate = function(e) {
var form = e.target;
gar.params = {
type: form.gartype.value,
notify: form.notify.checked,
reason: form.reason.value
};
gar.garc = gar.params.type === 'garc';
gar.gari = gar.params.type === 'gari';
Morebits.simpleWindow.setButtonsEnabled(false);
Morebits.status.init(form);
var title_obj = new mw.Title.newFromText(Morebits.pageNameNorm);
gar.title = title_obj.getSubjectPage().toText();
gar.talktitle = title_obj.getTalkPage().toText();
gar.usersToNotify = [];
var tm = new Morebits.taskManager();
tm.add(gar.tasks.getNumber, []);
tm.add(gar.tasks.editTalkPage, [ gar.tasks.getNumber ]);
tm.add(gar.tasks.createNomPage, [ gar.tasks.editTalkPage ]);
tm.add(gar.tasks.getCreator, []);
tm.add(gar.tasks.getLastGanNominator, []);
tm.add(gar.tasks.getOtherEditors, []);
tm.add(gar.tasks.notify, [ gar.tasks.getCreator, gar.tasks.getLastGanNominator, gar.tasks.getOtherEditors ]);
tm.execute().then(function() {
Morebits.status.actionCompleted('Nomination completed.');
new Morebits.status('Notifications', ['The script has notified the the reviewer and page creator. ' +
'Please consider manually notifying other involved editors and WikiProjects using ',
Morebits.htmlNode('code', '{{subst:GARMessage|' + gar.title + '|' + (gar.garc ? 'GAR' : '') + 'page=' + gar.num + '}} ~~~~') ], 'warn');
});
};
gar.tasks = {
getNumber: function() {
var def = $.Deferred();
var query = {
action: 'query',
format: 'json',
formatversion: '2',
list: 'allpages',
};
if (gar.garc) {
query.apnamespace = '4', // WP
query.apprefix = 'Good article reassessment/' + gar.title + '/';
} else {
query.apnamespace = '1', // Talk
query.apprefix = gar.title + '/GA'; // name without namespace
}
var api = new Morebits.wiki.api('Getting numbering', query);
api.post().then(function(apiobj) {
var pages = apiobj.response.query.allpages;
gar.num = pages.length + 1; // HACK
def.resolve();
}, def.reject);
return def;
},
createNomPage: function() {
var def = $.Deferred();
var appendtext;
if (gar.garc) {
appendtext =
'{{subst:GAR/header}}\n' +
gar.params.reason;
} else {
appendtext =
'==GA Reassessment==\n' +
'{{subst:GAR/subst|{{subst:PAGENAME}}}}\n' +
gar.params.reason;
}
var pageobj = new Morebits.wiki.page(gar.garpage, 'Creating nomination page');
pageobj.setAppendText(appendtext);
pageobj.setCreateOption('createonly');
pageobj.setWatchlist(true);
pageobj.setEditSummary('Creating GAR nomination page' + gar.advert);
pageobj.append(def.resolve, def.reject);
return def;
},
editTalkPage: function() {
var def = $.Deferred();
if (gar.garc) {
gar.garpage = 'Wikipedia:Good article reassessment/' + gar.title + '/' + gar.num;
} else {
gar.garpage = gar.talktitle + '/GA' + gar.num;
}
var talkpage = new Morebits.wiki.page(gar.talktitle, 'Editing talk page');
talkpage.load(function(talkpage) {
var text = talkpage.getPageText();
// prepend tag:
text = '{{subst:GAR}}\n' + text;
// append transclusion:
if (gar.garc) {
text += '\n\n==GA Reassessment==\n' +
'{{' + gar.garpage + '}}';
} else {
text += '\n\n{{' + gar.garpage + '}}';
}
talkpage.setPageText(text);
talkpage.setEditSummary('Nominating for good article reassessment' + gar.advert);
talkpage.save(def.resolve, def.reject);
}, def.reject);
return def;
},
getCreator: function() {
var def = $.Deferred();
var page = new Morebits.wiki.page(gar.title, 'Fetching article creator');
page.setLookupNonRedirectCreator(true);
page.lookupCreation(function() {
var author = page.getCreator();
page.getStatusElement().info('Got ' + author);
gar.usersToNotify.push(author);
def.resolve();
}, def.reject);
return def;
},
getLastGanNominator: function () {
return $.get({
url: 'https://sdzerobot.toolforge.org/gans/credit/' + mw.util.wikiUrlencode(gar.title) + '?raw=1',
timeout: 4000
}).then(function (nom) {
if (nom === '<Unknown>') {
return;
}
gar.usersToNotify.push(nom);
}).catch(function () {
return $.Deferred().resolve(); // might be some server issue; don't fail
});
},
getOtherEditors: function() {
var def = $.Deferred();
var query = {
"action": "query",
"format": "json",
"formatversion": "2",
"list": "allpages",
};
var api_gan = new Morebits.wiki.api('Getting previous GAN reviewers', $.extend(query, {
"apprefix": gar.title + '/GA',
"apnamespace": "1"
})).post();
var api_gar = new Morebits.wiki.api('Getting previous GAR nominators', $.extend(query, {
"apprefix": 'Good article reassessment/' + gar.title + '/',
"apnamespace": "4"
})).post();
$.when(api_gar, api_gan).then(function(result_gan, result_gar) {
var pages = result_gar.response.query.allpages
.concat(result_gan.response.query.allpages);
var lookupsDone = 0;
pages.forEach(function(page) {
var p = new Morebits.wiki.page(page.title, 'Looking up creator of ' + page.title);
p.lookupCreation(function() {
gar.usersToNotify.push(p.getCreator());
p.getStatusElement().info('found ' + p.getCreator());
if (++lookupsDone === pages.length) { // Hack: #911
def.resolve();
}
});
});
});
return def;
},
notify: function() {
var def = $.Deferred();
var users = Morebits.array.uniq(gar.usersToNotify).filter(user => {
return user !== mw.config.get('wgUserName');
});
var appendtext = '\n\n' +
(gar.garc ?
'{{subst:GARMessage|' + gar.title + '|GARpage=' + gar.num + '}} ~~~~' :
'{{subst:GARMessage|' + gar.title + '|page=' + gar.num + '}} ~~~~');
var editsummary = '[[' + gar.title + ']] listed for good article reassessment' + gar.advert;
var notificationsDone = 0;
users.forEach(function(user, idx) {
var usertalk = new Morebits.wiki.page('User talk:' + user, 'Notifying ' + user);
usertalk.setAppendText(appendtext);
usertalk.setEditSummary(editsummary);
usertalk.append(function() {
if (++notificationsDone === users.length) { // Hack: till .append() is promisified (#911)
def.resolve();
}
});
});
return def;
}
};
/* </nowiki> */