User:NguoiDungKhongDinhDanh/Gadget-markAdmins-data.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.
// Script that outputs an object similar to that of [[MediaWiki:Gadget-markAdmins-data.json]] ([[Special:Permalink/23110607]]).
// It is not supposed to work on its own and may be incompatible with your browser. Do not install.
// jshint esversion: 10

$(function() {
	'use strict';
	
	var MA = {};
	window.MA = MA;
	
	MA.d = {}; // Main object.
	
	MA.t = ['Regular admins', 'Temporary sysop', 'Global sysops who aren\'t local sysop', 'Interface Admin', 'Admin - Int-Admin by WMF decree',
			'WMF OIT', 'WMF T&S', 'Stewards who aren\'t local sysop', 'Ombuds commission members who aren\'t local sysop']; // Types of labels.
	for (let i of MA.t) { // Initialize objects.
		MA.d[i] = {};
	}
	
	MA.lg = ['bureaucrat', 'checkuser', 'interface-admin', 'steward', 'suppress', 'sysop', 'wmf-officeit', 'wmf-supportsafety']; // Local groups.
	MA.gg = ['global-sysop', 'ombuds', 'steward']; // Global groups.
	
	MA.al = ['bureaucrat', 'checkuser', 'int_admin', 'steward', 'oversight', 'sysop', 'wmfoit', 'wmftrusa']; // Aliases used in original page.
	MA.ag = ['global_sysop', 'ombudsman', 'steward']; // Idem.
	MA.la = ['Capucine-Marin Dubroca-Voisin', 'Lustiger seth']; // Limited admins. Can't find a workaround.
	
	(new mw.Api()).get({
		action: 'query',
		list: ['allusers', 'globalallusers'], // This results in two lists so our work gets harder, but after all these loops, who cares, really?
		augroup: MA.lg,
		auprop: ['groups', 'editcount'],
		aulimit: 500, // Max limit. Let's just hope that Meta won't have more than 500 users with these privileges in forseeable future.
		// auwitheditsonly: true, // <del>No, abuse filter, stay away from me.</del> This also cause AOtto (WMF) to disappear from the list.
		agugroup: MA.gg,
		aguprop: 'groups',
		agulimit: 500, // Idem. 500 GS/OB/S...
		format: 'json',
		formatversion: 2
	}).done(function(response) {
		MA.au = response.query.allusers;
		MA.gu = response.query.globalallusers;
		
		// WARNING: Things under this line may not be readable to you. Please make sure that your brain is ready.
		// Here we go...
		
		// Function declarations.
		MA.n = function(i, j, b) { // Find alias for given group.
			return MA['a' + (b ? 'g' : 'l')][MA[(b ? 'g' : 'l') + 'g'].indexOf(MA[(b ? 'g' : 'a') + 'u'][i].groups[j])];
		};
		MA.c = function(a, b, n) { // Check for non-null subset of two given arrays or if element n is in their subset.
			for (let i in a) {
				for (let j in b) {
					if (typeof n === 'undefined') {
						if (a[i] === b[j]) {
							return true;
						}
					} else {
						if (a[i].name === n.name && n.name === b[j].name) {
							return true;
						}
					}
				}
			}
			return false;
		};
		MA.s = function(a) {
			var q = ['sysop', 'interface-admin', 'bureaucrat', 'checkuser', 'suppress', 'wmf-officeit', 'wmf-supportsafety', 'global-sysop', 'ombuds', 'steward'];
			var l = []; // The array above is used to provide the order we want. This one is for labels.
			var r = [];
			
			for (let b of [0, 1]) { // Iterate array "q" twice.
				for (let i in q) { // As explained above, 
					if (b) { // Second, go through array "a"'s element(s) and add one by one to array "r" which will be returned.
						for (let j in a) {
							if (l[i] === a[j]) r.push(a[j]);
						}
					} else { // First, add labels of (global|local) groups to array "l" in order provided by "q".
						l.push(MA.al[MA.lg.indexOf(q[i])] || MA.ag[MA.gg.indexOf(q[i])]);
					}
				}
			}
			
			return r;
		};
		
		// For loops and conditions
		for (let i in MA.au) { // Iterate allusers.
			if ((MA.au[i].editcount === 0 || MA.au[i].groups.includes('bot')) && !MA.au[i].name.includes('WMF')) {
				continue; // Workaround since auwitheditsonly cannot be used due to false positive(s).
			} else if (MA.au[i].groups.includes(MA.lg[5]) && !MA.la.includes(MA.au[i].name) && !MA.au[i].name.includes('WMF')) { // Non-WMF sysop and not limited.
				MA.d[MA.t[0]][MA.au[i].name] = []; // Initialize array.
				for (let j in MA.au[i].groups) { // Iterate their groups
					if (MA.lg.includes(MA.au[i].groups[j])) { // Group defined in MA.lg.
						MA.d[MA.t[0]][MA.au[i].name].push(MA.n(i, j, false)); // Add it to data.regularadmin.username array.
					} else if (MA.au[i].groups[j] === MA.lg[2] && !MA.au[i].groups.includes(MA.lg[5])) { // Else, if group = int admin and user is not sysop.
						if (MA.d[MA.t[2]][MA.au[i].name] === undefined) // Initialize an array in "Interface admin" if there isn't one yet.
							MA.d[MA.t[2]][MA.au[i].name] = [];
						MA.d[MA.t[2]][MA.au[i].name].push(MA.n(i, j, false)); // Add group to that array.
					}
				}
				for (let k in MA.gu) { // Iterate globalallusers.
					if (MA.gu[k].name === MA.au[i].name) { // Found user.
						for (let l in MA.gu[k].groups) { // Iterate their global groups. Check if there are any identical one (primarily for S).
							if (MA.gg.includes(MA.gu[k].groups[l]) && !MA.d[MA.t[0]][MA.au[i].name].includes(MA.n(k, l, true))) {
								MA.d[MA.t[0]][MA.au[i].name].push(MA.n(k, l, true)); // Add it to array.
							}
						}
						break; // Already found them, no need to search further.
					}
				}
			} else if (MA.au[i].name.includes('WMF') && MA.c(MA.au[i].groups, [MA.lg[2], MA.lg[5]])) { // WMF sysop/int admin.
				if (MA.d[MA.t[4]][MA.au[i].name] === undefined) // If no array was specified,
					MA.d[MA.t[4]][MA.au[i].name] = []; // Initialize one.
				for (let j in MA.au[i].groups) { // Iterate their groups.
					if ([MA.lg[2], MA.lg[5], MA.lg[7], MA.lg[8]].includes(MA.au[i].groups[j])) { // Find sysop/int admin/wmf oit/wmf t&s.
						MA.d[MA.t[4]][MA.au[i].name].push(MA.n(i, j, false)); // Add group to array.
					}
				}
			} else if (MA.la.includes(MA.au[i].name)) { // Limited admins
				if (MA.d[MA.t[1]][MA.au[i].name] === undefined) // Initialize an array if there isn't one yet.
					MA.d[MA.t[1]][MA.au[i].name] = [];
				for (let j in MA.au[i].groups) { // Iterate their groups
					if ([MA.lg[2], MA.lg[5]].includes(MA.au[i].groups[j])) { // Limited admins cannot also be B/C/O/S/WMF. WMF ones are normally not limited.
						MA.d[MA.t[1]][MA.au[i].name].push(MA.n(i, j, false)); // Add group to array.
					}
				}
				for (let k in MA.gu) { // Iterate globalallusers.
					if (MA.gu[k].name === MA.au[i].name) { // Found user.
						for (let l in MA.gu[k].groups) { // Iterate their global groups and check for identical ones.
							if (MA.gg.includes(MA.gu[k].groups[l]) && !MA.d[MA.t[0]][MA.au[i].name].includes(MA.n(k, l, true))) {
								MA.d[MA.t[0]][MA.au[i].name].push(MA.n(k, l, true)); // Add group to array.
							}
						}
						break; // Found them, stop.
					}
				}
			} else if (MA.au[i].groups.includes(MA.lg[2]) && !MA.au[i].groups.includes(MA.lg[5])) { // Non-sysop int admins.
				if (MA.d[MA.t[3]][MA.au[i].name] === undefined) // Initialize array.
					MA.d[MA.t[3]][MA.au[i].name] = [];
				MA.d[MA.t[3]][MA.au[i].name].push(MA.al[2]); // Non-sysop int admins cannot also be B/C/O/WMF. GS/OM/S will be handled below.
				for (let k in MA.gu) { // Iterate globalallusers.
					if (MA.gu[k].name === MA.au[i].name) { // Found user.
						for (let l in MA.gu[k].groups) { // Iterate their global groups.
							if (MA.gg.includes(MA.gu[k].groups[l])) { // Only add GS/OM/S.
								MA.d[MA.t[0]][MA.au[i].name].push(MA.n(k, l, true));
							}
						}
						break; // Stop.
					}
				}
			} else if (MA.c(MA.au[i].groups, [MA.lg[6], MA.lg[7]])) { // WMF OIT/WMF T&S. I'm not sure where will a user be added if they have both.
				for (let j in MA.au[i].groups) { // Iterate their groups.
					if (MA.au[i].groups[j] === MA.lg[6]) { // WMF OIT.
						if (MA.d[MA.t[5]][MA.au[i].name] === undefined) // Initialize array.
							MA.d[MA.t[5]][MA.au[i].name] = [];
						MA.d[MA.t[5]][MA.au[i].name].push(MA.al[6]); // Add.
					} else if (MA.au[i].groups[j] === MA.lg[7]) { // WMF T&S.
						if (MA.d[MA.t[6]][MA.au[i].name] === undefined) // Initialize array.
							MA.d[MA.t[6]][MA.au[i].name] = [];
						MA.d[MA.t[6]][MA.au[i].name].push(MA.al[7]); // Add.
					}
				}
			}
		}
		for (let i in MA.gu) { // Iterate globalallusers
			if (!MA.c(MA.gu, MA.au, MA.gu[i])) { // Check if they are also local A/I/B/C/O/S/WMF.
				for (let k of [0, 1]) { // If not, iterate their global groups twice for GS and then OM.
					for (let l in MA.gu[i].groups) {
						if (MA.gu[i].groups[l] === MA.gg[k]) {
							if (MA.d[MA.t[(k ? 8 : 2)]][MA.gu[i].name] === undefined)
								MA.d[MA.t[(k ? 8 : 2)]][MA.gu[i].name] = [];
							MA.d[MA.t[(k ? 8 : 2)]][MA.gu[i].name].push(MA.n(i, l, true));
						}
					}
				}
			} else {
				for (let j in MA.au) { // Find S who are not local sysop/int admin.
					if (MA.gu[i].name === MA.au[j].name) {
						if (MA.c(MA.au[j].groups, [MA.lg[2], MA.lg[5]])) { // If they have sysop/int admin bits, skip.
							continue;
						} else if (!MA.gu[i].groups.includes(MA.gg[2])) { // Not S, skip.
							continue;
						} else { // Here's what we're looking for.
							for (let l in MA.gu[i].groups) {
								if (MA.gu[i].groups[l] === MA.gg[2]) {
									if (MA.d[MA.t[7]][MA.gu[i].name] === undefined)
										MA.d[MA.t[7]][MA.gu[i].name] = [];
									MA.d[MA.t[7]][MA.gu[i].name].push(MA.ag[2]);
								}
							}
						}
					}
				}
			}
		}
		
		// Sort arrays in MA.d.
		for (let i in MA.d) {
			for (let j in MA.d[i]) {
				MA.d[i][j] = MA.s(MA.d[i][j]);
			}
		}
		
	}).then(function() {
		console.log(MA.d);
		return MA.d;
	});
});