User:MarkTraceur/SandBox/UpdateMailingList.js

/* Mailing list member updating script Testcases: User:Technical 13/SandBox/MLsand // Once above is stable WikiProject Userboxes/Members 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 ),				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 ];			}			var blocked = template.match( /\| *blocked *= *(.*?)\|/i );			if ( blocked !== undefined && blocked !== null ) {				blocked = new Date( blocked[ 1 ] );			}			var joined = template.match( /\| *joined *= *(.*?)\|/i );			if ( joined !== undefined && joined !== null ) {				joined = new Date( joined[ 1 ] );			}			var lastactive = template.match( /\| *lastactive *= *(.*?)\|/i ); if ( lastactive !== undefined && lastactive !== null ) { lastactive = new Date( lastactive[ 1 ] ); }			var notarget = template.match( /\| *notarget *= *(.*?)\|/i ); if ( notarget !== undefined && notarget !== null ) { notarget = notarget[ 1 ]; }			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 = [];	$.each( mlmInfo, function ( thisUser ) { 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 );// 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 ); if ( lastLogged > mlmInfo[ thisUser ].lastactive ) { mlmInfo[ thisUser ].lastactive = lastLogged;// The last time they performed a logged ( edit | wlh ) action. }					}					for ( var uc in mlmUserInfo.query.usercontribs ) { var lastEdit = new Date( mlmUserInfo.query.usercontribs[ uc ].timestamp ); 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 ); }	} );

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 ); } ); //