sprout-ruby-aws 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +38 -0
- data/LICENSE.txt +202 -0
- data/Manifest.txt +69 -0
- data/NOTICE.txt +4 -0
- data/README.txt +105 -0
- data/Rakefile +20 -0
- data/bin/ruby-aws +9 -0
- data/lib/amazon/util.rb +10 -0
- data/lib/amazon/util/binder.rb +44 -0
- data/lib/amazon/util/data_reader.rb +157 -0
- data/lib/amazon/util/filter_chain.rb +79 -0
- data/lib/amazon/util/hash_nesting.rb +93 -0
- data/lib/amazon/util/lazy_results.rb +59 -0
- data/lib/amazon/util/logging.rb +23 -0
- data/lib/amazon/util/paginated_iterator.rb +70 -0
- data/lib/amazon/util/proactive_results.rb +116 -0
- data/lib/amazon/util/threadpool.rb +129 -0
- data/lib/amazon/util/user_data_store.rb +100 -0
- data/lib/amazon/webservices/mechanical_turk.rb +117 -0
- data/lib/amazon/webservices/mechanical_turk_requester.rb +340 -0
- data/lib/amazon/webservices/mturk/mechanical_turk_error_handler.rb +136 -0
- data/lib/amazon/webservices/mturk/question_generator.rb +58 -0
- data/lib/amazon/webservices/util/amazon_authentication_relay.rb +64 -0
- data/lib/amazon/webservices/util/command_line.rb +156 -0
- data/lib/amazon/webservices/util/convenience_wrapper.rb +90 -0
- data/lib/amazon/webservices/util/filter_proxy.rb +45 -0
- data/lib/amazon/webservices/util/mock_transport.rb +70 -0
- data/lib/amazon/webservices/util/request_signer.rb +42 -0
- data/lib/amazon/webservices/util/rest_transport.rb +108 -0
- data/lib/amazon/webservices/util/soap_simplifier.rb +48 -0
- data/lib/amazon/webservices/util/soap_transport.rb +38 -0
- data/lib/amazon/webservices/util/soap_transport_header_handler.rb +27 -0
- data/lib/amazon/webservices/util/unknown_result_exception.rb +27 -0
- data/lib/amazon/webservices/util/validation_exception.rb +55 -0
- data/lib/amazon/webservices/util/xml_simplifier.rb +61 -0
- data/lib/ruby-aws.rb +21 -0
- data/lib/ruby-aws/version.rb +8 -0
- data/samples/mturk/best_image/BestImage.rb +61 -0
- data/samples/mturk/best_image/best_image.properties +39 -0
- data/samples/mturk/best_image/best_image.question +82 -0
- data/samples/mturk/blank_slate/BlankSlate.rb +63 -0
- data/samples/mturk/blank_slate/BlankSlate_multithreaded.rb +67 -0
- data/samples/mturk/helloworld/MTurkHelloWorld.rb +56 -0
- data/samples/mturk/helloworld/mturk.yml +8 -0
- data/samples/mturk/reviewer/Reviewer.rb +103 -0
- data/samples/mturk/reviewer/mturk.yml +8 -0
- data/samples/mturk/simple_survey/SimpleSurvey.rb +90 -0
- data/samples/mturk/simple_survey/simple_survey.question +30 -0
- data/samples/mturk/site_category/SiteCategory.rb +87 -0
- data/samples/mturk/site_category/externalpage.htm +71 -0
- data/samples/mturk/site_category/site_category.input +6 -0
- data/samples/mturk/site_category/site_category.properties +45 -0
- data/samples/mturk/site_category/site_category.question +9 -0
- data/test/mturk/test_changehittypeofhit.rb +130 -0
- data/test/mturk/test_error_handler.rb +135 -0
- data/test/mturk/test_mechanical_turk_requester.rb +178 -0
- data/test/mturk/test_mock_mechanical_turk_requester.rb +205 -0
- data/test/test_ruby-aws.rb +22 -0
- data/test/unit/test_binder.rb +89 -0
- data/test/unit/test_data_reader.rb +135 -0
- data/test/unit/test_exceptions.rb +32 -0
- data/test/unit/test_hash_nesting.rb +93 -0
- data/test/unit/test_lazy_results.rb +89 -0
- data/test/unit/test_mock_transport.rb +132 -0
- data/test/unit/test_paginated_iterator.rb +58 -0
- data/test/unit/test_proactive_results.rb +108 -0
- data/test/unit/test_question_generator.rb +54 -0
- data/test/unit/test_threadpool.rb +50 -0
- data/test/unit/test_user_data_store.rb +80 -0
- metadata +177 -0
@@ -0,0 +1,61 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Copyright:: Copyright (c) 2007 Amazon Technologies, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
|
6
|
+
begin ; require 'rubygems' ; rescue LoadError ; end
|
7
|
+
|
8
|
+
# The Best Image sample application will create a HIT asking a worker
|
9
|
+
# to choose the best of three images, given a set of criteria.
|
10
|
+
#
|
11
|
+
# The following concepts are covered:
|
12
|
+
# - Using the <FormattedContent> functionality in QuestionForm
|
13
|
+
# - File-based QuestionForm and HIT properties HIT loading
|
14
|
+
# - Using a basic system qualification
|
15
|
+
|
16
|
+
require 'ruby-aws'
|
17
|
+
@mturk = Amazon::WebServices::MechanicalTurkRequester.new :Host => :Sandbox
|
18
|
+
|
19
|
+
# Use this line instead if you want to talk to Prod
|
20
|
+
#@mturk = Amazon::WebServices::MechanicalTurkRequester.new :Host => :Production
|
21
|
+
|
22
|
+
|
23
|
+
# Check to see if your account has sufficient funds
|
24
|
+
def hasEnoughFunds?
|
25
|
+
available = @mturk.availableFunds
|
26
|
+
puts "Got account balance: %.2f" % available
|
27
|
+
return available > 0.055
|
28
|
+
end
|
29
|
+
|
30
|
+
def getHITUrl( hitTypeId )
|
31
|
+
if @mturk.host =~ /sandbox/
|
32
|
+
"http://workersandbox.mturk.com/mturk/preview?groupId=#{hitTypeId}" # Sandbox Url
|
33
|
+
else
|
34
|
+
"http://mturk.com/mturk/preview?groupId=#{hitTypeId}" # Production Url
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Create the BestImage HIT
|
39
|
+
def createBestImage
|
40
|
+
|
41
|
+
# Defining the location of the file containing the QuestionForm and the properties of the HIT
|
42
|
+
rootDir = File.dirname $0;
|
43
|
+
questionFile = rootDir + "/best_image.question";
|
44
|
+
propertiesFile = rootDir + "/best_image.properties";
|
45
|
+
|
46
|
+
# Loading configuration properties from a HIT properties file.
|
47
|
+
# In this sample, the qualification is defined in the properties file.
|
48
|
+
props = Amazon::Util::DataReader.load( propertiesFile, :Properties )
|
49
|
+
props[:Reward] = { :Amount => 0.05, :CurrencyCode => 'USD'}
|
50
|
+
# Loading the question (QuestionForm) file.
|
51
|
+
question = File.read( questionFile )
|
52
|
+
# no validation
|
53
|
+
result = @mturk.createHIT( {:Question => question}.merge(props) )
|
54
|
+
puts "Created HIT: #{result[:HITId]}"
|
55
|
+
puts "Url: #{getHITUrl( result[:HITTypeId] )}"
|
56
|
+
|
57
|
+
# save the HIT Id to a file so we don't lose it...
|
58
|
+
Amazon::Util::DataReader.save( File.join( rootDir, "hits_created" ), [{:HITId => result[:HITId] }], :Tabular )
|
59
|
+
end
|
60
|
+
|
61
|
+
createBestImage if hasEnoughFunds?
|
@@ -0,0 +1,39 @@
|
|
1
|
+
######################################
|
2
|
+
## Basic HIT Properties
|
3
|
+
######################################
|
4
|
+
|
5
|
+
Title:Select the best image for a given topic
|
6
|
+
Description:The task is to select one image out of three that best represents the provided topic given a set of evaluation criteria.
|
7
|
+
Keywords:sample, SDK, best, image
|
8
|
+
Reward.Amount:0
|
9
|
+
Reward.CurrencyCode:USD
|
10
|
+
MaxAssignments:1
|
11
|
+
RequesterAnnotation:sample#image
|
12
|
+
|
13
|
+
######################################
|
14
|
+
## HIT Timing Properties
|
15
|
+
######################################
|
16
|
+
|
17
|
+
# this Assignment Duration value is 60 * 60 = 1 hour
|
18
|
+
AssignmentDurationInSeconds:3600
|
19
|
+
|
20
|
+
# this HIT Lifetime value is 60*60 = 1 hour
|
21
|
+
LifetimeInSeconds:3600
|
22
|
+
|
23
|
+
# this Auto Approval period is 60*60 = 1 hour
|
24
|
+
AutoApprovalDelayInSeconds:3600
|
25
|
+
|
26
|
+
######################################
|
27
|
+
## Qualification Properties
|
28
|
+
######################################
|
29
|
+
|
30
|
+
# Qualifications can be defined in the properties file instead of in code.
|
31
|
+
# You can add multiple qualifications for this HIT by simply increasing the # suffix.
|
32
|
+
# i.e. qualification.2: XXXXX
|
33
|
+
# qualification.comparator.2:greaterthan
|
34
|
+
|
35
|
+
# this is a built-in qualification -- user must have an approval rate of 25% or greater
|
36
|
+
QualificationRequirement.1.QualificationTypeId:000000000000000000L0
|
37
|
+
QualificationRequirement.1.Comparator:GreaterThan
|
38
|
+
QualificationRequirement.1.IntegerValue:25
|
39
|
+
QualificationRequirement.1.RequiredToPreview:false
|
@@ -0,0 +1,82 @@
|
|
1
|
+
<?xml version="1.0"?>
|
2
|
+
<QuestionForm xmlns="http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchemas/2005-10-01/QuestionForm.xsd">
|
3
|
+
<Overview>
|
4
|
+
<FormattedContent><![CDATA[
|
5
|
+
<h1 align="center">Select the best image</h1>
|
6
|
+
<h2>Instructions</h2>
|
7
|
+
Your task is to select <strong>one</strong> image out of <strong>three</strong> that best represents the provided topic given the evaluation criteria defined below.
|
8
|
+
<br/>It is possible that none of the images can satisfy all the evaluation criteria. Your goal is to select the best image of the three.
|
9
|
+
<br/>
|
10
|
+
<h3>Evaluation Criteria</h3>
|
11
|
+
<ul>
|
12
|
+
<li>The image should be a representation of the provided topic (i.e. If the topic is Ferris Wheel, you should not select images that are not related to a Ferris Wheel.)</li>
|
13
|
+
<li>The image should be in focus. (i.e. not blurry)</li>
|
14
|
+
<li>The image should have good color balance. (i.e. not tinted)</li>
|
15
|
+
<li>The image should be properly exposed. (i.e. not overexposed/underexposed)</li>
|
16
|
+
<li>The image should be composed well. (i.e. not skewed)</li>
|
17
|
+
<li>Please refer to the following <a href="http://s3.amazonaws.com/mturk/samples/bestimage/best-image-instructions.html" target="_blank" >link</a> for visual examples of the above criteria.</li>
|
18
|
+
</ul>
|
19
|
+
<h2>Task</h2>
|
20
|
+
]]></FormattedContent>
|
21
|
+
</Overview>
|
22
|
+
<Question>
|
23
|
+
<QuestionIdentifier>best_image</QuestionIdentifier>
|
24
|
+
<IsRequired>true</IsRequired>
|
25
|
+
<QuestionContent>
|
26
|
+
<FormattedContent><![CDATA[
|
27
|
+
<font size="4" color="darkblue" >Select the image below that best represents: Houses of Parliament, London, England</font>
|
28
|
+
]]></FormattedContent>
|
29
|
+
</QuestionContent>
|
30
|
+
<AnswerSpecification>
|
31
|
+
<SelectionAnswer>
|
32
|
+
<StyleSuggestion>radiobutton</StyleSuggestion>
|
33
|
+
<Selections>
|
34
|
+
<Selection>
|
35
|
+
<SelectionIdentifier>sample-bestimage-image1.jpg</SelectionIdentifier>
|
36
|
+
<Binary>
|
37
|
+
<MimeType>
|
38
|
+
<Type>image</Type>
|
39
|
+
<SubType>jpg</SubType>
|
40
|
+
</MimeType>
|
41
|
+
<DataURL>http://s3.amazonaws.com/mturk/samples/bestimage/sample-bestimage-image1.jpg</DataURL>
|
42
|
+
<AltText>sample-bestimage-image1.jpg</AltText>
|
43
|
+
</Binary>
|
44
|
+
</Selection>
|
45
|
+
<Selection>
|
46
|
+
<SelectionIdentifier>sample-bestimage-image2.jpg</SelectionIdentifier>
|
47
|
+
<Binary>
|
48
|
+
<MimeType>
|
49
|
+
<Type>image</Type>
|
50
|
+
<SubType>jpg</SubType>
|
51
|
+
</MimeType>
|
52
|
+
<DataURL>http://s3.amazonaws.com/mturk/samples/bestimage/sample-bestimage-image2.jpg</DataURL>
|
53
|
+
<AltText>sample-bestimage-image2.jpg</AltText>
|
54
|
+
</Binary>
|
55
|
+
</Selection>
|
56
|
+
<Selection>
|
57
|
+
<SelectionIdentifier>sample-bestimage-image3.jpg</SelectionIdentifier>
|
58
|
+
<Binary>
|
59
|
+
<MimeType>
|
60
|
+
<Type>image</Type>
|
61
|
+
<SubType>jpg</SubType>
|
62
|
+
</MimeType>
|
63
|
+
<DataURL>http://s3.amazonaws.com/mturk/samples/bestimage/sample-bestimage-image3.jpg</DataURL>
|
64
|
+
<AltText>sample-bestimage-image3.jpg</AltText>
|
65
|
+
</Binary>
|
66
|
+
</Selection>
|
67
|
+
</Selections>
|
68
|
+
</SelectionAnswer>
|
69
|
+
</AnswerSpecification>
|
70
|
+
</Question>
|
71
|
+
<Question>
|
72
|
+
<QuestionIdentifier>comments</QuestionIdentifier>
|
73
|
+
<QuestionContent>
|
74
|
+
<Text>Please help us improve this HIT by including any Questions and/or Comments (optional):</Text>
|
75
|
+
</QuestionContent>
|
76
|
+
<AnswerSpecification>
|
77
|
+
<FreeTextAnswer>
|
78
|
+
<NumberOfLinesSuggestion>10</NumberOfLinesSuggestion>
|
79
|
+
</FreeTextAnswer>
|
80
|
+
</AnswerSpecification>
|
81
|
+
</Question>
|
82
|
+
</QuestionForm>
|
@@ -0,0 +1,63 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Copyright:: Copyright (c) 2007 Amazon Technologies, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
|
6
|
+
begin ; require 'rubygems' ; rescue LoadError ; end
|
7
|
+
|
8
|
+
# The BlankSlate sample application disposes all of your HITs on sandbox
|
9
|
+
|
10
|
+
require 'ruby-aws'
|
11
|
+
@mturk = Amazon::WebServices::MechanicalTurkRequester.new :Host => :Sandbox
|
12
|
+
|
13
|
+
def forceExpire(id)
|
14
|
+
print "Ensuring HIT #{id} is expired: "
|
15
|
+
begin
|
16
|
+
@mturk.forceExpireHIT( :HITId => id )
|
17
|
+
rescue => e
|
18
|
+
raise e unless e.message == 'AWS.MechanicalTurk.InvalidHITState'
|
19
|
+
end
|
20
|
+
puts "OK"
|
21
|
+
end
|
22
|
+
|
23
|
+
def approveRemainingAssignments(id)
|
24
|
+
print "Approving remaining assignments for HIT #{id}: "
|
25
|
+
count = 0
|
26
|
+
@mturk.getAssignmentsForHITAll( :HITId => id ).each do |assignment|
|
27
|
+
@mturk.approveAssignment :AssignmentId => assignment[:AssignmentId] if assignment[:AssignmentStatus] == 'Submitted'
|
28
|
+
count += 1
|
29
|
+
end
|
30
|
+
puts "OK (Approved #{count})"
|
31
|
+
end
|
32
|
+
|
33
|
+
def dispose(id)
|
34
|
+
print "Disposing HIT #{id}: "
|
35
|
+
@mturk.disposeHIT( :HITId => id )
|
36
|
+
puts "OK"
|
37
|
+
end
|
38
|
+
|
39
|
+
def purge
|
40
|
+
hit_ids = @mturk.searchHITsAll.collect {|hit| hit[:HITId] }
|
41
|
+
puts "Found #{hit_ids.size} HITs"
|
42
|
+
|
43
|
+
return false if hit_ids.size == 0
|
44
|
+
|
45
|
+
hit_ids.each do |id|
|
46
|
+
begin
|
47
|
+
forceExpire id
|
48
|
+
approveRemainingAssignments id
|
49
|
+
dispose id
|
50
|
+
rescue Exception => e
|
51
|
+
raise e if e.is_a? Interrupt
|
52
|
+
puts e.inspect
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
return true
|
57
|
+
end
|
58
|
+
|
59
|
+
while purge
|
60
|
+
puts 'Ensuring there are no more hits...'
|
61
|
+
end
|
62
|
+
|
63
|
+
puts 'You now have a blank slate'
|
@@ -0,0 +1,67 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Copyright:: Copyright (c) 2007 Amazon Technologies, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
|
6
|
+
begin ; require 'rubygems' ; rescue LoadError ; end
|
7
|
+
|
8
|
+
# The BlankSlate sample application disposes all of your HITs on sandbox
|
9
|
+
|
10
|
+
require 'ruby-aws'
|
11
|
+
@mturk = Amazon::WebServices::MechanicalTurkRequester.new :Host => :Sandbox
|
12
|
+
require 'amazon/util/threadpool'
|
13
|
+
|
14
|
+
def forceExpire(id)
|
15
|
+
@mturk.forceExpireHIT( :HITId => id )
|
16
|
+
rescue
|
17
|
+
end
|
18
|
+
|
19
|
+
def approveRemainingAssignments(id)
|
20
|
+
@mturk.getAssignmentsForHITAll( :HITId => id ).each do |assignment|
|
21
|
+
begin
|
22
|
+
@mturk.approveAssignment :AssignmentId => assignment[:AssignmentId] if assignment[:AssignmentStatus] == 'Submitted'
|
23
|
+
rescue
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def dispose(id)
|
29
|
+
@mturk.disposeHIT( :HITId => id )
|
30
|
+
end
|
31
|
+
|
32
|
+
def purge
|
33
|
+
puts "*** starting purge ***"
|
34
|
+
hit_ids = @mturk.searchHITsAllProactive.collect {|hit| hit[:HITId] }
|
35
|
+
puts "Found #{hit_ids.size} HITs"
|
36
|
+
|
37
|
+
return false if hit_ids.size == 0
|
38
|
+
|
39
|
+
threadpool = Amazon::Util::ThreadPool.new(12)
|
40
|
+
|
41
|
+
puts "*** loading work ***"
|
42
|
+
hit_ids.each do |hid|
|
43
|
+
threadpool.addWork(hid) do |id|
|
44
|
+
begin
|
45
|
+
puts "starting #{id}"
|
46
|
+
forceExpire id
|
47
|
+
approveRemainingAssignments id
|
48
|
+
dispose id
|
49
|
+
puts "cleared #{id}"
|
50
|
+
rescue Exception => e
|
51
|
+
raise e if e.is_a? Interrupt
|
52
|
+
puts e.inspect
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
puts "*** finished adding to queue ***"
|
57
|
+
|
58
|
+
threadpool.finish
|
59
|
+
|
60
|
+
return true
|
61
|
+
end
|
62
|
+
|
63
|
+
while purge
|
64
|
+
puts 'Ensuring there are no more hits...'
|
65
|
+
end
|
66
|
+
|
67
|
+
puts 'You now have a blank slate'
|
@@ -0,0 +1,56 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Copyright:: Copyright (c) 2007 Amazon Technologies, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
|
6
|
+
begin ; require 'rubygems' ; rescue LoadError ; end
|
7
|
+
|
8
|
+
# The MTurk Hello World sample application creates a simple HIT via Libraries for Amazon Web Services.
|
9
|
+
|
10
|
+
require 'ruby-aws'
|
11
|
+
@mturk = Amazon::WebServices::MechanicalTurkRequester.new :Config => File.join( File.dirname(__FILE__), 'mturk.yml' )
|
12
|
+
|
13
|
+
require 'amazon/webservices/mturk/question_generator'
|
14
|
+
include Amazon::WebServices::MTurk
|
15
|
+
|
16
|
+
def createHelloWorld
|
17
|
+
title = "Answer a question"
|
18
|
+
desc = "This is a HIT created by the Amazon Mechanical Turk SDK for Ruby. Please answer the question."
|
19
|
+
keywords = "sample, SDK, hello"
|
20
|
+
numAssignments = 1
|
21
|
+
rewardAmount = 0.05 # 5 cents
|
22
|
+
|
23
|
+
question = QuestionGenerator.build(:Basic) do |q|
|
24
|
+
q.ask "What is the weather like right now in Seattle, WA?"
|
25
|
+
end
|
26
|
+
|
27
|
+
puts question
|
28
|
+
|
29
|
+
result = @mturk.createHIT( :Title => title,
|
30
|
+
:Description => desc,
|
31
|
+
:MaxAssignments => numAssignments,
|
32
|
+
:Reward => { :Amount => rewardAmount, :CurrencyCode => 'USD' },
|
33
|
+
:Question => question,
|
34
|
+
:Keywords => keywords )
|
35
|
+
|
36
|
+
puts "Created HIT: #{result[:HITId]}"
|
37
|
+
puts "Url: #{getHITUrl( result[:HITTypeId] )}"
|
38
|
+
end
|
39
|
+
|
40
|
+
def getHITUrl( hitTypeId )
|
41
|
+
if @mturk.host =~ /sandbox/
|
42
|
+
"http://workersandbox.mturk.com/mturk/preview?groupId=#{hitTypeId}" # Sandbox Url
|
43
|
+
else
|
44
|
+
"http://mturk.com/mturk/preview?groupId=#{hitTypeId}" # Production Url
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Check to see if your account has sufficient funds
|
49
|
+
def hasEnoughFunds?
|
50
|
+
available = @mturk.availableFunds
|
51
|
+
puts "Got account balance: %.2f" % available
|
52
|
+
return available > 0.055
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
createHelloWorld if hasEnoughFunds?
|
@@ -0,0 +1,103 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Copyright:: Copyright (c) 2007 Amazon Technologies, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
|
6
|
+
begin ; require 'rubygems' ; rescue LoadError ; end
|
7
|
+
|
8
|
+
# The Reviewer sample application will retrieve the completed assignments for a given HIT,
|
9
|
+
# output the results and approve the assignment.
|
10
|
+
#
|
11
|
+
# mturk.yml is used to configure default settings ( must be in the same directory as Reviewer.rb )
|
12
|
+
# You will need to have the HIT ID of an existing HIT that has been accepted, completed and
|
13
|
+
# submitted by a worker.
|
14
|
+
# Or you can use the .success file generated from bulk loading several HITs (i.e. Site Category sample application).
|
15
|
+
#
|
16
|
+
# The following concepts are covered:
|
17
|
+
# - Retrieve results for a HIT
|
18
|
+
# - Output results for several HITs to a file
|
19
|
+
# - Approve assignments
|
20
|
+
|
21
|
+
require 'ruby-aws'
|
22
|
+
@mturk = Amazon::WebServices::MechanicalTurkRequester.new :Config => File.join( File.dirname(__FILE__), 'mturk.yml' )
|
23
|
+
|
24
|
+
# Prints the submitted results of HITs when provided with a .success file.
|
25
|
+
# successFile:: The .success file containing the HIT ID and HIT Type ID
|
26
|
+
# outputFile:: The output file to write the submitted results to
|
27
|
+
def printResults( successFile, outputFile)
|
28
|
+
|
29
|
+
# Loads the .success file containing the HIT IDs and HIT Type IDs of HITs to be retrieved.
|
30
|
+
success = Amazon::Util::DataReader.load( successFile, :Tabular )
|
31
|
+
|
32
|
+
# Retrieves the submitted results of the specified HITs from Mechanical Turk
|
33
|
+
results = @mturk.getHITResults(success)
|
34
|
+
|
35
|
+
# parse answers to they're easier to digest
|
36
|
+
results.each { |assignment| assignment[:Answers] = @mturk.simplifyAnswer( assignment[:Answer] ) }
|
37
|
+
|
38
|
+
# Writes the submitted results to the defined output file.
|
39
|
+
# The output file is a tab delimited file containing all relevant details
|
40
|
+
# of the HIT and assignments. The submitted results are included as the last set of fields
|
41
|
+
# and are represented as tab separated question/answer pairs
|
42
|
+
Amazon::Util::DataReader.save( outputFile, results, :Tabular )
|
43
|
+
puts "Results have been written to: #{outputFile}"
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
# Prints the submitted results of a HIT when provided with a HIT ID.
|
48
|
+
# hitId:: The HIT ID of the HIT to be retrieved.
|
49
|
+
def reviewAnswers( hitId )
|
50
|
+
assignments = @mturk.getAssignmentsForHITAll( :HITId => hitId, :AssignmentStatus => 'Submitted')
|
51
|
+
|
52
|
+
puts "--[Reviewing HITs]----------"
|
53
|
+
puts " HIT Id: #{hitId}"
|
54
|
+
|
55
|
+
assignments.each do |assignment|
|
56
|
+
|
57
|
+
# By default, answers are specified in XML
|
58
|
+
answerXML = assignment[:Answer]
|
59
|
+
|
60
|
+
# Calling a convenience method that will parse the answer XML and extract out the question/answer pairs.
|
61
|
+
answers = @mturk.simplifyAnswer( answerXML )
|
62
|
+
|
63
|
+
answers.each do |id,answer|
|
64
|
+
assignmentId = assignment[:AssignmentId]
|
65
|
+
puts "Got an answer \"#{answer}\" for \"#{id}\" from worker #{assignment[:WorkerId]}"
|
66
|
+
end
|
67
|
+
|
68
|
+
# Approving the assignment
|
69
|
+
@mturk.approveAssignment(:AssignmentId => assignment[:AssignmentId], :RequesterFeedback => "Well Done!")
|
70
|
+
puts "Approved."
|
71
|
+
|
72
|
+
end
|
73
|
+
puts "--[End Reviewing HITs]----------"
|
74
|
+
end
|
75
|
+
|
76
|
+
require 'optparse'
|
77
|
+
hitsToReview = []
|
78
|
+
opts = OptionParser.new
|
79
|
+
opts.on( '--review HITId', 'Review Answers for a single HIT ( can be specified multiple times)') {|hit| hitsToReview << hit ; @review = true }
|
80
|
+
opts.on( '--results', 'Print Results using input and output files') { @getResults = true }
|
81
|
+
opts.on( '--input FILE', 'Input File to get results') {|file| @inputFile = file }
|
82
|
+
opts.on( '--output FILE', 'Output File to save results') {|file| @outputFile = file }
|
83
|
+
|
84
|
+
begin
|
85
|
+
opts.parse ARGV
|
86
|
+
raise "Please, either --review or --results, not both" if @review && @getResults
|
87
|
+
raise "Pick something to do ( either --review or --results )" unless @review || @getResults
|
88
|
+
if @getResults
|
89
|
+
raise "missing input file" unless @inputFile
|
90
|
+
raise "missing output file" unless @outputFile
|
91
|
+
raise "input file does not exist: #{@inputFile}" unless File.exists? @inputFile
|
92
|
+
end
|
93
|
+
rescue => e
|
94
|
+
puts e.message
|
95
|
+
puts opts.to_s
|
96
|
+
exit
|
97
|
+
end
|
98
|
+
|
99
|
+
if @getResults
|
100
|
+
printResults( @inputFile, @outputFile )
|
101
|
+
elsif @review
|
102
|
+
hitsToReview.each {|h| reviewAnswers(h) }
|
103
|
+
end
|