Jump to content

User:Sohom Datta/PageTriageUserspaceLogger.js

From Wikipedia, the free encyclopedia
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
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 );
            } );
        } );
    } );
})();