rturk 2.0.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.markdown +2 -1
- data/VERSION +1 -1
- data/examples/blank_slate.rb +4 -5
- data/examples/create_hit.rb +0 -4
- data/examples/review_answer.rb +4 -2
- data/lib/rturk/adapters/assignment.rb +22 -24
- data/lib/rturk/adapters/hit.rb +5 -16
- data/lib/rturk/logger.rb +4 -0
- data/rturk.gemspec +2 -1
- data/spec/fake_responses/get_assignments_multiple.xml +77 -0
- data/spec/operations/get_assignments_spec.rb +30 -8
- metadata +2 -1
data/README.markdown
CHANGED
@@ -70,7 +70,7 @@ Let's say you have a form at "http://myapp.com/turkers/add_tags" where Turkers c
|
|
70
70
|
### Logging
|
71
71
|
Want to see what's going on - enable logging.
|
72
72
|
|
73
|
-
RTurk::
|
73
|
+
RTurk::log.level = Logger::DEBUG
|
74
74
|
|
75
75
|
## Nitty Gritty
|
76
76
|
|
@@ -79,6 +79,7 @@ Here's a quick peak at what happens on the Mechanical Turk side.
|
|
79
79
|
A worker takes a look at your hit. The page will contain an iframe with your question URL loaded inside of it.
|
80
80
|
|
81
81
|
Amazon will append the AssignmentID parameter to the URL for your own information. In preview mode this will look like
|
82
|
+
|
82
83
|
http://myapp.com/turkers/add_tags?item_id=1234&AssignmentId=ASSIGNMENT_ID_NOT_AVAILABLE
|
83
84
|
|
84
85
|
If the Turker accepts the HIT, the page will reload and the iframe URL will resemble
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.0.
|
1
|
+
2.0.1
|
data/examples/blank_slate.rb
CHANGED
@@ -3,7 +3,7 @@ require 'rubygems'
|
|
3
3
|
require '../lib/rturk'
|
4
4
|
|
5
5
|
aws = YAML.load(File.open(File.join(File.dirname(__FILE__), 'mturk.yml')))
|
6
|
-
RTurk::setup(aws['AWSAccessKeyId'], aws['AWSAccessKey']
|
6
|
+
RTurk::setup(aws['AWSAccessKeyId'], aws['AWSAccessKey'])
|
7
7
|
|
8
8
|
hits = RTurk::Hit.all_reviewable
|
9
9
|
|
@@ -11,13 +11,12 @@ puts "#{hits.size} reviewable hits. \n"
|
|
11
11
|
|
12
12
|
unless hits.empty?
|
13
13
|
puts "Approving all assignments and disposing of each hit!"
|
14
|
-
|
14
|
+
|
15
15
|
hits.each do |hit|
|
16
|
-
hit.expire!
|
16
|
+
hit.expire! if (hit.status == "Assignable" || hit.status == 'Unassignable')
|
17
17
|
hit.assignments.each do |assignment|
|
18
|
-
assignment.approve!
|
18
|
+
assignment.approve! if assignment.status == 'Submitted'
|
19
19
|
end
|
20
20
|
hit.dispose!
|
21
21
|
end
|
22
22
|
end
|
23
|
-
|
data/examples/create_hit.rb
CHANGED
@@ -5,10 +5,6 @@ require '../lib/rturk'
|
|
5
5
|
aws = YAML.load(File.open(File.join(File.dirname(__FILE__), 'mturk.yml')))
|
6
6
|
RTurk::setup(aws['AWSAccessKeyId'], aws['AWSAccessKey'], :sandbox => true)
|
7
7
|
|
8
|
-
root = File.expand_path(File.dirname(__FILE__))
|
9
|
-
aws = YAML.load(File.open(File.join(root, 'mturk.yml')))
|
10
|
-
RTurk::setup(aws['AWSAccessKeyId'], aws['AWSAccessKey'], :sandbox => true)
|
11
|
-
|
12
8
|
hit = RTurk::Hit.create(:title => 'Write a tweet for me') do |hit|
|
13
9
|
hit.description = 'Simply write a witty twitter update for my account'
|
14
10
|
hit.reward = 0.05
|
data/examples/review_answer.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
$: << File.join(File.dirname(__FILE__), '..', 'lib')
|
2
2
|
require 'rubygems'
|
3
3
|
require '../lib/rturk'
|
4
|
+
require 'yaml'
|
4
5
|
|
5
6
|
aws = YAML.load(File.open(File.join(File.dirname(__FILE__), 'mturk.yml')))
|
6
|
-
RTurk::setup(aws['AWSAccessKeyId'], aws['AWSAccessKey']
|
7
|
+
RTurk::setup(aws['AWSAccessKeyId'], aws['AWSAccessKey'])
|
8
|
+
file = File.open(File.join(File.dirname(__FILE__), 'answers.yml'), 'w')
|
7
9
|
|
8
10
|
hits = RTurk::Hit.all_reviewable
|
9
11
|
|
@@ -14,7 +16,7 @@ unless hits.empty?
|
|
14
16
|
|
15
17
|
hits.each do |hit|
|
16
18
|
hit.assignments.each do |assignment|
|
17
|
-
puts assignment.answers
|
19
|
+
file.puts assignment.answers.to_hash.to_yaml
|
18
20
|
assignment.approve! if assignment.status == 'Submitted'
|
19
21
|
end
|
20
22
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'time'
|
2
2
|
|
3
3
|
module RTurk
|
4
|
-
|
4
|
+
|
5
5
|
# Parses:
|
6
6
|
# <Assignment>
|
7
7
|
# <AssignmentId>GYFTRHZ5J3DZREY48WNZE38ZR9RR1ZPMXGWE7WE0</AssignmentId>
|
@@ -22,28 +22,28 @@ module RTurk
|
|
22
22
|
# </QuestionFormAnswers>
|
23
23
|
# </Answer>
|
24
24
|
# </Assignment>
|
25
|
-
|
25
|
+
|
26
26
|
class Assignment
|
27
27
|
include RTurk::XmlUtilities
|
28
|
-
|
28
|
+
|
29
29
|
attr_accessor :worker_id, :id, :status, :submitted_at, :accepted_at, :approved_at
|
30
30
|
attr_reader :answers
|
31
|
-
|
31
|
+
|
32
32
|
def initialize(xml_object)
|
33
33
|
map_content(xml_object,
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
34
|
+
:id => 'AssignmentId',
|
35
|
+
:worker_id => 'WorkerId',
|
36
|
+
:status => 'AssignmentStatus',
|
37
|
+
:accepted_at => 'AcceptTime',
|
38
|
+
:approved_at => "ApprovalTime",
|
39
|
+
:submitted_at => 'SubmitTime')
|
40
|
+
self.answers = xml_object.xpath('Answer')
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
43
|
def approved_at=(time)
|
44
44
|
@approved_at = Time.parse(time)
|
45
45
|
end
|
46
|
-
|
46
|
+
|
47
47
|
def submitted_at=(time)
|
48
48
|
@submitted_at = Time.parse(time)
|
49
49
|
end
|
@@ -51,25 +51,23 @@ module RTurk
|
|
51
51
|
def accepted_at=(time)
|
52
52
|
@accepted_at = Time.parse(time)
|
53
53
|
end
|
54
|
-
|
54
|
+
|
55
55
|
def approve!(feedback = nil)
|
56
56
|
RTurk::ApproveAssignment(:assignment_id => self.id, :feedback => feedback)
|
57
57
|
end
|
58
|
-
|
58
|
+
|
59
59
|
def reject!(reason)
|
60
60
|
RTurk::ApproveAssignment(:assignment_id => self.id, :feedback => reason)
|
61
61
|
end
|
62
|
-
|
62
|
+
|
63
63
|
def bonus!(amount, reason)
|
64
|
-
|
64
|
+
RTurk::GrantBonus(:amount, :feedback => reason)
|
65
65
|
end
|
66
|
-
|
66
|
+
|
67
67
|
def answers=(answer_xml)
|
68
|
-
|
69
|
-
@answers = RTurk::Answers.new(answer_xml)
|
70
|
-
end
|
68
|
+
@answers = RTurk::Answers.new(answer_xml.children.to_s)
|
71
69
|
end
|
72
|
-
|
70
|
+
|
73
71
|
end
|
74
|
-
|
75
|
-
end
|
72
|
+
|
73
|
+
end
|
data/lib/rturk/adapters/hit.rb
CHANGED
@@ -48,22 +48,6 @@ module RTurk
|
|
48
48
|
def assignments
|
49
49
|
RTurk::GetAssignmentsForHIT(:hit_id => self.id).assignments
|
50
50
|
end
|
51
|
-
|
52
|
-
def type_id
|
53
|
-
@type_id ||= details.type_id
|
54
|
-
end
|
55
|
-
|
56
|
-
def status
|
57
|
-
@status ||= details.status
|
58
|
-
end
|
59
|
-
|
60
|
-
def expires_at
|
61
|
-
@expires_at ||= details.expires_at
|
62
|
-
end
|
63
|
-
|
64
|
-
def title
|
65
|
-
@title ||= details.title
|
66
|
-
end
|
67
51
|
|
68
52
|
def details
|
69
53
|
@details ||= RTurk::GetHIT(:hit_id => self.id)
|
@@ -90,6 +74,11 @@ module RTurk
|
|
90
74
|
end
|
91
75
|
end
|
92
76
|
|
77
|
+
def method_missing(method, *args)
|
78
|
+
if self.details.respond_to?(method)
|
79
|
+
self.details.send(method, *args)
|
80
|
+
end
|
81
|
+
end
|
93
82
|
|
94
83
|
|
95
84
|
end
|
data/lib/rturk/logger.rb
CHANGED
data/rturk.gemspec
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{rturk}
|
8
|
-
s.version = "2.0.
|
8
|
+
s.version = "2.0.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Mark Percival"]
|
@@ -74,6 +74,7 @@ Gem::Specification.new do |s|
|
|
74
74
|
"spec/fake_responses/force_expire_hit.xml",
|
75
75
|
"spec/fake_responses/get_account_balance.xml",
|
76
76
|
"spec/fake_responses/get_assignments.xml",
|
77
|
+
"spec/fake_responses/get_assignments_multiple.xml",
|
77
78
|
"spec/fake_responses/get_hit.xml",
|
78
79
|
"spec/fake_responses/get_reviewable_hits.xml",
|
79
80
|
"spec/fake_responses/grant_bonus.xml",
|
@@ -0,0 +1,77 @@
|
|
1
|
+
<?xml version="1.0"?>
|
2
|
+
<GetAssignmentsForHITResponse>
|
3
|
+
<OperationRequest>
|
4
|
+
<RequestId>a964d1f8-d315-4bbb-9ab6-692625d662ff</RequestId>
|
5
|
+
</OperationRequest>
|
6
|
+
<GetAssignmentsForHITResult>
|
7
|
+
<Request>
|
8
|
+
<IsValid>True</IsValid>
|
9
|
+
</Request>
|
10
|
+
<NumResults>3</NumResults>
|
11
|
+
<TotalNumResults>3</TotalNumResults>
|
12
|
+
<PageNumber>1</PageNumber>
|
13
|
+
<Assignment>
|
14
|
+
<AssignmentId>32A8TDZQEZYRV84XKZ4ZBT6JT05DKJRZ1BC42YSZ</AssignmentId>
|
15
|
+
<WorkerId>ADOJP7RNRYAFG</WorkerId>
|
16
|
+
<HITId>32A8TDZQEZYRV84XKZ4Z</HITId>
|
17
|
+
<AssignmentStatus>Submitted</AssignmentStatus>
|
18
|
+
<AutoApprovalTime>2009-11-25T05:17:32Z</AutoApprovalTime>
|
19
|
+
<AcceptTime>2009-10-26T05:17:18Z</AcceptTime>
|
20
|
+
<SubmitTime>2009-10-26T05:17:32Z</SubmitTime>
|
21
|
+
<Answer><?xml version="1.0" encoding="UTF-8"?>
|
22
|
+
<QuestionFormAnswers xmlns="http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchemas/2005-10-01/QuestionFormAnswers.xsd">
|
23
|
+
<Answer>
|
24
|
+
<QuestionIdentifier>tweet</QuestionIdentifier>
|
25
|
+
<FreeText>This is my tweet!</FreeText>
|
26
|
+
</Answer>
|
27
|
+
<Answer>
|
28
|
+
<QuestionIdentifier>Submit</QuestionIdentifier>
|
29
|
+
<FreeText>Submit</FreeText>
|
30
|
+
</Answer>
|
31
|
+
</QuestionFormAnswers>
|
32
|
+
</Answer>
|
33
|
+
</Assignment>
|
34
|
+
<Assignment>
|
35
|
+
<AssignmentId>32A8TDZQEZYRV84XKZ4ZBT6JT05DKJRZ1BC42YSX</AssignmentId>
|
36
|
+
<WorkerId>ADOJP7RNRYAF</WorkerId>
|
37
|
+
<HITId>32A8TDZQEZYRV84XKZ4Z</HITId>
|
38
|
+
<AssignmentStatus>Submitted</AssignmentStatus>
|
39
|
+
<AutoApprovalTime>2009-11-25T05:17:32Z</AutoApprovalTime>
|
40
|
+
<AcceptTime>2009-10-26T05:17:18Z</AcceptTime>
|
41
|
+
<SubmitTime>2009-10-26T05:17:32Z</SubmitTime>
|
42
|
+
<Answer><?xml version="1.0" encoding="UTF-8"?>
|
43
|
+
<QuestionFormAnswers xmlns="http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchemas/2005-10-01/QuestionFormAnswers.xsd">
|
44
|
+
<Answer>
|
45
|
+
<QuestionIdentifier>tweet</QuestionIdentifier>
|
46
|
+
<FreeText>Second Tweet</FreeText>
|
47
|
+
</Answer>
|
48
|
+
<Answer>
|
49
|
+
<QuestionIdentifier>Submit</QuestionIdentifier>
|
50
|
+
<FreeText>Submit</FreeText>
|
51
|
+
</Answer>
|
52
|
+
</QuestionFormAnswers>
|
53
|
+
</Answer>
|
54
|
+
</Assignment>
|
55
|
+
<Assignment>
|
56
|
+
<AssignmentId>32A8TDZQEZYRV84XKZ4ZBT6JT05DKJRZ1BC42YSY</AssignmentId>
|
57
|
+
<WorkerId>ADOJP7RNRYAFI</WorkerId>
|
58
|
+
<HITId>32A8TDZQEZYRV84XKZ4Z</HITId>
|
59
|
+
<AssignmentStatus>Submitted</AssignmentStatus>
|
60
|
+
<AutoApprovalTime>2009-11-25T05:17:32Z</AutoApprovalTime>
|
61
|
+
<AcceptTime>2009-10-26T05:17:18Z</AcceptTime>
|
62
|
+
<SubmitTime>2009-10-26T05:17:32Z</SubmitTime>
|
63
|
+
<Answer><?xml version="1.0" encoding="UTF-8"?>
|
64
|
+
<QuestionFormAnswers xmlns="http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchemas/2005-10-01/QuestionFormAnswers.xsd">
|
65
|
+
<Answer>
|
66
|
+
<QuestionIdentifier>tweet</QuestionIdentifier>
|
67
|
+
<FreeText>Third tweet</FreeText>
|
68
|
+
</Answer>
|
69
|
+
<Answer>
|
70
|
+
<QuestionIdentifier>Submit</QuestionIdentifier>
|
71
|
+
<FreeText>Submit</FreeText>
|
72
|
+
</Answer>
|
73
|
+
</QuestionFormAnswers>
|
74
|
+
</Answer>
|
75
|
+
</Assignment>
|
76
|
+
</GetAssignmentsForHITResult>
|
77
|
+
</GetAssignmentsForHITResponse>
|
@@ -1,26 +1,48 @@
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
2
2
|
|
3
|
-
describe
|
4
|
-
|
3
|
+
describe RTurk::GetAssignmentsForHIT do
|
4
|
+
|
5
5
|
before(:all) do
|
6
6
|
aws = YAML.load(File.open(File.join(SPEC_ROOT, 'mturk.yml')))
|
7
7
|
RTurk.setup(aws['AWSAccessKeyId'], aws['AWSAccessKey'], :sandbox => true)
|
8
|
-
faker('get_assignments', :operation => 'GetAssignmentsForHIT')
|
9
8
|
end
|
10
9
|
|
11
10
|
it "should ensure required params" do
|
12
11
|
lambda{RTurk::GetAssignmentsForHIT(:page_number => 5)}.should raise_error RTurk::MissingParameters
|
13
12
|
end
|
14
|
-
|
13
|
+
|
15
14
|
it "should successfully request an assignment" do
|
16
15
|
RTurk::Requester.should_receive(:request).once.with(
|
17
|
-
|
16
|
+
hash_including('Operation' => 'GetAssignmentsForHIT'))
|
18
17
|
RTurk::GetAssignmentsForHIT(:hit_id => "abcd") rescue RTurk::InvalidRequest
|
19
18
|
end
|
19
|
+
|
20
|
+
context "an HIT with one assignment" do
|
21
|
+
|
22
|
+
before(:all) do
|
23
|
+
FakeWeb.clean_registry
|
24
|
+
faker('get_assignments', :operation => 'GetAssignmentsForHIT')
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should parse and return and answer" do
|
28
|
+
assignments = RTurk::GetAssignmentsForHIT(:hit_id => "abcd").assignments
|
29
|
+
assignments.first.answers['tweet'].should eql("This is my tweet!")
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
20
33
|
|
21
|
-
|
22
|
-
|
23
|
-
|
34
|
+
context "an HIT with multiple assignment" do
|
35
|
+
|
36
|
+
before(:all) do
|
37
|
+
FakeWeb.clean_registry
|
38
|
+
faker('get_assignments_multiple', :operation => 'GetAssignmentsForHIT')
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should parse and return and answer" do
|
42
|
+
assignments = RTurk::GetAssignmentsForHIT(:hit_id => "abcd").assignments
|
43
|
+
assignments.first.answers['tweet'].should eql("This is my tweet!")
|
44
|
+
end
|
45
|
+
|
24
46
|
end
|
25
47
|
|
26
48
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rturk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mark Percival
|
@@ -81,6 +81,7 @@ files:
|
|
81
81
|
- spec/fake_responses/force_expire_hit.xml
|
82
82
|
- spec/fake_responses/get_account_balance.xml
|
83
83
|
- spec/fake_responses/get_assignments.xml
|
84
|
+
- spec/fake_responses/get_assignments_multiple.xml
|
84
85
|
- spec/fake_responses/get_hit.xml
|
85
86
|
- spec/fake_responses/get_reviewable_hits.xml
|
86
87
|
- spec/fake_responses/grant_bonus.xml
|