summaryrefslogtreecommitdiffstats
path: root/uftow-stats.user.js
diff options
context:
space:
mode:
Diffstat (limited to 'uftow-stats.user.js')
-rw-r--r--uftow-stats.user.js349
1 files changed, 349 insertions, 0 deletions
diff --git a/uftow-stats.user.js b/uftow-stats.user.js
new file mode 100644
index 0000000..fdfb838
--- /dev/null
+++ b/uftow-stats.user.js
@@ -0,0 +1,349 @@
+// ==UserScript==
+// @name uftow-stats
+// @namespace uftow-stats
+// @include http://ubuntuforums.org/showthread.php?t=1579442*
+// @version 1.2.1
+// @Description Generates stats for Tug of War.
+// @grant GM_getValue
+// @grant GM_setValue
+// @grant GM_log
+// @grant GM_listValues
+// @grant GM_setValue
+// @grant GM_addStyle
+// @grant GM_deleteValue
+// @grant GM_registerMenuCommand
+// ==/UserScript==
+
+var towConfig = {
+ multipliers:new Array(
+ //Forum Staff
+ 'images/rank_uf_moderator_2013-07.png',-2,
+ //Forum Admin
+ 'images/rank_uf_admin_2013-07.png',-4,
+ //LoCo mods
+ 'font-weight: bold; color: #339900;',2,
+ //Ubuntu Member
+ 'images/rank_ubuntumember_2013-02.png',2,
+ //Kubuntu Member - unchanged (2013.02.17)
+ 'images/rebrand/ranks/rankkubuntumember.png',2,
+ //Staff Emeritus
+ 'images/rank_oldstaff_2013-02.png',3,
+ //Forum Donators - unchanged (2013.02.13)
+ 'images/rank_forum_donators.png',4,
+ //Ubuntu Developers - unchanged (2013.02.13)
+ 'images/rank_ubuntudeveloper.png',4,
+ //Ubuntu One Developers - Unable to verify whether or not this has changed (2013.02.13)
+ 'http://kryogenix.org/random/u1-forums-rank-logo.png',4
+ )
+};
+var towStats = {
+ alreadyHasStartCounting:false,
+ scores:new Array(),
+ currentScore:0,
+ lastPostNumber:null,
+ winner:null,
+ marker:null,
+ markerPost:null,
+ lastPoster:null,
+ init:function(){
+ this.postContainers=document.getElementsByClassName('postcontainer');
+ this.firstPostNumber=this.parsePostNumber(this.postContainers[0].getElementsByClassName('postcounter')[0].textContent);
+ this.lastPostNumber=this.parsePostNumber(this.postContainers[this.postContainers.length-1].getElementsByClassName('postcounter')[0].textContent);
+ this.currentScore=0;
+ if(!GM_getValue("statsActive",false)){
+ GM_registerMenuCommand("Start counting posts",function(){towStats.startCounting();},'S');
+ this.alreadyHasStartCounting=true;
+ }else{
+ this.startCounting();
+ }
+ GM_registerMenuCommand("Clear counter",function(){towStats.clearStats();},'A');
+ },
+ recordPosts: function(start){
+ var postNumber;
+ var startDiff=start-this.firstPostNumber;
+ var postInfo;
+ GM_log("Seek ahead by "+startDiff+" posts");
+ //alt4Number=1+(startDiff*2);
+ if(startDiff<0){
+ alert("No such post exists on this page");
+ return false;
+ }
+ for (var i=startDiff;i<this.postContainers.length;i++){
+ //postInfo=this.getPostInfo(currentPagePost,i);
+ postInfo=this.getPostInfo(this.postContainers[i]);
+ this.lastPostNumber = postInfo[3];
+ //alt4Number+=2;
+ //currentPagePost++;
+ if(this.lastPoster==postInfo[0]){
+ GM_log("Post #"+this.lastPostNumber+" is a duplicate and has been skipped.");
+ continue;
+ }
+ this.scorePost(postInfo);
+ if(this.currentScore<=-200){
+ this.winner='mods';
+ }else if(this.currentScore>=200){
+ this.winner='community';
+ }if(this.winner!=undefined){
+ this.marker=postInfo[0];
+ this.markerPost=postInfo[3];
+ break;
+ }
+ GM_log("Post: "+postInfo[3]+", Round score: "+this.currentScore);
+ }
+ },
+ getPostInfo: function(postElement){
+ var userSpanTag=postElement.getElementsByClassName('username')[0].getElementsByTagName('span')[0];
+ var userName=userSpanTag.textContent;
+ var css=userSpanTag.getAttribute('style');
+ var rankURL=postElement.getElementsByClassName('rank')[0].getElementsByTagName('img')[0].getAttribute('src');
+ var postNumber=this.parsePostNumber(postElement.getElementsByClassName('postcounter')[0].textContent);
+ if(userName==""){
+ userName='[UNKNOWN USERNAME]';
+ }
+ return new Array(userName,css,rankURL,postNumber);
+ },
+ scorePost: function(postInfo){
+ this.lastPoster=postInfo[0];
+ var groupImgIndex=towConfig.multipliers.indexOf(postInfo[2]);
+ if(groupImgIndex==-1){
+ groupImgIndex=towConfig.multipliers.indexOf(postInfo[1]);
+ }
+ multiplier=(groupImgIndex==-1)?1:towConfig.multipliers[groupImgIndex+1];
+ this.currentScore+=multiplier;
+ userIndex=this.scores.indexOf(postInfo[0]);
+ //The second check in the if statement makes sure users with usernames being actual numbers don't break this script
+ if(userIndex!=-1&&userIndex%3==0){
+ this.scores[userIndex+2]++;
+ }else{
+ this.scores.push(postInfo[0]);
+ this.scores.push(multiplier);
+ this.scores.push(1);
+ }
+ },
+ getSummary: function(){
+ if(this.winner!=undefined){
+ var alertText="[B]TUG OF WAR LAST ROUND STATS[/B]\n";
+ var totalPoints=0;
+ var totalPosts=0;
+ var totalModPoints=0;
+ var totalModPosts=0;
+ var totalCommunityPoints=0;
+ var totalCommunityPosts=0;
+ var minimumRequiredMVP;
+ var mvpList=new Array();
+ var communityParticipants=new Array();
+ var winners;
+ var allowMVP;
+ var modParticipants=new Array();
+ GM_log(this.scores);
+ for(var i=1;i<this.scores.length;i+=3){
+ GM_log("STATS: User: "+this.scores[i-1]+", Multiplier: "+this.scores[i]+", Points: "+this.scores[i+1]+", Is Mod: "+this.scores[i+2]);
+ totalPoints+=(this.scores[i+1]*(Math.abs(this.scores[i])));
+ if(this.scores[i]<0){
+ totalModPoints+=this.scores[i+1]*(Math.abs(this.scores[i]));
+ totalModPosts+=this.scores[i+1];
+ }else if(this.scores[i]>0){
+ totalCommunityPoints+=this.scores[i+1]*this.scores[i];
+ totalCommunityPosts+=this.scores[i+1];
+ }
+ totalPosts+=this.scores[i+1];
+ }
+ minimumRequiredMVP=Math.round(((this.winner=='community')?totalCommunityPoints:totalModPoints)*0.15);
+ alertText+="[B]Total points:[/B] "+totalPoints+" from "+totalPosts+" posts\n";
+ alertText+="[B]Total community points:[/B] ";
+ if(totalCommunityPosts>0){
+ alertText+=totalCommunityPoints+" from "+totalCommunityPosts+" posts\n";
+ }else{
+ alertText+="None\n";
+ }
+ alertText+="[B]Total mod points:[/B] ";
+ if(totalModPosts>0){
+ alertText+=totalModPoints+" from "+totalModPosts+" posts\n";
+ }else{
+ alertText+="None\n";
+ }
+ alertText+="[B]Minimum required for MVP* ("+((this.winner=='community')?totalCommunityPoints:totalModPoints)+" x 0.15):[/B] "+minimumRequiredMVP+"\n\n";
+ for(var i=0;i<this.scores.length;i+=3){
+ if(this.scores[i+1]<0){
+ modParticipants.push(this.scores[i]);
+ modParticipants.push(Math.abs(this.scores[i+1]));
+ modParticipants.push(this.scores[i+2]);
+ }else{
+ communityParticipants.push(this.scores[i]);
+ communityParticipants.push(this.scores[i+1]);
+ communityParticipants.push(this.scores[i+2]);
+ }
+ }
+ alertText+="[B]COMMUNITY PARTICIPANTS[/B]\n";
+ allowMVP=(this.winner=='community');
+ communityStats=this.getListText(communityParticipants,minimumRequiredMVP);
+ alertText+=communityStats[0]+"\n";
+ alertText+="[B]MODERATOR PARTICIPANTS[/B]\n";
+ allowMVP=(this.winner=='mods');
+ modStats=this.getListText(modParticipants,minimumRequiredMVP);
+ alertText+=modStats[0]+"\n";
+ alertText+="[B]LAST ROUND MVPs[/B]\n";
+ alertText+="- "+this.marker+" (at post #"+this.lastPostNumber+") \n";
+ GM_log("MVP Order: "+this.marker+" made the mark at post #"+this.markerPost);
+ mvpList=(this.winner=='community')?communityStats[1]:modStats[1];
+ for(var i=0;i<mvpList.length;i++){
+ if(mvpList[i]!=this.marker){
+ alertText+="- "+mvpList[i]+"\n";
+ GM_log("MVP Order: "+mvpList[i]+" has spot #"+(i+2));
+ }
+ }
+ alertText+="\n*Starting with second place. The marker gets first place MVP.";
+ window.alert(alertText);
+ }else{
+ window.alert("Tug of War is yet to be completed.\nIts score is "+this.currentScore+" points as of post #"+this.lastPostNumber);
+ }
+ this.clearStats();
+ },
+ getListText: function(participants,minimumRequiredMVP){
+ var statsText="";
+ var thisScore;
+ var mvpList=new Array();
+ var doneSorting=false;
+ var reCheck=true;
+ GM_log("Participant List: "+participants);
+ var tempSpot;
+ while(reCheck){
+
+ reCheck=false;
+ for(var i=0;i<participants.length;i+=3){
+ if(i+3>=participants.length){
+ break;
+ }
+ if(participants[i+2]*participants[i+1]<participants[i+5]*participants[i+4]){
+ tempSpot=new Array(participants[i],participants[i+1],participants[i+2]);
+ participants[i]=participants[i+3];
+ participants[i+1]=participants[i+4];
+ participants[i+2]=participants[i+5];
+ participants[i+3]=tempSpot[0];
+ participants[i+4]=tempSpot[1];
+ participants[i+5]=tempSpot[2];
+ reCheck=true;
+ }
+ }
+ }
+ for(var i=0;i<participants.length;i+=3){
+ thisScore=participants[i+2]*participants[i+1];
+ statsText+="[B]"+participants[i]+":[/B] "+participants[i+2]+" x "+participants[i+1]+" = "+thisScore+" ";
+ statsText+="point"+((thisScore!=1)?"s":"");
+ statsText+="\n";
+ GM_log("Added "+participants[i]+" to the stats list DEBUG: Posts: "+participants[i+2]+", Multiplier: "+participants[i+1]+", Total Score: "+thisScore+", minimumRequiredMVP: "+minimumRequiredMVP);
+ if(thisScore>=minimumRequiredMVP){
+ GM_log("Adding "+participants[i]+" to the MVP list.");
+ mvpList.push(participants[i]);
+ }
+ }
+ if(participants.length==0){
+ statsText+="None\n";
+ }
+ return new Array(statsText,mvpList);
+ },
+ restoreStats: function(){
+ var statsActive=GM_getValue("statsActive",false);
+ var scoresCount=GM_getValue("scores.count",0);
+ if(statsActive==false){
+ GM_log("Attempting to save setting statsActive");
+ GM_setValue("statsActive",true);
+ return false;
+ }else{
+ this.lastUser=GM_getValue("lastPoster",null);
+ this.currentScore = parseInt(GM_getValue("CurrentScore"));
+ this.lastPostNumber = parseInt(GM_getValue("lastPostNumber"));
+ for(i=0;i<scoresCount;i++){
+ this.scores.push(GM_getValue("scores."+i));
+ //alert(GM_getValue("scores."+i));
+ }
+ return true;
+ }
+ },
+ startCounting: function(){
+ //alert(5);
+ //var theAnswer;
+ //alert(6);
+ if(this.restoreStats()){
+ startPost=this.lastPostNumber+1;
+ }else{
+ theAnswer=window.prompt("Specifiy a post number to begin counting.\nIf you do not know the post number, click Cancel.");
+ if(theAnswer!=null){
+ startPost=parseInt(theAnswer);
+ GM_setValue('statsActive',true);
+ }else{
+ this.clearStats();
+ return false;
+ }
+ }
+ GM_log("Round score before counting: "+this.currentScore);
+ this.recordPosts(startPost);
+ if(this.winner!=null){
+ window.alert("Counting complete.\n"+
+ "The "+((this.winner=='mods')?'-':'')+"200 mark is at post #"+this.markerPost+"\n"+
+ "Stats will be displayed in the next dialog box.");
+ this.getSummary();
+ }else{
+ this.saveStats();
+ if(!this.goToNextPage()){
+ window.alert("Tug of War is yet to be completed.\nIts score is "+this.currentScore+" points as of post #"+this.lastPostNumber);
+ this.clearStats();
+ }
+ }
+ },
+ saveStats: function(){
+ GM_log("lastPostNumber: "+this.lastPostNumber);
+ //GM_log("Attempting to save setting lastPostNumber, value: "+this.lastPostNumber);
+ GM_setValue("lastPostNumber",this.lastPostNumber);
+ GM_log("Round score after counting this page's posts: "+this.currentScore);
+ //GM_log("Attempting to save setting currentScore, value: "+this.currentScore);
+ GM_setValue("CurrentScore",this.currentScore);
+ for(i=0;i<this.scores.length;i++){
+ //GM_log("Attempting to save setting this.scores."+i+", value: "+this.scores[i]);
+ GM_setValue("scores."+i,this.scores[i]);
+ //GM_log("Attempting to save setting this.scores.length, value: "+this.scores.length);
+ GM_setValue("scores.count",this.scores.length);
+ }
+ //GM_log("Attempting to save setting lastPoster, value: "+this.lastPoster);
+ GM_setValue("lastPoster",this.lastPoster);
+ },
+ goToNextPage: function(){
+ var pageLinks=document.getElementsByClassName('pagination_top')[0];
+ var nextLinkContainer=pageLinks.getElementsByClassName('prev_next')[1];
+ if(nextLinkContainer!=undefined){
+ nextLinkContainer.getElementsByTagName('a')[0].click();
+ return true;
+ }else{
+ return false;
+ }
+ },
+ isUserOnScoresList: function(username){
+ for(var i=0;i<this.scores.length;i++){
+
+ }
+ },
+ clearStats: function(){
+ this.scores=new Array();
+ this.currentScore=0;
+ this.lastPostNumber=null;
+ this.winner=null;
+ this.marker=null;
+ this.markerPost=null;
+ this.lastPoster=null;
+ keys = GM_listValues();
+ for (var i=0, key=null; key=keys[i]; i++) {
+ GM_deleteValue(key);
+ GM_log("Deleted key: "+key);
+ }
+ GM_log("Reset Successful");
+ if(!this.alreadyHasStartCounting){
+ GM_registerMenuCommand("Start counting posts",function(){towStats.startCounting()},'S');
+ this.alreadyHasStartCounting=true;
+ }
+ },
+ parsePostNumber:function(numStr){
+ return parseInt(numStr.substr(1));
+ }
+};
+
+towStats.init(); \ No newline at end of file