turkee 1.1.1 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +29 -8
- data/Rakefile +10 -10
- data/lib/generators/turkee/templates/add_completed_tasks.rb.erb +17 -0
- data/lib/generators/turkee/templates/turkee_migration.rb.erb +1 -0
- data/lib/generators/turkee/turkee_generator.rb +11 -5
- data/lib/tasks/turkee.rb +1 -6
- data/lib/turkee.rb +95 -52
- data/spec/spec_helper.rb +60 -8
- data/spec/turkee_spec.rb +43 -4
- metadata +96 -59
data/README.rdoc
CHANGED
@@ -17,18 +17,24 @@ Mechanical Turk is now requiring that the hitId, workerId, and the turkSubmitTo
|
|
17
17
|
What does this mean for you? Not much besides the fact that now when you construct your forms using turkee_form_for, you'll be passing in your entire params hash instead of just the assignment_id. The code snippet below reflect this change.
|
18
18
|
|
19
19
|
|
20
|
-
== Install
|
20
|
+
== Install/Upgrade
|
21
21
|
|
22
22
|
Add turkee to your Gemfile as a gem dependency, then do a 'bundle install':
|
23
23
|
|
24
24
|
gem 'turkee'
|
25
25
|
|
26
|
-
To access the Turkee rake tasks, add the following to your application's Rakefile:
|
27
|
-
require 'tasks/turkee'
|
28
26
|
|
29
|
-
Run the turkee generator from your application directory to copy the needed migrations and config/initializer into your application:
|
30
27
|
|
31
|
-
|
28
|
+
If you're upgrading Turkee (1.1.1 and prior) or installing for the first time, run:
|
29
|
+
|
30
|
+
rails g turkee --skip
|
31
|
+
|
32
|
+
(the skip flag will ensure that you don't overwrite prior Turkee initializers and migrations.)
|
33
|
+
|
34
|
+
This will copy the needed migrations and config/initializer into your application directory.
|
35
|
+
|
36
|
+
To access the Turkee rake tasks, add the following to your application's Rakefile:
|
37
|
+
require 'tasks/turkee'
|
32
38
|
|
33
39
|
If you haven't created a Mechanical Turk account, surf on over to {Amazon's Web Services}[http://aws.amazon.com/] and create an AWS account.
|
34
40
|
|
@@ -94,8 +100,6 @@ This will insert a row for the requested HIT into the turkee_tasks table. The t
|
|
94
100
|
|
95
101
|
When a Turk worker views your HIT, the HIT will display your form within an iFrame. With the above example, Mechanical Turk will open an iFrame for the HIT assignment displaying the form http://www.yourapp.com/surveys/new
|
96
102
|
|
97
|
-
** The application that hosts your external forms preferably should have an https interface (you're going to have to buy an SSL certificate). If the forms are hosted on an unsecured host (http), because Mechanical Turk defaults to https, you're going to receive the ugly popup from IE regarding "mixed content" (http://msdn.microsoft.com/en-us/library/ee264315%28v=vs.85%29.aspx).
|
98
|
-
|
99
103
|
5) Allow some time for the Mechanical Turk workers ("Turkers") to respond to your HIT.
|
100
104
|
|
101
105
|
6) Run the rake task that retrieves the values from Mechanical Turk and stores the user entered values into your model.
|
@@ -120,6 +124,23 @@ As for Mechanical Turk approval, if the row is created and you haven't specified
|
|
120
124
|
end
|
121
125
|
end
|
122
126
|
|
127
|
+
|
128
|
+
== Advanced Usage
|
129
|
+
|
130
|
+
You can use the params hash to pass object IDs to your forms. E.g. if you wanted to setup a form of questions about a given URL (let's call the model UrlSurvey), your code would look something like :
|
131
|
+
|
132
|
+
URL.all do |url|
|
133
|
+
Turkee::TurkeeTask.create_hit(host, hit_title, hit_description, UrlSurvey, num_assignments, reward,
|
134
|
+
lifetime, qualifications = {}, params = {:url_id => url.id}, opts = {})
|
135
|
+
end
|
136
|
+
|
137
|
+
Then when displaying your form, you can find the URL object via the params[:url_id] value.
|
138
|
+
|
139
|
+
== Gotchas
|
140
|
+
|
141
|
+
1) The application that hosts your external forms preferably should have an https interface (you're going to have to buy an SSL certificate). If the forms are hosted on an unsecured host (http), because Mechanical Turk defaults to https, you're going to receive the ugly popup from IE regarding "mixed content" (http://msdn.microsoft.com/en-us/library/ee264315%28v=vs.85%29.aspx).
|
142
|
+
|
143
|
+
|
123
144
|
== Copyright
|
124
145
|
|
125
|
-
Copyright (c) 2010 -
|
146
|
+
Copyright (c) 2010 - 2012 Jim Jones. See LICENSE for details.
|
data/Rakefile
CHANGED
@@ -1,15 +1,20 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'rake'
|
3
|
+
require 'bundler'
|
4
|
+
Bundler::GemHelper.install_tasks
|
3
5
|
|
4
|
-
|
6
|
+
$:.push File.expand_path("../lib", __FILE__)
|
5
7
|
|
6
8
|
begin
|
7
9
|
INSTALL_MESSAGE = %q{
|
8
10
|
========================================================================
|
9
11
|
Turkee Installation Complete.
|
10
12
|
------------------------------------------------------------------------
|
13
|
+
If you're upgrading Turkee (1.1.1 and prior) or installing for the first time, run:
|
11
14
|
|
12
|
-
|
15
|
+
rails g turkee --skip
|
16
|
+
|
17
|
+
For full instructions on gem usage, visit:
|
13
18
|
http://github.com/aantix/turkee#readme
|
14
19
|
|
15
20
|
** If you like the Turkee gem, please click the "watch" button on the
|
@@ -17,11 +22,9 @@ begin
|
|
17
22
|
http://github.com/aantix/turkee
|
18
23
|
|
19
24
|
========================================================================
|
20
|
-
-- Gobble, gobble.
|
21
25
|
}
|
22
|
-
|
23
|
-
|
24
|
-
Jeweler::Tasks.new do |gem|
|
26
|
+
|
27
|
+
Gem::Specification.new do |gem|
|
25
28
|
gem.name = "turkee"
|
26
29
|
gem.summary = "Turkee makes dealing with Amazon's Mechnical Turk a breeze."
|
27
30
|
gem.description = "Turkee will help you to create your Rails forms, post the HITs, and retrieve the user entered values from Mechanical Turk."
|
@@ -35,9 +38,6 @@ begin
|
|
35
38
|
gem.post_install_message = INSTALL_MESSAGE
|
36
39
|
gem.require_path = 'lib'
|
37
40
|
gem.files = %w(MIT-LICENSE README.textile Gemfile Rakefile init.rb) + Dir.glob("{lib,spec}/**/*")
|
38
|
-
|
41
|
+
|
39
42
|
end
|
40
|
-
Jeweler::GemcutterTasks.new
|
41
|
-
rescue LoadError
|
42
|
-
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
43
43
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class AddCompletedTasks< ActiveRecord::Migration
|
2
|
+
|
3
|
+
def self.up
|
4
|
+
unless column_exists? :turkee_tasks, :completed_assignments
|
5
|
+
add_column :turkee_tasks, :completed_assignments, :integer, :default => 0
|
6
|
+
end
|
7
|
+
|
8
|
+
unless column_exists? :turkee_tasks, :hit_num_assignments
|
9
|
+
add_column :turkee_tasks, :hit_num_assignments, :integer
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.down
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
@@ -14,16 +14,22 @@ class TurkeeGenerator < Rails::Generators::Base
|
|
14
14
|
|
15
15
|
desc "Creates initializer and migrations."
|
16
16
|
|
17
|
-
def create_initializer
|
18
|
-
template "turkee.rb", "config/initializers/turkee.rb"
|
19
|
-
end
|
20
|
-
|
21
17
|
def create_migrations
|
22
18
|
migration_template "turkee_migration.rb.erb", "db/migrate/create_turkee_tasks.rb"
|
23
|
-
|
19
|
+
|
24
20
|
# Need this sleep so that we don't get the same migration timestamp for both migrations
|
25
21
|
sleep 1
|
26
22
|
|
27
23
|
migration_template "turkee_imported_assignments.rb.erb", "db/migrate/create_turkee_imported_assignments.rb"
|
24
|
+
|
25
|
+
sleep 1
|
26
|
+
|
27
|
+
migration_template "add_completed_tasks.rb.erb", "db/migrate/add_completed_tasks.rb"
|
28
|
+
|
28
29
|
end
|
30
|
+
|
31
|
+
def create_initializer
|
32
|
+
template "turkee.rb", "config/initializers/turkee.rb"
|
33
|
+
end
|
34
|
+
|
29
35
|
end
|
data/lib/tasks/turkee.rb
CHANGED
@@ -1,14 +1,9 @@
|
|
1
1
|
require 'rake'
|
2
2
|
require 'turkee'
|
3
3
|
|
4
|
-
#include ActionController::PolymorphicRoutes
|
5
|
-
#include ActionView::Helpers::UrlHelper
|
6
|
-
|
7
|
-
# clear && rake turkee:post_hit['Test title','Test desc','Joke',3,0.05,1] --trace
|
8
|
-
|
9
4
|
namespace :turkee do
|
10
5
|
desc "Post your form to Mechanical Turk (HIT). Task takes the application's host URL, HIT title, HIT description, model name, number of responses, reward for each response, and number of days the HIT should be valid."
|
11
|
-
task :post_hit, :host, :title, :description, :model, :num_assignments, :reward, :lifetime
|
6
|
+
task :post_hit, [:host, :title, :description, :model, :num_assignments, :reward, :lifetime] => :environment do |t, args|
|
12
7
|
hit = Turkee::TurkeeTask.create_hit(args[:host],args[:title], args[:description], args[:model],
|
13
8
|
args[:num_assignments], args[:reward], args[:lifetime])
|
14
9
|
puts "Hit created ( #{hit.hit_url} )."
|
data/lib/turkee.rb
CHANGED
@@ -4,7 +4,7 @@ require 'rturk'
|
|
4
4
|
require 'lockfile'
|
5
5
|
require 'active_record'
|
6
6
|
require 'action_view'
|
7
|
-
require
|
7
|
+
require "active_support/core_ext/object/to_query"
|
8
8
|
require 'action_controller'
|
9
9
|
|
10
10
|
module Turkee
|
@@ -14,7 +14,9 @@ module Turkee
|
|
14
14
|
end
|
15
15
|
|
16
16
|
class TurkeeTask < ActiveRecord::Base
|
17
|
-
|
17
|
+
attr_accessible :sandbox, :hit_title, :hit_description, :hit_reward, :hit_num_assignments, :hit_lifetime,
|
18
|
+
:form_url, :hit_url, :hit_id, :task_type, :complete
|
19
|
+
|
18
20
|
HIT_FRAMEHEIGHT = 1000
|
19
21
|
|
20
22
|
scope :unprocessed_hits, :conditions => ['complete = ?', false]
|
@@ -28,43 +30,32 @@ module Turkee
|
|
28
30
|
# Using a lockfile to prevent multiple calls to Amazon.
|
29
31
|
Lockfile.new('/tmp/turk_processor.lock', :max_age => 3600, :retries => 10) do
|
30
32
|
|
31
|
-
turks = turkee_task
|
33
|
+
turks = task_items(turkee_task)
|
32
34
|
|
33
35
|
turks.each do |turk|
|
34
|
-
hit
|
36
|
+
hit = RTurk::Hit.new(turk.hit_id)
|
35
37
|
|
38
|
+
models = []
|
36
39
|
hit.assignments.each do |assignment|
|
37
|
-
next unless assignment.status
|
40
|
+
next unless submitted?(assignment.status)
|
38
41
|
next unless TurkeeImportedAssignment.find_by_assignment_id(assignment.id).nil?
|
39
42
|
|
40
|
-
params = assignment.answers
|
43
|
+
params = assignment_params(assignment.answers)
|
41
44
|
param_hash = Rack::Utils.parse_nested_query(params)
|
42
45
|
model = find_model(param_hash)
|
43
46
|
|
44
47
|
next if model.nil?
|
45
|
-
|
48
|
+
puts "param_hash = #{param_hash}"
|
46
49
|
result = model.create(param_hash[model.to_s.underscore])
|
47
50
|
|
48
51
|
# If there's a custom approve? method, see if we should approve the submitted assignment
|
49
52
|
# otherwise just approve it by default
|
50
|
-
|
51
|
-
logger.info "Errors : #{result.inspect}"
|
52
|
-
assignment.reject!('Failed to enter proper data.')
|
53
|
-
elsif result.respond_to?(:approve?)
|
54
|
-
logger.debug "Approving : #{result.inspect}"
|
55
|
-
result.approve? ? assignment.approve!('') : assignment.reject!('Rejected criteria.')
|
56
|
-
else
|
57
|
-
assignment.approve!('')
|
58
|
-
end
|
53
|
+
process_result(assignment, result, turk)
|
59
54
|
|
60
55
|
TurkeeImportedAssignment.create(:assignment_id => assignment.id) rescue nil
|
61
|
-
|
62
56
|
end
|
63
57
|
|
64
|
-
|
65
|
-
hit.dispose!
|
66
|
-
model.hit_complete(turk) if model.respond_to?(:hit_complete)
|
67
|
-
end
|
58
|
+
check_hit_completeness(hit, turk, models)
|
68
59
|
end
|
69
60
|
end
|
70
61
|
rescue Lockfile::MaxTriesLockError => e
|
@@ -74,11 +65,11 @@ module Turkee
|
|
74
65
|
end
|
75
66
|
|
76
67
|
# Creates a new Mechanical Turk task on AMZN with the given title, desc, etc
|
77
|
-
def self.create_hit(host, hit_title, hit_description, typ, num_assignments, reward, lifetime)
|
68
|
+
def self.create_hit(host, hit_title, hit_description, typ, num_assignments, reward, lifetime, qualifications = {}, params = {}, opts = {})
|
78
69
|
|
79
70
|
model = Object::const_get(typ)
|
80
71
|
duration = lifetime.to_i
|
81
|
-
f_url = form_url(host, model)
|
72
|
+
f_url = (full_url(opts[:form_url], params) || form_url(host, model, params))
|
82
73
|
|
83
74
|
h = RTurk::Hit.create(:title => hit_title) do |hit|
|
84
75
|
hit.assignments = num_assignments
|
@@ -86,7 +77,11 @@ module Turkee
|
|
86
77
|
hit.reward = reward
|
87
78
|
hit.lifetime = duration.days.seconds.to_i
|
88
79
|
hit.question(f_url, :frame_height => HIT_FRAMEHEIGHT)
|
89
|
-
|
80
|
+
unless qualifications.empty?
|
81
|
+
qualifications.each do |key, value|
|
82
|
+
hit.qualifications.add key, value
|
83
|
+
end
|
84
|
+
end
|
90
85
|
end
|
91
86
|
|
92
87
|
TurkeeTask.create(:sandbox => RTurk.sandbox?,
|
@@ -102,9 +97,9 @@ module Turkee
|
|
102
97
|
# DON'T PUSH THIS BUTTON UNLESS YOU MEAN IT. :)
|
103
98
|
def self.clear_all_turks(force = false)
|
104
99
|
# Do NOT execute this function if we're in production mode
|
105
|
-
raise "You can only clear turks in the sandbox/development environment unless you pass 'true' for the force flag." if
|
100
|
+
raise "You can only clear turks in the sandbox/development environment unless you pass 'true' for the force flag." if Rails.env == 'production' && !force
|
106
101
|
|
107
|
-
hits = RTurk::Hit.
|
102
|
+
hits = RTurk::Hit.all
|
108
103
|
|
109
104
|
logger.info "#{hits.size} reviewable hits. \n"
|
110
105
|
|
@@ -113,7 +108,7 @@ module Turkee
|
|
113
108
|
|
114
109
|
hits.each do |hit|
|
115
110
|
begin
|
116
|
-
hit.expire!
|
111
|
+
hit.expire!
|
117
112
|
|
118
113
|
hit.assignments.each do |assignment|
|
119
114
|
|
@@ -144,6 +139,51 @@ module Turkee
|
|
144
139
|
@logger ||= Logger.new($stderr)
|
145
140
|
end
|
146
141
|
|
142
|
+
def self.check_hit_completeness(hit, turk, models)
|
143
|
+
puts "#### turk.completed_assignments == turk.hit_num_assignments :: #{turk.completed_assignments} == #{turk.hit_num_assignments}"
|
144
|
+
if turk.completed_assignments == turk.hit_num_assignments
|
145
|
+
hit.dispose!
|
146
|
+
turk.complete = true
|
147
|
+
turk.save
|
148
|
+
models.each { |model| model.hit_complete(turk) if model.respond_to?(:hit_complete) }
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
|
153
|
+
def self.process_result(assignment, result, turk)
|
154
|
+
if result.errors.size > 0
|
155
|
+
logger.info "Errors : #{result.inspect}"
|
156
|
+
assignment.reject!('Failed to enter proper data.')
|
157
|
+
elsif result.respond_to?(:approve?)
|
158
|
+
logger.debug "Approving : #{result.inspect}"
|
159
|
+
increment_complete_assignments(turk)
|
160
|
+
result.approve? ? assignment.approve!('') : assignment.reject!('Rejected criteria.')
|
161
|
+
else
|
162
|
+
increment_complete_assignments(turk)
|
163
|
+
assignment.approve!('')
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def self.increment_complete_assignments(turk)
|
168
|
+
# Backward compatibility; completed_assignments may not exist in the table
|
169
|
+
if turk.respond_to?(:completed_assignments)
|
170
|
+
turk.completed_assignments += 1
|
171
|
+
turk.save
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def self.task_items(turkee_task)
|
176
|
+
turkee_task.nil? ? TurkeeTask.unprocessed_hits : Array.new << turkee_task
|
177
|
+
end
|
178
|
+
|
179
|
+
def self.submitted?(status)
|
180
|
+
(status == 'Submitted')
|
181
|
+
end
|
182
|
+
|
183
|
+
def self.assignment_params(answers)
|
184
|
+
answers.to_query
|
185
|
+
end
|
186
|
+
|
147
187
|
# Method looks at the parameter and attempts to find an ActiveRecord model
|
148
188
|
# in the current app that would match the properties of one of the nested hashes
|
149
189
|
# x = {:submit = 'Create', :iteration_vote => {:iteration_id => 1}}
|
@@ -152,17 +192,21 @@ module Turkee
|
|
152
192
|
param_hash.each do |k, v|
|
153
193
|
if v.is_a?(Hash)
|
154
194
|
model = Object::const_get(k.to_s.camelize) rescue next
|
155
|
-
return model if model.descends_from_active_record?
|
195
|
+
return model if model.descends_from_active_record? rescue next
|
156
196
|
end
|
157
197
|
end
|
158
198
|
nil
|
159
199
|
end
|
160
200
|
|
161
|
-
def self.form_url(host, typ)
|
201
|
+
def self.form_url(host, typ, params = {})
|
162
202
|
@app ||= ActionController::Integration::Session.new(Rails.application)
|
163
|
-
|
164
|
-
url
|
165
|
-
|
203
|
+
url = (host + @app.send("new_#{typ.to_s.underscore}_path"))
|
204
|
+
full_url(url, params)
|
205
|
+
end
|
206
|
+
|
207
|
+
def self.full_url(u, params)
|
208
|
+
url = u
|
209
|
+
url = "#{u}?#{params.to_query}" unless params.empty?
|
166
210
|
url
|
167
211
|
end
|
168
212
|
|
@@ -171,41 +215,40 @@ module Turkee
|
|
171
215
|
|
172
216
|
module TurkeeFormHelper
|
173
217
|
|
174
|
-
# Rails 3.
|
218
|
+
# Rails 3.1.1 form_for implementation with the exception of the form action url
|
175
219
|
# will always point to the Amazon externalSubmit interface and you must pass in the
|
176
220
|
# assignment_id parameter.
|
177
|
-
def turkee_form_for(
|
221
|
+
def turkee_form_for(record, params, options = {}, &proc)
|
178
222
|
raise ArgumentError, "Missing block" unless block_given?
|
179
223
|
raise ArgumentError, "turkee_form_for now requires that you pass in the entire params hash, instead of just the assignmentId value. " unless params.is_a?(Hash)
|
224
|
+
options[:html] ||= {}
|
180
225
|
|
181
|
-
|
182
|
-
|
183
|
-
case record_or_name_or_array
|
226
|
+
case record
|
184
227
|
when String, Symbol
|
185
|
-
|
186
|
-
|
187
|
-
when Array
|
188
|
-
object = record_or_name_or_array.last
|
189
|
-
object_name = options[:as] || ActiveModel::Naming.singular(object)
|
190
|
-
apply_form_for_options!(record_or_name_or_array, options)
|
191
|
-
args.unshift object
|
228
|
+
object_name = record
|
229
|
+
object = nil
|
192
230
|
else
|
193
|
-
object
|
194
|
-
object_name = options[:as] || ActiveModel::Naming.
|
195
|
-
apply_form_for_options!(
|
196
|
-
args.unshift object
|
231
|
+
object = record.is_a?(Array) ? record.last : record
|
232
|
+
object_name = options[:as] || ActiveModel::Naming.param_key(object)
|
233
|
+
apply_form_for_options!(record, options)
|
197
234
|
end
|
198
235
|
|
199
|
-
|
236
|
+
options[:html][:remote] = options.delete(:remote) if options.has_key?(:remote)
|
237
|
+
options[:html][:method] = options.delete(:method) if options.has_key?(:method)
|
238
|
+
options[:html][:authenticity_token] = options.delete(:authenticity_token)
|
239
|
+
|
240
|
+
builder = options[:parent_builder] = instantiate_builder(object_name, object, options, &proc)
|
241
|
+
fields_for = fields_for(object_name, object, options, &proc)
|
242
|
+
default_options = builder.multipart? ? { :multipart => true } : {}
|
200
243
|
|
201
|
-
output = form_tag(mturk_url, options.delete(:html)
|
244
|
+
output = form_tag(mturk_url, default_options.merge!(options.delete(:html)))
|
202
245
|
params.each do |k,v|
|
203
|
-
unless k =~ /^action$/i || k =~ /^controller$/i
|
246
|
+
unless k =~ /^action$/i || k =~ /^controller$/i || v.class != String
|
204
247
|
output.safe_concat("<input type=\"hidden\" id=\"#{k}\" name=\"#{CGI.escape(k)}\" value=\"#{CGI.escape(v)}\"/>")
|
205
248
|
end
|
206
249
|
end
|
207
250
|
options[:disabled] = true if params[:assignmentId].nil? || Turkee::TurkeeFormHelper::disable_form_fields?(params[:assignmentId])
|
208
|
-
output << fields_for
|
251
|
+
output << fields_for
|
209
252
|
output.safe_concat('</form>')
|
210
253
|
end
|
211
254
|
|
data/spec/spec_helper.rb
CHANGED
@@ -1,9 +1,61 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
require '
|
5
|
-
require '
|
6
|
-
|
7
|
-
|
8
|
-
|
1
|
+
require 'rubygems'
|
2
|
+
require "bundler/setup"
|
3
|
+
|
4
|
+
require 'factory_girl'
|
5
|
+
require 'rspec'
|
6
|
+
require 'spork'
|
7
|
+
require 'growl'
|
8
|
+
require 'rails'
|
9
|
+
require 'rturk'
|
10
|
+
require 'lockfile'
|
11
|
+
require 'active_record'
|
12
|
+
|
13
|
+
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
14
|
+
ActiveRecord::Schema.define(:version => 1) do
|
15
|
+
create_table :turkee_tasks do |t|
|
16
|
+
t.string "hit_url"
|
17
|
+
t.boolean "sandbox"
|
18
|
+
t.string "task_type"
|
19
|
+
t.text "hit_title"
|
20
|
+
t.text "hit_description"
|
21
|
+
t.string "hit_id"
|
22
|
+
t.decimal "hit_reward", :precision => 10, :scale => 2
|
23
|
+
t.integer "hit_num_assignments"
|
24
|
+
t.integer "hit_lifetime"
|
25
|
+
t.string "form_url"
|
26
|
+
t.boolean "complete"
|
27
|
+
end
|
9
28
|
end
|
29
|
+
|
30
|
+
|
31
|
+
Spork.prefork do
|
32
|
+
# Loading more in this block will cause your tests to run faster. However,
|
33
|
+
# if you change any configuration or code from libraries loaded here, you'll
|
34
|
+
# need to restart spork for it take effect.
|
35
|
+
|
36
|
+
FactoryGirl.find_definitions
|
37
|
+
|
38
|
+
RSpec.configure do |config|
|
39
|
+
# == Mock Framework
|
40
|
+
#
|
41
|
+
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
|
42
|
+
#
|
43
|
+
# config.mock_with :mocha
|
44
|
+
# config.mock_with :flexmock
|
45
|
+
# config.mock_with :rr
|
46
|
+
config.mock_with :rspec
|
47
|
+
|
48
|
+
#config.fixture_path = "#{::Rails.root}/spec/fixtures"
|
49
|
+
|
50
|
+
# If you're not using ActiveRecord, or you'd prefer not to run each of your
|
51
|
+
# examples within a transaction, comment the following line or assign false
|
52
|
+
# instead of true.
|
53
|
+
#config.use_transactional_fixtures = true
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
Spork.each_run do
|
59
|
+
$LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
|
60
|
+
Dir["#{File.dirname(__FILE__)}/../lib/**/*.rb"].each {|f| require f}
|
61
|
+
end
|
data/spec/turkee_spec.rb
CHANGED
@@ -1,7 +1,46 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
|
4
|
+
describe Turkee::TurkeeTask do
|
5
|
+
#include ActionController::Routing::Routes
|
6
|
+
class TestTask < ActiveRecord::Base
|
7
|
+
def self.abstract_class; true; end
|
8
|
+
attr_accessor :description
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "#process_hits" do
|
12
|
+
before(:each) do
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
describe "#find_model" do
|
20
|
+
|
21
|
+
it "should return a turkee_task mode " do
|
22
|
+
returned_data = {:submit => 'Create', "test_task" => {:description => "desc"}}
|
23
|
+
Turkee::TurkeeTask.find_model(returned_data).should == TestTask
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should return a nil" do
|
27
|
+
returned_data = {:submit => 'Create', "another_task_class" => {:description => "desc"}}
|
28
|
+
Turkee::TurkeeTask.find_model(returned_data).should be_nil
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#assignment_params" do
|
34
|
+
it "should encode the params properly" do
|
35
|
+
answers = {:test => "abc", :test2 => "this is a test"}
|
36
|
+
Turkee::TurkeeTask.assignment_params(answers).should == "test2=this+is+a+test&test=abc"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "#submitted" do
|
41
|
+
it "should return true for a submitted status" do
|
42
|
+
Turkee::TurkeeTask.submitted?("Submitted").should == true
|
43
|
+
end
|
6
44
|
end
|
45
|
+
|
7
46
|
end
|
metadata
CHANGED
@@ -1,75 +1,107 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: turkee
|
3
|
-
version: !ruby/object:Gem::Version
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.2.0
|
4
5
|
prerelease:
|
5
|
-
version: 1.1.1
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
7
|
+
authors:
|
8
8
|
- Jim Jones
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
12
|
+
date: 2012-05-09 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: lockfile
|
16
|
+
requirement: &70100423349140 !ruby/object:Gem::Requirement
|
18
17
|
none: false
|
19
|
-
requirements:
|
20
|
-
- -
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version:
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
23
22
|
type: :runtime
|
24
23
|
prerelease: false
|
25
|
-
version_requirements: *
|
26
|
-
- !ruby/object:Gem::Dependency
|
24
|
+
version_requirements: *70100423349140
|
25
|
+
- !ruby/object:Gem::Dependency
|
27
26
|
name: rails
|
28
|
-
requirement: &
|
27
|
+
requirement: &70100423348080 !ruby/object:Gem::Requirement
|
29
28
|
none: false
|
30
|
-
requirements:
|
31
|
-
- -
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: 3.
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 3.1.1
|
34
33
|
type: :runtime
|
35
34
|
prerelease: false
|
36
|
-
version_requirements: *
|
37
|
-
- !ruby/object:Gem::Dependency
|
35
|
+
version_requirements: *70100423348080
|
36
|
+
- !ruby/object:Gem::Dependency
|
38
37
|
name: rturk
|
39
|
-
requirement: &
|
38
|
+
requirement: &70100423347560 !ruby/object:Gem::Requirement
|
40
39
|
none: false
|
41
|
-
requirements:
|
42
|
-
- -
|
43
|
-
- !ruby/object:Gem::Version
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
44
43
|
version: 2.3.0
|
45
44
|
type: :runtime
|
46
45
|
prerelease: false
|
47
|
-
version_requirements: *
|
48
|
-
- !ruby/object:Gem::Dependency
|
49
|
-
name:
|
50
|
-
requirement: &
|
46
|
+
version_requirements: *70100423347560
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: mocha
|
49
|
+
requirement: &70100423347160 !ruby/object:Gem::Requirement
|
51
50
|
none: false
|
52
|
-
requirements:
|
53
|
-
- -
|
54
|
-
- !ruby/object:Gem::Version
|
55
|
-
version:
|
56
|
-
type: :
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70100423347160
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: sqlite3
|
60
|
+
requirement: &70100423346420 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70100423346420
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: factory_girl
|
71
|
+
requirement: &70100423345240 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 1.3.2
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *70100423345240
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: rspec
|
82
|
+
requirement: &70100423343480 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: 2.5.0
|
88
|
+
type: :development
|
57
89
|
prerelease: false
|
58
|
-
version_requirements: *
|
59
|
-
description: Turkee will help you to create your Rails forms, post the HITs, and retrieve
|
90
|
+
version_requirements: *70100423343480
|
91
|
+
description: Turkee will help you to create your Rails forms, post the HITs, and retrieve
|
92
|
+
the user entered values from Mechanical Turk.
|
60
93
|
email: jjones@aantix.com
|
61
94
|
executables: []
|
62
|
-
|
63
95
|
extensions: []
|
64
|
-
|
65
|
-
extra_rdoc_files:
|
96
|
+
extra_rdoc_files:
|
66
97
|
- LICENSE
|
67
98
|
- README.rdoc
|
68
|
-
files:
|
99
|
+
files:
|
69
100
|
- Gemfile
|
70
101
|
- Rakefile
|
71
102
|
- lib/generators/turkee/templates/turkee.rb
|
72
103
|
- lib/generators/turkee/templates/turkee_imported_assignments.rb.erb
|
104
|
+
- lib/generators/turkee/templates/add_completed_tasks.rb.erb
|
73
105
|
- lib/generators/turkee/templates/turkee_migration.rb.erb
|
74
106
|
- lib/generators/turkee/turkee_generator.rb
|
75
107
|
- lib/tasks/turkee.rb
|
@@ -81,30 +113,35 @@ files:
|
|
81
113
|
- README.rdoc
|
82
114
|
homepage: http://github.com/aantix/turkee
|
83
115
|
licenses: []
|
84
|
-
|
85
|
-
|
116
|
+
post_install_message: ! "\n ========================================================================\n
|
117
|
+
\ Turkee Installation Complete.\n ------------------------------------------------------------------------\n\n
|
118
|
+
\ If you're upgrading, be sure to execute the following to receive the\n latest
|
119
|
+
migration changes.\n rails g turkee --skip\n\n (the skip flag will ensure that
|
120
|
+
you don't overwrite prior\n Turkee initializers and migrations)\n\n\n For instructions
|
121
|
+
on gem usage, visit:\n http://github.com/aantix/turkee#readme\n\n ** If you
|
122
|
+
like the Turkee gem, please click the \"watch\" button on the\n Github project
|
123
|
+
page. You'll make me smile and feel appreciated. :)\n http://github.com/aantix/turkee\n\n
|
124
|
+
\ ========================================================================\n --
|
125
|
+
Gobble, gobble.\n "
|
86
126
|
rdoc_options: []
|
87
|
-
|
88
|
-
require_paths:
|
127
|
+
require_paths:
|
89
128
|
- lib
|
90
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
129
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
91
130
|
none: false
|
92
|
-
requirements:
|
93
|
-
- -
|
94
|
-
- !ruby/object:Gem::Version
|
95
|
-
version:
|
96
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
131
|
+
requirements:
|
132
|
+
- - ! '>='
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: '0'
|
135
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
97
136
|
none: false
|
98
|
-
requirements:
|
99
|
-
- -
|
100
|
-
- !ruby/object:Gem::Version
|
101
|
-
version:
|
137
|
+
requirements:
|
138
|
+
- - ! '>='
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: '0'
|
102
141
|
requirements: []
|
103
|
-
|
104
142
|
rubyforge_project:
|
105
|
-
rubygems_version: 1.8.
|
143
|
+
rubygems_version: 1.8.15
|
106
144
|
signing_key:
|
107
145
|
specification_version: 3
|
108
146
|
summary: Turkee makes dealing with Amazon's Mechnical Turk a breeze.
|
109
147
|
test_files: []
|
110
|
-
|