Jump to content

User:Novem Linguae/Scripts/DetectG4G5.js

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Novem Linguae (talk | contribs) at 09:42, 15 December 2021 (remove console.log). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
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.
// <nowiki>

/*
- Displays an alert if an article may be a CSD G4 (previous AFD) or CSD G5 (created by a sockpuppet)
- Useful for new page patrolling
- Only runs on pages that have not been marked as reviewed
*/

// TODO: Code review. Is there a way to reduce the # of API queries?

$(async function() {
	async function getWikicode(title) {
		if ( ! mw.config.get('wgCurRevisionId') ) return ''; // if page is deleted, return blank
		var wikicode = '';
		title = encodeURIComponent(title);
		await $.ajax({
			url: 'https://en.wikipedia.org/w/api.php?action=parse&page='+title+'&prop=wikitext&formatversion=2&format=json',
			success: function (result) {
				wikicode = result['parse']['wikitext'];
			},
			dataType: "json",
			async: false
		});
		return wikicode;
	}

	async function hasAFDTemplate(title) {
		let wikicode = await getWikicode(title);
		return wikicode.indexOf('{{Article for deletion') !== -1;
	}

	function displayWarning(html) {
		$('#contentSub').before(`<div class="DetectG4G5" style="background-color: red">${html}</div>`);
	}

	async function isReviewed(title) {
		let api = new mw.Api();
		let response = await api.get( {
			action: 'query',
			format: 'json',
			list: 'logevents',
			letype: 'pagetriage-curation',
			letitle: title,
		} );
		let isReviewed = typeof response.query.logevents[0] !== 'undefined' && response.query.logevents[0].action === 'reviewed';
		return isReviewed;
	}

	async function afdExists(title) {
		title = 'Wikipedia:Articles_for_deletion/' + title;
		return await pageExists(title);
	}

	async function pageExists(title) {
		let api = new mw.Api();
		let response = await api.get( {
			action: 'query',
			format: 'json',
			prop: 'revisions',
			titles: title,
		} );
		let exists = typeof response.query.pages['-1'] === 'undefined';
		return exists;
	}

	async function isBlocked(username) {
		let api = new mw.Api();
		let response = await api.get( {
			action: "query",
			format: "json",
			list: "users",
			usprop: "blockinfo",
			ususers: username,
		} );
		let isBlocked = typeof response.query.users[0].blockid !== 'undefined';
		return isBlocked;
	}

	async function isGloballyLocked(username) {
		let api = new mw.Api();
		let response = await api.get( {
			action: 'query',
			list: 'globalallusers',
			agulimit: '1',
			agufrom: username,
			aguto: username,
			aguprop: 'lockinfo',
		} );
		let isLocked = response.query.globalallusers.length !== 0 && response.query.globalallusers[0].locked === '';
		return isLocked;
	}

	function getFirstValueInObject(obj) {
		return obj[Object.keys(obj)[0]];
	}

	async function getPageInfo(title) {
		let api = new mw.Api();
		let response = await api.get( {
			"action": "query",
			"format": "json",
			"prop": "revisions",
			"titles": title,
			"rvlimit": "1",
			"rvdir": "newer"
		} );
		return response;
	}
	
	// don't run when not viewing articles
	let action = mw.config.get('wgAction');
	if ( action != 'view' ) return;
	
	// don't run when viewing diffs
	let isDiff = mw.config.get('wgDiffNewId');
	if ( isDiff ) return;
	
	let isDeletedPage = ( ! mw.config.get('wgCurRevisionId') );
	if ( isDeletedPage ) return;
	
	// Only run in mainspace
	let namespace = mw.config.get('wgNamespaceNumber');
	let title = mw.config.get('wgPageName'); // includes namespace, underscores instead of spaces
	if ( namespace !== 0 && title != 'User:Novem_Linguae/sandbox' ) return;
	
	// Get two pieces of info (pageCreator and pageCreationDate) in one API query
	let pageInfo = await getPageInfo(title);
	let page = getFirstValueInObject(pageInfo.query.pages);
	let pageCreator = page.revisions[0].user;

	// figure out if page is overOneYearOld
	let pageCreationDate = page.revisions[0].timestamp; // Example format: 2021-12-15T04:55:55Z
	pageCreationDate = new Date(pageCreationDate);
	let today = new Date();
	let overOneYearOld = (today - pageCreationDate) / (1000 * 3600 * 24 * 365) > 1;

	// PageCuration deletes log entries of reviews after 1 year. So we need to check and make sure the article isn't over 1 year old. If it is, assume it is marked as reviewed.
	if ( await isReviewed(title) || overOneYearOld ) {
		return;
	}

	if ( await afdExists(title) && ! await hasAFDTemplate(title) ) {
		displayWarning('<span style="font-weight:bold">CSD G4:</span> There is an AFD page for this article. It may qualify for CSD G4.');
	}

	if ( await isBlocked(pageCreator) ) {
		displayWarning('<span style="font-weight:bold">CSD G5:</span> The creator of this page is blocked. This article may qualify for CSD G5.');
	}

	if ( await isGloballyLocked(pageCreator) ) {
		displayWarning('<span style="font-weight:bold">CSD G5:</span> The creator of this page is globally locked. This article may qualify for CSD G5.');
	}
});

// </nowiki>