MediaWiki:Gadget-spamBlock.js/sandbox.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 hideType = 'content|comment|user'; var reasonDelLog = 'Vandalism only account. Removing '; switch ( delLogReason ) { case 'phone' : hideType = 'content'; reasonDelLog += 'possible phone number'; break; case 'long' : hideType = 'content'; reasonDelLog += 'long page name'; break; case 'ucl': hideType = 'user'; reasonDelLog += 'User Creation log'; break; default : reasonDelLog += 'plausible'; }   reasonDelLog += ' RC spam with DeSpammer.'; ( new mw.Api ).postWithToken( 'delete', {     action: 'revisiondelete',      type: 'logging',      ids: entryID,      hide: hideType,      reason: reasonDelLog    } ).done( function( rdResult ) {      console.log( '%o', rdResult );      if( delLogReason == 'phone' || delLogReason == 'long' ) {        $( 'a#logID-' + entryID )//  Might change           .text( 'log cleaned' )//   this later so          .removeAttr( 'onclick' )// the onclick takes          .removeAttr( 'style' )//   you to the log          .removeAttr( 'title' );//  entry to review it.      } else if( delLogReason == 'ucl' ) {        despammerStatus += ' User Creation log ID#' +          thisLogData[ i ].logid + ' hidden. ';     } else { /* stuff */ }     mw.notify( $( despammerStatus ), { tag: 'DeSpammer', title: 'DeSpammer!', autoHide: false } ); } ).fail( function( rdFailed ) { console.error( '%o', rdFailed ); if( delLogReason == 'phone' || delLogReason == 'long' ) { /* stuff */ } else if( delLogReason == 'ucl' ) { despammerStatus += ' Failed to hide User Creation log ID#' + thisLogData[ i ].logid + '. ';                 } else { /* stuff */ }     mw.notify( $( despammerStatus ), { tag: 'DeSpammer', title: 'DeSpammer!', autoHide: false } ); } ); }  /* 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 } ); } );     /* user creation log */      ( new mw.Api ).get( { action: 'query', list: 'logevents',// Get a list of log events for the user. letype: 'newusers', // Only get the user creation log // May not work if bot created multiple accounts. leuser: thisSpammer, } ).done( function( leResponse ) { console.log( '%o', leResponse ); if( leResponse.query && leResponse.query.logevents ) { var thisLogData = leResponse.query.logevents; $.each( thisLogData, function( i ) {           var thisUser = thisLogData[ i ].title.replace( 'User:', '' );            if( thisLogData[ i ].user == thisUser ) {              var userCreationDeleted = deleteLogEntry( thisLogData[ i ].logid, 'ucl' );            }          } ); }     } );      /* 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 += ' ' + this.pageid + ' 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!!!' ); } } ); } //