Guest User

Friend or Foe

a guest
Nov 1st, 2010
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ==UserScript==
  2. // @name           Friend or Foe
  3. // @version        1.0.2
  4. // @author         TheRedTeam
  5. // @namespace      reddit
  6. // @description    Create list of friends and foes and perform actions on them
  7. // @include        *reddit.com/r/*
  8. // @exclude        *iframe*reddit.com/*
  9. // ==/UserScript==
  10.  
  11. /*
  12. Changelog:
  13. 09/23/10:1.0.0: First release, works decent
  14. 09/23/10:1.0.1: Fixed race condition if multiple tabs open
  15. 11/01/10:1.0.2: Fixed opacity disallowing link clicking on right floating div
  16.  
  17. */
  18.  
  19.  
  20. // current lists
  21. var friend_list = [];
  22. var foe_list = [];
  23. var fof_user = "";
  24. var fof_usercolors = []; // cache of link colors
  25.  
  26. // reddit can't handle clicking things too fast or it will miss some
  27. // so we save all objects to click in an array, and use an interval on a timer
  28. // this does the clicking asycronously in the background for us
  29. var clicklist = new Array();
  30. var clickinterval = null;
  31.  
  32. // prototype the crap out of the array object
  33. Array.prototype.has = function (obj) {
  34.     for (var i = 0, j = this.length; i < j; i++) {
  35.         if (this[i] == obj)
  36.             return true;
  37.     }
  38.     return false;
  39. };
  40. Array.prototype.remove = function(obj) {
  41.   for(i=0; i<this.length; i++)
  42.     if(this[i] == obj){
  43.         this.splice(i, 1);
  44.         i--;
  45.     }
  46. };
  47.  
  48.  
  49. // get jquery from reddit
  50. $ = unsafeWindow.$;
  51.  
  52. // add menu bar items
  53. var mymenu = document.createElement("div");
  54. mymenu.className = "sidecontentbox";
  55. var side = document.getElementsByClassName("side")[0];
  56. side.style.zIndex = 100;
  57. side.insertBefore(mymenu,side.firstChild);
  58. // we do inline CSS here to override reddit's styles because
  59. // they use the !important attribute on everything >:(
  60. mymenu.innerHTML = "<div class='content' style='-moz-border-radius-bottomright: 10px; -moz-border-radius-bottomleft: 10px; border-top: 0px; background-color: #FFFFBB;'> \
  61.                     <div style='text-align: center; border-bottom: 1px solid #888;'><span style='font-family: arial; font-size: 14px; font-weight: bold; color: #996633;'>Friend or Foe</span></div> \
  62.                     <div style='margin-bottom: 5px; font-family: arial; font-size: 10px; color: #444;'><span id='fofcounts'></span> (<a href='javascript:userViewLists();'>details</a>)</div> \
  63.                     <ul>   \
  64.                         <li><a href='javascript: autoh();'>auto-hide</a></li> \
  65.                     </ul> \
  66.                     <div style='margin-top: 5px; font-family: arial; font-size: 10px; color: #444;' id='fofstatus'></div> \
  67.                     </div>";
  68.  
  69.  
  70.  
  71.  
  72. /*
  73. ########################  Start Helper Functions ############################
  74. */
  75.  
  76. unsafeWindow.userViewLists =
  77. function(){
  78.     alert("Friends: "+friend_list.toString()+"\n\nFoes: "+foe_list.toString());
  79. };
  80.  
  81.  
  82. function userSetCounts(){
  83.     var counts = document.getElementById('fofcounts');
  84.     counts.innerHTML = friend_list.length+" friends and "+foe_list.length+" foes";
  85. };
  86.  
  87. // pull lists
  88. function getlists(){
  89.     var t1 = GM_getValue('fof_foelist','');
  90.     var t2 = GM_getValue('fof_friendlist','');
  91.     // see if there is a difference
  92.     if(t1=='') foe_list = [];
  93.     else foe_list = t1.split(',');
  94.     if(t2=='') friend_list = [];
  95.     else friend_list = t2.split(',');
  96. }
  97.  
  98. // save changes to lists
  99. function savelists(){
  100.     // get current lists again to see if another tab/window updated anything
  101.     var t1 = GM_getValue('fof_foelist','');
  102.     var t2 = GM_getValue('fof_friendlist','');
  103.     // if difference save changes
  104.     if(t1 != foe_list.toString()){
  105.         GM_setValue('fof_foelist',foe_list.toString());
  106.     }
  107.     if(t2 != friend_list.toString()){
  108.         GM_setValue('fof_friendlist',friend_list.toString());
  109.     }
  110. }
  111.  
  112.  
  113.  
  114. // Add a Foe function
  115. unsafeWindow.userAddFoe =  
  116. function(s){
  117.     fof_user = s;
  118.     // run in timeout so we can call GM_ funcs
  119.     setTimeout(
  120.         function (){
  121.             if(foe_list.has(fof_user))
  122.                 return;
  123.             getlists();
  124.             foe_list.push(fof_user);
  125.             savelists();
  126.             addButtons();
  127.             userSetCounts();
  128.             setstatus("Set '"+fof_user+"' as Foe");
  129.         },
  130.     0);
  131. };
  132.  
  133. // Add a Friend function
  134. unsafeWindow.userAddFriend =  
  135. function (s){
  136.     fof_user = s;
  137.     // run in timeout so we can call GM_ funcs
  138.     setTimeout(
  139.         function (){
  140.             if(friend_list.has(fof_user))
  141.                 return;
  142.             getlists();
  143.             friend_list.push(fof_user);
  144.             savelists();
  145.             addButtons();
  146.             userSetCounts();
  147.             setstatus("Set '"+fof_user+"' as Friend");
  148.         },
  149.     0);
  150. };
  151.  
  152. // unset user from both friend and foe lists
  153. unsafeWindow.userUnset =  
  154. function (s){
  155.     fof_user = s;
  156.     // run in timeout so we can call GM_ funcs
  157.     setTimeout(
  158.         function (){
  159.             getlists()
  160.             friend_list.remove(fof_user);
  161.             foe_list.remove(fof_user);
  162.             savelists();
  163.             addButtons();
  164.             userSetCounts();
  165.             setstatus("Removed '"+fof_user+"' from lists");
  166.         },
  167.     0);
  168. };
  169.  
  170. // create click event to use on divs and anchor tags
  171. function clickevent(){
  172.     var evt = document.createEvent("MouseEvents");
  173.     evt.initMouseEvent("click", true, true, window,0, 0, 0, 0, 0, false, false, false, false, 0, null);
  174.     return evt;
  175. }
  176.  
  177. // shortcut to set the status
  178. function setstatus(s){
  179.     var stat = document.getElementById('fofstatus');
  180.     stat.innerHTML = stat.innerHTML+s+"<br>";
  181. }
  182.  
  183. // loop through and click everything in the list
  184. // note we kill the interval that calls this when the list is empty
  185. function clickloop(){
  186.     if(clicklist.length==0){
  187.         clickinterval = null;
  188.         return;
  189.     }
  190.     var elm = clicklist.pop();
  191.     elm.dispatchEvent(clickevent());
  192. }
  193.  
  194. // get a css property, you'd think this would be easier...
  195. function getStyle(x,styleProp)
  196. {
  197.     if (x.currentStyle)
  198.         var y = x.currentStyle[styleProp];
  199.     else if (window.getComputedStyle)
  200.         var y = document.defaultView.getComputedStyle(x,null).getPropertyValue(styleProp);
  201.     return y;
  202. }
  203.  
  204.  
  205.  
  206.  
  207.  
  208. /*
  209. ########################  Start Main Functions ############################
  210. */
  211.  
  212.  
  213. function addButtons(){
  214.     // div that holds all the submissions
  215.     var t = document.getElementsByClassName("midcol");
  216.     // loop through submissions
  217.     for(i=0; i < t.length; i++){
  218.         // parent node is the div container for the submission
  219.         submission = t[i].parentNode;
  220.         // try to find the username
  221.         var userbox = submission.getElementsByClassName("tagline")[0];
  222.         var title = submission.getElementsByClassName("title loggedin")[0];
  223.         // if in the recently viewed box (no username shown there) skip it
  224.         try{
  225.             var user = userbox.getElementsByTagName("a")[0];
  226.         }catch(e){
  227.             continue; // no username section
  228.         }
  229.         if(user == undefined)
  230.             continue; // user is [deleted]
  231.         var username = user.innerHTML;
  232.         // save reddit's user colors so we can reset if needed
  233.         if(fof_usercolors[username]==undefined){
  234.             fof_usercolors[username] = getStyle(user, "color");
  235.         }
  236.         // now chose what colors to use according to the user
  237.         if(foe_list.has(username)){
  238.             user.style.color = fof_usercolors[username]; //"#336699"
  239.             $(submission).css('opacity',0.3);
  240.             submission.style.marginRight = "300px"; // opacity annoyance
  241.         }
  242.         else if(friend_list.has(username)){
  243.             user.style.color = "#00AA00";
  244.             title.style.color = "#00AA00";
  245.             $(submission).css('opacity',1);
  246.         }
  247.         else{
  248.             user.style.color = fof_usercolors[username]; //"#336699"
  249.             title.style.color = "inherit";
  250.             $(submission).css('opacity',1);
  251.         }
  252.         // see if userops is already set, if not append it
  253.         var userops = userbox.getElementsByClassName("userops")[0];
  254.         if(userops == undefined){
  255.             userops = document.createElement("span");
  256.             userops.className = "userops";
  257.             userbox.appendChild(userops);
  258.         }
  259.         // now fill with appropriate links
  260.         if(foe_list.has(username) | friend_list.has(username))
  261.             userops.innerHTML = " (<a style='color: #666;' href=\"javascript:userUnset('"+username+"');\">unset</a>)";
  262.         else
  263.             userops.innerHTML = " (<a style='color: #666;' href=\"javascript:userAddFoe('"+username+"');\">foe</a>|<a style='color: #666;' href=\"javascript:userAddFriend('"+username+"');\">friend</a>)";
  264.     }
  265. }
  266.  
  267.  
  268. // This goes through and clicks the "hide" button on the submissions
  269. // we add it to the reddit context so the link we add can call it
  270. unsafeWindow.autoh =  
  271. function (){
  272.     // div that holds all the submissions
  273.     var t = document.getElementsByClassName("midcol");
  274.     var c = 0;
  275.     var v = 0;
  276.     // loop through submissions
  277.     for(i=0; i < t.length; i++){
  278.         // parent node is the div container for the submission
  279.         submission = t[i].parentNode;
  280.         var userbox = submission.getElementsByClassName("tagline")[0];
  281.         // if in the recently viewed box (no username shown there) skip it
  282.         try{
  283.             var username = userbox.getElementsByTagName("a")[0].innerHTML;
  284.         }catch(e){
  285.             continue; // no username section
  286.         }
  287.         // if not a bad user, skip this iteration
  288.         if(!foe_list.has(username))
  289.             continue;
  290.         c++;
  291.         // hide it if it's down voted only
  292.         if(t[i].className == "midcol dislikes"){
  293.             // add object to click to the clicklist
  294.             clicklist.push(submission.getElementsByClassName('state-button hide-button')[0].getElementsByTagName('a')[0]);
  295.             v++;
  296.         }
  297.     }
  298.     // start hiding (3 second time due to stupid fade out effect)
  299.     clickinterval = setInterval(clickloop, 3000);
  300.     // set status
  301.     setstatus("Hid "+v+" of "+c+" bad submissions");
  302. };
  303.  
  304.  
  305.  
  306.  
  307. // function to perform action on submissions
  308. function autov(){
  309.     try{
  310.     // get all submissions
  311.     var t = document.getElementsByClassName("midcol");
  312.     // loop through unvoted submissions
  313.     var c = 0;
  314.     var v = 0;
  315.     for(i=0; i < t.length; i++){
  316.         // parent node is the div container for the submission
  317.         var submission = t[i].parentNode;
  318.         // now get the appropriate objects we check
  319.         var downarrow = submission.getElementsByClassName("arrow down")[0];
  320.         var userbox = submission.getElementsByClassName("tagline")[0];
  321.         // if in the recently viewed box (no username shown there) skip it
  322.         try{
  323.             var username = userbox.getElementsByTagName("a")[0].innerHTML;
  324.         }catch(e){
  325.             continue; // no username section
  326.         }
  327.         // if not a bad user, skip this iteration
  328.         if(!foe_list.has(username))
  329.             continue;
  330.         c++;
  331.         // if not already down voted, down vote it
  332.         if(t[i].className == "midcol unvoted"){
  333.             // save arrow to an array for down-voting later
  334.             clicklist.push(downarrow);
  335.             v++;
  336.         }
  337.     }
  338.     // start down voting form the list we made (1 second timer)
  339.     clickinterval = setInterval(clickloop, 1000);
  340.     // set status
  341.     if(c==0)
  342.         setstatus("No bad submissions found");
  343.     else
  344.         setstatus("Auto down voted "+v+" of "+c+" bad submissions");
  345.     }
  346.     catch(e){
  347.         setstatus("Error: "+e);
  348.     }
  349. }
  350.  
  351.  
  352.  
  353.  
  354. /*
  355. ########################  Begin auto-procedures ############################
  356. */
  357.                    
  358. // do auto-voting only if we are on a table with submissions listed
  359. if(document.getElementById('siteTable') != null){
  360.     getlists();
  361.     userSetCounts();
  362.     autov();
  363.     addButtons();
  364. }
Add Comment
Please, Sign In to add comment