// ==UserScript== // @name mmmturkeybacon Ghost HIT Buster for Forums // @version 1.32 // @description Searches forum posts for HIT links, follows them, determines if the HIT is still available, and strikes the post if the HIT is ghost or changes the link text to show the automatic approval time and number of remaining if the HIT is available. Using this script will increase the number of page requests you make to mturk and may cause "maximum allowed page request rate" errors. // @author mmmturkeybacon // @namespace http://userscripts.org/users/523367 // @match http://mturkgrind.com/threads/* // @match http://www.mturkgrind.com/threads/* // @match http://mturkforum.com/showthread.php?* // @match http://www.mturkforum.com/showthread.php?* // @match http://turkernation.com/showthread.php?* // @match http://www.turkernation.com/showthread.php?* // @require https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js // @grant GM_xmlhttpRequest // @downloadURL none // ==/UserScript== var REQUEST_DELAY = 800; // milliseconds var posts_dict = {}; var preview_link_queue_count = 0; $(document).ready(function () { var $preview_links = $('a[href*="/mturk/preview?"], a[href*="/mturk/searchbar?"]:contains("(Requester link substituted)")'); var $hit_posts = $('div[id^="post_message_"], li[id^="post-"]').has('a[href*="/mturk/preview?"], a[href*="/mturk/searchbar?"]:contains("(Requester link substituted)")'); $hit_posts.each(function() { var num_links = $(this).find('a[href*="/mturk/preview?"], a[href*="/mturk/searchbar?"]:contains("(Requester link substituted)")').length; posts_dict[$(this).attr('id')] = {num_links: num_links, link_cnt: 0, strike_all: false, strike_all_override: false}; }); function bustin_makes_me_feel_good($link) { GM_xmlhttpRequest( { method: "GET", url: $link.attr('href'), onerror: function(){alert('mmmturkeybacon Ghost HIT Buster for Forums: Page request failed.');}, onload: function (response) { var $src = $(response.responseText); var id = $link.closest('div[id^="post_message_"], li[id^="post-"]').attr('id'); var maxpagerate = $src.find('td[class="error_title"]:contains("You have exceeded the maximum allowed page request rate for this website.")'); if (maxpagerate.length == 0) { var is_a_HIT = $src.find('input[type="hidden"][name="isAccepted"]').length > 0; var not_qualified = $src.find('span[id="alertboxHeader"]:contains("Your Qualifications do not meet the requirements to preview HITs in this group.")').length > 0; var requester_results = $src.find('td[class="title_orange_text_bold"]:contains("HITs Created by")').length > 0; if (is_a_HIT) { var hitAutoAppDelayInSeconds = $src.find('input[type="hidden"][name="hitAutoAppDelayInSeconds"]').val(); var num_available = $src.find('a[id="number_of_hits.tooltip"]').parent().next().text().trim(); // time formatting code modified from http://userscripts.org/scripts/show/169154 var days = Math.floor((hitAutoAppDelayInSeconds/(60*60*24))); var hours = Math.floor((hitAutoAppDelayInSeconds/(60*60)) % 24); var mins = Math.floor((hitAutoAppDelayInSeconds/60) % 60); var secs = hitAutoAppDelayInSeconds % 60; var time_str = (days == 0 ? '' : days + (days > 1 ? ' days ' : ' day ')) + (hours == 0 ? '' : hours + (hours > 1 ? ' hours ' : ' hour ')) + (mins == 0 ? '' : mins + (mins > 1 ? ' minutes ' : ' minute ')) + (secs == 0 ? '' : secs + (secs > 1 ? ' seconds ' : ' second ')); time_str = time_str.replace(/\s+$/, ''); if (hitAutoAppDelayInSeconds == 0) { time_str = "0 seconds"; } $link.text('['+time_str+'|'+num_available+'] -- ' + $link.text()); posts_dict[id].link_cnt++; posts_dict[id].strike_all_override = true; } else if (not_qualified) { $link.text('[not qualified] -- ' + $link.text()); } else if (!is_a_HIT && !requester_results) { var $hit_container = $link.closest('table[class^="cms_table"], table[class^="ctaBbcodeTable"]'); if ($hit_container.length > 0) { $hit_container.css('text-decoration', 'line-through'); posts_dict[id].link_cnt++; } else { $link.css('text-decoration', 'line-through'); posts_dict[id].link_cnt++; posts_dict[id].strike_all = true; } } } else { $link.text('[Page Request Rate Error] -- ' + $link.text()); posts_dict[id].link_cnt++; posts_dict[id].strike_all_override = true; } if ((posts_dict[id].strike_all_override == false) && (posts_dict[id].strike_all == true) && (posts_dict[id].link_cnt == posts_dict[id].num_links)) { $link.closest('div[id^="'+id+'"], li[id^="'+id+'"]').css('text-decoration', 'line-through'); } } }); preview_link_queue_count--; } function preview_links_loop(i) { var $next_link = $preview_links.eq(i); i++; if ($next_link.length > 0) { bustin_makes_me_feel_good($next_link); // Slow down page request rate. // This won't make the script immune to page request // errors. Retrying after an error would take too long. setTimeout(function(){preview_links_loop(i)}, REQUEST_DELAY); } } function queue_preview_links(new_preview_link) { var $link = $(new_preview_link); (function($link, preview_link_queue_count){setTimeout(function(){bustin_makes_me_feel_good($link)}, preview_link_queue_count*REQUEST_DELAY)})($link, preview_link_queue_count); preview_link_queue_count++; } if ($preview_links.length > 0) { preview_link_queue_count = $preview_links.length; preview_links_loop(0); } /* //http://stackoverflow.com/questions/25711476/why-is-my-mutationobserver-callback-not-being-executed-for-some-new-tags var observer = new MutationObserver(function(mutations, obs) { for(var i=0; i