/*<nowiki>
Mailing list member updating script
Testcases:
[[User:Technical 13/SandBox/MLsand]]
// Once above is stable
[[Wikipedia:WikiProject Userboxes/Members]]
[[Wikipedia:WikiProject Maine/members]]
[[:Category:MassMessage delivery lists]]
*/
var pageid = mw.config.get( 'wgArticleId' );
//mlmInfo[ mw.config.get( 'wgPageName' ) ] = { blocked: false, extras: '', joined: false, lastactive: false, notarget: true, status: 'self', type: 'page' };
function getEditors() {
console.log( 'Getting editors' );
return new mw.Api().get( {
action: 'query',
pageids: pageid,
prop: 'revisions',
rvlimit: 'max',
rvprop: [ 'timestamp', 'user' ],
rawcontinue: ''
} ).then( function( mlRevisions ) {
var thisUser, mlmInfo = {};
for ( var u in mlRevisions.query.pages[ pageid ].revisions ) {
thisUser = mlRevisions.query.pages[ pageid ].revisions[ u ].user;
mlmInfo[ thisUser ] = {
blocked: false,
extras: '',
groups: [],
joined: new Date( mlRevisions.query.pages[ pageid ].revisions[ u ].timestamp ).getTime(),
lastactive: false,
notarget: false,
status: 'edited',
type: 'user'
};
}
return mlmInfo;
} );
}
function parseList( mlmInfo ) {
console.log( 'Parsing list' );
return new mw.Api().get( {
action: 'query',
pageids: pageid,
prop: 'revisions',
rvprop: 'content',
rawcontinue: ''
} ).then( function( mlContents ) {
var mlPage = mlContents.query.pages[ pageid ].revisions[ 0 ][ '*' ] + '\n';
var tArray = mlPage.match( /\{\{Mailing list member\|(.*?)\n/gi );
$.each( tArray, function( index, template ) {
var extras = template.replace( /\{\{Mailing list member\|(.*?)\}\}/i, '' ).replace( /[\r\n]/g, '' );
if ( extras === undefined && extras === null ) {
extras = '';
}
template = template.replace( /\{\{Mailing list member/i, '' ).replace( /\}\}/, '|' );
var page = template.match( /\| *page *= *(.*?)\|/i );
if ( page !== undefined && page !== null ) {
page = page[ 1 ];
}
var user = template.match( /\| *user *= *(.*?)\|/i );
if ( user !== undefined && user !== null ) {
user = user[ 1 ];
} else {
user = mlmInfo[ user ].user;
}
var blocked = template.match( /\| *blocked *= *(.*?)\|/i );
if ( blocked !== undefined && blocked !== null ) {
blocked = new Date( blocked[ 1 ] ).getTime();
} else {
blocked = false;
}
var joined = template.match( /\| *joined *= *(.*?)\|/i );
if ( joined !== undefined && joined !== null ) {
joined = new Date( joined[ 1 ] ).getTime();
} else {
joined = false;
}
var lastactive = template.match( /\| *lastactive *= *(.*?)\|/i );
if ( lastactive !== undefined && lastactive !== null ) {
lastactive = new Date( lastactive[ 1 ] ).getTime();
} else {
lastactive = false;
}
var notarget = template.match( /\| *notarget *= *(.*?)\|/i );
if ( notarget !== undefined && notarget !== null ) {
notarget = notarget[ 1 ];
} else {
notarget = false;
}
if ( user !== undefined && user !== null && mlmInfo.hasOwnProperty( user ) ) {
/* confirmed user */// Is a user that has edited the page and is still on the list
if ( blocked !== undefined && blocked !== null && blocked < mlmInfo[ user ].blocked ) {
mlmInfo[ user ].blocked = blocked;
}
if ( extras !== undefined && extras !== null ) {
mlmInfo[ user ].extras = extras;
}
if ( joined !== undefined && joined !== null && joined < mlmInfo[ user ].joined ) {
mlmInfo[ user ].joined = joined;
}
if ( lastactive !== undefined && lastactive !== null && lastactive < mlmInfo[ user ].lastactive ) {
mlmInfo[ user ].lastactive = lastactive;
}
if ( notarget !== undefined && notarget !== null ) {
mlmInfo[ user ].notarget = notarget;
}
mlmInfo[ user ].status = 'confirmed';
} else if ( page !== undefined && page !== null ) {
/* listed page */// Is a page instead of a user.
if ( extras !== undefined && extras !== null ) {
mlmInfo[ user ].extras = extras;
}
mlmInfo[ page ].status = 'listed';
mlmInfo[ page ].type = 'page';
} else {
/* listed user */// Is a user that is listed but hasn't edited the page.
mlmInfo[ user ] = {
blocked: blocked,
extras: extras,
groups: [],
joined: joined,
lastactive: lastactive,
notarget: notarget,
status: 'listed',
type: 'user'
};
}
} );
return mlmInfo;
} );
}
function userInfo( mlmInfo ) {
console.log( 'Updating user information' );
var promises = [];
var userList = [];
$.each( mlmInfo, function( aUser ) {
userList.push( aUser );
}
var offset = 0;
while ( offset <= userList.length ) {
$.each( mlmInfo.slice( offset, offset + 20 ), function ( i ) {
thisUser = userList[ offset + i ];
console.log( 'Updating information for: ' + thisUser );
if ( mlmInfo[ thisUser ].type === 'user' ) {
promises.push(
new mw.Api().get( {
action: 'query',
list: [ 'logevents', 'usercontribs', 'users' ],
leprop: 'timestamp',
ucprop: 'timestamp',
usprop: [ 'blockinfo', 'groups' ],
lelimit: 1,
uclimit: 1,
leuser: thisUser,
ucuser: thisUser,
ususers: thisUser,
rawcontinue: ''
} ).then( function( mlmUserInfo ) {
if ( mlmUserInfo.query.users[ 0 ].blockid ) {
var isBlockedExpiry = mlmUserInfo.query.users[ 0 ].blockexpiry;
if ( isBlockedExpiry === 'infinity' || new Date( isBlockedExpiry ) > Date.now() ) {
mlmInfo[ thisUser ].blocked = new Date( mlmUserInfo.query.users[ 0 ].blockedtimestamp ).getTime();// They're blocked
}
}
mlmInfo[ thisUser ].groups = mlmUserInfo.query.users[ 0 ].groups;
for ( var le in mlmUserInfo.query.logevents ) {
var lastLogged = new Date( mlmUserInfo.query.logevents[ le ].timestamp ).getTime();
if ( lastLogged > mlmInfo[ thisUser ].lastactive ) {
mlmInfo[ thisUser ].lastactive = lastLogged;// The last time they performed a [[Help:Log|logged]] action.
}
}
for ( var uc in mlmUserInfo.query.usercontribs ) {
var lastEdit = new Date( mlmUserInfo.query.usercontribs[ uc ].timestamp ).getTime();
if ( lastEdit > mlmInfo[ thisUser ].lastactive ) {
mlmInfo[ thisUser ].lastactive = lastEdit;// The last time they edited a page
}
}
if ( mlmUserInfo.query.users[ 0 ].invalid || $.inArray( 'user', mlmUserInfo.query.users[ 0 ].groups ) === -1 ) {
mlmInfo[ thisUser ].notarget = true;// They're not a user and can't get mass mailings.
mlmInfo[ thisUser ].type = 'IP';
}
if ( $.inArray( 'bot', mlmUserInfo.query.users[ 0 ].groups ) > -1 ) {
mlmInfo[ thisUser ].notarget = true;// They're a bot and don't want mass mailings.
mlmInfo[ thisUser ].type = 'bot';
}
return $.Deferred().resolve();
} )
);
} else if ( mlmInfo[ thisUser ].type === 'page' ) {
if ( mlmInfo[ thisUser ].joined === false ) {
promises.push(
new mw.Api().get( {
action: 'query',
pageids: pageid,
prop: 'revisions',
rvprop: 'timestamp',
rvdir: 'newer',
rvlimit: 1,
rawcontinue: ''
} ).then( function( mlmPageInfo ) {
mlmInfo[ thisUser ].joined = new Date( mlmPageInfo.query.pages[ pageid ].revisions[ 0 ].timestamp );
return $.Deferred().resolve();
} )
);
}
promises.push(
new mw.Api().get( {
action: 'query',
pageids: pageid,
prop: 'revisions',
rvprop: 'timestamp',
rvlimit: 1,
rawcontinue: ''
} ).then( function( mlmPageInfo ) {
mlmInfo[ thisUser ].lastactive = new Date( mlmPageInfo.query.pages[ pageid ].revisions[ 0 ].timestamp );
return $.Deferred().resolve();
} )
);
} else {
console.warn( 'Skipping %s because it is of type: %s', thisUser, mlmInfo[ thisUser ].type );
}
} );
offset += 20;
}
return $.when.apply( $, promises ).then( function () {
return mlmInfo;
} );
}
getEditors().then( function ( mlmInfo ) {
return parseList( mlmInfo );
} ).then( function ( mlmInfo ) {
return userInfo( mlmInfo );
} ).done( function ( mlmInfo ) {
/* show result */
console.info( mlmInfo );
} );
//</nowiki>