User:Terasail/ArticleInfo.js

From Wikipedia, the free encyclopedia
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>
	Article Info
	Created by: Terasail
*/
// jshint esnext: false, esversion: 8
var api = new mw.Api();
if (mw.config.get("skin").split("-")[0] == "vector") { //If skin is 'vector' or 'vector-2022'
	mw.loader.load('https://en.wikipedia.org/w/index.php?title=User:Terasail/ArticleInfo.css&action=raw&ctype=text/css', 'text/css');
	let wgUsername = mw.config.get("wgRelevantUserName");
	$.when(mw.loader.using('mediawiki.util'), $.ready).then(function () {
		if (wgUsername != null) {
			userInfo(wgUsername);
		}
		let wgAction = mw.config.get("wgAction");
		let wgArticleId = mw.config.get("wgRelevantArticleId");
		if (wgArticleId !== 0 && (wgAction === "view" || wgAction === "edit")) {
			pageInfo(wgArticleId);
		}
	});
}

async function userInfo(username) {
	let userGroups = {
		accountcreator: ["AC", "Account creator"],
		abusefilter: ["EFM", "Edit filter manager"],
		"abusefilter-helper": ["EFH", "Edit filter helper"],
		autopatrolled: ["AP", "Autopatrolled"],
		autoreviewer: ["AP", "Autopatrolled"],
		bot: ["BOT", "BOT"],
		bureaucrat: ["B", "Bureaucrat"],
		centralnoticeadmin: ["CNA", "Central notice administrator"],
		checkuser: ["CU", "Checkuser"],
		confirmed: ["C", "Confirmed"],
		eventcoordinator: ["EvCo", "Event coordinator"],
		extendedconfirmed: ["EC", "Extended confirmed"],
		extendedmover: ["PM", "Page mover"],
		filemover: ["FM", "File mover"],
		flood: ["Fl", "Flooder"],
		founder: ["Founder", "Founder"],
		"functioneer": ["F", "Functioneer"],
		"functionmaintainer": ["M", "Maintainer"],
		"global-renamer": ["GR", "Global renamer"],
		gwtoolset: ["GWT", ""],
		"image-reviewer": ["IR", "Image reviewer"],
		"import": ["IM", "Importer"],
		"interface-admin": ["IA", "Interface administrator"],
		"ipblock-exempt": ["IPBE", "IP block exempt"],
		"machinevision-tester": ["MVT", "Machine vision tester"],
		"massmessage-sender": ["MMS", "Mass message sender"],
		oauthadmin: ["OAA", "OAuth administrator"],
		patroller: ["P", "Patroller"],
		propertycreator: ["PC", "Property creator"],
		reviewer: ["PCR", "Pending changes reviewer"],
		rollbacker: ["R", "Rollbacker"],
		steward: ["S", "Steward"],
		suppress: ["O", "Oversighter"],
		sysop: ["A", "Administrator"],
		templateeditor: ["TE", "Template editor"],
		translationadmin: ["TA", "Translation administrator"],
		transwiki: ["TW", ""],
		uploader: ["U", "Uploader"],
		upwizcampeditors: ["UWC", ""],
		"wikifunctions-staff": ["WFS", "Wikifunctions Staff"],
	};
	let links = [$('#t-contributions'), $('#t-log')];
	mw.util.addPortlet('p-uinfo', 'User information', '#p-tb');
	mw.util.addPortletLink(
		'p-uinfo',
		"https://xtools.wmflabs.org/ec/" + mw.config.get("wgServerName") + "/" + username,
		'User xTools',
		't-uxtools',
		'Open xTools user information', '', ''
	);
	if ($('#t-userrights').length > 0) { //If a registered user
		mw.util.addPortletLink(
			'p-uinfo',
			"/wiki/Special:CentralAuth/" + username,
			'Global account',
			't-cauth',
			'View global account information', '', '#t-uxtools'
		);
		links.push($('#t-userrights'));
		//Add user info to the top of the page
		let userData = await aiApiGet({
			action: "query",
			list: "users",
			ususers: username,
			usprop: "editcount|groups|implicitgroups",
			format: "json"
		});
		userData = userData.query.users[0];
		let ubar = mw.util.addPortlet('p-ubar');
		$('#firstHeading').append(ubar);
		mw.util.addPortletLink(
			'p-ubar',
			"/wiki/Special:Contributions/" + username,
			'Edits: ' + addCommas(userData.editcount),
			't-uedits',
			'Special:Contributions', '', ''
		);
		let groups = userData.groups;
		groups = groups.slice(0, 0 - userData.implicitgroups.length);
		for (let i = 0; i < groups.length; i++) {
			let temp = userGroups[groups[i]];
			if (temp != undefined) {
				groups[i] = temp[0];
				// groups[i] = '<abbr title="' + temp[1] + '">' + temp[0] + '</abbr>';
			}
		}
		if (groups.length > 0) {
			mw.util.addPortletLink(
				'p-ubar',
				"/wiki/Special:UserRights/" + username,
				'Groups: ' + groups.toString().replaceAll(",", ", "),
				't-ugroups',
				'Special:UserRights', '', ''
			);
		}
	}
	$('#p-uinfo ul').append(links);
}

async function pageInfo(articleId) {
	let pXTools = mw.util.addPortletLink(
		'p-cactions',
		'https://xtools.wmflabs.org/articleinfo/' + mw.config.get("wgServerName") + '/' + encodeURIComponent(mw.config.get("wgRelevantPageName")),
		'Page xTools',
		't-pxtools',
		'Open xTools page information', '', ''
	);
	pXTools.children[0].target = "_blank";
	let editLocks = {
		move: ["4/44/Move-protection-shackle"],
		upload: ["d/d7/Upload-protection-shackle"],
		cascade: ["0/0f/Cascade-protection-shackle"],
		sysop: ["1/12/Full-protection-shackle-block", "c"],
		templateeditor: ["5/53/Template-protection-shackle"],
		extendedconfirmed: ["8/8c/Extended-protection-shackle"],
		autoconfirmed: ["1/1b/Semi-protection-shackle"]
	};
	let pbar = mw.util.addPortlet('p-pbar');
	$('#bodyContent').prepend(pbar);

	let pageBar = ["revs", "editors", "views", "watch", "created"];//"icons", 
	for (let a = 0; a < pageBar.length; a++) {
		mw.util.addPortletLink('p-pbar', '', '', 't-' + pageBar[a], '', '', '');
		$('#t-' + pageBar[a])[0].style = "display:none";
		$('#t-' + pageBar[a]).append($('#t-' + pageBar[a] + ' span'));
		$('#t-' + pageBar[a] + ' a').remove();
	}
	getPageviews(articleId); //Separate - Can throw errors on new pages
	//Separate - Speed up load: no need to wait on loading other requests
	getPageCounts();
	getAssessment(articleId); 

	let pageQuery = await aiApiGet({
		action: "query",
		prop: "info|revisions",
		pageids: articleId,
		inprop: "protection|watchers",
		rvprop: "timestamp|user",
		rvlimit: "1",
		rvdir: "newer",
		format: "json"
	});
	let pageInfo = pageQuery.query.pages[articleId];
	//Watchers
	if (pageInfo.watchers != null) {
		$('#t-watch span').append(addCommas(pageInfo.watchers) + ' <abbr title="Users with this page on their watchlist">Watchers</abbr>');
		$('#t-watch')[0].style = "";
	}
	//Page Protection
	let protections = pageInfo.protection;
	if (protections.length > 0) {
		let elemBefore = "#t-revs";
		if (document.getElementById('t-pasmt')) {
			elemBefore = "#t-pasmt";
		}
		let pProt = mw.util.addPortletLink(
			'p-pbar',
			mw.util.getUrl('Special:Log', {type: 'protect', page: mw.config.get('wgRelevantPageName')}),
			'',
			't-pprot',
			'Open page protection log', '', elemBefore
		);
		pProt.children[0].target = "_blank";
		$('#t-pprot span')[0].remove();
	}
	let cascade = false;
	for (let i = 0; i < protections.length; i++) {
		if (protections[i].source) {
			if (!cascade) {
				cascade = true;
				$('#t-pprot a').append(createImg(editLocks.cascade));
			}
		} else {
			if (protections[i].type == "edit") {
				$('#t-pprot a').append(createImg(editLocks[protections[i].level]));
			} else {
				$('#t-pprot a').append(createImg(editLocks[protections[i].type]));
			}
		}
	}
	//First page revision
	let pageRev = pageQuery.query.pages[articleId].revisions[0];
	let userQuery = await aiApiGet({
		action: "query",
		list: "users",
		ususers: pageRev.user,
		usprop: "editcount|groups|implicitgroups",
		format: "json"
	});
	userQuery = userQuery.query.users[0];
	let created = 'Created ' + new Date(pageRev.timestamp).toUTCString().slice(5, 16) + ', by ';
	created += '<a target="_blank" href="/wiki/User:' + pageRev.user + '">' + pageRev.user + '</a>';
	if (typeof (userQuery.editcount) !== "undefined" && typeof (userQuery.groups) !== "undefined") {
		created += ' (' + addCommas(userQuery.editcount) + " edits";
		let numRights = userQuery.groups.length - userQuery.implicitgroups.length;
		if (numRights > 0) {
			created += " | " + numRights + " group";
			if (numRights > 1) {
				created += "s";
			}
		}
		created += ")";
	}
	$('#t-created span').append(created);
	$('#t-created')[0].style = "";
}

async function getAssessment(articleId) {
	let assessments = {
		NA: ["6/6a/Symbol_na_class"],
		Draft: ["0/09/Symbol_draft_class"],
		Template: ["5/5c/Symbol_template_class"],
		Redirect: ["a/a2/Symbol_redirect_class", "c"],
		Project: ["7/72/Symbol_project_class"],
		Portal: ["e/e2/Symbol_portal_class"],
		File: ["9/9c/Symbol_file_class"],
		Disambig: ["2/2a/Symbol_dab_class", "c"],
		Category: ["9/96/Symbol_category_class"],
		List: ["d/db/Symbol_list_class"],
		Stub: ["f/f5/Symbol_stub_class"],
		Start: ["a/a4/Symbol_start_class"],
		C: ["e/e6/Symbol_c_class"],
		B: ["5/5f/Symbol_b_class"],
		A: ["2/25/Symbol_a_class", "c"],
		GA: ["9/94/Symbol_support_vote"],
		FM: ["b/bc/Featured_article_star", "c"],
		FL: ["b/bc/Featured_article_star", "c"],
		FA: ["b/bc/Featured_article_star", "c"],
		"": ["e/e0/Symbol_question"]
	};
	if (mw.config.get("wgServerName") == "en.wikipedia.org" && mw.config.get("wgCanonicalNamespace") == "") {
		pageQuery = await aiApiGet({
			action: "query",
			prop: "pageassessments",
			pageids: articleId,
			palimit: "1",
			format: "json"
		});
		let assessment = pageQuery.query.pages[articleId].pageassessments;
		if (assessment != null) {
			mw.util.addPortletLink('p-pbar', '', '', 't-pasmt','', '', '#t-revs');
			$('#t-pasmt a')[0].remove();
			$('#t-pasmt').append(createImg(assessments[Object.entries(assessment)[0][1].class]));
		}
	}
}

async function getPageviews(articleId) {
	let pageQuery = await aiApiGet({
		action: "query",
		prop: "pageviews",
		pageids: articleId,
		pvipdays: "30",
		format: "json"
	});
	let rawViews = Object.entries(pageQuery.query.pages[articleId].pageviews);
	let totalViews = 0;
	for (let i = 0; i < rawViews.length; i++) {
		if (typeof rawViews[i][1] == "number") {
			totalViews += rawViews[i][1];
		}
	}
	$('#t-views span').append(addCommas(totalViews) + ' <abbr title="Pageviews in the last 30 days">Pageviews</abbr>');
	$('#t-views')[0].style = "";
}

async function getPageCounts() {
	let fetchTarget = "https://" + mw.config.get("wgServerName") + "/w/rest.php/v1/page/" + encodeURIComponent(mw.config.get("wgRelevantPageName")) + "/history/counts/";
	let counts = [["edits", "Revision", "revs"], ["editors", "Editor", "editors"]];
	for (let j = 0; j < counts.length; j++) {
		let fetchResult = await fetch(fetchTarget + counts[j][0] + "?");
		fetchResult = await fetchResult.json();
		fetchResult = addCommas(fetchResult.count) + " " + counts[j][1];
		fetchResult = fetchResult.replace(/(?<=^30),000/, "k+").replace(/(?!^1 \w+)$/, "s");
		$('#t-' + counts[j][2] + ' span').append(fetchResult);
		$('#t-' + counts[j][2])[0].style = "";
	}
}

function aiApiGet(params) {
	return new Promise(function(resolve) {api.get(params)
		.done(function (data) {resolve(data);})
		.fail(function (data) {console.error(data);});
	});
}

function addCommas(number) {
	if (typeof(number) == "number") {
		return number.toLocaleString('en-US');
	}
	return number;
}

function createImg(data) {
	if (data.length === 1) {
		data[1] = "en";
	} else if (data[1] === "c") {
		data[1] = "commons";
	}
	let imageStr = '<img src="//upload.wikimedia.org/wikipedia/' + data[1] + '/thumb/';
	imageStr += data[0] + ".svg/25px-" + data[0].slice(5);
	imageStr += '.svg.png" decoding="async" width="18" height="18"></a>';
	return imageStr;
}
//</nowiki>[[Category:Wikipedia scripts]]