// <nowiki>
var api = new mw.Api();
importScript('User:Theleekycauldron/Query pages.js');
let nompage, nomtext, preptexts;
let isEmpty = [];
let alphanumericals="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
function mod(n, m) {
return ((n % m) + m) % m;
}
$.when(
mw.loader.using('ext.gadget.morebits'),
$.ready
).then(async function() {
console.log("ready!");
await nomtext;
if (mw.config.get('wgPageName').includes("Template:Did_you_know_nominations/")) {
$(mw.util.addPortletLink(window.DYKH_portlet || 'p-cactions', '#', 'PSHAW', 'dyk-portlet', 'Close nomination')).click(promote);
} else if (mw.config.get('wgPageName').includes("Template:Did_you_know/Preparation_area")) {
importScript('User:Theleekycauldron/Prep tools.js');
$(mw.util.addPortletLink(window.DYKH_portlet || 'p-cactions', '#', 'PSHAW', 'dyk-portlet', 'Prep set tools')).click(preptools_handler);
}
});
function getHooks(wikiText) {
var re = /('''ALT.+?)?(\.\.\..*?)(?:{{-\?}}|\?)/g;
var hooks = wikiText.match(re);
return hooks;
}
function biwikitext(t){
while (t.includes("\'\'\'")){
t = t.replace(/'''/,"<b>");
t = t.replace(/'''/,"</b>");
}
while (t.includes("\'\'")){
t = t.replace(/''/,"<i>");
t = t.replace(/''/,"</i>");
}
return t;
}
promote = async function (e) {
nompage = await get_pages(mw.config.get('wgPageName'),"user|content",null,"older");
nomtext = nompage[0].revisions[0].slots.main.content;
await nomtext;
if (nomtext.includes("'''No further edits should be made to this page'''.")){
alert("Hang on, you can't promote a closed nomination!");
return;
}
for (revision of nompage[0].revisions){
user = revision.user;
if (user==mw.config.get('wgUserName')){
alert("Looks like you've edited this nompage before. Make sure you're not an \"involved user\" before proceeding with a close; if you've nominated or edited the article, reviewed the nomination, or wrote the hook you're about to promote, you are most likely involved.");
break;
}
}
//nomtext = nomtext.replaceAll(/<s>.*?<\/s>/g,"");
e.preventDefault();
var Window = new Morebits.simpleWindow(900, 800);
Window.setTitle( "The prep set's half-assed workbench (PSHAW)" );
Window.addFooterLink( "DYK promoter's rules", "WP:DYKSG#Rules of thumb for preparing updates" );
var form = new Morebits.quickForm();
function reject(w){
form.root.childs = [];
console.log(w,(w)?("withdrawn"):("unsuccessful"))
form.append({type: 'div', name: 'closing', label: 'Closing as '+((w)?("withdrawn"):("unsuccessful"))+"... "});
nomtext = nomtext.split("\n");
nomtext[0] = "{{subst:DYKsubpage";
nomtext[2] = "|passed="+((w)?"withdrawn":"no");
nomtext = nomtext.join("\n");
var params = {
action: 'edit',
title: nompage[0].title,
summary: "Closing as "+((w)?("withdrawn"):("unsuccessful"))+" ([[User:Theleekycauldron/DYK promoter|PSHAW]])",
text: nomtext,
format: 'json'
}
api.postWithToken( 'csrf', params ).done( function ( data ) {
console.log( data );
form.root.childs[0].data.label += 'done! :)';
console.log(form.root.childs[0]);
show();
location.reload(true);
} );
}
form.append({type: 'button', name: 'reject', label: 'mark as rejected', style: 'float: right', event: function r(){reject(false)}})
form.append({type: 'button', name: 'withdrawn', label: 'mark as withdrawn', style: 'float: right', event: function w(){reject(true)}})
// Grabbing hooks from nomination page
function createHookObject(){
var res = [];
let u=0;
let hooks = getHooks(nomtext);
for (hook of hooks){
hook = hook.split("...");
if (hook[0].includes("ALT")){
let i;
for (i=hook[0].indexOf("ALT")+3; alphanumericals.includes(hook[0].charAt(i)); i++){}
hook[0] = hook[0].substring(hook[0].indexOf("ALT"),i);
} else {
hook[0] = "U"+u;
u++;
}
res.push({ type: 'option', label: "<b>"+hook[0]+"</b>: ..."+biwikitext(hook[1].slice()), value: "* ..."+hook[1]});
}
return res;
}
hooks = createHookObject()
//prep and queue selection
form.append({type: 'select',name: 'area',label: 'Transport hook to:',list: [{ type: 'option', label: "Prep", value: "Template:Did you know/Preparation area "},{ type: 'option', label: "Queue (admins only)", value: "Template:Did you know/Queue/"}]});
form.append({type: 'number', name: 'pqid', label: 'Prep/queue number:', min: 1, max: 7, step: 1})
// render
let result;
function show(){
result = form.render();
Window.setContent(result);
Window.display();
}
show();
// load up the prep/queue
let firstLoad = true;
form.append({type: 'button',name: 'load', label: 'load prep/queue', event: load});
async function load(){
console.log("howdy :)");
let pagename = result.area.value+result.pqid.value;
let nextpreppage = await get_pages("Template:Did you know/Queue/NextPrep","user|content",null,"older");
await nextpreppage;
let nextpreptext = nextpreppage[0].revisions[0].slots.main.content;
let previousprep = mod(nextpreptext[0]-2,7)+1;
let dolastprepmessage = previousprep == result.pqid.value;
console.log(form,previousprep,result.pqid.value,dolastprepmessage);
form.root.childs[4].data.disabled = true; //disable button
show(); //reload while button is being disabled
if (firstLoad){ //these should only be done once
if (!(nomtext.includes("[[File:Symbol voting keep.svg|16px]]") || nomtext.includes("[[File:Symbol confirmed.svg|16px]]")|| nomtext.match(/\|.*?status.*?=.*?y/g)!=undefined)){
alert("Looks like you're trying to promote a nomination that hasn't been approved yet. Make sure the nomination's got a green or grey check mark!")
}
form.append({type: 'div', name: 'preppagename', label: "<b>[["+pagename+"]]</b>"}) //child 5
form.append({name: 'hooksinprep', type: 'radio', label: 'Hooks:', list: []});
form.append({type: 'div', name: 'hooktopromote', label: '<b>Hook to promote: </b>'})
form.append({type: 'radio', name: 'nomhooks', list: []});
} else { //update prepnum
form.root.childs[5].data.label = "<b>[["+pagename+"]]</b>";
}
preppage = await get_pages(pagename,"content",null,"older");
preptext = preppage[0].revisions[0].slots.main.content;
prephooks = preptext.split("\n");
prephooks = prephooks.slice(prephooks.indexOf("<!--Hooks-->")+2,prephooks.indexOf("<!--HooksEnd-->"));
form.root.childs[6].data.list = []; //clear prep set's hook list
for (var i=0; i<prephooks.length; i++){
let matches = prephooks[i].match(/('{3}[^']*?\[\[.*?]].*?'{3})|(\[\[.*'{3}.*?'{3}]])/g);
if (matches != null){
form.root.childs[6].data.list.push({ type: 'option', label: i+": "+matches.join(", ").replaceAll("\'\'\'",""), value: i});
isEmpty.push(false);
} else {
form.root.childs[6].data.list.push({ type: 'option', label: i+": barren", value: i});
isEmpty.push(true);
}
}
if (isEmpty.slice(1).every(v => v === false)){
form.root.childs[6].data.list.push({ type: 'option', label: " create new slot", value: "[append]"});
}
form.root.childs[8].data.list = createHookObject();
if (nomtext.includes("{{main page image/DYK") && firstLoad){
imgfiles = nomtext.match(/\{\{main page image\/DYK.*?}}/g);
console.log(imgfiles);
optionsbox = [{type: 'option', label: 'nope', value: ""}];
for (file of imgfiles){
file = file.replaceAll(/= /g,"=");
s = file.match(/\|image=.*?(?:\||})/g)[0];
optionsbox.push({ type: 'option', label: s.slice(7,s.length-1), value: file})
}
console.log(optionsbox);
form.append({type: 'div', name: 'label', label: '<b>File: </b>'});
form.append({type: 'radio', name: 'images', list: optionsbox});
}
if (firstLoad){
form.append({type: 'button', name: 'submit', label: 'submit!', event: function l(){evaluate(e, result)}});
}
if (dolastprepmessage){
alert("This appears to be the bottom prep set – per WP:DYKSG#J14, try to leave the image slot, quirky slot, and at least two middle slots open for bumps and replacements!");
}
firstLoad = false;
form.root.childs[4].data.disabled = false; //re-enable button
show();
}
show();
evaluate = function (e, result){
let slotnum = result.hooksinprep.value;
if (slotnum == ""){
alert("Which slot is this hook going in?");
return;
}
let hook = result.nomhooks.value;
if (hook == ""){
alert("You gotta pick a hook!");
return;
}
let imgfile;
if (result.images==undefined){
imgfile="";
} else {
imgfile=result.images.value;
}
if (imgfile==""){ //scrub ''(pictured)'' from hook if no image
hook = hook.replace(/[^']''\(.*?\)''/,"");
}
if (slotnum == 0 && imgfile == ""){
alert("You can't put this in the lead slot unless you've got an image to go along with it!");
return;
}
form.root.childs = [];
form.append({type: 'div', name: 'Promoting hook', label: 'Promoting hook to [['+preppage[0].title+']]... '})
form.append({type: 'div', name: 'Closing nomination', label: 'Closing [['+nompage[0].title+']]... '})
show();
preptext = preptext.split("\n");
if (slotnum == "[append]"){
preptext.splice(preptext.indexOf("<!--HooksEnd-->"),0,hook);
preptext.splice(preptext.lastIndexOf("</div>"),0,getCredits(nomtext));
} else {
preptext[preptext.indexOf("<!--Hooks-->")+parseInt(slotnum)+2] = hook;
isEmpty[slotnum] = "a";
let j=1;
for (i=0; i<isEmpty.length; i++){
if (isEmpty[i]=="a") {break;}
else if (isEmpty[i]) {j++;}
}
let p=0;
while (j>0){
p++;
if (preptext[p].includes("* {{DYKmake|Example|Editor|subpage=}}")) {j--;}
if (preptext[p]=="===Credit templates===") {alert("I couldn't find anywhere to put the credits? Make sure that there are enough empty credit slots for all the empty hook slots."); return null;}
}
preptext[p] = getCredits(nomtext);
if (slotnum==7 && preptext.includes("* {{DYKnom|Example|Nominator}}")){
preptext.splice(preptext.indexOf("* {{DYKnom|Example|Nominator}}"),1);
}
}
if (imgfile != ""){
preptext[preptext.indexOf("<!--Hooks-->")+1]=result.images.value;
}
preptext = preptext.join("\n");
nomtext = nomtext.split("\n");
nomtext[0] = "{{subst:DYKsubpage";
nomtext[2] = "|passed=yes";
nomtext.splice(nomtext.length-1,"To [[" + preppage[0].title + "]]");
nomtext = nomtext.join("\n");
console.log(preppage[0].title,nompage[0].title);
var params = {
action: 'edit',
title: nompage[0].title,
summary: "To [[" + preppage[0].title + "]] ([[User:Theleekycauldron/DYK promoter|PSHAW]])",
text: nomtext,
format: 'json'
}
api.postWithToken( 'csrf', params ).done( function ( data ) {
form.root.childs[1].data.label += 'done! :)';
console.log( data );
show();
location.reload(true);
} );
var params = {
action: 'edit',
title: preppage[0].title,
summary: "Promoting [[" + nompage[0].title + "]] ([[User:Theleekycauldron/DYK promoter|PSHAW]])",
text: preptext,
format: 'json'
}
api.postWithToken( 'csrf', params ).done( function ( data ) {
console.log( data );
form.root.childs[0].data.label += 'done! :)';
console.log(form.root.childs[0]);
show();
} );
}
}
function getCredits(t){
matches = t.match(/\* \{\{DYK(make|nom).*?\}\}/g);
if (matches != null){
return matches.join("\n");
} else {
return "* {{DYKmake|Example|Editor|subpage=}}"
}
}
preptools_handler = async function(e){
preptools(e);
}
// </nowiki>