CH Block Using HIT Scraper's Blocklist

Block requesters and HITs on regular MTurk search results pages using your blocklist from 'HIT Scraper With Export'. Also highlights favorite requesters from your includelist.

当前为 2015-05-18 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name CH Block Using HIT Scraper's Blocklist
  3. // @description Block requesters and HITs on regular MTurk search results pages using your blocklist from 'HIT Scraper With Export'. Also highlights favorite requesters from your includelist.
  4. // @version 2.0c
  5. // @author clickhappier
  6. // @namespace clickhappier
  7. // @include https://www.mturk.com/mturk/findhits*
  8. // @include https://www.mturk.com/mturk/viewhits*
  9. // @include https://www.mturk.com/mturk/sorthits*
  10. // @include https://www.mturk.com/mturk/searchbar*selectedSearchType=hitgroups*
  11. // @include https://www.mturk.com/mturk/viewsearchbar*selectedSearchType=hitgroups*
  12. // @include https://www.mturk.com/mturk/sortsearchbar*HITGroup*
  13. // @include https://www.mturk.com/mturk/preview*
  14. // @include https://www.mturk.com/mturk/accept*
  15. // @include https://www.mturk.com/mturk/return*
  16. // @include https://www.mturk.com/mturk/submit*
  17. // @exclude https://www.mturk.com/*hit_scraper
  18. // @require http://code.jquery.com/jquery-latest.min.js
  19. // @grant GM_log
  20. // ==/UserScript==
  21.  
  22. // adaptations from Kerek+Tjololo's 'HIT Scraper WITH EXPORT': https://greasyfork.org/en/scripts/2002-hit-scraper-with-export
  23.  
  24.  
  25. // use localStorage instead of GM's storage
  26. //if (!this.GM_getValue || (this.GM_getValue.toString && this.GM_getValue.toString().indexOf("not supported")>-1)) { // these grants aren't declared, so the answer's always no
  27. this.GM_getValue = function(key,def) {
  28. return localStorage[key] || def;
  29. };
  30. this.GM_setValue = function(key,value) {
  31. return localStorage[key]=value;
  32. };
  33. this.GM_deleteValue = function(key) {
  34. return localStorage.removeItem(key);
  35. };
  36. //}
  37.  
  38.  
  39. // load ignore (block) list
  40. console.log("blocklist script loaded");
  41. var ignore_list;
  42. if ( !GM_getValue("scraper_ignore_list") )
  43. {
  44. GM_setValue("scraper_ignore_list","nothing blocked yet");
  45. }
  46. if ( GM_getValue("scraper_ignore_list") )
  47. {
  48. ignore_list = GM_getValue("scraper_ignore_list").split('^');
  49. // console.log(ignore_list);
  50. }
  51.  
  52. // check ignore list for requester name and HIT title
  53. function ignore_check(r,t)
  54. {
  55. var tempList = ignore_list.map(function(item) { return item.toLowerCase().replace(/\s+/g," "); });
  56. var foundR = -1;
  57. var foundT = -1;
  58. foundR = tempList.indexOf(r.toLowerCase().replace(/\s+/g," "));
  59. foundT = tempList.indexOf(t.toLowerCase().replace(/\s+/g," "));
  60. var found = foundR == -1 && foundT == -1;
  61. return found; // returns false (making !(ignore_check(x,y)) true) if HIT should be blocked, returns true if it shouldn't be blocked
  62. }
  63.  
  64.  
  65. // load include list
  66. var include_list = [];
  67. if ( !GM_getValue("scraper_include_list") )
  68. {
  69. GM_setValue("scraper_include_list","nothing includelisted yet");
  70. }
  71. if ( GM_getValue("scraper_include_list") )
  72. {
  73. include_list = GM_getValue("scraper_include_list").split('^');
  74. // console.log(include_list);
  75. }
  76.  
  77. // check include list for requester name and HIT title
  78. function include_check(r,t)
  79. {
  80. var tempList = include_list.map(function(item) { return item.toLowerCase().replace(/\s+/g," "); });
  81. var foundR = -1;
  82. var foundT = -1;
  83. foundR = tempList.indexOf(r.toLowerCase().replace(/\s+/g," "));
  84. foundT = tempList.indexOf(t.toLowerCase().replace(/\s+/g," "));
  85. var found = foundR == -1 && foundT == -1;
  86. return found; // returns false (making !(include_check(x,y)) true) if HIT should be highlighted, returns true if it shouldn't be highlighted
  87. }
  88.  
  89.  
  90. // identify HITs, requesters, and titles
  91. var $requester = $('a[href^="/mturk/searchbar?selectedSearchType=hitgroups&requester"]');
  92. var $title = $('a[class="capsulelink"]');
  93. var $hitcapsule = $("table[width='100%'][cellspacing='0'][cellpadding='0'][border='0'][height='100%']").parent(); // using parent td for compatibility with 'mmmturkeybacon Color-Coded Search' / 'mmmturkeybacon Color-Coded Search with Checkpoints', which hides/shows the table inside the parent td
  94. console.log("HIT capsules identified: " + $hitcapsule.length);
  95.  
  96. // hide blocked hits
  97. var blockedcount = 0;
  98. var blockednames = "";
  99. function hideBlocked()
  100. {
  101. // reload lists
  102. if ( GM_getValue("scraper_ignore_list") ) { ignore_list = GM_getValue("scraper_ignore_list").split('^'); }
  103. if ( GM_getValue("scraper_include_list") ) { include_list = GM_getValue("scraper_include_list").split('^'); }
  104. console.log("starting to block, total HITs to check: " + $requester.length);
  105. blockedcount = 0;
  106. blockednames = "";
  107. for (var j = 0; j < $requester.length; j++)
  108. {
  109. var requester_name = $requester.eq(j).text().trim();
  110. var title = $title.eq(j).text().trim();
  111. console.log("HIT " + (j+1) + " detected. Requester: " + requester_name + ", Title: " + title);
  112. var hitcapsule = $hitcapsule.eq(j);
  113. // hide hit if requester name or hit title is in your blocklist
  114. if (!ignore_check(requester_name,title))
  115. {
  116. hitcapsule.css('border','red solid thick');
  117. hitcapsule.hide();
  118. blockedcount++;
  119. blockednames += requester_name + ", ";
  120. console.log("blocked HIT " + (j+1) );
  121. }
  122. // check includelist for favorite hits to highlight (green outline)
  123. else if (!include_check(requester_name,title))
  124. {
  125. hitcapsule.css('border','green dashed thick');
  126. hitcapsule.show();
  127. console.log("highlighted HIT " + (j+1) );
  128. }
  129. // reset display for hits no longer on blocklist or includelist
  130. else
  131. {
  132. hitcapsule.css('border','none');
  133. hitcapsule.show();
  134. }
  135. }
  136. console.log("Total HITs blocked: " + blockedcount);
  137. blockednames = blockednames.replace(/,\s*$/, ""); // remove final comma and space
  138. }
  139.  
  140. $(document).ready(hideBlocked()); // initiate hiding first time when page loads
  141.  
  142. // unhide blocked hits
  143. function showBlocked(){
  144. console.log("starting to un-hide");
  145. for (var j = 0; j < $requester.length; j++){
  146. var hitcapsule = $hitcapsule.eq(j);
  147. hitcapsule.show();
  148. }
  149. }
  150.  
  151. // open blocklist editor
  152. var edit_blocks = document.createElement("span");
  153. edit_blocks.innerHTML = '<a href="#" class="footer_links" id="blocklist_edit_link" title="Blocklist = Disliked requester names and HIT titles to be hidden/ignored, and displayed with a red solid border when unhidden.">Edit Blocklist</a>';
  154. edit_blocks.onclick = function(){
  155. // console.log("opened blocklist editor");
  156. ignore_list = GM_getValue("scraper_ignore_list").split('^');
  157. var textarea = $("#blocklist_text");
  158. var text = "";
  159. for (var i = 0; i < ignore_list.length; i++){
  160. text += ignore_list[i]+"^";
  161. }
  162. textarea.val(text.substring(0, text.length - 1));
  163. $("#blocklist_div").show();
  164. };
  165.  
  166. // show/hide blocked hits
  167. var showAllBlocked = document.createElement("span");
  168. showAllBlocked.innerHTML = '<a href="#" class="footer_links" id="showblocked" title="' + blockednames + '">Show ' + blockedcount + ' Blocked</a>';
  169. showAllBlocked.onclick = function(){
  170. if ( document.getElementById('showblocked').innerHTML.indexOf("Show") > -1 ) {
  171. console.log("Un-hiding blocked hits - " + document.getElementById('showblocked').innerHTML );
  172. showBlocked();
  173. document.getElementById('showblocked').innerHTML = "Hide " + blockedcount + " Blocked";
  174. }
  175. else if ( document.getElementById('showblocked').innerHTML.indexOf("Hide") > -1 ) {
  176. console.log("Re-hiding blocked hits - " + document.getElementById('showblocked').innerHTML );
  177. hideBlocked();
  178. document.getElementById('showblocked').innerHTML = "Show " + blockedcount + " Blocked";
  179. }
  180. };
  181.  
  182. // open includelist editor
  183. var edit_includes = document.createElement("span");
  184. edit_includes.innerHTML = '<a href="#" class="footer_links" id="includelist_edit_link" title="Includelist = Favorite requester names and HIT titles to be displayed with a green dashed border to make them easy to spot.">Edit Includelist</a>';
  185. edit_includes.onclick = function(){
  186. // console.log("opened includelist editor");
  187. include_list = GM_getValue("scraper_include_list").split('^');
  188. var textarea = $("#includelist_text");
  189. var text = "";
  190. for (var i = 0; i < include_list.length; i++){
  191. text += include_list[i]+"^";
  192. }
  193. textarea.val(text.substring(0, text.length - 1));
  194. $("#includelist_div").show();
  195. };
  196.  
  197. // add edit and show/hide links to regular search results pages
  198. var blocklinksDivider = '&nbsp;&nbsp;<font color="#9ab8ef">|</font>&nbsp;&nbsp;';
  199. if ( document.location.href.indexOf('?last_hits_previewed') < 0 ) {
  200. $('#collapseall').eq(0).after("<br>", edit_blocks, blocklinksDivider, showAllBlocked, blocklinksDivider, edit_includes);
  201. // collapseAll.parentNode.insertBefore(showAllBlocked, collapseAll.nextSibling);
  202. // collapseAll.parentNode.insertBefore(edit_blocks, collapseAll.nextSibling);
  203. }
  204. else { // add edit and show/hide links to last_hits_previewed page
  205. // edit_blocks.innerHTML = edit_blocks.innerHTML.replace(blocklinksDivider, '');
  206. $("h1:contains('Last HITs Previewed')").eq(0).after(edit_blocks, blocklinksDivider, showAllBlocked, blocklinksDivider, edit_includes, "<br><br>");
  207. }
  208.  
  209.  
  210. // For editing the blocklist
  211. var blocklistdiv = document.createElement('div');
  212. var blocklisttextarea = document.createElement('textarea');
  213.  
  214. blocklistdiv.style.position = 'fixed';
  215. blocklistdiv.style.width = '500px';
  216. blocklistdiv.style.height = '255px';
  217. blocklistdiv.style.left = '50%';
  218. blocklistdiv.style.right = '50%';
  219. blocklistdiv.style.margin = '-250px 0px 0px -250px';
  220. blocklistdiv.style.top = '300px';
  221. blocklistdiv.style.padding = '5px';
  222. blocklistdiv.style.border = '2px';
  223. blocklistdiv.style.backgroundColor = 'black';
  224. blocklistdiv.style.color = 'white';
  225. blocklistdiv.style.zIndex = '100';
  226. blocklistdiv.setAttribute('id','blocklist_div');
  227. blocklistdiv.style.display = 'none';
  228.  
  229. blocklisttextarea.style.padding = '2px';
  230. blocklisttextarea.style.width = '500px';
  231. blocklisttextarea.style.height = '180px';
  232. blocklisttextarea.title = 'Block list';
  233. blocklisttextarea.setAttribute('id','blocklist_text');
  234.  
  235. blocklistdiv.textContent = 'This BLOCKLIST (ignored requesters/HITs) is shared with HIT Scraper With Export. Separate requester names and HIT titles with the ^ character. After clicking "Save", changes will be immediately applied in this tab (for other tabs to reflect the changes, refresh them or click their show/hide links twice).';
  236. blocklistdiv.style.fontSize = '12px';
  237. blocklistdiv.appendChild(blocklisttextarea);
  238.  
  239. var save_BLbutton = document.createElement('button');
  240. var cancel_BLbutton = document.createElement('button');
  241.  
  242. save_BLbutton.textContent = 'Save';
  243. save_BLbutton.setAttribute('id', 'save_BLblocklist');
  244. save_BLbutton.style.height = '18px';
  245. save_BLbutton.style.width = '100px';
  246. save_BLbutton.style.fontSize = '10px';
  247. save_BLbutton.style.paddingLeft = '3px';
  248. save_BLbutton.style.paddingRight = '3px';
  249. save_BLbutton.style.backgroundColor = 'white';
  250. save_BLbutton.style.marginLeft = '5px';
  251.  
  252. cancel_BLbutton.textContent = 'Cancel';
  253. cancel_BLbutton.setAttribute('id', 'cancel_BLblocklist');
  254. cancel_BLbutton.style.height = '18px';
  255. cancel_BLbutton.style.width = '100px';
  256. cancel_BLbutton.style.fontSize = '10px';
  257. cancel_BLbutton.style.paddingLeft = '3px';
  258. cancel_BLbutton.style.paddingRight = '3px';
  259. cancel_BLbutton.style.backgroundColor = 'white';
  260. cancel_BLbutton.style.marginLeft = '5px';
  261.  
  262. blocklistdiv.appendChild(save_BLbutton);
  263. blocklistdiv.appendChild(cancel_BLbutton);
  264. document.body.insertBefore(blocklistdiv, document.body.firstChild);
  265.  
  266. // save and cancel for blocklist
  267. function save_BLblocklist() {
  268. // console.log("Save blocklist");
  269. var textarea = $("#blocklist_text");
  270. var text = textarea.val();
  271. var temp_block_list = text.split("^");
  272. var trimmed_list = [];
  273. for (var requester in temp_block_list){
  274. if (temp_block_list[requester].trim().length !== 0)
  275. trimmed_list.push(temp_block_list[requester].toLowerCase().trim());
  276. }
  277. // console.log(trimmed_list);
  278. GM_setValue("scraper_ignore_list",trimmed_list.join('^'));
  279. ignore_list = GM_getValue("scraper_ignore_list").split('^');
  280. // console.log("Save blocklist complete: ");
  281. // console.log(ignore_list);
  282. $("#blocklist_div").hide();
  283. // apply changes to current page
  284. hideBlocked();
  285. document.getElementById('showblocked').innerHTML = "Show " + blockedcount + " Blocked";
  286. }
  287. save_BLbutton.addEventListener("click", function(){ save_BLblocklist(); }, false);
  288. cancel_BLbutton.addEventListener("click", function(){
  289. // reset textarea contents upon cancel
  290. ignore_list = GM_getValue("scraper_ignore_list").split('^');
  291. var textarea = $("#blocklist_text");
  292. var text = "";
  293. for (var i = 0; i < ignore_list.length; i++){
  294. text += ignore_list[i]+"^";
  295. }
  296. textarea.val(text.substring(0, text.length - 1));
  297. // close editor
  298. $("#blocklist_div").hide();
  299. }, false);
  300.  
  301.  
  302. // For editing the includelist
  303. var includelistdiv = document.createElement('div');
  304. var includelisttextarea = document.createElement('textarea');
  305.  
  306. includelistdiv.style.position = 'fixed';
  307. includelistdiv.style.width = '500px';
  308. includelistdiv.style.height = '255px';
  309. includelistdiv.style.left = '50%';
  310. includelistdiv.style.right = '50%';
  311. includelistdiv.style.margin = '-250px 0px 0px -250px';
  312. includelistdiv.style.top = '300px';
  313. includelistdiv.style.padding = '5px';
  314. includelistdiv.style.border = '2px';
  315. includelistdiv.style.backgroundColor = 'black';
  316. includelistdiv.style.color = 'white';
  317. includelistdiv.style.zIndex = '100';
  318. includelistdiv.setAttribute('id','includelist_div');
  319. includelistdiv.style.display = 'none';
  320.  
  321. includelisttextarea.style.padding = '2px';
  322. includelisttextarea.style.width = '500px';
  323. includelisttextarea.style.height = '180px';
  324. includelisttextarea.title = 'Include list';
  325. includelisttextarea.setAttribute('id','includelist_text');
  326.  
  327. includelistdiv.textContent = 'This INCLUDELIST (favorite requesters/HITs) is shared with HIT Scraper With Export. Separate requester names and HIT titles with the ^ character. After clicking "Save", changes will be immediately applied in this tab (for other tabs to reflect the changes, refresh them or click their show/hide links twice).';
  328. includelistdiv.style.fontSize = '12px';
  329. includelistdiv.appendChild(includelisttextarea);
  330.  
  331. var save_ILbutton = document.createElement('button');
  332. var cancel_ILbutton = document.createElement('button');
  333.  
  334. save_ILbutton.textContent = 'Save';
  335. save_ILbutton.setAttribute('id', 'save_ILincludelist');
  336. save_ILbutton.style.height = '18px';
  337. save_ILbutton.style.width = '100px';
  338. save_ILbutton.style.fontSize = '10px';
  339. save_ILbutton.style.paddingLeft = '3px';
  340. save_ILbutton.style.paddingRight = '3px';
  341. save_ILbutton.style.backgroundColor = 'white';
  342. save_ILbutton.style.marginLeft = '5px';
  343.  
  344. cancel_ILbutton.textContent = 'Cancel';
  345. cancel_ILbutton.setAttribute('id', 'cancel_ILincludelist');
  346. cancel_ILbutton.style.height = '18px';
  347. cancel_ILbutton.style.width = '100px';
  348. cancel_ILbutton.style.fontSize = '10px';
  349. cancel_ILbutton.style.paddingLeft = '3px';
  350. cancel_ILbutton.style.paddingRight = '3px';
  351. cancel_ILbutton.style.backgroundColor = 'white';
  352. cancel_ILbutton.style.marginLeft = '5px';
  353.  
  354. includelistdiv.appendChild(save_ILbutton);
  355. includelistdiv.appendChild(cancel_ILbutton);
  356. document.body.insertBefore(includelistdiv, document.body.firstChild);
  357.  
  358. // save and cancel for includelist
  359. function save_ILincludelist() {
  360. // console.log("Save includelist");
  361. var textarea = $("#includelist_text");
  362. var text = textarea.val();
  363. var temp_include_list = text.split("^");
  364. var trimmed_list = [];
  365. for (var requester in temp_include_list){
  366. if (temp_include_list[requester].trim().length !== 0)
  367. trimmed_list.push(temp_include_list[requester].toLowerCase().trim());
  368. }
  369. // console.log(trimmed_list);
  370. GM_setValue("scraper_include_list",trimmed_list.join('^'));
  371. include_list = GM_getValue("scraper_include_list").split('^');
  372. // console.log("Save includelist complete: ");
  373. // console.log(include_list);
  374. $("#includelist_div").hide();
  375. // apply changes to current page
  376. hideBlocked();
  377. document.getElementById('showblocked').innerHTML = "Show " + blockedcount + " Blocked";
  378. }
  379. save_ILbutton.addEventListener("click", function(){ save_ILincludelist(); }, false);
  380. cancel_ILbutton.addEventListener("click", function(){
  381. // reset textarea contents upon cancel
  382. include_list = GM_getValue("scraper_include_list").split('^');
  383. var textarea = $("#includelist_text");
  384. var text = "";
  385. for (var i = 0; i < include_list.length; i++){
  386. text += include_list[i]+"^";
  387. }
  388. textarea.val(text.substring(0, text.length - 1));
  389. // close editor
  390. $("#includelist_div").hide();
  391. }, false);