User:DannyS712/FindBlacklistEntry.js

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
// <nowiki>
// Quick script to find the cause of a spamblacklist on titleblacklist hit
// @author DannyS712
$(() => {
const FindBlacklistEntry = {};
window.FindBlacklistEntry = FindBlacklistEntry;

FindBlacklistEntry.init = function () {
	window.document.title = 'FindBlacklistEntry search';
	$( '#firstHeading' ).text( 'FindBlacklistEntry search' );
	mw.loader.using(
		[ 'mediawiki.api', 'mediawiki.util', 'mediawiki.ForeignApi', 'oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui-windows' ],
		FindBlacklistEntry.run
	);
};

FindBlacklistEntry.run = function () {
	var typeWidget = new OO.ui.RadioSelectInputWidget( {
		// default to spam blacklist
		options: [
			{ data: 'spam', label: 'Spam blacklist' },
			{ data: 'title', label: 'Title blacklist (page creation)' },
			{ data: 'user', label: 'Title blacklist (user creation)' }
		]
	} );
	var typeLayout = new OO.ui.FieldLayout(
		typeWidget,
		{ label: 'Which blacklist to check' }
	);
	var violationWidget = new OO.ui.TextInputWidget( {
		value: mw.util.getParamValue( 'link' ) || mw.util.getParamValue( 'title' ) || mw.util.getParamValue( 'username' )
	} );
	var violationLayout = new OO.ui.FieldLayout(
		violationWidget,
		{ label: 'URL/title/username to check' }
	);
	var submit = new OO.ui.ButtonInputWidget( { 
		label: 'Search',
		flags: [
			'primary',
			'progressive'
		]
	} );
	submit.on( 'click', function () {
		console.log( typeWidget, violationWidget );
		FindBlacklistEntry.onSubmit( typeWidget.value, violationWidget.value );
	} );
	var fieldSet = new OO.ui.FieldsetLayout( { 
		label: 'Search for the cause of a spam blacklist or title blacklist hit'
	} );
	fieldSet.addItems( [
		typeLayout,
		violationLayout,
		new OO.ui.FieldLayout( submit )
	] );

	var $results = $('<div>')
		.attr( 'id', 'FindBlacklistEntry-results' );
	$('#mw-content-text').empty().append(
		fieldSet.$element,
		$( '<hr>' ),
		$results
	);
};

FindBlacklistEntry.violationToCheck = '';
FindBlacklistEntry.violationType = '';
FindBlacklistEntry.causeFound = false;

FindBlacklistEntry.onSubmit = function ( violationType, violationToCheck ) {
	console.log( 'Form submitted with: ' + violationType + ' and ' + violationToCheck );
	// needed later
	FindBlacklistEntry.violationToCheck = violationToCheck;
	FindBlacklistEntry.violationType = violationType;
	FindBlacklistEntry.causeFound = false;
	
	$( '#FindBlacklistEntry-results' ).empty();
	if ( violationType === 'spam' ) {
		new mw.Api().get( {
			action: 'spamblacklist',
			url: violationToCheck,
			formatversion: 2
		} ).done( FindBlacklistEntry.afterSpamQuery );
		return;
	}
	new mw.Api().get( {
		action: 'titleblacklist',
		tbtitle: violationToCheck,
		tbaction: ( violationType === 'title' ? 'createpage' : 'new-account' ),
		tbnooverride: true,
		formatversion: 2
	} ).done( FindBlacklistEntry.afterTitleQuery );
};

FindBlacklistEntry.afterSpamQuery = function ( res ) {
	console.log( res );
	var isBlacklist = res.spamblacklist.result;
	
	var $output = $( '#FindBlacklistEntry-results' );
	$output.append(
		$( '<p>' ).append(
			'Spam blacklist check result: ' + isBlacklist
		)
	);
	
	if ( isBlacklist !== 'blacklisted' ) {
		return;
	}
	
	$output.append(
		$( '<p>' ).text( 'Match: ' + res.spamblacklist.matches ),
		$( '<p>' ).attr( 'id', 'FindBlacklistEntry-wiki' )
			.text( 'Checking wiki: local' ),
		$( '<p>' ).attr( 'id', 'FindBlacklistEntry-causedByLine' )
			.text( 'Caused by: unknown' ),
		$( '<div>' ).attr( 'id', 'FindBlacklistEntry-contents' )
	);
	FindBlacklistEntry.getSpamBlacklistContent( false ).then(
		function ( text ) {
			FindBlacklistEntry.tryBlamingBlacklist( text );
			if ( FindBlacklistEntry.causeFound === false ) {
				// Try again with global spam blacklist
				$( '#FindBlacklistEntry-wiki' ).text( 'Checking wiki: meta' );
				FindBlacklistEntry.getSpamBlacklistContent( true ).then(
					function ( text ) {
						FindBlacklistEntry.tryBlamingBlacklist( text );
					}
				);
			}
		}
	);
};

FindBlacklistEntry.afterTitleQuery = function ( res ) {
	console.log( res );
	var isBlacklist = res.titleblacklist.result;
	
	var $output = $( '#FindBlacklistEntry-results' );
	$output.append(
		$( '<p>' ).append(
			'Title blacklist check result: ' + isBlacklist
		)
	);
	
	if ( isBlacklist !== 'blacklisted' ) {
		return;
	}

	var matchline = res.titleblacklist.line;
	matchline = matchline.replace( /&lt;/g, '<' )
		.replace( /&gt;/g, '>' );
	$output.append(
		$( '<p>' ).text( 'Line:' ),
		$( '<pre>' ).text( matchline ),
		$( '<p>' ).attr( 'id', 'FindBlacklistEntry-wiki' )
			.text( 'Checking which blacklist (local / global) caused this...' )
	);
	new mw.Api().get( {
		action: 'query',
		titles: [ 'MediaWiki:Titleblacklist' ],
		prop: 'revisions',
		rvprop: 'content',
		rvslots: 'main',
		formatversion: 2
	} ).then(
		function ( response ) {
			console.log( response );
			var text = response.query.pages[0].revisions[0].slots.main.content;
			var onLocal = ( text.indexOf( matchline ) !== -1 );
			var causedByTitle = onLocal ? 'MediaWiki:Titleblacklist' : 'm:Title blacklist';
			var causedBy = onLocal ? 'local' : 'global';
			$( '#FindBlacklistEntry-wiki' ).empty().append(
				'Caused by the ' + causedBy + ' blacklist: ',
				$( '<a>' )
					.attr( 'href', '/wiki/' + causedByTitle )
					.attr( 'target', '_blank' )
					.text( causedByTitle )
			);
		},
		FindBlacklistEntry.onErrHandler
	);
};

FindBlacklistEntry.tryBlamingBlacklist = function ( text ) {
	var filtered = FindBlacklistEntry.cleanupText( text );
	$( '#FindBlacklistEntry-contents' ).empty().append(
		$( '<p>' ).append( 'Blacklist content:' ),
		$( '<pre>' ).text( text ),
		$( '<p>' ).append( 'Filtered lines:' ),
		$( '<pre>' ).text( filtered )
	);
	FindBlacklistEntry.blameAnEntry( filtered );
};

FindBlacklistEntry.onErrHandler = function () {
	// Shared error handler
	alert( 'Something went wrong' );
	console.log( arguments );
};

FindBlacklistEntry.getSpamBlacklistContent = function ( global ) {
	return new Promise( function ( resolve ) {
		var api = global ? new mw.ForeignApi( '//meta.wikimedia.org/w/api.php' ) : new mw.Api();
		var title = global ? 'Spam blacklist' : 'MediaWiki:Spam-blacklist';
		
		api.get( {
			action: 'query',
			titles: [ title ],
			prop: 'revisions',
			rvprop: 'content',
			rvslots: 'main',
			formatversion: 2
		} ).then(
			function ( response ) {
				console.log( response );
				var text = response.query.pages[0].revisions[0].slots.main.content;
				resolve( text );
			},
			FindBlacklistEntry.onErrHandler
		);
	} );
};

FindBlacklistEntry.cleanupText = function ( originalText ) {
	var lines = originalText.split( '\n' );
	var finalLines = [];
	lines.forEach( function ( line ) {
		console.log( line );
		if ( !line.match( /^\s*#/ ) && !line.match( /^\s*$/ ) ) {
			line = line.replace( /\s*#.*/, '' );
			finalLines.push( line );
		}
	} );
	return finalLines.join( '\n' );
};

FindBlacklistEntry.blameAnEntry = function ( entriesText ) {
	var lines = entriesText.split( '\n' );
	var line;
	for ( var iii = 0; iii < lines.length; iii++ ) {
		// Use for loop so we can return early
		line = lines[iii];
		var reg = new RegExp( line, 'i' );
		if ( FindBlacklistEntry.violationToCheck.match( reg ) ) {
			$( '#FindBlacklistEntry-causedByLine' ).text(
				'Caused by: ' + line
			);
			console.log( 'Caused by: ', line );
			FindBlacklistEntry.causeFound = true;
			return;
		}
	}
};

});

$(document).ready(() => {
	mw.loader.using(
		[ 'mediawiki.util' ],
		function () {
			mw.util.addPortletLink(
				'p-tb',
				'/wiki/Special:BlankPage/FindBlacklistEntry',
				'FindBlacklistEntry'
			);
		}
	);
	if ( mw.config.get( 'wgNamespaceNumber' ) === -1 ) {
		const page = mw.config.get( 'wgCanonicalSpecialPageName' );
		if ( page === 'Blankpage' ) {
			const page2 = mw.config.get( 'wgTitle' ).split( '/' );
			if ( page2[1] && page2[1] === 'FindBlacklistEntry' ) {
				window.FindBlacklistEntry.init();
			}
		}
	}
});
// </nowiki>