Hermes HIT exporter

Adds an Export button to MTurk HIT capsules to generate a bbCode export format to share on forums.

目前為 2016-07-06 提交的版本,檢視 最新版本

// ==UserScript==
// @name         Hermes HIT exporter
// @namespace    mobiusevalon.tibbius.com
// @version      1.0
// @author       Mobius Evalon <[email protected]>
// @description  Adds an Export button to MTurk HIT capsules to generate a bbCode export format to share on forums.
// @license      Creative Commons Attribution-ShareAlike 4.0; http://creativecommons.org/licenses/by-sa/4.0/
// @require      https://code.jquery.com/jquery-1.12.4.min.js
// @include      /^https{0,1}:\/\/\w{0,}\.?mturk\.com\/mturk\/(?:searchbar|viewsearchbar|sortsearchbar|findhits|viewhits|sorthits)/
// @grant        none
// ==/UserScript==

$(document).ready(function() {
	script_version = 1.0;
	function hit_info($element)
	{
		function highlight_qual(q)
		{
			var h = (q.indexOf("Masters") > -1);
			return ((h ? "[color=red]" : "")+q.collapse_whitespace()+(h ? "[/color]" : ""));
		}
		// basic HIT info that must be scraped off the page
		var obj = {hit_name:$("a.capsulelink[href='#']",$element).first().text().collapse_whitespace(),
				   hit_id:$("a[href*='groupId']",$element).first().attr("href").match(/groupId=([A-Z0-9]{30})(?:&|$)/)[1],
				   hit_desc:$("a[id*='description.tooltip']",$element).parent().next().text().collapse_whitespace(),
				   hit_time:$("a[id*='duration_to_complete.tooltip']",$element).parent().next().text().collapse_whitespace(),
				   hits_available:$("a[id*='number_of_hits.tooltip']",$element).parent().next().text().collapse_whitespace(),
				   hit_reward:$("a[id*='reward.tooltip']",$element).parent().next().text().collapse_whitespace(),
				   requester_name:$("a[href*='selectedSearchType=hitgroups']",$element).first().text().collapse_whitespace(),
				   requester_id:$("a[href*='requesterId']",$element).first().attr("href").match(/requesterId=([A-Z0-9]{12,14})(?:&|$)/)[1]
				  };
		// link properties for convenience, since these are long URLs that only use one bit of previously collected info
		obj.preview_link = ("https://www.mturk.com/mturk/preview?groupId="+obj.hit_id);
		obj.panda_link = ("https://www.mturk.com/mturk/previewandaccept?groupId="+obj.hit_id);
		obj.requester_hits = ("https://www.mturk.com/mturk/searchbar?selectedSearchType=hitgroups&requesterId="+obj.requester_id);
		obj.to_reviews = ("https://turkopticon.ucsd.edu/"+obj.requester_id);

		// parse qualifications
		var $qual_anchor = $("a[id*='qualificationsRequired.tooltip']",$element);
		if($qual_anchor.parent().next().text().trim() === "None") obj.quals = "None";
		else
		{
			var quals = [];
			$("tr:not(:first-of-type) td:first-of-type",$qual_anchor.closest("table")).each(function() {quals.push(highlight_qual($(this).text()));});
			obj.quals = quals.join("; ");
		}

		obj.author_url = "https://greasyfork.org/en/users/9665-mobius-evalon";
		obj.hermes_version = hermes_version;
		obj.hermes_url = "";

		localStorage.hermes_hit = JSON.stringify(obj);
	}

	function display_template()
	{
		var obj = localstorage_obj("hermes_hit"),
			template = (localStorage.hermes_template || default_template());
		$("div#hermes_export_window textarea#template").hide().text(template);
		$.each(obj,function(key,val) {template = template.replace(new RegExp(("\\{"+key+"\\}"),"gi"),val);});
		$("div#hermes_export_window textarea#output").show().text(template);
	}

	function turkopticon(rid)
	{
		// mirror: https://mturk-api.istrack.in/multi-attrs.php?ids=
		// to: https://turkopticon.ucsd.edu/api/multi-attrs.php?ids=
		var obj = localstorage_obj("hermes_hit");
		$("div#hermes_export_window textarea#output").show().text("Gathering Turkopticon data for "+obj.requester_name+"...");

		$.ajax({async:true,
				method:"GET",
				url:("https://turkopticon.ucsd.edu/api/multi-attrs.php?ids="+obj.requester_id)
			   })
			.done(function(response) {var to_info = JSON.parse(response);
									  obj.to_pay = to_info[obj.requester_id].attrs.pay;
									  obj.to_fair = to_info[obj.requester_id].attrs.fair;
									  obj.to_fast = to_info[obj.requester_id].attrs.fast;
									  obj.to_comm = to_info[obj.requester_id].attrs.comm;
									  localStorage.hermes_hit = JSON.stringify(obj);

									  display_template();
									 });
	}

	function default_template()
	{
		return "[url={preview_link}][color=blue]{hit_name}[/color][/url] [[url={panda_link}][color=blue]PANDA[/color][/url]]\n"+
			"[b]Reward[/b]: {hit_reward}\n"+
			"[b]Time allowed[/b]: {hit_time}\n"+
			"[b]Available[/b]: {hits_available}\n"+
			"[b]Description[/b]: {hit_desc}\n"+
			"[b]Qualifications[/b]: {quals}\n\n"+
			"[b]Requester[/b]: [url={requester_hits}][color=blue]{requester_name}[/color][/url] [{requester_id}]\n"+
			"[url={to_reviews}][color=blue][b]Turkopticon[/b][/color][/url]: [Pay: {to_pay}] [Fair: {to_fair}] [Fast: {to_fast}] [Comm: {to_comm}]"+
			"[url={hermes_url}][color=blue]Hermes HIT exporter[/color][/url] {hermes_version} by [url={author_url}][color=blue]Mobius Evalon[/color][/url]";
	}

	function json_obj(json)
	{
		var obj;
		if(typeof json === "string" && json.trim().length)
		{
			try {obj = JSON.parse(json);}
			catch(e) {console.log("Malformed JSON object.  Error message from JSON library: ["+e.message+"]");}
		}
		return obj;
	}

	function localstorage_obj(key)
	{
		var obj = json_obj(localStorage.getItem(key));
		if(typeof obj !== "object") localStorage.removeItem(key);
		return obj;
	}

	String.prototype.collapse_whitespace = function() {
		return this.replace(/\s+/g," ").trim();
	};

	String.prototype.contains_substring = function() {
		for(var i=0;i<arguments.length;i++) if(this.indexOf(arguments[i]) > -1) return true;
		return false;
	};

	$("head").append($("<style/>")
					 .attr("type","text/css")
					 .text("#hermes_export_button {height: 16px; font-size: 10px; font-weight: bold; border: 1px solid; margin-left: 5px; padding: 0px 5px; background-color: transparent;} "+
						   "#hermes_export_window {position: fixed; left: 15vw; top: 10vh; background-color: #a5ccdd; border: 2px solid #5c9ebf; border-radius: 10px;} "+
						   "#hermes_export_window textarea {width: 400px; height: 250px; margin: 0px auto; display: block;} "+
						   "#hermes_export_window h1 {margin: 10px 0px; padding: 0px; font-size: 150%; font-weight: bold; text-align: center;} "+
						   "#hermes_export_window button {margin: 10px auto; display: block;} ")
					);
	$("body").append($("<div/>")
					 .attr("id","hermes_export_window")
					 .append($("<h1/>")
							 .text("Evalon HIT export"),
							 $("<textarea/>")
							 .attr("id","output")
							 .hide(),
							 $("<textarea/>")
							 .attr({"id":"template",
									"title":"{hit_name}\n{hit_id}\n{hit_desc}\n{hit_time}\n{hit_reward}\n{hits_available}\n{quals}\n{requester_id}\n{requester_name}\n{preview_link}\n{panda_link}\n{requester_hits}\n{to_reviews}\n{to_pay}\n{to_fair}\n{to_fast}\n{to_comm}"})
							 .hide(),
							 $("<button/>")
							 .text("Close")
							 .click(function() {$("#hermes_export_window").hide();}))
					 .hide()
					);

	$("a.capsulelink").after(
		$("<button/>")
		.attr("id","hermes_export_button")
		.text("Export")
		.click(function() {
			var template = (localStorage.hermes_template || default_template());
			hit_info($(this).closest("table").parent().closest("table"));

			$("div#hermes_export_window").show();
			$("div#hermes_export_window textarea").hide();

			if(template.contains_substring("{to_pay}","{to_fair}","{to_fast}","{to_comm}")) turkopticon();
			else display_template();
		})
	);
});