Jump to content

User:EpochFail/NOOB.js

From Wikipedia, the free encyclopedia
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
/*******************************************************************************
********************************************************************************
           ***      **     ******       ******     ********                     
           ****     **    **    **     **    **    **     **                    
           ** **    **   **      **   **      **   **     **                    
           **  **   **   **      **   **      **   *******                      
           **   **  **   **      **   **      **   **     **                    
           **    ** **   **      **   **      **   **     **                    
           **     ****    **    **     **    **    **     **                    
           **      ***     ******       ******     ********                     
********************************************************************************
*****************It isn't an acronym. Caps lock broke.**************************
********************************************************************************
This gadget was developed by the Grouplens Research lab (http://grouplens.org)
to be used in the English Wikipedia.  See 
http://en.wikipedia.org/wiki/User:EpochFail/NOOB for documentation and 
installation instructions.  Any questions or concerns should be directed to
User:EpochFail.  
*******************************************************************************/
if(!NOOB){
	var NOOB = {}
}

function getParameterByName(name) {
    name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
    var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
        results = regex.exec(location.search);
    return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}

NOOB.DateDiffer = {
	second: 1000,
	minute: 1000 * 60,
	hour: 1000 * 60 * 60,
	day: 1000 * 60 * 60 * 24,
	week: 1000 * 60 * 60 * 24 * 7,
	month: 1000 * 60 * 60 * 24 * 30.44,
	year: 1000 * 60 * 60 * 24 * 365.242,
	approxDiff: function(date1, date2){
		var dateDiffMS = date1-date2
		diff = {}
		diff.years = Math.floor(dateDiffMS/this.year)
		dateDiffMS -= diff.years*this.year
		diff.months = Math.floor(dateDiffMS/this.month)
		dateDiffMS -= diff.months*this.month
		diff.weeks = Math.floor(dateDiffMS/this.week)
		dateDiffMS -= diff.weeks*this.week
		diff.days= Math.floor(dateDiffMS/this.day)
		dateDiffMS -= diff.days*this.day
		diff.hours = Math.floor(dateDiffMS/this.hour)
		dateDiffMS -= diff.hours*this.hour
		diff.minutes = Math.floor(dateDiffMS/this.minute)
		dateDiffMS -= diff.minutes*this.minute
		diff.seconds = Math.floor(dateDiffMS/this.second)
		dateDiffMS -= diff.seconds*this.second
		diff.milliseconds = Math.floor(dateDiffMS)
		return diff
	},
	human: function(diff){
		var timeString = ""
		if(diff.years > 0){
			timeString += diff.years + " year"
			if(diff.years > 1){
				timeString += "s"
			}
			timeString += " and " + diff.months + " month"
			if(diff.months > 1){
				timeString += "s"
			}
		}else if(diff.months > 0){
			timeString += diff.months + "month"
			if(diff.months > 1){
				timeString += "s"
			}
			timeString += " and " + diff.weeks*7+diff.days + " day"
			if(diff.weeks*7+diff.days > 1){
				timeString += "s"
			}
		}else if(diff.weeks > 0){
			timeString += diff.weeks + "week"
			if(diff.weeks > 1){
				timeString += "s"
			}
			timeString += " and " + diff.days + " day"
			if(diff.days > 1){
				timeString += "s"
			}
		}else if(diff.days > 0){
			timeString += diff.days + "day"
			if(diff.days > 1){
				timeString += "s"
			}
			timeString += " and " + diff.hours + " hour"
			if(diff.hours > 1){
				timeString += "s"
			}
		}else if(diff.hours > 0){
			timeString += diff.hours + "hour"
			if(diff.hours > 1){
				timeString += "s"
			}
			timeString += " and " + diff.minutes + " minute"
			if(diff.minutes > 1){
				timeString += "s"
			}
		}else if(diff.minutes > 0){
			timeString += diff.minutes + "minute"
			if(diff.minutes > 1){
				timeString += "s"
			}
			timeString += " and " + diff.seconds + " second"
			if(diff.seconds > 1){
				timeString += "s"
			}
		}else{
			timeString += diff.seconds + "second"
			if(diff.seconds > 1){
				timeString += "s"
			}
			timeString += " and " + diff.milliseconds + " ms"
		}
		return timeString
	}
}

if(!NOOB){
	var NOOB = {}
}
NOOB.Editor = function(username){
	this.username = username
	this.links = []
	this.signatures = []
	
}
	
	NOOB.Editor.prototype.addLink = function(link){
		this.links.push(link)
	}
	
	NOOB.Editor.prototype.addSignature = function(signature){
		this.signatures.push(signature)
	}
	
	NOOB.Editor.prototype.updateEditCount = function(user){
		if(user.registration){
			var dateParts = user.registration.match(/([0-9]{4})-([0-1][0-9])-([0-3][0-9])T([0-9]{2}):([0-9]{2}):([0-9]{2})Z/)
			var regDate = new Date(dateParts[1], dateParts[2], dateParts[3], dateParts[4], dateParts[5], dateParts[6])
			var nowDate = new Date()
			var diff = NOOB.DateDiffer.approxDiff(nowDate, regDate)
			var diffString = NOOB.DateDiffer.human(diff)
		}else{
			var diffString = " an unknown amount of time"
		}
		
		var className = ""
		if(user.editcount < 10){
			className = "ten_1"
		}else if(user.editcount < 100){
			className = "ten_2"
		}else if(user.editcount < 1000){
			className = "ten_3"
		}else if(user.editcount < 10000){
			className = "ten_4"
		}else{
			className = "ten_5"
		}
		
		for(var i=0;i<this.links.length;i++){
			var link = this.links[i]
			
			link.update(className, user.editcount, diffString)
		}
		for(var i=0;i<this.signatures.length;i++){
			var signature = this.signatures[i]
			
			signature.update(className, user.editcount, diffString)
		}
		
	}
	
	NOOB.Editor.prototype.setUnknown = function(){
		for(var i=0;i<this.links.length;i++){
			var link = this.links[i]
			
			link.unknown()
		}
		for(var i=0;i<this.signatures.length;i++){
			var signature = this.signatures[i]
			
			signature.unknown()
		}
	}
	

if(!NOOB){
	var NOOB = {}
}
NOOB.Signature = function(userHref, spanNode){
	this.expressions = []
	this.expressions.push(/\/wiki\/(U|u)ser(_talk)?:([^\/#]+)/)
	this.expressions.push(/\/wiki\/(S|s)pecial:(C|c)ontributions\/([^\/#]+)/)
	this.expressions.push(/\/w\/index\.php\?title=User_talk:([^\/#]+)&action=edit&redlink=1/)
	this.expressions.push(/\/wiki\/(S|s)pecial:(E|e)mailUser\/([^\/#]+)/)
	
	if(userHref){
		for(var i=0;i<this.expressions.length && !this.username;i++){
			var expression = this.expressions[i]
			match = userHref.match(expression)
			if(match != null){
				this.username = match[match.length-1]
			}
		}
	}
	if(!this.username){
		this.username = "?unknown?"
	}
	
	this.spanNode = spanNode
}

	NOOB.Signature.prototype.update = function(className, editCount, diffString){
		this.spanNode.removeClass('loading')
		this.spanNode.addClass(className)
		this.spanNode.html('<a href="/wiki/Special:Contributions/' + this.username + '">hist</a>')
		this.spanNode.attr('title', editCount + " revisions in " + diffString)
	}
	
	NOOB.Signature.prototype.unknown = function(){
		this.spanNode.removeClass('loading')
		this.spanNode.addClass('unknown')
		this.spanNode.html('<a href="/wiki/Special:Contributions/' + this.username + '">?</a>')
	}

if(!NOOB){
	var NOOB = {}
}
NOOB.Link = function(editorLink){
	this.username = editorLink.text().replace(/ /g, "_")
	this.link = editorLink
}
	NOOB.Link.prototype.update = function(className, editCount, diffString){
		this.link.attr("title", user.editcount + " revisions in " + diffString)
		$('&nbsp;<span class="contribs ' + className + '" title="' + user.editcount + " revisions in " + diffString + '">&nbsp;</span>&nbsp;').insertBefore(this.link)
	}
	NOOB.Link.prototype.unknown = function(){
		$('&nbsp;<span class="contribs unknown" title="unknown">?</span>&nbsp;').insertBefore(this.link)
	}

if(!NOOB){
	var NOOB = {}
}

NOOB.Editors = function(){
	this.editors = {}
}
	
	NOOB.Editors.prototype.addEditorLink = function(editorLink){
		var link = new NOOB.Link(editorLink)
		if(this.editors[link.username] == undefined){
			this.editors[link.username] = new NOOB.Editor(link.username)
		}
		this.editors[link.username].addLink(link)
	}
	NOOB.Editors.prototype.addEditorSignature = function(href, spanNode){
		var signature = new NOOB.Signature(href, spanNode)
		if(this.editors[signature.username] == undefined){
			this.editors[signature.username] = new NOOB.Editor(signature.username)
		}
		this.editors[signature.username].addSignature(signature)
	}
	
	NOOB.Editors.prototype.loadEditCount = function(){
		var usernames = []
		for(var username in this.editors){
			usernames.push(username)
		}
		
		var params = {
			"action": 'query',
			"list": 'users',
			"ususers": usernames.join("|"),
			"usprop": 'editcount|registration',
			"format": 'json'
		}
		
		NOOB.WPAPIHandler.performGET(
			params, 
			function(res, args){
				
				try{
					var users = res.query.users
				}
				catch(e){
					alert("Invalid result structure")
					return
				}
				
				for(var i=0;i<users.length;i++){
					user = users[i]
					
					if(user.editcount != undefined){
						user.hrefName = user.name.replace(/ /g, "_")
						try{
							args.self.editors[user.hrefName].updateEditCount(user)
						}catch(e){
							alert(user.hrefName)
						}
					}else{
						user.hrefName = user.name.replace(/ /g, "_")
						args.self.editors[user.hrefName].setUnknown()
					}
				}
			}, 
			{self: this},
			function(message){
				alert(message)
			}
		)
		
	}

if(!NOOB){
	var NOOB = {}
}

/**
 * Wikipedia API Handler
 *
 * A simple object for interacting with Wikipedia's API.
 */
NOOB.WPAPIHandler=function(){};NOOB.WPAPIHandler.timeoutSeconds=25;if(mw.config.get('wgServer')&&wgScriptPath){NOOB.WPAPIHandler.url=mw.config.get('wgServer')+mw.config.get('wgScriptPath')+"/api.php"}else{NOOB.WPAPIHandler.url="http://en.wikipedia.org/w/api.php"}NOOB.WPAPIHandler.performGET=function(d,b,a,c){this.performRequest(d,b,a,c,"GET")};NOOB.WPAPIHandler.performPOST=function(d,b,a,c){this.performRequest(d,b,a,c,"POST")};NOOB.WPAPIHandler.performRequest=function(f,b,a,e,d){var c=function(g,h){if(h=="success"){b(g,a)}else{e(h)}};if(d=="POST"){$.post(this.url,f,c,"json")}else{$.get(this.url,f,c,"json")}};NOOB.WPAPIHandler.objectToString=function(c,b){b=b||0;str="";for(thing in c){for(var a=0;a<b;a++){str+="  "}if(typeof(c[thing])=="object"){str+=thing+": \n"+NOOB.WPAPIHandler.objectToString(c[thing],b+1)}else{str+=thing+": `"+c[thing]+"`\n"}}return str};

NOOB.getPrecedingAnchor = function(nodeList, i){
	for(var j=i;j>0;j--){
		node = nodeList[j]
		if(node.constructor){
			if(node.constructor == HTMLAnchorElement){
				return node
			}
			else{
				lastAnchor = $('a:last', node)
				if(lastAnchor.length > 0){
					return lastAnchor
				}
			}
		}
	}
	return null
}
NOOB.getSignatures = function(){
	var signatureNodes = []
	//First process the autosigned comments (because it is easiest)
	var autoSigned = $('.autosigned:not(p > small > .autosigned)')
	for(var i=0;i<autoSigned.length;i++){
		var sigElement = $(autoSigned.get(i))
		
		var lastAnchor = $('a:last', sigElement)
		var signature = {href:lastAnchor.attr('href'), spanNode:$('<span class="signature loading"></span>')}
		signatureNodes.push(signature)
		signature.spanNode.insertAfter(sigElement)
	}
	
	//Next process all first-level comments
	var pTags = $('#contentSub ~ p')
	for(var i=0;i<pTags.length;i++){
		var textBlock = $(pTags.get(i))
		if(textBlock.text().match(/[0-9]{2}:[0-9]{2}, [0-9]{1,2} (January|Febuary|March|April|May|June|July|August|September|October|November|December) (1|2)[0-9]{3} \(UTC\)$/g) != null){
			var lastAnchor = $('a:last', textBlock)
			var signature = {href:lastAnchor.attr('href'), spanNode:$('<span class="signature loading"></span>')}
			signatureNodes.push(signature)
			textBlock.append(signature.spanNode)
		}
	}
	
	//Finally, process all nested comments
	var definitionLists = $('#contentSub ~ dl')
	for(var k=0;k<definitionLists.length;k++){
		var definitions = $('dd', definitionLists.get(k))
		for(var i=0;i<definitions.length;i++){
			var definition = definitions.get(i)
			for(var j=0;j<definition.childNodes.length;j++){
				var node = definition.childNodes[j]
				if(node.constructor && node.constructor == Text){
					if(node.textContent.match(/[0-9]{2}:[0-9]{2}, [0-9]{1,2} (January|Febuary|March|April|May|June|July|August|September|October|November|December) (1|2)[0-9]{3} \(UTC\)(\n)?$/g) != null){
						var precedingAnchor = this.getPrecedingAnchor(definition.childNodes, j)
						if(precedingAnchor){
							precedingAnchor = $(precedingAnchor)
							var signature = {href:precedingAnchor.attr('href'), spanNode:$('<span class="signature loading"></span>')}
							signatureNodes.push(signature)
							if(definition.childNodes.length > j+1){
								definition.insertBefore(signature.spanNode[0], definition.childNodes[j+1])
							}else{
								definition.appendChild(signature.spanNode[0])
							}
							
						}
					}
				}
			}
		}
	}
	
	return signatureNodes
}



if(getParameterByName("action") == "history"){
	importStylesheet("User:EpochFail/NOOB.css")
	NOOB.editors= new NOOB.Editors()
	
	$(document).ready(function(){
		
		var editorLinks = $('.mw-userlink')
		for(var i=0;i<editorLinks.length;i++){
			var editorLink = $(editorLinks[i])
			NOOB.editors.addEditorLink(editorLink)
		}
		NOOB.editors.loadEditCount()
		
	})
}else{
	if(getParameterByName("title") != ''){
		var title = getParameterByName("title")
	}else{
		matches = window.location.href.match(/https?:\/\/[a-z]{2}\.wikipedia\.org\/wiki\/(.+)/)
		if(matches != null){
			var title = matches[1]
		}else{
			var title = ""
		}
	}
	
	var namespace = title.split(":", 1)[0]
	title = title.substring(namespace.length+1)
	if(namespace.match(/(((T|t)alk)|(((U|u)ser)|((W|w)ikipedia)|((I|i)mage)|((M|m)ediaWiki)|((T|t)emplate)|((H|h)elp)|((C|c)ategory)|((P|p)ortal))(_| )talk)/) != null){
		//We know we are on a talk page!  Let's look for signiatures
		importStylesheet("User:EpochFail/NOOB.css")
		//importStylesheetURI('http://wikipedia.grouplens.org/NOOB/css/NOOB.css')
		NOOB.editors = new NOOB.Editors()
		
		$(document).ready(function(){
			var signatureNodes = NOOB.getSignatures()
			for(var i=0;i<signatureNodes.length;i++){
				sigNode = signatureNodes[i]
				NOOB.editors.addEditorSignature(sigNode.href, sigNode.spanNode)
			}
			NOOB.editors.loadEditCount()
		})
	}
	
	
}