User:Sohom Datta/PageTriageUserspaceLogger.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. |
This user script seems to have a documentation page at User:Sohom Datta/PageTriageUserspaceLogger. |
(() => {
const branding = 'using [[User:Sohom_Datta/PageTriageUserspaceLogger|PTUL]]';
function normalizeParams( params ) {
const keys = Object.keys(params);
let np = {};
for(let i =0; i < keys.length; i++) {
np[ keys[ i ] ] = params[ keys[ i ] ]['value'];
}
return np;
}
// https://github.com/wikimedia-gadgets/twinkle/blob/e6e05d914f8d226dcb670e81677e5530cae84175/modules/twinklespeedy.js#L1519-L1536
function formatCSDParamForLog(normalize, csdparam, input) {
if ((normalize === 'G4' && csdparam === 'xfd') ||
(normalize === 'G6' && csdparam === 'page') ||
(normalize === 'G6' && csdparam === 'fullvotepage') ||
(normalize === 'G6' && csdparam === 'sourcepage') ||
(normalize === 'A2' && csdparam === 'source') ||
(normalize === 'A10' && csdparam === 'article') ||
(normalize === 'F1' && csdparam === 'filename')) {
input = '[[:' + input + ']]';
} else if (normalize === 'G5' && csdparam === 'user') {
input = '[[:User:' + input + ']]';
} else if (normalize === 'G12' && csdparam.lastIndexOf('url', 0) === 0 && input.lastIndexOf('http', 0) === 0) {
input = '[' + input + ' ' + input + ']';
} else if (normalize === 'F8' && csdparam === 'filename') {
input = '[[commons:' + input + ']]';
}
return ' {' + normalize + ' ' + csdparam + ': ' + input + '}';
}
function serializeParams(code, params) {
let additionInfoString = '';
for ( const [key, val] of Object.entries(params) ) {
additionInfoString += formatCSDParamForLog(code, key, val);
}
return additionInfoString;
}
function serializeCSDTags( csd ) {
if ( csd.length === 1 ) {
const c = csd[0];
let titleText = `[[:${c.title}]]`;
if (c.code === 'G10') {
titleText = `[[:${c.title}|Nominated this attack page]]`;
}
return `# ${titleText}: [[WP:CSD#${c.code}|CSD ${c.code}]] ({{tl|${c.tag}}}); ${serializeParams(c.code, c.params)} {{small|via [[mw:Extension:PageTriage|PageTriage]]}} ~~${'~'}~~`;
}
let titleText = `[[:${csd[0].title}]]`;
if (isAttack(csd)) {
titleText = `[[:${csd[0].title}|Nominated this attack page]]`;
}
let csdText = '';
for(let i = 0; i < csd.length; i++) {
csdText += `[[WP:CSD#${csd[i].code}|CSD ${csd[i].code}]] `;
}
let additionInfoString = '';
for(let i = 0; i < csd.length; i++) {
additionInfoString += ` ${serializeParams(csd[i].code, csd[i].params)}`;
}
return `# ${titleText}: ${csdText} ({{tl|db-multiple}}); ${additionInfoString} {{small|via [[mw:Extension:PageTriage|PageTriage]]}} ~~${'~'}~~`;
}
function serializeXFDTags( xfd ) {
if ( xfd.length > 1 ) {
console.error('More than one AFD tag encountered, this is not normal, something is wrong');
throw new Error('too-many-afd-tags');
}
const a = xfd[0];
const venueText = a.venue === 'RfD' ? `at [[WP:${a.venue}|${a.venue}]]` : `[[Wikipedia:Articles for deletion/${a.title}|nominated]] at [[WP:${a.venue}|${a.venue}]]`;
return `# [[:${a.title}]]: ${venueText}; notified {{user|${a.creator}}} {{small|via [[mw:Extension:PageTriage|PageTriage]]}} ~~${'~'}~~` +
`\n#* '''Reason''': ${a.params['1']}`;
}
function serializePRODTags( prod ) {
if ( prod.length > 1 ) {
console.error('More than one prod tag, this is not normal something has gone wrong');
throw new Error('too-many-prod-tags');
}
const p = prod[0];
return `# [[:${p.title}]] ([{{fullurl:Special:Log|page=${p.title}}} log]): ${p.blp ? 'BLP PROD' : 'PROD'} notified {{user|${p.creator}}} {{small|via [[mw:Extension:PageTriage|PageTriage]]}} at ~~${'~'}~~` +
(p.blp ? '' : `\n#* '''Reason''': ${p.params['1']}` );
}
function getVenue( xfd ) {
return (xfd[0] && xfd[0].venue) || 'NOT A VENUE';
}
function isAttack(csd) {
for(let i = 0; i < csd.length; i++) {
if ( csd[i].code === 'G10' ) return true;
}
return false;
}
function isBlp(prod) {
return prod[0].blp;
}
function canLogCSD(csd) {
let canLog = Twinkle.getPref('logSpeedyNominations');
let shouldLog = false;
for(let i = 0; i < csd.length; i++) {
if ( Twinkle.getPref('noLogOnSpeedyNomination').indexOf(csd[i].code.toLowerCase()) !== -1 ) {
shouldLog = shouldLog || false;
} else {
shouldLog = shouldLog || true;
}
}
return canLog && shouldLog;
}
function processLogActions( logActions, title ) {
let allLoggingActions = [];
const allowCSDLogging = canLogCSD(logActions.csd);
if ( logActions.csd.length > 0 && allowCSDLogging) {
const logText = serializeCSDTags(logActions.csd);
const attack = isAttack(logActions.csd);
const usl = new Morebits.userspaceLogger(Twinkle.getPref('speedyLogPageName'));
usl.initialText =
"This is a log of all [[WP:CSD|speedy deletion]] nominations made by this user using [[WP:TW|Twinkle]]'s CSD module.\n\n" +
'If you no longer wish to keep this log, you can turn it off using the [[Wikipedia:Twinkle/Preferences|preferences panel]], and ' +
'nominate this page for speedy deletion under [[WP:CSD#U1|CSD U1]].' +
(Morebits.userIsSysop ? '\n\nThis log does not track outright speedy deletions made using Twinkle.' : '');
const editSummary = `Logging speedy deletion nomination of ${ attack ? `a attack page`: `[[:${title}]]` } ${branding}`;
allLoggingActions.push( usl.log(logText, editSummary) );
}
const allowXfdLogging = !(!Twinkle.getPref('logXfdNominations') || Twinkle.getPref('noLogOnXfdNomination').indexOf(getVenue(logActions.xfd)) !== -1);
if ( logActions.xfd.length > 0 && allowXfdLogging) {
const logText = serializeXFDTags(logActions.xfd);
const usl = new Morebits.userspaceLogger(Twinkle.getPref('xfdLogPageName'));
const venue = getVenue(logActions.xfd);
const subPageText = venue === 'RfD' ? '' : ` at [[Wikipedia:Articles for deletion/${title}]]`;
usl.initialText =
"This is a log of all [[WP:XFD|deletion discussion]] nominations made by this user using [[WP:TW|Twinkle]]'s XfD module.\n\n" +
'If you no longer wish to keep this log, you can turn it off using the [[Wikipedia:Twinkle/Preferences|preferences panel]], and ' +
'nominate this page for speedy deletion under [[WP:CSD#U1|CSD U1]].' +
(Morebits.userIsSysop ? '\n\nThis log does not track XfD-related deletions made using Twinkle.' : '');
allLoggingActions.push( usl.log(logText, `Logging [[WP:${venue}|${venue}]] nomination of [[:${title}]]${subPageText} ${branding}`) );
}
const allowProdLogging = Twinkle.getPref('logProdPages');
if (logActions.prod.length > 0 && allowProdLogging) {
const logText = serializePRODTags(logActions.prod);
const usl = new Morebits.userspaceLogger(Twinkle.getPref('prodLogPageName'));
const blp = isBlp(logActions.prod);
usl.initialText =
"This is a log of all [[WP:PROD|proposed deletion]] tags applied or endorsed by this user using [[WP:TW|Twinkle]]'s PROD module.\n\n" +
'If you no longer wish to keep this log, you can turn it off using the [[Wikipedia:Twinkle/Preferences|preferences panel]], and ' +
'nominate this page for speedy deletion under [[WP:CSD#U1|CSD U1]].';
allLoggingActions.push( usl.log( logText, `Logging ${blp ? 'BLP PROD' : 'PROD'} nomation for [[:${title}]] ${branding}` ) );
}
return $.when.apply($, allLoggingActions );
}
mw.loader.using( [ 'ext.gadget.Twinkle' ] ).then( function () {
mw.hook( 'ext.pageTriage.toolbar.ready' ).add( function ( queue ) {
if ( !window['Morebits'] ) {
console.error('PageTriageUserspaceLogger -- Crucial dependency "morebits" failed to load, aborting any further execution as it might lead to breakages');
return;
}
if ( !window['Twinkle'] ) {
console.error('PageTriageUserspaceLogger -- Crucial dependency "Twinkle" failed to load, aborting any further execution as it might lead to breakages');
return;
}
queue.add( 'delete', function ( data ) {
const { tags } = data;
const keys = Object.keys(tags);
const logActions = { csd: [], prod: [], xfd: [] };
for ( let i = 0; i < keys.length; i++ ) {
const tag = tags[ keys[ i ] ];
if ( tag.tag.startsWith( 'speedy deletion' ) || tag.tag.startsWith( 'db-' ) || tag.tag.startsWith( 'Db-' ) ) {
logActions.csd.push( { tag: tag.tag, params: normalizeParams( tag.params ), code: tag.code, creator: data.creator, title: data.title } );
} else if ( tag.tag === 'subst:prod' || tag.tag === 'subst:blp-prod' ) {
logActions.prod.push( { blp: tag.tag === 'subst:blp-prod', params: normalizeParams( tag.params ), creator: data.creator, title: data.title } );
} else {
let venue = 'AfD';
if ( tag.tag === 'rfd-NPF' ) venue = 'RfD';
logActions.xfd.push( { venue, params: normalizeParams( tag.params ), creator: data.creator, title: data.title } );
}
}
return processLogActions( logActions, data.title );
} );
} );
} );
})();