// based on http://en.wikipedia.org/wiki/User:Fran_Rogers/dimorphism.js
// and on http://en.wikipedia.org/wiki/User:Splarka/sysopdectector.js
( function ( mw, $ ) {
var h = mw.html,
api,
ns = mw.config.get( 'wgNamespaceNumber' ),
title = mw.config.get( 'wgTitle' );
// Bail out unless on a user or user talk page, and not a subpage.
if ( ns & ~1 !== 2 || title.indexOf( '/' ) >= 0 ) {
return;
}
// TODO: add additional languages
mw.messages.set( {
'ps-userinfo-separator': ' | ',
'ps-userinfo-seconds': '$1 {{PLURAL:$1|second|seconds}}',
'ps-userinfo-minutes': '$1 {{PLURAL:$1|minute|minutes}}',
'ps-userinfo-hours': '$1 {{PLURAL:$1|hour|hours}}',
'ps-userinfo-days': '$1 {{PLURAL:$1|day|days}}',
'ps-userinfo-weeks': '$1 {{PLURAL:$1|week|weeks}}',
'ps-userinfo-months': '$1 {{PLURAL:$1|month|months}}',
'ps-userinfo-years': '$1 {{PLURAL:$1|year|years}}',
'ps-userinfo-years-months': '$1 {{PLURAL:$1|year|years}} $2 {{PLURAL:$2|month|months}}',
'ps-userinfo-blocked': "'''BLOCKED'''",
'ps-userinfo-editcount': '$1 {{PLURAL:$1|edit|edits}}',
'ps-userinfo-invalid': 'invalid username',
'ps-userinfo-ipv4': 'IPv4 address',
'ps-userinfo-ipv6': 'IPv6 address',
'ps-userinfo-lastedited': 'last edited $1 ago',
'ps-userinfo-missing': 'unregistered username',
'ps-userinfo-registration': 'since $1',
'ps-userinfo-user': '{{GENDER:$1|registered user}}'
} );
/**
* Get the user's information by performing an AJAX request and processing the response.
* @param {string} userName The user to retrieve information for
* @return {jQuery.Deferred}
*/
function getInfo( userName ) {
return api.get( {
action: 'query',
list: 'users|usercontribs',
maxage: 300,
uclimit: 1,
ucprop: 'timestamp',
ucuser: userName,
usprop: 'blockinfo|editcount|gender|registration|groups',
ususers: userName
} ).then( function ( data ) {
var query = data.query, user = query.users[0], contribs = query.usercontribs;
return {
name: userName,
isInvalid: 'invalid' in user,
isIPv4: mw.util.isIPv4Address( user ),
isIPv6: mw.util.isIPv6Address( user ),
isMissing: 'missing' in user,
groups: user.groups || [],
editCount: 'editcount' in user ? user.editcount : null,
registration: parseDate( user.registration ),
isBlocked: 'blockexpiry' in user,
gender: user.gender || 'unknown',
lastEdited: ( contribs && contribs[0] ) ? parseDate( contribs[0].timestamp ) : null
};
} );
}
/**
* Display the user's information on screen.
* @param info Information about the user
*/
function displayInfo( info ) {
var userPrefix = mw.config.get( 'wgFormattedNamespaces' )[2] + ':',
hostParts = ___location.hostname.split( '.' ),
items = [],
text = '';
if ( info.isBlocked ) {
items.push( h.element( 'a', { href:
mw.util.wikiScript( 'index' ) + '?' + $.param( {
title: 'Special:Log',
page: userPrefix + info.name
} )
}, new h.Raw( mw.message( 'ps-userinfo-blocked' ).parse() ) ) );
}
if ( info.isMissing ) {
items.push( mw.message( 'ps-userinfo-missing' ).parse() );
} else if ( info.isIPv4 ) {
items.push( mw.message( 'ps-userinfo-ipv4' ).parse() );
} else if ( info.isIPv6 ) {
items.push( mw.message( 'ps-userinfo-ipv6' ).parse() );
} else if ( info.isInvalid ) {
items.push( mw.message( 'ps-userinfo-invalid' ).parse() );
} else {
$.each( info.groups, function ( i, v ) {
if ( $.inArray( v, ['*', 'user', 'autoconfirmed'] ) < 0 ) {
items.push( mw.message( 'group-' + v + '-member', info.gender ).parse() );
}
} );
if ( info.registration ) {
items.push( mw.message(
'ps-userinfo-registration',
buildDurationMessage( 'ps-userinfo-', info.registration, new Date() ).text(),
info.gender
).parse() );
}
if ( info.editCount !== null ) {
items.push( h.element( 'a', { href:
'//tools.wmflabs.org/supercount/index.php?' + $.param( {
user: info.name,
project: hostParts.slice( 0, -1 )
} )
}, new h.Raw( mw.message( 'ps-userinfo-editcount', info.editCount ).parse() ) ) );
}
}
if ( info.lastEdited ) {
items.push( mw.message(
'ps-userinfo-lastedited',
buildDurationMessage( 'ps-userinfo-', info.lastEdited, new Date() ).text(),
info.name
).parse() );
}
console.log( items.join( mw.message( 'ps-userinfo-separator' ).parse() ) );
}
/**
* Load messages corresponding to MediaWiki user groups into mw.messages.
* @return {jQuery.Deferred}
*/
function loadGroupMemberMessages() {
return api.get( {
action: 'query',
amfilter: '-member',
amlang: document.documentElement.lang,
amprefix: 'group-',
maxage: 86400,
meta: 'allmessages'
} ).then( function ( data ) {
$.each( data.query.allmessages, function ( i, message ) {
mw.messages.set( message.name, message['*'] );
} );
} );
}
/**
* Parse a UTC date in the subset of ISO 8601 used by MediaWiki's API.
* That format is YYYY-MM-DDTHH:MM:SSZ.
* @param {string} str The UTC date returned
* @return {Date} object
*/
function parseDate( str ) {
var m = /^(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)Z$/.exec( str );
if ( !m ) {
return null;
}
var d = new Date();
d.setUTCFullYear( m[1], m[2] - 1, m[3] );
d.setUTCHours( m[4], m[5], m[6] );
return d;
}
/**
* Convert a duration to a message object.
* @param {string} prefix Message prefix
* @param {Date} start The duration's start
* @param {Date} end The duration's end
* @return {mediaWiki.Message}
*/
function buildDurationMessage( prefix, start, end ) {
var age = ( end - start ) / 1000; // start with seconds
if ( age < 60 ) {
return mw.message( prefix + 'seconds', Math.floor( age ) );
}
age /= 60; // convert to minutes
if ( age < 60 ) {
return mw.message( prefix + 'minutes', Math.floor( age ) );
}
age /= 60; // convert to hours
if ( age < 24 ) {
return mw.message( prefix + 'hours', Math.floor( age ) );
}
age /= 24; // convert to days
if ( age < 7 ) {
return mw.message( prefix + 'days', Math.floor( age ) );
}
age /= 7; // convert to weeks
if ( age < 4.3481 ) {
return mw.message( prefix + 'weeks', Math.floor( age ) );
}
age /= 4.3481; // convert to months
if ( age < 12 ) {
return mw.message( prefix + 'months', Math.floor( age ) );
}
// convert to years and months
var years = Math.floor( age / 12 ), months = Math.floor( age % 12 );
if ( months ) {
return mw.message( prefix + 'years-months', years, months );
}
return mw.message( prefix + 'years', years );
}
mw.loader.using( [
'mediawiki.api',
'mediawiki.jqueryMsg',
'mediawiki.util'
], function () {
api = new mw.Api();
loadGroupMemberMessages().done( function () {
getInfo( title ).done( displayInfo );
} );
} );
} )( mediaWiki, jQuery );