mmmturkeybacon Ghost HIT Buster for Forums

Searches forum posts for HIT links, follows them, determines if the HIT is still available, and strikes the post if the HIT is a ghost or changes the link text to show the automatic approval time and number remaining if the HIT is available. Works with Live Update. Uses just-in-time link checking to reduce "maximum allowed page request rate" errors. Uncomment CHIME to receive an audio alert if there is a new HIT post.

  1. // ==UserScript==
  2. // @name mmmturkeybacon Ghost HIT Buster for Forums
  3. // @version 1.39
  4. // @description Searches forum posts for HIT links, follows them, determines if the HIT is still available, and strikes the post if the HIT is a ghost or changes the link text to show the automatic approval time and number remaining if the HIT is available. Works with Live Update. Uses just-in-time link checking to reduce "maximum allowed page request rate" errors. Uncomment CHIME to receive an audio alert if there is a new HIT post.
  5. // @author mmmturkeybacon
  6. // @namespace http://userscripts.org/users/523367
  7. // @match http://mturkgrind.com/threads/*
  8. // @match http://www.mturkgrind.com/threads/*
  9. // @match http://mturkforum.com/showthread.php?*
  10. // @match http://www.mturkforum.com/showthread.php?*
  11. // @match http://turkernation.com/showthread.php?*
  12. // @match http://www.turkernation.com/showthread.php?*
  13. // @match http://mturkcrowd.com/threads/*
  14. // @match http://www.mturkcrowd.com/threads/*
  15. // @require https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js
  16. // @grant GM_log
  17. // @grant GM_xmlhttpRequest
  18. // ==/UserScript==
  19.  
  20. var REQUEST_DELAY = 500; // milliseconds
  21. var LINK_POSITION_OFFSET = 400; // number of pixels abover or below viewport to trigger link check
  22. // remove the // on the next line to enable audio notification
  23. //var CHIME = 'data:audio/ogg;base64, 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Y5l93VlmX3eO4Rg6v/Djqaqvm64rDKcsC7/t68az+76yjK7r+6osC78q28Kx677z/L6wLKPs+sJqy8Kw2rYx3L5uLL9wHMtr68ox675RtnV8X3gKw/N0dV15Zl3H9nV040c4fsoAAIABBwCAABPKQKEhKwKAOAEAjySJomRZoihZliiKpui6omi6rqRppqlpnmlammeapmmqsimarixpmmlanmaamqeZpmiarmuapqyKpinLpmrKsmmasuy6sm27rmzbomnKsmmasmyapiy7sqvbruzquqRZpql5nmlqnmeapmrKsmmarqt5nmp6nmiqniiqqmqqqq2qqixbnmeamuippieKqmqqpq2aqirLpqrasmmqtmyqqm27quz6sm3rummqsm2qpi2bqmrbruzqsizbui9pmmlqnmeamueZpmmasmyaqitbnqeaniiqquaJpmqqqiybpqrKlueZqieKquqJnmuaqirLpmraqmmatmyqqi2bpirLrm37vuvKsm6qqmybqmrrpmrKsmzLvu/Kqu6KpinLpqrasmmqsi3bsu/Lsqz7omnKsmmqsm2qqi7Lsm0bs2z7umiasm2qpi2bqirbsi37uizbuu/Krm+rqqzrsi37uu76rnDrujC8smz7qqz6uivbum/rMtv2fUTTlGVTNW3bVFVZdmXZ9mXb9n3RNG1bVVVbNk3VtmVZ9n1Ztm1hNE3ZNlVV1k3VtG1Zlm1htmXhdmXZt2Vb9nXXlXVf133j12Xd5rqy7cuyrfuqq/q27vvCcOuu8AoAABhwAAAIMKEMFBqyEgCIAgAAjGGMMQiNUs45B6FRyjnnIGTOQQghlcw5CCGUkjkHoZSUMucglJJSCKGUlFoLIZSUUmsFAAAUOAAABNigKbE4QKEhKwGAVAAAg+NYlueZomrasmNJnieKqqmqtu1IlueJommqqm1bnieKpqmqruvrmueJommqquvqumiapqmqruu6ui6aoqmqquu6sq6bpqqqriu7suzrpqqqquvKriz7wqq6rivLsm3rwrCqruvKsmzbtm/cuq7rvu/7wpGt67ou/MIxDEcBAOAJDgBABTasjnBSNBZYaMhKACADAIAwBiGDEEIGIYSQUkohpZQSAAAw4AAAEGBCGSg0ZEUAECcAABhDKaSUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJIKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKqaSUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKZVSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUgoAkIpwAJB6MKEMFBqyEgBIBQAAjFFKKcacgxAx5hhj0EkoKWLMOcYclJJS5RyEEFJpLbfKOQghpNRSbZlzUlqLMeYYM+ekpBRbzTmHUlKLseaaa+6ktFZrrjXnWlqrNdecc825tBZrrjnXnHPLMdecc8455xhzzjnnnHPOBQDgNDgAgB7YsDrCSdFYYKEhKwGAVAAAAhmlGHPOOegQUow55xyEECKFGHPOOQghVIw55xx0EEKoGHPMOQghhJA55xyEEEIIIXMOOugghBBCBx2EEEIIoZTOQQghhBBKKCGEEEIIIYQQOgghhBBCCCGEEEIIIYRSSgghhBBCCaGUUAAAYIEDAECADasjnBSNBRYashIAAAIAgByWoFLOhEGOQY8NQcpRMw1CTDnRmWJOajMVU5A5EJ10EhlqQdleMgsAAIAgACDABBAYICj4QgiIMQAAQYjMEAmFVbDAoAwaHOYBwANEhEQAkJigSLu4gC4DXNDFXQdCCEIQglgcQAEJODjhhife8IQbnKBTVOogAAAAAAAMAOABAOCgACIimquwuMDI0Njg6PAIAAAAAAAWAPgAADg+gIiI5iosLjAyNDY4OjwCAAAAAAAAAACAgIAAAAAAAEAAAACAgE9nZ1MABKqeAAAAAAAAcIMRZAIAAABPPJt5Kh0YKh4eIB4eHh8fHh4eHiAfHh4eHh8fIB4eHh4eHiAeIiMmKC01PUBATnTp9+Cu+MEFMImro6Hixysv30/P/74ZP0/l5Xs9jPPu9fcg6B866L7djw5BTS9KLyWoJhUNmlvfg5tUOrtR71MEICEKAAAAAAAAAAAUgIS2r6+fPn1Hk6EoSd7eHgAA3ms/7ZtUpoSjnlMFrAbAPfUAAAAAAAAAAEAhcFgA3ms/rZsUpoSjnlMDVgPQP18BAAAAAAAAAADgOgYA3ls/1ZsUJodQ71MDTgoAAAAAAAAAAJwLAECEzfFnAgDeWz/Vm1SmhKPepwpYDUD/7QIAAAAAAAAAAAW1ugK+Wz+smxSWhKOeUwNWA9A/XwUAAAAAAAAAAAIvwQK+Wz/tm1SmhKOeUxysBsBdZRMAAAAAAAAAAIF4PwO+Sz+tm1SmhKPepzg4KQAAAAAAAAAAoAQAIBRdhDMCnks/rJsUloQjn1MDTgoAAAAAAAAAAKwSAICAXrfLCJ5LP62bFKaEo55TA1YDsP+eAgAAAAAAAAAAYK1oAZ47P62bFKaEo96nOFgNwP67AQAAAAAAAACUg1cEAH47P+ybVJaEI59TA1YDsL9XBwAAAAAAAACAw7pWAH47P62bFKaEo55TA1YD4Gu1AwAAAAAAAAAAhec2C34rP62bFCZHot6nODgpAAAAAAAAAACgAACgguSrRQMAXis/7atUloSjnlMcnBQAAAAAAAAAAFAAAFCBfzlgAF4bP62bFCaHo96nBqwGwMepAwAAAAAAAAAA2FY0AD4bP+ybVJaEI59TA1YD0D9PAwAAAAAAAACg4C4RAD4LP62bFCaHo96nGFgNQP9tBgAAAAAAAABAUeUDAB4LP+ybVJaEI59TA1YD0D9fBgAAAAAAAABAwXVrAR4LP62bFKaEo55TBawGwMcqLwEAAAAAAAAAENjrMAD++j7tq1SWhKOeUxycFAAAAAAAAAAAUAIAEIqOTY0A/uo+rZtUpoSj3qcKOCkAAAAAAAAAALBKAAAC8uZMIwDe6j6tmxSmhKOeUwNWA+D3qQAAAAAAAAAAAFy3FgC+2j7sm1SWhFDPqQJWA7D/HgAAAAAAAAAAcFgrKwC+yj6tmxSmhKPepwpYDcD+uwYAAAAAAAAAUA5LkgCeuj6tm1Qmh1DvUwdWA7C/VwsAAAAAAAAAAAqrmgF+uj7tm1SmRKKeUwNWA+BVpQAAAAAAAAAAQOEhWQBeqj7tq1SWhFDPKQxOCgAAAAAAAAAAKAAAqEBQZAA+mn7nVqnxSaTo7S4OVgOgrwCAAAAAAAAAABTC2g0AGh6KfudWqfFJpOjtLg5WA+DjNAAAAAAAAAAAFNZNAv55fmdXqf5JuOjtLgZWA9A/L4BQAAAAAAAABfc1gASQAFjeWX5nd2n+crjo6xQHqwHojxcAQgAAAAAAAADuHhRAMAHQAJ5JfuZ3afFLpOjpFF+F1QC4KwFUAAAAAAAAll8LQAEWLJAAsA0Afil+53ap8Upkip528S2sBkBXBVABABAAAAAC0dWCCSgAEAALdAWAAh4ZfuVXKfFJpOjpFNuH1QBQFUCFAggIAAAAUfSeFpYFJmhAB3SgSQBogA4kAP74/Z9hUaos9c+CnZkVgtUAeE0BUFWhAAAAal0LFjxcQaBAXwAFD1AAdKADYIEOFBIAEiABHtn9PwNRhmzqX+qxLzFcGFYD4DUAoapCAQAgcJ+p0AFQDJcK54VHS8+cB04SCWBBB6CRADABCZiABtCABv7I/Z+BIlO7+p967GIVWA2AVwNCVFUAADjc5wGAIWQD+s31+taUot9kTuwToT9kgsVDgwWwPMACNDABEKABBAD+yP2fXJHuXUOpwy5WhtUAeBUAsqpCAQDgyimgqVB4BXOm8hCJp7r7nQdoqTNAwoECPAAPgKQAQAALWB2AAJAAfsj9N1Mkza5uN3bWkxZOAAuep8GoqlAAXmut6+XZEQUYjUZz80Sj0ejdxcX1dWGK09DaMSRJRy+C+RKYcwFA92BBAjwIEIAETAAEeIAF';
  24. var VOLUME = 0.1; // volume of chime
  25.  
  26. var audio;
  27. var $preview_links;
  28. var posts_dict = {};
  29. var delay_counter = 0;
  30.  
  31. function mark_hit_post($link)
  32. {
  33. $link.text($link.text().replace('[Page Request Rate Error] -- ', ''));
  34. GM_xmlhttpRequest(
  35. {
  36. method: "GET",
  37. url: $link.attr('href'),
  38. onerror: function()
  39. {
  40. delay_counter--;
  41. alert('mmmturkeybacon Ghost HIT Buster for Forums: Page request failed.');
  42. },
  43. onload: function (response)
  44. {
  45. delay_counter--;
  46. var $src = $(response.responseText);
  47. var id = $link.closest('div[id^="post_message_"], li[id^="post-"]').attr('id');
  48. var maxpagerate = $src.find('td[class="error_title"]:contains("You have exceeded the maximum allowed page request rate for this website.")');
  49. if (maxpagerate.length == 0)
  50. {
  51. var is_a_HIT = $src.find('input[type="hidden"][name="isAccepted"]').length > 0;
  52. var not_qualified = $src.find('span[id="alertboxHeader"]:contains("Your Qualifications do not meet the requirements to preview HITs in this group.")').length > 0;
  53. var requester_results = $src.find('td[class="title_orange_text_bold"]:contains("HITs Created by")').length > 0;
  54. if (is_a_HIT)
  55. {
  56. var hitAutoAppDelayInSeconds = $src.find('input[type="hidden"][name="hitAutoAppDelayInSeconds"]').val();
  57. var num_available = $src.find('a[id="number_of_hits.tooltip"]').parent().next().text().trim();
  58. // time formatting code modified from http://userscripts.org/scripts/show/169154
  59. var days = Math.floor((hitAutoAppDelayInSeconds/(60*60*24)));
  60. var hours = Math.floor((hitAutoAppDelayInSeconds/(60*60)) % 24);
  61. var mins = Math.floor((hitAutoAppDelayInSeconds/60) % 60);
  62. var secs = hitAutoAppDelayInSeconds % 60;
  63. var time_str = (days == 0 ? '' : days + (days > 1 ? ' days ' : ' day ')) +
  64. (hours == 0 ? '' : hours + (hours > 1 ? ' hours ' : ' hour ')) +
  65. (mins == 0 ? '' : mins + (mins > 1 ? ' minutes ' : ' minute ')) +
  66. (secs == 0 ? '' : secs + (secs > 1 ? ' seconds ' : ' second '));
  67.  
  68. time_str = time_str.replace(/\s+$/, '');
  69.  
  70. if (hitAutoAppDelayInSeconds == 0)
  71. {
  72. time_str = "0 seconds";
  73. }
  74. $link.text('['+time_str+'|'+num_available+'] -- ' + $link.text());
  75. posts_dict[id].link_cnt++;
  76. posts_dict[id].strike_all_override = true;
  77. }
  78. else if (not_qualified)
  79. {
  80. $link.text('[not qualified] -- ' + $link.text());
  81. }
  82. else if (!is_a_HIT && !requester_results)
  83. {
  84. var $hit_container = $link.closest('table[class^="cms_table"], table[class^="ctaBbcodeTable"]');
  85. if ($hit_container.length > 0)
  86. {
  87. $hit_container.css('text-decoration', 'line-through');
  88. posts_dict[id].link_cnt++;
  89. }
  90. else
  91. {
  92. $link.css('text-decoration', 'line-through');
  93. posts_dict[id].link_cnt++;
  94. posts_dict[id].strike_all = true;
  95. }
  96. }
  97. }
  98. else
  99. {
  100. $link.text('[Page Request Rate Error] -- ' + $link.text());
  101. posts_dict[id].link_cnt++;
  102. posts_dict[id].strike_all_override = true;
  103. $link.attr('mtbghbff_checked', 'false');
  104. }
  105.  
  106. if ((posts_dict[id].strike_all_override == false) &&
  107. (posts_dict[id].strike_all == true) &&
  108. (posts_dict[id].link_cnt == posts_dict[id].num_links))
  109. {
  110. $link.closest('div[id^="'+id+'"], li[id^="'+id+'"]').css('text-decoration', 'line-through');
  111. }
  112. }
  113. });
  114. }
  115.  
  116. function check_link_position()
  117. {
  118. $preview_links.each(function()
  119. {
  120. var $link = $(this);
  121. if ($link.attr('mtbghbff_checked') != 'true')
  122. {
  123. var link_position = $link.offset().top;
  124. var top_of_viewport = $(window).scrollTop();
  125. var bottom_of_viewport = $(window).scrollTop() + $(window).height();
  126.  
  127. if(top_of_viewport-LINK_POSITION_OFFSET < link_position && bottom_of_viewport+LINK_POSITION_OFFSET > link_position)
  128. {
  129. setTimeout(function(){mark_hit_post($link)}, REQUEST_DELAY*delay_counter);
  130. $link.attr('mtbghbff_checked', 'true');
  131. delay_counter++;
  132. }
  133. }
  134. });
  135. }
  136.  
  137. function bustin_makes_me_feel_good()
  138. {
  139. $preview_links = $('a[href*="/mturk/preview?"][mtbghbff_checked!="true"], a[href*="/mturk/searchbar?"][mtbghbff_checked!="true"]:contains("(Requester link substituted)")');
  140.  
  141. if ($preview_links.length > 0)
  142. {
  143. var $hit_posts = $('div[id^="post_message_"], li[id^="post-"]').has('a[href*="/mturk/preview?"][mtbghbff_checked!="true"], a[href*="/mturk/searchbar?"][mtbghbff_checked!="true"]:contains("(Requester link substituted)")');
  144.  
  145. $hit_posts.each(function()
  146. {
  147. var num_links = $(this).find('a[href*="/mturk/preview?"][mtbghbff_checked!="true"], a[href*="/mturk/searchbar?"][mtbghbff_checked!="true"]:contains("(Requester link substituted)")').length;
  148. posts_dict[$(this).attr('id')] = {num_links: num_links, link_cnt: 0, strike_all: false, strike_all_override: false};
  149. });
  150.  
  151. if (typeof CHIME != 'undefined' && CHIME != '')
  152. {
  153. audio.play();
  154. }
  155.  
  156. check_link_position();
  157. }
  158. }
  159.  
  160. $(document).ready(function()
  161. {
  162. if (typeof CHIME != 'undefined' && CHIME != '')
  163. {
  164. audio = document.createElement('audio');
  165. audio.src = CHIME;
  166. audio.volume = VOLUME;
  167. document.body.appendChild(audio);
  168. }
  169.  
  170. bustin_makes_me_feel_good();
  171. });
  172.  
  173.  
  174. $(window).scroll(check_link_position);
  175.  
  176. $(window).load(function()
  177. {
  178. var observer = new MutationObserver(function(mutations, obs)
  179. {
  180. var new_links_available = false;
  181. for(var i = 0; i < mutations.length; i++)
  182. {
  183. for(var j = 0; j < mutations[i].addedNodes.length; j++)
  184. {
  185. var new_tag = mutations[i].addedNodes[j];
  186. if ($(new_tag).find('a[href*="/mturk/preview?"][mtbghbff_checked!="true"], a[href*="/mturk/searchbar?"][mtbghbff_checked!="true"]:contains("(Requester link substituted)")').length > 0)
  187. {
  188. new_links_available = true;
  189. break;
  190. }
  191. }
  192. if (new_links_available)
  193. {
  194. break;
  195. }
  196. }
  197.  
  198. if (new_links_available)
  199. {
  200. bustin_makes_me_feel_good();
  201. }
  202. });
  203.  
  204. observer.observe(document.documentElement,
  205. {
  206. childList: true,
  207. subtree: true
  208. });
  209. });