rturk 2.10.3 → 2.11.0
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.
- checksums.yaml +7 -0
- data/.rspec +1 -0
- data/.travis.yml +1 -2
- data/Gemfile +1 -1
- data/README.markdown +15 -8
- data/examples/create_hit.rb +1 -1
- data/lib/rturk/adapters/assignment.rb +2 -0
- data/lib/rturk/adapters/hit.rb +11 -5
- data/lib/rturk/builders/answer_key_builder.rb +39 -0
- data/lib/rturk/builders/{question_builder.rb → external_question_builder.rb} +14 -14
- data/lib/rturk/builders/qualification_builder.rb +28 -12
- data/lib/rturk/builders/qualifications_builder.rb +3 -1
- data/lib/rturk/builders/question_form_builder.rb +86 -0
- data/lib/rturk/operations/create_hit.rb +16 -8
- data/lib/rturk/operations/register_hit_type.rb +2 -2
- data/lib/rturk/parsers/responses/get_assignments_for_hit_response.rb +21 -5
- data/lib/rturk/parsers/responses/get_hit_response.rb +3 -2
- data/lib/rturk/parsers/responses/get_reviewable_hits_response.rb +20 -5
- data/lib/rturk/parsers/responses/search_hits_response.rb +23 -7
- data/lib/rturk/requester.rb +1 -1
- data/lib/rturk/version.rb +1 -1
- data/rturk.gemspec +3 -2
- data/spec/builders/answer_key_builder_spec.rb +26 -0
- data/spec/builders/{question_spec.rb → external_question_spec.rb} +20 -20
- data/spec/builders/question_form_builder_spec.rb +75 -0
- data/spec/example_question_form.rb +106 -0
- data/spec/example_question_form.xml +64 -0
- data/spec/operations/create_hit_spec.rb +33 -6
- data/spec/requester_spec.rb +8 -0
- data/spec/spec_helper.rb +4 -1
- metadata +114 -121
@@ -1,7 +1,7 @@
|
|
1
1
|
module RTurk
|
2
2
|
class RegisterHITType < Operation
|
3
3
|
|
4
|
-
attr_accessor :title, :description, :reward, :currency, :duration, :keywords, :
|
4
|
+
attr_accessor :title, :description, :reward, :currency, :duration, :keywords, :auto_approval_delay
|
5
5
|
|
6
6
|
|
7
7
|
# @param [Symbol, Hash] qualification_key opts The unique qualification key
|
@@ -54,7 +54,7 @@ module RTurk
|
|
54
54
|
'Reward.Amount' => reward,
|
55
55
|
'Reward.CurrencyCode' => (currency || 'USD'),
|
56
56
|
'Keywords' => keyword_string,
|
57
|
-
'AutoApprovalDelayInSeconds' =>
|
57
|
+
'AutoApprovalDelayInSeconds' => auto_approval_delay }
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
@@ -27,9 +27,9 @@
|
|
27
27
|
# </GetAssignmentsForHITResult>
|
28
28
|
|
29
29
|
module RTurk
|
30
|
-
|
30
|
+
|
31
31
|
class GetAssignmentsForHITResponse < Response
|
32
|
-
|
32
|
+
|
33
33
|
def assignments
|
34
34
|
@assignments ||= []
|
35
35
|
@xml.xpath('//Assignment').each do |assignment_xml|
|
@@ -37,7 +37,23 @@ module RTurk
|
|
37
37
|
end
|
38
38
|
@assignments
|
39
39
|
end
|
40
|
-
|
40
|
+
|
41
|
+
# todo: test
|
42
|
+
def total_num_results
|
43
|
+
@xml.xpath('//TotalNumResults').inner_text.to_i
|
44
|
+
end
|
45
|
+
|
46
|
+
# todo: test
|
47
|
+
def num_results
|
48
|
+
@xml.xpath('//NumResults').inner_text.to_i
|
49
|
+
end
|
50
|
+
|
51
|
+
# todo: test
|
52
|
+
def page_number
|
53
|
+
@xml.xpath('//PageNumber').inner_text.to_i
|
54
|
+
end
|
55
|
+
|
56
|
+
|
41
57
|
end
|
42
|
-
|
43
|
-
end
|
58
|
+
|
59
|
+
end
|
@@ -49,7 +49,7 @@ module RTurk
|
|
49
49
|
:auto_approval_delay, :description, :reward, :lifetime, :annotation,
|
50
50
|
:similar_hits_count, :assignments_pending_count, :assignments_available_count,
|
51
51
|
:assignments_completed_count, :question_external_url, :qualification_requirement_comparator,
|
52
|
-
:qualification_requirement_value
|
52
|
+
:qualification_requirement_value, :question
|
53
53
|
|
54
54
|
def initialize(response)
|
55
55
|
@raw_xml = response.body
|
@@ -78,7 +78,8 @@ module RTurk
|
|
78
78
|
:assignments_completed_count => 'NumberOfAssignmentsCompleted',
|
79
79
|
:question_external_url => 'Question/*/*[1]',
|
80
80
|
:qualification_requirement_comparator => 'QualificationRequirement/Comparator',
|
81
|
-
:qualification_requirement_value => 'QualificationRequirement/IntegerValue'
|
81
|
+
:qualification_requirement_value => 'QualificationRequirement/IntegerValue',
|
82
|
+
:question => 'Question'
|
82
83
|
)
|
83
84
|
|
84
85
|
@keywords = @keywords.split(', ') if @keywords
|
@@ -17,15 +17,30 @@
|
|
17
17
|
# </GetReviewableHITsResult>
|
18
18
|
|
19
19
|
module RTurk
|
20
|
-
|
20
|
+
|
21
21
|
class GetReviewableHITsResponse < Response
|
22
|
-
|
22
|
+
|
23
23
|
def hit_ids
|
24
24
|
@xml.xpath('//HIT').inject([]) do |arr, hit_xml|
|
25
25
|
arr << hit_xml.inner_text.strip; arr
|
26
26
|
end
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
|
+
# todo: test
|
30
|
+
def total_num_results
|
31
|
+
@xml.xpath('//TotalNumResults').inner_text.to_i
|
32
|
+
end
|
33
|
+
|
34
|
+
# todo: test
|
35
|
+
def num_results
|
36
|
+
@xml.xpath('//NumResults').inner_text.to_i
|
37
|
+
end
|
38
|
+
|
39
|
+
# todo: test
|
40
|
+
def page_number
|
41
|
+
@xml.xpath('//PageNumber').inner_text.to_i
|
42
|
+
end
|
43
|
+
|
29
44
|
end
|
30
|
-
|
31
|
-
end
|
45
|
+
|
46
|
+
end
|
@@ -6,7 +6,7 @@ module RTurk
|
|
6
6
|
# <NumResults>2</NumResults>
|
7
7
|
# <TotalNumResults>2</TotalNumResults>
|
8
8
|
# <PageNumber>1</PageNumber>
|
9
|
-
#
|
9
|
+
#
|
10
10
|
# <HIT>
|
11
11
|
# <HITId>GBHZVQX3EHXZ2AYDY2T0</HITId>
|
12
12
|
# <HITTypeId>NYVZTQ1QVKJZXCYZCZVZ</HITTypeId>
|
@@ -27,7 +27,7 @@ module RTurk
|
|
27
27
|
# <NumberOfAssignmentsAvailable>0</NumberOfAssignmentsAvailable>
|
28
28
|
# <NumberOfAssignmentsCompleted>1</NumberOfAssignmentsCompleted>
|
29
29
|
# </HIT>
|
30
|
-
#
|
30
|
+
#
|
31
31
|
# <HIT>
|
32
32
|
# <HITId>ZZRZPTY4ERDZWJ868JCZ</HITId>
|
33
33
|
# <HITTypeId>NYVZTQ1QVKJZXCYZCZVZ</HITTypeId>
|
@@ -49,9 +49,9 @@ module RTurk
|
|
49
49
|
# <NumberOfAssignmentsCompleted>0</NumberOfAssignmentsCompleted>
|
50
50
|
# </HIT>
|
51
51
|
# </SearchHITsResult>
|
52
|
-
|
52
|
+
|
53
53
|
class SearchHITsResponse < Response
|
54
|
-
|
54
|
+
|
55
55
|
def hits
|
56
56
|
@hits ||= begin
|
57
57
|
@xml.xpath('//HIT').inject([]) do |arr, hit_xml|
|
@@ -59,7 +59,23 @@ module RTurk
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
end
|
62
|
-
|
62
|
+
|
63
|
+
# todo: merge with GetReviewableHITsResponse and GetAssignmentsForHITResponse
|
64
|
+
# todo: test
|
65
|
+
def total_num_results
|
66
|
+
@xml.xpath('//TotalNumResults').inner_text.to_i
|
67
|
+
end
|
68
|
+
|
69
|
+
# todo: test
|
70
|
+
def num_results
|
71
|
+
@xml.xpath('//NumResults').inner_text.to_i
|
72
|
+
end
|
73
|
+
|
74
|
+
# todo: test
|
75
|
+
def page_number
|
76
|
+
@xml.xpath('//PageNumber').inner_text.to_i
|
77
|
+
end
|
78
|
+
|
63
79
|
end
|
64
|
-
|
65
|
-
end
|
80
|
+
|
81
|
+
end
|
data/lib/rturk/requester.rb
CHANGED
data/lib/rturk/version.rb
CHANGED
data/rturk.gemspec
CHANGED
@@ -25,8 +25,9 @@ Gem::Specification.new do |s|
|
|
25
25
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
26
26
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
27
27
|
s.require_paths = ["lib"]
|
28
|
-
s.add_dependency('rest-client'
|
29
|
-
s.add_dependency('nokogiri'
|
28
|
+
s.add_dependency('rest-client')
|
29
|
+
s.add_dependency('nokogiri')
|
30
|
+
s.add_dependency('erector')
|
30
31
|
|
31
32
|
# Development dependencies
|
32
33
|
s.add_development_dependency('rspec', "~> 1.3.1")
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
2
|
+
require 'rturk/builders/answer_key_builder'
|
3
|
+
|
4
|
+
module RTurk
|
5
|
+
describe AnswerKey do
|
6
|
+
|
7
|
+
before(:all) do
|
8
|
+
end
|
9
|
+
|
10
|
+
class SillyAnswerKey < AnswerKey
|
11
|
+
def answer_key_content
|
12
|
+
Question "Why did the chicken cross the road?"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it "is an abstract base class that calls down to 'answer_key_content' in its concrete subclasses" do
|
17
|
+
RTurk::SillyAnswerKey.new.to_xml.should ==
|
18
|
+
"<AnswerKey xmlns=\"#{RTurk::AnswerKey::XMLNS}\">" +
|
19
|
+
"<Question>Why did the chicken cross the road?</Question>" +
|
20
|
+
"</AnswerKey>"
|
21
|
+
end
|
22
|
+
|
23
|
+
# todo: test more
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -1,52 +1,52 @@
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
2
2
|
require 'cgi'
|
3
3
|
|
4
|
-
describe RTurk::
|
5
|
-
|
4
|
+
describe RTurk::ExternalQuestion do
|
5
|
+
|
6
6
|
before(:all) do
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
9
|
it "should build a question" do
|
10
|
-
question = RTurk::
|
11
|
-
question.url.should == 'http://mpercival.com'
|
10
|
+
question = RTurk::ExternalQuestion.new('http://mpercival.com')
|
11
|
+
question.url.should == 'http://mpercival.com'
|
12
12
|
question.frame_height.should == 400
|
13
13
|
end
|
14
14
|
|
15
15
|
it "should build a question " do
|
16
|
-
question = RTurk::
|
16
|
+
question = RTurk::ExternalQuestion.new('http://mpercival.com', :frame_height => 500, :chapter => 1)
|
17
17
|
question.params[:chapter] = 2
|
18
|
-
question.url.should == 'http://mpercival.com?chapter=2'
|
18
|
+
question.url.should == 'http://mpercival.com?chapter=2'
|
19
19
|
question.frame_height.should == 500
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
it "should build a question " do
|
23
|
-
question = RTurk::
|
23
|
+
question = RTurk::ExternalQuestion.new('http://mpercival.com?myparam=true&anotherparam=12', :frame_height => 500)
|
24
24
|
question.url.should == 'http://mpercival.com?myparam=true&anotherparam=12'
|
25
25
|
question.frame_height.should == 500
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
it "should build a question with params" do
|
29
|
-
params = RTurk::
|
30
|
-
CGI.unescape(params).should ==
|
29
|
+
params = RTurk::ExternalQuestion.new('http://google.com/', :id => 'foo').to_params
|
30
|
+
CGI.unescape(params).should ==
|
31
31
|
<<-XML
|
32
32
|
<ExternalQuestion xmlns="http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchemas/2006-07-14/ExternalQuestion.xsd">
|
33
|
-
<ExternalURL>http://google.com/?id=foo</ExternalURL>
|
33
|
+
<ExternalURL>http://google.com/?id=foo</ExternalURL>
|
34
34
|
<FrameHeight>400</FrameHeight>
|
35
35
|
</ExternalQuestion>
|
36
36
|
XML
|
37
37
|
end
|
38
38
|
|
39
39
|
it "should build a question without params" do
|
40
|
-
params = RTurk::
|
41
|
-
CGI.unescape(params).should ==
|
40
|
+
params = RTurk::ExternalQuestion.new('http://google.com/').to_params
|
41
|
+
CGI.unescape(params).should ==
|
42
42
|
<<-XML
|
43
43
|
<ExternalQuestion xmlns="http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchemas/2006-07-14/ExternalQuestion.xsd">
|
44
|
-
<ExternalURL>http://google.com/</ExternalURL>
|
44
|
+
<ExternalURL>http://google.com/</ExternalURL>
|
45
45
|
<FrameHeight>400</FrameHeight>
|
46
46
|
</ExternalQuestion>
|
47
47
|
XML
|
48
48
|
end
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
end
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
2
|
+
require 'rturk/builders/question_form_builder'
|
3
|
+
|
4
|
+
module RTurk
|
5
|
+
describe QuestionForm do
|
6
|
+
|
7
|
+
before(:all) do
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should build a question, using its xml param as the full QuestionForm since it starts with <QuestionForm" do
|
11
|
+
xml = <<-XML
|
12
|
+
<QuestionForm xmlns="#{RTurk::QuestionForm::XMLNS}">
|
13
|
+
[...]
|
14
|
+
</QuestionForm>
|
15
|
+
XML
|
16
|
+
question = RTurk::QuestionForm.new(:xml => xml)
|
17
|
+
question.to_params.should == xml
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should build a question, using its xml param as the QuestionForm content" do
|
21
|
+
question = RTurk::QuestionForm.new(:xml => "[...]")
|
22
|
+
question.to_params.should ==
|
23
|
+
"<QuestionForm xmlns=\"#{RTurk::QuestionForm::XMLNS}\">[...]</QuestionForm>"
|
24
|
+
end
|
25
|
+
|
26
|
+
class SillyQuestionForm < QuestionForm
|
27
|
+
def question_form_content
|
28
|
+
Question "Why did the chicken cross the road?"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
it "is an abstract base class that calls down to 'question_form_content' in its concrete subclasses" do
|
33
|
+
RTurk::SillyQuestionForm.new.to_xml.should ==
|
34
|
+
"<QuestionForm xmlns=\"#{RTurk::QuestionForm::XMLNS}\">" +
|
35
|
+
"<Question>Why did the chicken cross the road?</Question>" +
|
36
|
+
"</QuestionForm>"
|
37
|
+
end
|
38
|
+
|
39
|
+
class AnotherSillyQuestionForm < QuestionForm
|
40
|
+
def question_form_content
|
41
|
+
question {
|
42
|
+
question_content {
|
43
|
+
Text "How many licks?" # note: Text vs text vs text_element gotcha
|
44
|
+
}
|
45
|
+
answer_specification {
|
46
|
+
free_text_answer {
|
47
|
+
constraints {
|
48
|
+
is_numeric true
|
49
|
+
}
|
50
|
+
}
|
51
|
+
}
|
52
|
+
}
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
it "allows snake_case element names" do
|
57
|
+
RTurk::AnotherSillyQuestionForm.new.to_xml.should ==
|
58
|
+
"<QuestionForm xmlns=\"#{RTurk::QuestionForm::XMLNS}\">" +
|
59
|
+
"<Question>" +
|
60
|
+
"<QuestionContent>" +
|
61
|
+
"<Text>How many licks?</Text>" +
|
62
|
+
"</QuestionContent>" +
|
63
|
+
"<AnswerSpecification>" +
|
64
|
+
"<FreeTextAnswer>" +
|
65
|
+
"<Constraints>" +
|
66
|
+
"<IsNumeric>true</IsNumeric>" +
|
67
|
+
"</Constraints>" +
|
68
|
+
"</FreeTextAnswer>" +
|
69
|
+
"</AnswerSpecification>" +
|
70
|
+
"</Question>" +
|
71
|
+
"</QuestionForm>"
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
class ExampleQuestionForm < RTurk::QuestionForm
|
2
|
+
def question_form_content
|
3
|
+
Overview do
|
4
|
+
Title do
|
5
|
+
text 'Game 01523, "X" to play'
|
6
|
+
end
|
7
|
+
Text do
|
8
|
+
text 'You are helping to decide the next move in a game of Tic-Tac-Toe. The board looks like this:'
|
9
|
+
end
|
10
|
+
Binary do
|
11
|
+
MimeType do
|
12
|
+
Type do
|
13
|
+
text 'image'
|
14
|
+
end
|
15
|
+
SubType do
|
16
|
+
text 'gif'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
DataURL do
|
20
|
+
text 'http://tictactoe.amazon.com/game/01523/board.gif'
|
21
|
+
end
|
22
|
+
AltText do
|
23
|
+
text 'The game board, with "X" to move.'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
Text do
|
27
|
+
text 'Player "X" has the next move.'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
Question do
|
31
|
+
QuestionIdentifier do
|
32
|
+
text 'nextmove'
|
33
|
+
end
|
34
|
+
DisplayName do
|
35
|
+
text 'The Next Move'
|
36
|
+
end
|
37
|
+
IsRequired do
|
38
|
+
text 'true'
|
39
|
+
end
|
40
|
+
QuestionContent do
|
41
|
+
Text do
|
42
|
+
text 'What are the coordinates of the best move for player "X" in this game?'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
AnswerSpecification do
|
46
|
+
FreeTextAnswer do
|
47
|
+
Constraints do
|
48
|
+
Length :minLength => '2', :maxLength => '2'
|
49
|
+
end
|
50
|
+
DefaultText do
|
51
|
+
text 'C1'
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
Question do
|
57
|
+
QuestionIdentifier do
|
58
|
+
text 'likelytowin'
|
59
|
+
end
|
60
|
+
DisplayName do
|
61
|
+
text 'The Next Move'
|
62
|
+
end
|
63
|
+
IsRequired do
|
64
|
+
text 'true'
|
65
|
+
end
|
66
|
+
QuestionContent do
|
67
|
+
Text do
|
68
|
+
text 'How likely is it that player "X" will win this game?'
|
69
|
+
end
|
70
|
+
end
|
71
|
+
AnswerSpecification do
|
72
|
+
SelectionAnswer do
|
73
|
+
StyleSuggestion do
|
74
|
+
text 'radiobutton'
|
75
|
+
end
|
76
|
+
Selections do
|
77
|
+
Selection do
|
78
|
+
SelectionIdentifier do
|
79
|
+
text 'notlikely'
|
80
|
+
end
|
81
|
+
Text do
|
82
|
+
text 'Not likely'
|
83
|
+
end
|
84
|
+
end
|
85
|
+
Selection do
|
86
|
+
SelectionIdentifier do
|
87
|
+
text 'unsure'
|
88
|
+
end
|
89
|
+
Text do
|
90
|
+
text 'It could go either way'
|
91
|
+
end
|
92
|
+
end
|
93
|
+
Selection do
|
94
|
+
SelectionIdentifier do
|
95
|
+
text 'likely'
|
96
|
+
end
|
97
|
+
Text do
|
98
|
+
text 'Likely'
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|