MediaWiki:Gadget-spamBlock.js

// if ( mw.config.get( 'wgCanonicalSpecialPageName' ) === 'Recentchanges'// Recent Changes && ( $.inArray( 'sysop', mw.config.get( 'wgUserGroups' ) ) !== -1// You are a sysop || $.inArray( 'steward', mw.config.get( 'wgUserGroups' ) ) !== -1 )// or a steward ) { function deleteLogEntry( entryID, delLogReason ) { var reasonDelLog = 'Vandalism only account. Removing '; switch ( delLogReason ) { case 'phone' : reasonDelLog += 'possible phone number '; case 'long' : reasonDelLog += 'long page name '; default : reasonDelLog += 'plausible '; }   reasonDelLog += 'RC spam with DeSpammer.'; ( new mw.Api ).postWithToken( 'delete', {     action: 'revisiondelete',      type: 'logging',      ids: entryID,      hide: 'content',      reason: reasonDelLog    } ).done( function( rdResult ) {      console.log( '%o', rdResult );      $( 'a#logID-' + entryID ).text( 'log cleaned' ).removeAttr( 'onclick' ).removeAttr( 'style' ).removeAttr( 'title' );// Might change this later so the onclick takes you to the log entry to review it.    } ); } /* create link */// Create links for each new account to be able to one click deal with obvious spam accounts var Spammer = ''; $( '.mw-changeslist-line-not-watched' ).has( 'a[title="Special:Log/newusers"]' ).find( '.mw-usertoollinks' ).find( 'a[title^="Special:Block/"]' ).each( function( i ) {   Spammer = this.title.substr( this.title.lastIndexOf( '/' ) + 1 );    // Create the link to click to block this account and delete all the contributions    $( this ).after( ' | spam' );  } );

/* process click */// This is what will happen when a link is clicked $( '.spammer-link' ).click( function ( e ) {   e.preventDefault;    /* get spammer */// Who we cleaning up after?    var thisSpammer = $( this ).attr( 'id' ).replace( 'spammer-link-', '' );    /* confirm */// Confirm this because it could be a lot of work to revert the process.    var confirmSpammer = confirm( 'Click OK if you are sure you want to block ' + thisSpammer + ' and delete all of their contributions?' );    if ( confirmSpammer ) {      var despammerStatus = ' DeSpammer is processing account: ' + thisSpammer + ' Click here to reload the page when done. ';      mw.notify( $( despammerStatus ), { tag: 'DeSpammer', title: 'DeSpammer!', autoHide: false } );      /* block */// First step is to block the account to prevent further damage      ( new mw.Api ).postWithToken( 'block', { action: 'block',// Blocks the account user: thisSpammer, expiry: 'infinite',// If set to 'infinite', 'indefinite' or 'never', the block will never expire. nocreate: true,// Prevent account creation autoblock: true,// Automatically block the last used IP address, and any subsequent IP addresses they try to login from //       noemail: true,// Prevent user from sending email through the wiki. reason: 'Vandalism only account. Blocking with DeSpammer.' } ).done( function( bResult ) { console.log( '%o', bResult ); despammerStatus += ' Account #' + bResult.block.userID + ' blocked '; mw.notify( $( despammerStatus ), { tag: 'DeSpammer', title: 'DeSpammer!', autoHide: false } ); } );     /* contribs */// Get all the contributions of a user to be able to rollback or delete as needed.      ( new mw.Api ).get( { action: 'query', list: 'usercontribs',// Get a list of contributions for the user. ucuser: thisSpammer, ucprop: 'ids|title|flags',// Get the pageid and new/top(/minor) flags for the edit. uclimit: 'max'// Get all that you can. } ).done( function( ucResponse ) { $.each( ucResponse.query.usercontribs, function( i ) {         if( this[ 'new' ] !== undefined ) {            /* delete */// This is a new page created by the vandal, just delete it.            ( new mw.Api ).postWithToken( 'delete', { action: 'delete',// Deletes a single page. reason: 'Page created by vandalism only account. Deletion by DeSpammer.', pageid: this.pageid } ).done( function( dResult ) { console.log( '%o', dResult ); despammerStatus += ' ' + dResult[ 'delete' ].title + ' has been deleted.'; if ( /[0-9-+]{3,20}/.test( dResult[ 'delete' ].title ) ) { console.log( '%s has content that matches the formatting of a telephone number.', dResult[ 'delete' ].title ); despammerStatus += ' - delete log '; } else if ( dResult[ 'delete' ].title.length >= 20 ) { console.log( '%s is %d characters long which meets the 20 character threshold.', dResult[ 'delete' ].title, dResult[ 'delete' ].title.length ); despammerStatus += ' - = 20 characters?" style="color: #FF8800;">delete log '; } else { despammerStatus += ' '; }             mw.notify( $( despammerStatus ), { tag: 'DeSpammer', title: 'DeSpammer!', autoHide: false } ); } );         } else if ( this.top !== undefined ) {            /* rollback */// This is an existing page edited by the vandal, roll it back to what it was.            var thisPageId = this.pageid;// because we're nesting Api calls, "this" will change.            var thisTitle = this.title;// because we're nesting Api calls, "this" will change.            ( new mw.Api ).get( {// Won't need to get the token once we get to MW1.24+. action: 'query',// Won't need to get the token once we get to MW1.24+. prop: 'revisions',// Won't need to get the token once we get to MW1.24+. rvtoken: 'rollback',// Won't need to get the token once we get to MW1.24+. titles: thisTitle// Won't need to get the token once we get to MW1.24+. } ).done( function( gotToken ) {// Won't need to get the token once we get to MW1.24+. var thisRollbackToken = gotToken.query.pages[ thisPageId ].revisions[ 0 ].rollbacktoken; ( new mw.Api ).post( {// Use .postWithToken( 'rollback', ... once we get to MW1.24+. action: 'rollback',// Rollback all revisions of this page. summary: 'Page edited by vandalism only account. Rollback by DeSpammer.', token: thisRollbackToken,// Won't need this token once we get to MW1.24+. markbot: true, user: thisSpammer, title: thisTitle } ).done( function( rbResult ) { console.log( '%o', rbResult ); despammerStatus += ' ' + rbResult.rollback.title + ' has been rolledback. ';               mw.notify( $( despammerStatus ), { tag: 'DeSpammer', title: 'DeSpammer!', autoHide: false } ); } );           } );          } else { /* leave alone */// Assume that someone else has edited, reverted, deleted, or otherwise fixed this contribution. }       } );      } );    } else { alert( 'PHEW! That was close!  Please be much more careful where you click next time!!!' ); } } ); } //