Skip to content

Commit

Permalink
Most features now working. Basic qualifications and auth
Browse files Browse the repository at this point in the history
  • Loading branch information
Mark Percival committed Jun 19, 2009
1 parent 944cc14 commit d970ace
Show file tree
Hide file tree
Showing 11 changed files with 148 additions and 25 deletions.
2 changes: 1 addition & 1 deletion examples/external_page.rb
Expand Up @@ -21,4 +21,4 @@

puts page

p @turk.createHIT(props, page)
p @turk.create_hit(props, page)
12 changes: 12 additions & 0 deletions examples/review_answer.rb
@@ -0,0 +1,12 @@
require '../lib/rturk'
root = File.expand_path(File.dirname(__FILE__))
aws = YAML.load(File.open(File.join(root, 'mturk.yml')))
@turk = RTurk::Requester.new(aws['AWSAccessKeyId'], aws['AWSAccessKey'], :sandbox => true)

#GroupID PHAZMBRQNVRTGK0KZZ6Z
#HIT ID CYBGWCWJAXETWZW23X20

p @turk.get_assignments_for_hit('CYBGWCWJAXETWZW23X20')


p @turk.kill_hit('CYBGWCWJAXETWZW23X20')
1 change: 1 addition & 0 deletions lib/rturk.rb
Expand Up @@ -5,5 +5,6 @@ module RTurk

require 'rturk/utilities'
require 'rturk/actions'
require 'rturk/answer'
require 'rturk/external_question_builder'
require 'rturk/requester'
67 changes: 58 additions & 9 deletions lib/rturk/actions.rb
@@ -1,22 +1,71 @@
module RTurk::Actions
require 'cgi'
# Overides createHIT to allow for easier entry
def createHIT(props, page)
def create_hit(props, page)
props = format_props(props)
props = props.merge(:Question => page, :Operation => 'CreateHIT')
p props = props.merge(:Question => page, :Operation => 'CreateHIT')
request(props)
end

# Attempt to expire hit, then approve assignments, and finally dispose of
def kill_hit(hit_id)
p forceExpireHIT(:HITId => hit_id)
get_assignments_for_hit(hit_id).each do |assignment|
p approveAssignment(:AssignmentId => assignment[:AssignmentId])
end
p disposeHIT(:HITId => hit_id)
end

# Wipe out all HIT's associated with this account
def blank_slate

end


def get_assignments_for_hit(hit)
response = request(:Operation => 'GetAssignmentsForHIT', :HITId => hit)
assignments = []
if response['GetAssignmentsForHITResult']['Assignment'].instance_of?(Array)
response['GetAssignmentsForHITResult']['Assignment'].each do |assignment|
answer = RTurk::Answer.parse(assignment['Answer'])
assignment.delete('Answer')
assignment['Answer'] = answer
assignments << assignment
end
else
assignment = response['GetAssignmentsForHITResult']['Assignment']
answer = RTurk::Answer.parse(response['GetAssignmentsForHITResult']['Assignment']['Answer'])
assignment.delete('Answer')
assignment['Answer'] = answer
assignments << assignment
end
assignments
end

def url_for_hit(hit_id)
url_for_hit_type(getHIT(:HITId => hit_id)[:HITTypeId])
end

def url_for_hit_type(hit_type_id)
if @host =~ /sandbox/
"http://workersandbox.mturk.com/mturk/preview?groupId=#{hit_type_id}" # Sandbox Url
else
"http://mturk.com/mturk/preview?groupId=#{hit_type_id}" # Production Url
end
end

private

def format_props(params)
params = stringify_keys(params)
reward = params['Reward']
qualifiers = params['QualificationRequirement']
params.delete('Reward')
params.delete('QualificationRequirement')
reward = params[:Reward]
qualifiers = params[:QualificationRequirement]
params.delete(:Reward)
params.delete(:QualificationRequirement)
params.merge!('Reward.1.Amount' => reward[:Amount], 'Reward.1.CurrencyCode' => reward[:CurrencyCode])
p params
qualifiers.each_with_index do |qualifier, i|
params["QualificationRequirement.#{i+1}.QualificationTypeId"] = qualifier[:QualificationTypeId]
params["QualificationRequirement.#{i+1}.Comparator"] = qualifier[:Comparator]
params["QualificationRequirement.#{i+1}.IntegerValue"] = qualifier[:IntegerValue]
end
params
end

Expand Down
18 changes: 18 additions & 0 deletions lib/rturk/answer.rb
@@ -0,0 +1,18 @@
module RTurk
class Answer

def self.parse(xml)
answer = XmlSimple.xml_in(xml, {'ForceArray' => false})
response = {}
answer['Answer'].each do |a|
question = a['QuestionIdentifier']
a.delete('QuestionIdentifier')
a.each_value do |v|
response[question] = v
end
end
response
end

end
end
2 changes: 1 addition & 1 deletion lib/rturk/external_question_builder.rb
Expand Up @@ -6,7 +6,7 @@ def self.build(url, opts = {})
frame_height = opts[:frame_height] || 400
opts.delete(:frame_height)
querystring = opts.collect { |key, value| [CGI.escape(key.to_s), CGI.escape(value.to_s)].join('=') }.join('&')
@url = opts.empty? ? url : "#{url}?#{querystring}"
url = opts.empty? ? url : "#{url}?#{querystring}"
xml = <<-XML
<ExternalQuestion xmlns="http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchemas/2006-07-14/ExternalQuestion.xsd">
<ExternalURL>#{url}</ExternalURL>
Expand Down
20 changes: 11 additions & 9 deletions lib/rturk/requester.rb
Expand Up @@ -23,12 +23,9 @@ def initialize(access_key, secret_key, opts ={})
@secret_key = secret_key
@host = opts[:sandbox] ? SANDBOX : PRODUCTION
end

def request(params = {})
params = params.inject({}) do |options, (key, value)|
options[(key.to_s rescue key) || key] = value
options
end

def raw_request(params = {})
params = stringify_keys(params)
base_params = {
'Service'=>'AWSMechanicalTurkRequester',
'AWSAccessKeyId' => self.access_key,
Expand All @@ -42,12 +39,17 @@ def request(params = {})
querystring = params.collect { |key, value| [CGI.escape(key.to_s), CGI.escape(value.to_s)].join('=') }.join('&') # order doesn't matter for the actual request

response = RestClient.get("#{self.host}?#{querystring}")
XmlSimple.xml_in(response.to_s)
end

def request(params = {})
response = self.raw_request(params)
XmlSimple.xml_in(response.to_s, {'ForceArray' => false})
end

def method_missing(method, opts)
method = method.to_s.capitalize
opts.merge(:Operation => method)
method = method.to_s
method = method[0,1].upcase + method[1,method.size-1]
opts.merge!(:Operation => method)
request(opts)
end

Expand Down
4 changes: 0 additions & 4 deletions lib/rturk/utilities.rb
Expand Up @@ -13,9 +13,5 @@ def stringify_keys(ahash)
end
ahash
end

def url_for_hit

end

end
19 changes: 19 additions & 0 deletions spec/answer_spec.rb
@@ -0,0 +1,19 @@
require File.dirname(__FILE__) + '/spec_helper'


describe RTurk::Answer do

before(:all) do
@answer = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<QuestionFormAnswers xmlns=\"http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchemas/2005-10-01/QuestionFormAnswers.xsd\">
<Answer>\n<QuestionIdentifier>tweet</QuestionIdentifier>\n<FreeText>Spec example</FreeText>\n</Answer>
<Answer>\n<QuestionIdentifier>Submit</QuestionIdentifier>\n<FreeText>Submit</FreeText>\n</Answer>
<Answer>\n<QuestionIdentifier>Foo</QuestionIdentifier>\n<RandomSelector>Bar</RandomSelector>\n</Answer>
</QuestionFormAnswers>\n"
end

it "should parse an answer" do
RTurk::Answer.parse(@answer).should == {'Submit' => 'Submit', 'tweet' => 'Spec example', 'Foo' => 'Bar'}
end

end
27 changes: 27 additions & 0 deletions spec/external_question_spec.rb
@@ -0,0 +1,27 @@
require File.dirname(__FILE__) + '/spec_helper'


describe RTurk::ExternalQuestionBuilder do


it "should build a question with params" do
RTurk::ExternalQuestionBuilder.build('http://google.com/', :id => 'foo').should ==
<<-XML
<ExternalQuestion xmlns="http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchemas/2006-07-14/ExternalQuestion.xsd">
<ExternalURL>http://google.com/?id=foo</ExternalURL>
<FrameHeight>400</FrameHeight>
</ExternalQuestion>
XML
end

it "should build a question without params" do
RTurk::ExternalQuestionBuilder.build('http://google.com/').should ==
<<-XML
<ExternalQuestion xmlns="http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchemas/2006-07-14/ExternalQuestion.xsd">
<ExternalURL>http://google.com/</ExternalURL>
<FrameHeight>400</FrameHeight>
</ExternalQuestion>
XML
end

end
1 change: 0 additions & 1 deletion spec/requester_spec.rb
Expand Up @@ -9,7 +9,6 @@

it "should perform raw operations" do
@turk.request(:Operation => 'GetHIT', 'HITId' => 'test').include?(:errors).should be_true
# p turk.getHIT(:HITId => 'test')
end

it "should also interpret methods as operations" do
Expand Down

0 comments on commit d970ace

Please sign in to comment.