Jump to content

User:Sohom Datta/PageTriageUserspaceLogger.js

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Sohom Datta (talk | contribs) at 20:37, 7 November 2023. The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
(() => {
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 = `[[:${c.title}]]`;
    if (c.code === 'G10') {
        titleText = `[[:${c.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''': ${p.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 ~~${'~'}~~` +
    `\n#* '''Reason''': ${p.params['1']}`;
}

function getVenue( xfd ) {
    return xfd[0].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[i].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(logActions.xfd[0].venue) !== -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}| 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( 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' ) ) {
                    logActions.csd.push( { tag: tag.tag, params: normalizeParams( tag.params ), code: tag.code, creator: data.creator, title: data.title } );
                } else if ( tag.tag === 'prod' || tag.tag === 'blp-prod' ) {
                    logActions.prod.push( { blp: tag.tag === '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 );
        } );
    } );
} );
})();