|
MediaWiki:Gadget-cats-LookupUser.js
Jump to navigation
Jump to search
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.
const {i18n: {LookupUser: i18n}, wikiList: wikis} = require( './cats-utils.js' );
const config = mw.config.get([
'wgCanonicalSpecialPageName',
'wgRelevantUserName',
'wgArticlePath',
'wgMonthNames',
'wgTitle',
'wgLegalTitleChars'
]);
var output = [],
elements = {},
input,
button,
widget,
length,
count = 0,
found = 0,
username = '',
globalgroups = ['autoconfirmed', 'cats', 'global-interface-maintainer', 'checkuser', 'staff'],
regex = new RegExp('^[' + config.wgLegalTitleChars + ']+$');
function log(msg) {
console.log('[LookupContribs]', msg);
}
function wikiLink(wiki, page, text, title, query) {
return mw.html.element( 'a', {
href: wiki + mw.util.getUrl( page ) + (query || ''),
title: title
}, text );
}
function formatDate(date) {
if (date.length) {
const d = new Date(date);
return ('0' + d.getHours()).slice(-2) + ':' + ('0' + d.getMinutes()).slice(-2) + ', ' + // Time
d.getDate() + ' ' + config.wgMonthNames[d.getMonth()+1] + ' ' + d.getFullYear(); // Date
} else {
return '';
}
}
function filterEntry(groups) {
return !['*', 'user'].concat(globalgroups).includes(groups);
}
function done() {
const table = document.createElement('table');
table.classList = 'wikitable';
table.style.width = '100%';
table.innerHTML =
'<thead>' +
'<tr>' +
mw.html.element( 'th', {}, i18n['wikis-title'] ) +
mw.html.element( 'th', {}, i18n['wikis-last-edited'] ) +
mw.html.element( 'th', {}, i18n['wikis-edits'] ) +
( mw.util.isIPAddress(username, true) && !mw.util.isIPAddress(username, false) ? '' :
mw.html.element( 'th', {}, i18n['wikis-logs'] ) +
mw.html.element( 'th', {}, i18n['wikis-deleted'] ) +
mw.html.element( 'th', {}, i18n['wikis-abuselog'] )
) +
( mw.util.isIPAddress(username, true) ? '' :
mw.html.element( 'th', {}, i18n['wikis-rights'] )
) +
mw.html.element( 'th', {}, i18n['wikis-blocked'] ) +
'</tr>' +
'</thead>' +
'<tbody>' +
'</tbody>';
const tbody = table.querySelector('tbody');
var globalEditCount = 0;
for (var i=0; i<output.length; i++) {
const row = tbody.insertRow(),
url = row.insertCell(),
timestamp = row.insertCell(),
edits = row.insertCell(),
logs = row.insertCell(),
deleted = row.insertCell(),
abuselog = row.insertCell(),
rights = row.insertCell(),
blocks = row.insertCell();
if (output[i].timestamp.length || output[i].blocks[0] !== '—' || output[i].blocks.length > 1) {
found++;
}
url.dataset.sortValue = (wikis[i].id === 'meta' ? 'zz-meta' : wikis[i].id);
url.innerHTML = wikiLink(
output[i].name,
( mw.util.isIPAddress(username, true) ? 'Special:Contributions/' : 'User:' ) + output[i].username,
output[i].name,
mw.format(i18n['wikis-url-content'], output[i].username, output[i].name)
);
timestamp.dataset.sortValue = output[i].timestamp;
timestamp.textContent = formatDate(output[i].timestamp);
edits.dataset.sortValue = output[i].usercontribs;
edits.innerHTML = wikiLink(
output[i].name,
'Special:Contributions/' + output[i].username,
mw.language.convertNumber(output[i].usercontribs),
mw.format(
mw.language.convertPlural(output[i].usercontribs, i18n['wikis-edits-content']),
mw.language.convertNumber(output[i].usercontribs),
output[i].name
)
);
if ( mw.util.isIPAddress(username, true) && !mw.util.isIPAddress(username, false) ) {
logs.remove();
deleted.remove();
abuselog.remove();
}
else {
logs.dataset.sortValue = output[i].logevents;
logs.innerHTML = wikiLink(
output[i].name,
'Special:Logs/User:' + output[i].username,
mw.language.convertNumber(output[i].logevents),
mw.format(
mw.language.convertPlural(output[i].logevents, i18n['wikis-logs-content']),
mw.language.convertNumber(output[i].logevents),
output[i].name
)
);
deleted.dataset.sortValue = output[i].deletedcontribs;
deleted.innerHTML = wikiLink(
output[i].name,
'Special:DeletedContributions/' + output[i].username,
mw.language.convertNumber(output[i].deletedcontribs),
mw.format(
mw.language.convertPlural(output[i].deletedcontribs, i18n['wikis-deleted-content']),
mw.language.convertNumber(output[i].deletedcontribs),
output[i].name
)
);
abuselog.dataset.sortValue = output[i].abuselog;
abuselog.innerHTML = wikiLink(
output[i].name,
'Special:AbuseLog',
mw.language.convertNumber(output[i].abuselog),
mw.format(
mw.language.convertPlural(output[i].abuselog, i18n['wikis-abuselog-content']),
mw.language.convertNumber(output[i].abuselog),
output[i].name
),
'?wpSearchUser=' + output[i].username
);
}
if ( mw.util.isIPAddress(username, true) ) rights.remove();
else {
rights.dataset.sortValue = output[i].groups.filter(filterEntry).length;
rights.textContent = output[i].groups.filter(filterEntry).join(', ');
}
blocks.dataset.sortValue = output[i].blocks.filter( function(block) {
return block !== '—';
} ).length;
blocks.innerHTML = output[i].blocks.map( function(block, j) {
return wikiLink(
output[i].name,
'Special:Log/block',
block,
i18n['wikis-blocked-content'],
'?page=User:' + ( j ? output[i].username.split('/')[0] + block : output[i].username )
);
} ).join(', ');
globalEditCount += output[i].usercontribs + output[i].deletedcontribs;
}
if ( mw.util.isIPAddress(username, true) ) {
elements.userinfo.querySelector('#global-editcount').innerHTML =
mw.html.element( 'strong', {}, i18n['global-editcount'] ) + ' ' + mw.html.escape( mw.language.convertNumber( globalEditCount ) );
}
widget.setNotices( [] );
widget.setSuccess( [ mw.format(mw.language.convertPlural(found, i18n['wikis-found']), mw.language.convertNumber(found)) ] );
$(table).tablesorter();
elements.wikis.append(table);
input.setReadOnly(false);
button.setDisabled(false);
}
function updateCount() {
count++;
widget.setNotices( [ mw.format(i18n['wikis-checking'], mw.language.convertNumber(count + 1), mw.language.convertNumber(length)) ] );
if (count === length) done();
}
function sendRequest(host, id) {
var queryArgs = {
action: 'query',
list: ['usercontribs'],
uclimit: 'max',
ucprop: ['timestamp'],
formatversion: 2
};
if ( mw.util.isIPAddress(username, true) ) {
queryArgs.list.push( 'blocks' );
if ( mw.util.isIPAddress(username, false) ) {
queryArgs.list.push( 'logevents', 'alldeletedrevisions', 'abuselog' );
queryArgs.ucuser = username;
queryArgs.leuser = username;
queryArgs.lelimit = 'max';
queryArgs.leprop = ['timestamp'];
queryArgs.adruser = username;
queryArgs.adrlimit = 'max';
queryArgs.adrprop = ['timestamp'];
queryArgs.afluser = username;
queryArgs.afllimit = 'max';
queryArgs.aflprop = ['timestamp', 'wiki'];
}
else {
queryArgs.uciprange = username;
}
queryArgs.bkip = username;
queryArgs.bklimit = 'max';
queryArgs.bkprop = ['user'];
}
else {
queryArgs.list.push( 'users', 'logevents', 'alldeletedrevisions', 'abuselog' );
if ( /^#\d+$/.test(username) ) {
var userid = username.slice(1);
queryArgs.ususerids = userid;
queryArgs.ucuserids = userid;
}
else {
queryArgs.ususers = username;
queryArgs.ucuser = username;
}
queryArgs.usprop = ['groups', 'blockinfo'];
queryArgs.leuser = username;
queryArgs.lelimit = 'max';
queryArgs.leprop = ['timestamp'];
queryArgs.adruser = username;
queryArgs.adrlimit = 'max';
queryArgs.adrprop = ['timestamp'];
queryArgs.afluser = username;
queryArgs.afllimit = 'max';
queryArgs.aflprop = ['timestamp', 'wiki'];
}
var api = new mw.ForeignApi( host + '/api.php', {
parameters: queryArgs
} );
var result = {
name: host,
username: username,
usercontribs: 0,
logevents: 0,
deletedcontribs: 0,
abuselog: 0,
groups: [],
timestamp: '',
blocks: ['—'],
id: id
};
output[id] = result;
sendSingleRequest(api, result);
}
function sendSingleRequest(api, result, datacontinue) {
api.get( datacontinue ).then(function(data) {
if ( data.query.usercontribs ) result.usercontribs += data.query.usercontribs.length;
if ( data.query.logevents ) result.logevents += data.query.logevents.length;
if ( data.query.alldeletedrevisions ) result.deletedcontribs += data.query.alldeletedrevisions.reduce( function(sum, cur) {
return sum + cur.revisions.length;
}, 0 );
if ( data.query.abuselog ) result.abuselog += data.query.abuselog.length;
if ( data.query.blocks && data.query.blocks.length ) {
data.query.blocks.forEach( function(block) {
if ( block.user.split('/')[1] === username.split('/')[1] ) result.blocks[0] = 'Y';
else result.blocks.push('/' + block.user.split('/')[1]);
} );
}
if ( api.defaults.parameters.uciprange && data.query.usercontribs ) {
result.timestamp = data.query.usercontribs.reduce(function(acc, cur) {
if ( acc > cur.timestamp ) return acc;
return cur.timestamp;
}, result.timestamp);
}
if ( !datacontinue ) {
if ( data.query.users && data.query.users[0] ) {
result.username = data.query.users[0].name;
result.groups = data.query.users[0].groups;
if ( data.query.users[0].blockid ) result.blocks[0] = 'Y';
}
if ( data.query.usercontribs && data.query.usercontribs[0]
&& data.query.usercontribs[0].timestamp > result.timestamp ) {
result.timestamp = data.query.usercontribs[0].timestamp;
}
if ( data.query.logevents && data.query.logevents[0]
&& data.query.logevents[0].timestamp > result.timestamp ) {
result.timestamp = data.query.logevents[0].timestamp;
}
if ( data.query.alldeletedrevisions && data.query.alldeletedrevisions[0] && data.query.alldeletedrevisions[0].revisions[0]
&& data.query.alldeletedrevisions[0].revisions[0].timestamp > result.timestamp ) {
result.timestamp = data.query.alldeletedrevisions[0].revisions[0].timestamp;
}
if ( data.query.abuselog && data.query.abuselog[0]
&& data.query.abuselog[0].timestamp > result.timestamp ) {
let abuselog = data.query.abuselog.find( logentry => !logentry.wiki );
if ( abuselog && abuselog.timestamp > result.timestamp ) {
result.timestamp = abuselog.timestamp;
}
}
}
if ( data.continue ) {
sendSingleRequest(api, result, data.continue);
}
else updateCount();
}).catch(function(error) {
log(error);
updateCount();
});
}
/**
* Initiate wiki list.
*/
function lookupWikis() {
length = wikis.length;
for (var i=0; i<length; i++) {
sendRequest(wikis[i].url, i);
}
}
/**
* Button action to start the process.
*/
function start() {
if (input.isReadOnly() || button.isDisabled()) return;
// Reset
username = '';
count = 0;
found = 0;
output = [];
elements.userinfo.textContent = '';
elements.wikis.textContent = '';
widget.setSuccess( [] );
widget.setNotices( [] );
widget.setWarnings( [] );
widget.setErrors( [] );
username = input.getValue().trim();
if (!username.length) return;
input.setReadOnly(true);
button.setDisabled(true);
widget.setNotices( [ i18n['main-loading'] ] );
var api = new mw.Api();
if ( mw.util.isIPAddress(username, true) ) {
username = mw.util.sanitizeIP(username);
api.get( {
action: 'query',
list: ['globalblocks'],
bgip: username,
bglimit: 'max',
bgprop: ['address', 'expiry'],
formatversion: 2
} ).then(function(data) {
elements.userinfo.innerHTML =
'<fieldset>' +
mw.html.element( 'legend', {}, i18n['global-header'] ) +
'<div>' + mw.html.element( 'strong', {}, i18n['global-username'] ) + ' ' + mw.html.escape( mw.util.prettifyIP( username ) ) + '</div>' +
'<div id="global-editcount">' + mw.html.element( 'strong', {}, i18n['global-editcount'] ) + ' ' + mw.html.escape( mw.language.convertNumber( 0 ) ) + '</div>' +
( data.query.globalblocks.length ? '<div>' + mw.html.element( 'strong', {}, i18n['global-blocked'] ) + ' ' + mw.html.element( 'a', {
href: mw.util.getUrl( 'Special:GlobalBlockList/' + username ), title: 'Special:GlobalBlockList'
}, new mw.html.Raw( data.query.globalblocks.map( function (globalblock) {
if ( new Date(globalblock.expiry) < Date.now() ) return mw.html.element( 's', {}, globalblock.address );
return mw.html.escape( globalblock.address );
} ).join(', ') ) ) + '</div>' : '' ) +
'</fieldset>';
lookupWikis();
}).catch(log);
return;
}
var queryArgs = {
action: 'query',
list: ['users'],
usprop: [
'editcount',
'groups',
'registration',
'gender',
'emailable'
],
formatversion: 2
};
if ( /^#\d+$/.test(username) ) queryArgs.ususerids = username.slice(1);
else queryArgs.ususers = username;
api.get( queryArgs ).then(function(data) {
const users = data.query.users[0];
if ( /^#\d+$/.test(username) ) username = '#' + users.userid;
else username = users.name;
if (users.missing || users.invalid) {
widget.setNotices( [] );
widget.setErrors( [ mw.format(i18n['global-error'], username) ] );
input.setReadOnly(false);
button.setDisabled(false);
} else {
elements.userinfo.innerHTML =
'<fieldset>' +
mw.html.element( 'legend', {}, i18n['global-header'] ) +
'<div>' + mw.html.element( 'strong', {}, i18n['global-username'] ) + ' ' + mw.html.escape( users.name ) + '</div>' +
'<div>' + mw.html.element( 'strong', {}, i18n['global-id'] ) + ' ' + mw.html.escape( '#' + users.userid ) + '</div>' +
'<div>' + mw.html.element( 'strong', {}, i18n['global-editcount'] ) + ' ' + mw.html.escape( mw.language.convertNumber( users.editcount ) ) + '</div>' +
'<div>' + mw.html.element( 'strong', {}, i18n['global-groups'] ) + ' ' + mw.html.escape( users.groups.filter( function (groups) {
return globalgroups.includes(groups);
} ).join(', ') ) + '</div>' +
'<div>' + mw.html.element( 'strong', {}, i18n['global-registration'] ) + ' ' + mw.html.escape( users.registration ? formatDate(users.registration) : i18n['registration-unknown'] ) + '</div>' +
//'<div>' + mw.html.element( 'strong', {}, i18n['global-emailable'] ) + ' ' + mw.html.escape( users.emailable ? 'Yes' : 'No' ) + '</div>' +
'<div>' + mw.html.element( 'strong', {}, i18n['global-gender'] ) + ' ' + mw.html.escape( i18n.gender[users.gender] || users.gender ) + '</div>' +
'</fieldset>';
lookupWikis();
}
}).catch(log);
}
function init() {
var $content = $( '#mw-content-text' );
var mwf = $content.find('#globalTracker')[0];
if (mwf) return;
document.getElementById('firstHeading').textContent = i18n.title;
document.title = i18n.title + ' – Minecraft Wiki';
$content.empty().addClass('loaded');
input = new mw.widgets.UserInputWidget( {
required: true,
validate: function(inputValue) {
inputValue = inputValue.trim();
if ( regex.test(inputValue) && !/[:/]/.test(inputValue) ) return true;
if ( mw.util.isIPAddress(inputValue, true) ) {
if ( mw.util.isIPAddress(inputValue, false) ) return true;
var iprange = inputValue.split('/')[1];
if ( mw.util.isIPv4Address(inputValue, true) && iprange < 16 ) return false;
if ( mw.util.isIPv6Address(inputValue, true) && iprange < 32 ) return false;
return true;
}
if ( /^#\d+$/.test(inputValue) ) return true;
return false;
},
placeholder: i18n['main-placeholder']
} );
button = new OO.ui.ButtonWidget( {
label: i18n['main-button'],
flags: ['primary', 'progressive']
} );
widget = new OO.ui.ActionFieldLayout(
input, button, {
id: 'globalTracker',
label: i18n['main-header'],
align: 'top'
}
);
$content.append(
widget.$element,
$('<div>').attr('id', 'tracker-userinfo'),
$('<div>').attr('id', 'tracker-wikis')
);
elements = {
userinfo: $content.find('#tracker-userinfo')[0],
wikis: $content.find('#tracker-wikis')[0]
};
input.on('enter', function() {
input.getValidity().done(start);
});
button.on('click', function() {
input.getValidity().done(start);
});
const targetParam = mw.util.getParamValue('target');
if (targetParam) {
input.setValue(targetParam);
input.getValidity().done(start);
}
}
if (config.wgCanonicalSpecialPageName === 'Blankpage' && config.wgTitle.endsWith('/LookupUser')) {
mw.loader.using( [
'oojs-ui-widgets',
'mediawiki.widgets.UserInputWidget',
'mediawiki.ForeignApi'
] ).then( init );
}
function createLookupUserLink(portlet) {
var link = mw.util.getUrl('Special:BlankPage/LookupUser') + (config.wgRelevantUserName ? '?target=' + mw.util.wikiUrlencode(config.wgRelevantUserName) : '');
if (config.wgCanonicalSpecialPageName === 'Contributions') {
$('<span>').append(
$('<a>').addClass('mw-contributions-link-lookupuser').attr('href', link).text(i18n.title)
).appendTo('.mw-contributions-user-tools .mw-changeslist-links');
}
return mw.util.addPortletLink(portlet, link, i18n.title, 't-cats-LookupUser', '', null, 'li:first-of-type');
}
module.exports = createLookupUserLink;