Jump to content

User:Sohom Datta/PageTriageUserspaceLogger.js

From Wikipedia, the free encyclopedia
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 = `[[:${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 );
            } );
        } );
    } );
})();