User:SD0001/GAR-helper.js

/**

* Script to easily make Good Article Reassessment (GAR)

* nominations.

*/

/* */

/* 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 = ' (GAR-helper)';

gar.callback = function garCallback(e) {

if (e) e.preventDefault();

var Window = new Morebits.simpleWindow(600, 600);

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 field = form.append({

type: 'field',

label: 'Details',

name: 'details'

});

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.'

});

var previewlink = Morebits.htmlNode('a', 'Preview');

previewlink.style.cursor = "pointer";

$(previewlink).click(function() {

// |result| is defined below

gar.preview(result);

});

form.append( { type: 'div', id: 'garpreview', label: [ previewlink ] } );

form.append( { type: 'div', id: 'gar-previewbox', style: 'display: none' } );

form.append({ type: 'submit', label: 'Submit' });

var result = form.render();

Window.setContent(result);

Window.display();

gar.previewbox = document.getElementById('gar-previewbox');

result.previewer = new Morebits.wiki.preview(gar.previewbox);

};

gar.initParams = function (form) {

gar.params = {

reason: form.reason.value

};

var title_obj = mw.Title.newFromText(Morebits.pageNameNorm);

gar.title = title_obj.getSubjectPage().toText();

gar.talktitle = title_obj.getTalkPage().toText();

gar.usersToNotify = [];

};

gar.preview = function(form) {

gar.initParams(form);

Morebits.status.init(gar.previewbox);

$(gar.previewbox).show();

var tm = new Morebits.taskManager();

tm.add(gar.tasks.getNumber, []);

tm.add(gar.tasks.getCreator, []);

tm.add(gar.tasks.getLastGanNominator, []);

tm.add(gar.tasks.getOtherEditors, []);

tm.execute().then(function() {

gar.garpage = 'Wikipedia:Good article reassessment/' + gar.title + '/' + gar.num;

var previewText =

'Preview of ' + gar.garpage + ':\n'

+ '----\n'

+ gar.tasks.getNomPageText()

+ '\n----\n'

+ 'Notifications will be automatically delivered to the following pages. Uncheck to prevent notification:\n\n'

+ (gar.tasks.getNotificationTargets().length > 0 ?

gar.tasks.getNotificationTargets()

.map(p => '*User talk:' + p + '').join('\n') :

'*None');

form.previewer.beginRender(previewText, gar.garpage).then(function () {

$(gar.previewbox).find('.gar-user-to-notify').each(function (_, e) {

$(e).prepend(

$('')

.attr('type', 'checkbox')

.attr('value', mw.Title.newFromText($(e).text()).getMainText())

.prop('checked', true)

);

});

});

}, function () {

form.previewer.beginRender("Unable to render preview", gar.garpage);

});

};

gar.evaluate = function(e) {

var form = e.target;

gar.initParams(form);

gar.usersNotToNotify = new Set($(gar.previewbox)

.find('.gar-user-to-notify input:not(:checked)')

.get()

.map(e => e.value));

Morebits.simpleWindow.setButtonsEnabled(false);

Morebits.status.init(form);

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 ], function () {

Morebits.status.printUserText(gar.tasks.getNomPageText(),

'Your nomination text is provided below, with which you can manually create the page ' + gar.garpage + '.');

});

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 + '|GARpage=' + gar.num + '}} ~~~~') ], 'warn');

});

};

gar.tasks = {

getNumber: function() {

var def = $.Deferred();

var query = {

action: 'query',

format: 'json',

formatversion: '2',

list: 'allpages',

apnamespace: '4', // WP

apprefix: 'Good article reassessment/' + gar.title + '/',

aplimit: 'max'

};

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

apiobj.getStatusElement().info('Next number is ' + gar.num);

def.resolve();

}, def.reject);

return def;

},

getNomPageText: function() {

return '{{subst:GAR/header}}\n' + gar.params.reason.trim() +

(gar.params.reason.trim().endsWith('~~~~') ? '' : ' ~~~~');

},

createNomPage: function() {

var def = $.Deferred();

var appendtext = gar.tasks.getNomPageText();

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();

gar.garpage = 'Wikipedia:Good article reassessment/' + gar.title + '/' + 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:

text += '\n\n==GA Reassessment==\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 === '') {

return;

}

gar.usersToNotify.push(nom);

}).catch(function () {

return $.Deferred().resolve(); // might be some server issue; don't fail

});

},

getOtherEditors: function() {

var query = {

"action": "query",

"format": "json",

"formatversion": "2",

"list": "allpages",

"aplimit": "max"

};

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();

return $.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 defs = pages.map(function(page) {

var def = $.Deferred();

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());

def.resolve();

}, def.reject);

return def;

});

return $.when.apply($, defs);

});

},

getNotificationTargets: function() {

return Morebits.array.uniq(gar.usersToNotify).filter(function (user) {

return user !== mw.config.get('wgUserName');

});

},

notify: function() {

var usersToNotify = gar.tasks.getNotificationTargets().filter(name => !gar.usersNotToNotify.has(name));

var appendtext = '\n\n' +

'{{subst:GARMessage|' + gar.title + '|GARpage=' + gar.num + '}} ~~~~';

var editsummary = '' + gar.title + ' listed for good article reassessment' + gar.advert;

var defs = usersToNotify.map(function(user) {

var def = $.Deferred();

var usertalk = new Morebits.wiki.page('User talk:' + user, 'Notifying ' + user);

usertalk.setAppendText(appendtext);

usertalk.setEditSummary(editsummary);

usertalk.append(def.resolve, def.reject);

return def;

});

return $.when.apply($, defs);

}

};

/* */