There are 7 previous versions of this script.
// ==UserScript==
// @name Deviant Statistics
// @namespace falexx.deviantart.com
// @description Displays additional statistics about a Deviant.
// @include http://*.deviantart.com/
// @include http://*.deviantart.com/?*
// ==/UserScript==
/**** COPYRIGHT STUFF GOES HERE
* If you have done some improvements to this script, please let me know :)
****/
var styles = [];
var dialog;
//displaying a friendsmenu while not logged in isn't a good idea
if(!unsafeWindow.deviantART.deviant)
return;
if(!(dialog=$X('//div[@id="super-secret-stats"]/div/div/div[@class="pbox pppbox"]')[0]))
return;
var Settings = {
Version : '3.3',
Url : {
updVersion : 'http://da.elexx.org/stats/version.php',
updScript : 'http://da.elexx.org/stats/deviantstatistics.user.js',
statisticsData : 'http://'+window.location.host+'/stats/gallery/'
}
}
GM_log(Settings.Url.statisticsData);
/* Install the updater */
if(!$('gmscripts-updater')){
$('rockdock-message-count').insertAfter($E('span', {id:'gmscripts-updater',style:{position:'relative'}}));
$('rockdock-message-count').insertAfter($S(' | '));
$('gmscripts-updater').innerHTML = '<a href="#updating" id="gmscripts-updatelink">All scripts are up-to-date.</a><ul id="gmscripts-updatelist"><li>Updatable scripts:</li></ul>';
GM_addStyle('#gmscripts-updatelist { display:none; position:absolute; top:15px; left:0px; background-color:#40534A; border:1px solid #6B8075; list-style:none; margin:0px; padding:0px 5px; }');
GM_addStyle('#gmscripts-updatelist li:first-child { font-weight:bold; border-bottom:1px solid #707E77; }');
addEvent($('gmscripts-updatelink'), 'click', function(evt){evt.preventDefault();}, true);
}
if(GM_getValue('timeToUpdate', -1) < Math.floor(new Date().getTime() / 1000 / 60 / 60 / 24))
get(Settings.Url.updVersion,
function(e){
var version=e.replace(/[^a-z0-9.]/g, '');
var updateLink=$('gmscripts-updatelink');
if(version!=Settings.Version){
/* We found a different version!! */
$('gmscripts-updatelist').appendChild($E('li', {}, [$E('a', {href:Settings.Url.updScript}, ['DeviantStatistics'])]));
if(updateLink.innerHTML=='All scripts are up-to-date.')
updateLink.innerHTML='1 script is not up-to-date.';
else
updateLink.innerHTML=(parseInt(/^(\d+)/.exec(updateLink.innerHTML)[1])+1) + ' scripts are not up-to-date.'
GM_addStyle('#gmscripts-updatelist:hover { display:block; }');
GM_addStyle('#gmscripts-updater:hover #gmscripts-updatelist { display:block; }');
}
else
/* Nothing different, let's check tomorrow again */
GM_setValue('timeToUpdate', Math.floor(new Date().getTime() / 1000 / 60 / 60 / 24));
}
);
/* Get, calculate and display the statistics */
var Cache = {
top : {fullviews:null, views:null, favourites:null, comments:null, cat:{name:'',count:0}, caty:{name:'',count:0}},
total : {given:{comments:0, favourites:0, watches:0}, received:{comments:0, favourites:0, watches:0}, categories:0, pageviews:0, views:0, deviations:0, scraps:0, shouts:0, forumposts:0},
average : {day:{given:{comments:0, favourites:0, watches:0}, received:{comments:0, favourites:0, watches:0}, uploads:0, pageviews:0, views:0}, deviation:{comments:0, favourites:0, views:0}},
other : {username:null},
getData : function(){
var sSpan = $X('//div[@class="blues-bar-ctrl"]/span[@class="bb bb-with-sep"]/a/span[@class="tight"]')[0];
sSpan.innerHTML += '<br /><span id="dsStatus">Loading ...</span>';
get(Settings.Url.statisticsData, function(e){
e = e.substring(e.indexOf('deviantART.pageData=')+20);
e = e.substring(0, e.indexOf('\n</script>'));
eval('var gFeed = ' + e.replace(/\\'|\\\\"/g, '\'') + ';');
Cache.checkAndCalcData(gFeed);
window.setTimeout(function(){ $('dsStatus').remove(); GM_addStyle('div.blues-bar span.bb span.tight { font-size:7pt !important; top:-0.1em !important; }');}, 3000);
});
},
checkAndCalcData : function(feed){
if(!feed.userstats){
if(window.location.host.substring(0, window.location.host.indexOf('.')) == unsafeWindow.deviantART.deviant.username)
dialog.parentNode.appendChild($E('div',{className:'pbox pppbox'},['Make sure you checked the "Accept thir-party cookies" in your Firefox Preferences => Privacy => Cookies. Or add an exception for "deviantart.com" on the right side of the preference window!']));
if($X('//div[@class="gruserbadge"]/h1')[0].innerHTML.indexOf('!')>=0)
dialog.parentNode.appendChild($E('div',{className:'pbox pppbox'},['No additional statistics, because this Deviant got banned.']));
else
dialog.parentNode.appendChild($E('div',{className:'pbox pppbox'},['This user doesn\'t allow you to access the statistics.']));
$('dsStatus').innerHTML = 'An error occurred';
return;
}
if(feed.devstats.length==0){
dialog.parentNode.appendChild($E('div',{className:'pbox pppbox'},['No additional statistics, because the gallery is empty.']));
$('dsStatus').innerHTML = 'An error occurred';
return;
}
$('dsStatus').innerHTML = 'Calculating ...';
/* Copy copy copy */
this.other.username = feed.userstats.username;
this.total.given.comments = feed.userstats.comments;
this.total.given.favourites = feed.userstats.favourites;
this.total.given.watches = feed.userstats.friends;
this.total.received.watches = feed.userstats.friendswatching;
this.total.pageviews = feed.userstats.pageviews;
this.total.deviations = feed.userstats.deviations;
this.total.scraps = feed.userstats.scraps;
this.total.shouts = feed.userstats.shouts;
this.total.forumposts = feed.userstats.forum_posts;
/* Now calculate the rest */
var cat = [];
var caty = [];
for(i in feed.devstats){
var D = feed.devstats[i];
$('dsStatus').innerHTML = D.title;
this.total.received.comments += D.comments;
this.total.received.favourites += D.favourites;
this.total.views += D.views;
if(!this.top.fullviews || D.fullviews > this.top.fullviews.fullviews) this.top.fullviews = D;
if(!this.top.views || D.views > this.top.views.views) this.top.views = D;
if(!this.top.favourites || D.favourites > this.top.favourites.favourites) this.top.favourites = D;
if(!this.top.comments || D.comments > this.top.comments.comments) this.top.comments = D;
D.cat = D.category.split('/')[0];
if(cat[D.cat]) cat[D.cat]++;
else cat[D.cat] = 1;
if(cat[D.cat] > this.top.cat.count){
this.top.cat.name = D.cat;
this.top.cat.count = cat[D.cat];
}
if(caty[D.category]) caty[D.category]++;
else{
caty[D.category] = 1;
this.total.categories++;
}
if(caty[D.category] > this.top.caty.count){
this.top.caty.name = D.category;
this.top.caty.count = caty[D.category];
}
}
var daysSinceJoined = Math.floor((new Date().getTime() - new Date(feed.userstats.since).getTime()) / 1000 / 60 / 60 / 24);
this.average.day.given.comments = this.total.given.comments / daysSinceJoined;
this.average.day.given.favourites = this.total.given.favourites / daysSinceJoined;
this.average.day.given.watches = this.total.given.watches / daysSinceJoined;
this.average.day.received.comments = this.total.received.comments / daysSinceJoined;
this.average.day.received.favourites = this.total.received.favourites / daysSinceJoined;
this.average.day.received.watches = this.total.received.watches / daysSinceJoined;
this.average.day.uploads = (this.total.deviations + this.total.scraps) / daysSinceJoined;
this.average.day.pageviews = this.total.pageviews / daysSinceJoined;
this.average.day.views = this.total.views / daysSinceJoined;
this.average.deviation.comments = this.total.received.comments / (this.total.deviations + this.total.scraps);
this.average.deviation.favourites = this.total.received.favourites / (this.total.deviations + this.total.scraps);
this.average.deviation.views = this.total.views / (this.total.deviations + this.total.scraps);
Cache.displayData();
},
displayData : function(){
/* Ereasing the original displayed data */
dialog.innerHTML = ''; // :-)
dialog.newInfo(this.total.deviations, 'Deviation#');
dialog.newInfo(this.total.scraps, 'Scrap#');
dialog.newInfo(this.total.pageviews, 'Pageview#');
dialog.newInfo(this.total.views, 'View#');
dialog.newInfo(this.total.shouts, 'Shout#');
dialog.newInfo(this.total.forumposts, 'Forum Post#');
dialog.newInfo(this.total.categories, 'Different Categories');
dialog.newSpacer();
dialog.newInfo(this.total.given.comments, 'Comment# given');
dialog.newInfo(this.total.received.comments, 'Comment# received');
dialog.newInfo(this.total.given.favourites, 'Favourite# given');
dialog.newInfo(this.total.received.favourites, 'Favourite# received');
dialog.newInfo(this.total.given.watches, 'Friend#');
dialog.newInfo(this.total.received.watches, 'Watcher#');
dialog.newSpacer();
dialog.newInfo(this.average.day.given.comments, 'Comment# given per day');
dialog.newInfo(this.average.day.received.comments, 'Comment# received per day');
dialog.newInfo(this.average.day.given.favourites, 'Favourite# given per day');
dialog.newInfo(this.average.day.received.favourites, 'Favourite# received per day');
dialog.newInfo(this.average.day.given.watches, 'Friend# added per day');
dialog.newInfo(this.average.day.received.watches, 'Watche# received per day');
dialog.newSpacer();
dialog.newInfo(this.average.day.uploads, 'Submission# per day');
dialog.newInfo(this.average.day.pageviews, 'Pageview# per day');
dialog.newInfo(this.average.day.views, 'View# per day');
dialog.newSpacer();
dialog.newInfo(this.average.deviation.comments, 'Comment# received per Deviation');
dialog.newInfo(this.average.deviation.favourites, 'Favourite# received per Deviation');
dialog.newInfo(this.average.deviation.views, 'View# received per Deviation');
dialog.newSpacer();
dialog.newUrl(this.top.views.views, 'Most viewed Deviation', this.top.views.id, this.top.views.title);
dialog.newUrl(this.top.fullviews.fullviews, 'Most fullviewed Deviation', this.top.fullviews.id, this.top.fullviews.title);
dialog.newUrl(this.top.favourites.favourites, 'Most favoured Deviation', this.top.favourites.id, this.top.favourites.title);
dialog.newUrl(this.top.comments.comments, 'Most commented Deviation', this.top.comments.id, this.top.comments.title);
dialog.newSpacer();
dialog.innerHTML += 'Most used gallery: <a href="http://'+this.other.username+'.deviantart.com/gallery/#_browse/'+this.top.cat.name+'/" class="a">'+this.top.cat.name.replace(/\//g,' > ')+'</a> (<strong>'+comma(this.top.cat.count)+' Deviations</strong>)<br />';
dialog.innerHTML += 'Most used category: <a href="http://'+this.other.username+'.deviantart.com/gallery/#_browse/'+this.top.caty.name+'/" class="a">'+this.top.caty.name.replace(/\//g,' > ')+'</a> (<strong>'+comma(this.top.caty.count)+' Deviations</strong>)<br />';
//dialog.newCat(this.top.cat.count, 'Most used gallery', this.top.cat.name);
//dialog.newCat(this.top.caty.count, 'Most used category', this.top.caty.name);
$('dsStatus').innerHTML = 'Finished';
GM_addStyle('body div.popup2-gruser-stats { width:auto; white-space:nowrap; }');
}
}
/* Now start it!!! */
Cache.getData();
/* Do the prototyping!! */
String.prototype.trim = function(){
return this.replace(/^\s+|\s+$/g, '');
}
dialog.newInfo = function(num, txt){
txt = num==1 ? txt.replace(/#/,'') : txt.replace(/#/,'s');
this.innerHTML += '<strong>'+comma(num)+'</strong> '+txt + '<br />';
}
dialog.newUrl = function(num, txt, url, urlTxt){
this.innerHTML += txt+': <a href="http://www.deviantart.com/deviation/'+url+'/" class="a">'+urlTxt+'</a> (<strong>'+comma(num)+'</strong>)<br />';
}
dialog.newCat = function(num, txt, url){
this.innerHTML += txt+': <a href="http://browse.deviantart.com/'+url+'/" class="a">'+url.replace(/\//g,' > ')+'</a> (<strong>'+comma(num)+' Deviations</strong>)<br />';
}
dialog.newSpacer = function(){
this.innerHTML += '<hr />';
}
function $(id){
var el =(typeof(id)=='string'?document.getElementById(id):false);
if(el){
el.remove=function(){
this.parentNode.removeChild(this);
}
el.insertAfter=function(newElement) {
if(this.parentNode.lastchild == this)
this.parentNode.appendChild(newElement);
else
this.parentNode.insertBefore(newElement, this.nextSibling);
}
}
return el;
}
function $X(xpath,root){
var got=document.evaluate(xpath,root||document,null,null,null), result=[];
while(next=got.iterateNext()) result.push(next);
return result;
}
function $E(tag, attributes, children){
var e=document.createElement(tag);
function applyObj(to, obj){
for(prop in obj) if(obj.hasOwnProperty(prop))
if(typeof(obj[prop])=='object')
applyObj(to[prop], obj[prop]);
else
to[prop]=obj[prop];
}
applyObj(e, attributes);
for(var c in children)
if(typeof(children[c])=='string') e.appendChild($S(children[c]));
else e.appendChild(children[c]);
return e;
}
function $S(str){
return document.createTextNode(str);
}
function comma(flo) {
if(!flo) return 'none';
flo = new String(Math.floor(flo*100)/100);
var integer = flo.split('.')[0];
if(integer.length>3) {
var start = integer.length-3;
return comma(integer.substring(0,start))+','+integer.substring(start);
}
else if(flo.split('.').length > 1)
return integer+'.'+flo.split(".")[1];
else
return integer;
}
function addEvent(obj, evType, fn, useCapture){
if(!obj) return;
if(typeof(evType)=='string') evType=[evType];
evType.forEach(
function(evnt, idx, ary){
obj.addEventListener(evnt, fn, useCapture);
}
)
}
/* get post data */
function get(url,cb){GM_xmlhttpRequest({method:"GET", url:url, headers:{'User-Agent':'Firefox / GreaseMonkey / deviantFriends'}, onload:function(xhr){cb(xhr.responseText,xhr.status)}})}
styles.push('body div.popup2-gruser-stats { height:auto !important; }');
styles.push('.pppbox hr { margin-top:15px; }');
styles.push('div.blues-bar span.bb span.tight { font-size:6pt !important; top:-0.5em !important; }');
GM_addStyle(styles.join('\n'));
