Greasy Fork

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 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.

当前为 2015-04-22 提交的版本,查看 最新版本

// ==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
// ==/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<mutations.length; ++i)
        {
            for(var j=0; j<mutations[i].addedNodes.length; ++j)
            {
                var newTag = mutations[i].addedNodes[j];
                if (newTag.querySelectorAll)
                {
                    Array.prototype.forEach.call(
                    newTag.querySelectorAll('a[href*="/mturk/preview?"], a[href*="/mturk/searchbar?"]:contains("(Requester link substituted)")'), queue_preview_links);
                }
            }
        }
    });

    observer.observe(document.documentElement,
    {
        childList: true,
        subtree: true
    });
*/
});