mmmturkeybacon Queue Order Fix

After completing a HIT anywhere within your queue (i.e. HITs Assigned To You), this script will automatically continue the HIT at the top of your queue.

  1. // ==UserScript==
  2. // @name mmmturkeybacon Queue Order Fix
  3. // @version 2.22
  4. // @description After completing a HIT anywhere within your queue (i.e. HITs Assigned To You), this script will automatically continue the HIT at the top of your queue.
  5. // For example, if you sort your queue by Time Left (least first), you can use this script to work on the HITs that are closest to expiring instead of mturk's default behavior ignoring what your queue is sorted by and putting the oldest HIT next in line. You should only need to set the sort order once. HITs accepted after setting the sort order will be sorted automatically by mturk. Additionally you can manually continue the HIT at the top of your queue if you visit "https://www.mturk.com/mturk/myhits?first". Create a bookmark on your toolbar to quickly jump to the first HIT in your queue. This is especially useful if you just caught a HIT that will expire quickly.
  6. // @author mmmturkeybacon
  7. // @namespace http://userscripts.org/users/523367
  8. // @match https://*.mturk.com/mturk/myhits*
  9. // @match https://*.mturk.com/mturk/sortmyhits?*
  10. // @match https://*.mturk.com/mturk/viewmyhits?*
  11. // @match https://*.mturk.com/mturk/continue*
  12. // @match https://*.mturk.com/mturk/submit
  13. // @match https://*.mturk.com/mturk/return?requesterId=*
  14. // @require https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js
  15. // @grant GM_log
  16. // ==/UserScript==
  17.  
  18. /*
  19. * Mechanical Turk has two types of HITs. By far the ExternalQuestion HITs are
  20. * the most common. These HITs use an iframe to display the task, disable the
  21. * yellow Submit HIT button, and use the hidden link with the id hitExternalNextLink
  22. * to direct the browser to a new page after the task has been submitted in the
  23. * iframe. The second type of HIT is the QuestionForm HIT. These HITs do not use
  24. * an iframe, use the yellow Submit HIT button to submit, and do not use
  25. * hitExternalNextLink to direct the browser to a new page.
  26. *
  27. * For ExternalQuestion HITs, fixing the queue order is as simple as replacing
  28. * hitExternalNextLink with the URL of the next link you wish to work on.
  29. *
  30. * QuestionForm HITs don't use the hitExternalNextLink, however we can utilize
  31. * the fact that after a QuestionForm HIT is submitted the URL ends with
  32. * /mturk/submit to redirect the browser to the top of the queue.
  33. *
  34. */
  35.  
  36. /* NOTE: This script doesn't actually do anything on the /mturk/myhits page but running it on that page makes it convenient to disable the script by unchecking it in the greasemonkey dropdown menu. */
  37.  
  38. /*
  39. ___Bookmarklets___
  40. First HIT in the fixed queue -- javascript:(function(){window.open('https://www.mturk.com/mturk/myhits?first')})()
  41. Last HIT in the fixed queue -- javascript:(function(){window.open('https://www.mturk.com/mturk/myhits?last')})()
  42. Last HIT in the fixed queue* -- javascript:(function(){window.open(localStorage.getItem('mtbqof_sortmyhits_URL').replace('sortmyhits?','viewmyhits?')+'?last')})()
  43. *Will only work if a window with the mturk.com domain is in focus when the bookmarklet is clicked.
  44.  
  45. First HIT in the unfixed queue -- javascript:(function(){window.open('https://www.mturk.com/mturk/viewmyhits?searchSpec=HITSearch%2523T%25231%2523100%2523-1%2523T%2523!Status!0!rO0ABXQACEFzc2lnbmVk!%2523!CreationTime!0!%2523!&selectedSearchType=hitgroups&searchWords=&sortType=CreationTime%253A0&pageSize=100&?first','mtbqswin')})()
  46. Last HIT in the unfixed queue -- javascript:(function(){window.open('https://www.mturk.com/mturk/viewmyhits?searchSpec=HITSearch%2523T%25231%2523100%2523-1%2523T%2523!Status!0!rO0ABXQACEFzc2lnbmVk!%2523!CreationTime!0!%2523!&selectedSearchType=hitgroups&searchWords=&sortType=CreationTime%253A0&pageSize=100&?last','mtbqswin')})()
  47.  
  48. */
  49.  
  50. var DEFAULT_SORT_URL = '/mturk/sortmyhits?searchSpec=HITSearch%23T%231%23100%23-1%23T%23!Status!0!rO0ABXQACEFzc2lnbmVk!%23!Deadline!0!%23!&selectedSearchType=hitgroups&searchWords=&sortType=Deadline%3A0&pageSize=100'; // Show up to 100 HITs on a single page. The most HITs I've ever seen in a full queue is 27, so set the max to 100 (instead of 25) to get every HIT and to future-proof.
  51.  
  52. var TIMEOUT_TIMELIMIT = 10000; // 10000 [ms]
  53. var ON_ERROR_REDIRECT_URL = '/mturk/myhits';
  54.  
  55. $(document).ready(function()
  56. {
  57. var this_URL = window.location.href;
  58. var this_URL_type = this_URL.split(/mturk\/|\?/)[1];
  59.  
  60. /* if hitExternalNextLink contains the groupId we are not working from the queue */
  61. var hitExternalNextLink = $('a[id="hitExternalNextLink"]:not([href*="groupId="])');
  62. var is_external_HIT = $('iframe').length > 0;
  63. var sortmyhits_URL = localStorage.getItem('mtbqof_sortmyhits_URL') || DEFAULT_SORT_URL;
  64.  
  65.  
  66. if (hitExternalNextLink.length > 0 && window.name.indexOf('mtbqswin') == -1)
  67. { // This HIT is in the queue pipeline.
  68. var this_hitId = hitExternalNextLink.attr('href').split(/&|hitId=/)[2];
  69. if (this_URL_type == 'continue' || this_URL_type == 'submit' || this_URL_type == 'return')
  70. {
  71. $.ajax({
  72. url: sortmyhits_URL,
  73. type: 'GET',
  74. success: function(data)
  75. {
  76. var $src = $(data);
  77. var maxpagerate = $src.find('td[class="error_title"]:contains("You have exceeded the maximum allowed page request rate for this website.")');
  78. if (maxpagerate.length == 0)
  79. {
  80. var $continue_links = $src.find('a[href^="/mturk/continue"]');
  81. var first_queue_URL = $continue_links.eq(0).attr('href');
  82. if (first_queue_URL)
  83. {
  84. var first_queue_hitId = first_queue_URL.split('hitId=')[1];
  85. if (this_hitId != first_queue_hitId)
  86. {
  87. if (this_URL_type == 'submit' || this_URL_type == 'return')
  88. {
  89. window.location.replace(first_queue_URL);
  90. }
  91. else if (is_external_HIT)
  92. {
  93. hitExternalNextLink.attr('href', first_queue_URL);
  94. }
  95. }
  96. else if (is_external_HIT)
  97. {
  98. var second_queue_URL = $continue_links.eq(1).attr('href');
  99. if (second_queue_URL)
  100. {
  101. hitExternalNextLink.attr('href', second_queue_URL);
  102. }
  103. else
  104. {
  105.  
  106. // No more HITs left when we last checked but it's possible one arrived afterwards,
  107. // so redirect to the first HIT in the queue if it is there.
  108. hitExternalNextLink.attr('href', '/mturk/myhits?first');
  109. }
  110. }
  111.  
  112. var num_hits = $src.find('td[class="title_orange_text"]:contains("Results")').text().trim().split(' ')[2];
  113. var hit_rank = $continue_links.index($src.find('a[href^="/mturk/continue?hitId='+this_hitId+'"]')) + 1;
  114.  
  115. if (hit_rank > 0 && num_hits > 0)
  116. {
  117. document.title = hit_rank+'/'+num_hits+' '+document.title;
  118. }
  119. }
  120. }
  121. else
  122. {
  123. hitExternalNextLink.attr('href', ON_ERROR_REDIRECT_URL);
  124. }
  125. },
  126. error: function(xhr, status, error)
  127. {
  128. hitExternalNextLink.attr('href', ON_ERROR_REDIRECT_URL);
  129. },
  130. timeout: TIMEOUT_TIMELIMIT
  131. });
  132. }
  133. }
  134. else if (this_URL.endsWith('?first') || (this_URL_type == 'continue' && $('span[id="alertboxHeader"]:contains("You have already")').length > 0))
  135. { // When we see a that URL that ends with ?first jump to the first HIT in the queue. Or if you've already completed or returned a HIT then jump to the first HIT in the queue.
  136. var first_queue_URL = $('a[href^="/mturk/continue"]:first').attr('href');
  137. if (first_queue_URL)
  138. {
  139. window.location.replace(first_queue_URL);
  140. }
  141. }
  142. else if (this_URL.endsWith('myhits?last'))
  143. {
  144. window.location.replace(sortmyhits_URL.replace('sortmyhits?','viewmyhits?')+'?last');
  145. }
  146. else if (this_URL.endsWith('?last'))
  147. { // When we see a that URL that ends with ?last jump to the first HIT in the queue.
  148. var last_queue_URL = $('a[href^="/mturk/continue"]:last').attr('href');
  149. if (last_queue_URL)
  150. {
  151. window.location.replace(last_queue_URL);
  152. }
  153. }
  154. else if (this_URL_type == 'sortmyhits')
  155. { // Modify and save the queue sort URL so the code can see all queue HITs on the same page to determine rank.
  156. localStorage.setItem('mtbqof_sortmyhits_URL', window.location.href.split("mturk.com")[1].replace("%2310%23", "%23100%23").replace(/&pageSize=\d{1,3}/, '&pageSize=100')); // Show up to 100 HITs on a single page. The most HITs I've ever seen in a full queue is 27, so set the max to 100 (instead of 25) to get every HIT and to future-proof.
  157. }
  158. // else it's a submit link but not inside the queue pipeline, so do nothing
  159.  
  160. });