turkee 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Jim Jones
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,91 @@
1
+ == Description
2
+
3
+ Turkee simplifies the process of posting and retrieving HIT (Human Intelligence Task) data from Amazon's Mechanical Turk.
4
+
5
+ Forms are created using a simple form helper. HITs are created by issuing a rake command. Retrieving form data from Amazon requires just one more rake command.
6
+
7
+ == Dependencies
8
+
9
+ Make sure that the rturk gem is installed, referenced in your environment.rb :
10
+
11
+ config.gem 'rturk'
12
+
13
+ ...and configured with your Amazon Turk credentials. I created a config/initializers/turk_task_config.rb file with the following in it:
14
+
15
+ TURKTASK_AWSACCESSKEYID = 'XXXXXXXXXXXXXXXXXX'
16
+ TURKTASK_AWSACCESSKEY = 'YYYYYYYYYYYYYYYYYYYYYYYYYYYY'
17
+
18
+ RTurk::logger.level = Logger::DEBUG
19
+ RTurk.setup(AWSACCESSKEYID, AWSACCESSKEY, :sandbox => (Rails.env == 'production' ? false : true))
20
+
21
+ == Install
22
+
23
+ Install the Turkee gem:
24
+
25
+ sudo gem install turkee
26
+
27
+ And add it to your environment.rb configuration as a gem dependency:
28
+
29
+ config.gem 'turkee'
30
+
31
+ To access the Turkee rake tasks, add the following to your application's Rakefile:
32
+ require 'tasks/turkee'
33
+
34
+ Run the turkee generator from your application directory to copy the needed javascript file and migrations into your application:
35
+
36
+ ./script/generate turkee # Rails 2
37
+ ## Support for Rails 3 in the future.
38
+
39
+ == Use
40
+
41
+ 1) Add 'turkee' to your javascript includes in your application.html.erb
42
+ <%= javascript_include_tag :defaults, :turkee %>
43
+ * Turkee requires the default Rails javascript libraries, so be sure you are including those as well (as show above with :defaults).
44
+ 2) Run your migrations :
45
+
46
+ rake db:migrate
47
+
48
+ 3) Change your forms to use the form helper.
49
+ <% turkee_form_for @user do |form| %>
50
+ <%= form.inputs %>
51
+ <%= form.buttons %>
52
+ <% end %>
53
+ Using the turkee_form_for helper will post the form to the Mechanical Turk sandbox if you're in development/test mode, otherwise it will be posted to Mechanical Turk production/live site.
54
+
55
+ 4) Run the following rake task to post to Mechanical Turk :
56
+ # Title of your HIT
57
+ # Description of your HIT
58
+ # Model name of your task form (the New action should be implemented)
59
+ # Number of assignments for HIT
60
+ # The reward for a successful completion
61
+ # The lifetime of the HIT in days (e.g. 5 days)
62
+
63
+ rake turkee:posthit[<Title>, <Description>, <Model>, <Number of Assignments>, <Reward>, <Lifetime>]
64
+
65
+ e.g. :
66
+ rake turkee:posthit ["Please complete our survey", "Tell us your favorite color.", "Survey", 100, 0.05, 2]
67
+
68
+ 5) Allow some time for the "Turkers" to respond to your HIT.
69
+
70
+ 6) Run the rake task that retrieves the values from Mechanical Turk and stores the user entered values into your model.
71
+ rake turkee::getresults
72
+
73
+ Rerun this task periodically to retrieve newly entered form values. You can setup this task as a cronjob to automate this.
74
+
75
+ crontab -e
76
+
77
+ # E.g. run every five minutes
78
+ */5 * * * * cd /var/www/your/turk/application && rake turkee:getresults
79
+
80
+
81
+ 7) When a response is retrieved from Mechanical Turk, Turkee attempts to create a data row for the model specified using the corresponding retrieved data. If the row cannot be created (input failed model validations), the assignment is rejected.
82
+ As for Mechanical Turk approval, if the row is created and you haven't specified your own custom approve? method for the model, the assignment will automatically be approved. If you'd like to add your own custom approval method, add the approve? instance method to your model. E.g. :
83
+ class Survey < ActiveRecord::Base
84
+ def approve?
85
+ (!response.blank? && !comment.blank?)
86
+ end
87
+ end
88
+
89
+ == Copyright
90
+
91
+ Copyright (c) 2010 Jim Jones. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,64 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ $LOAD_PATH.unshift('lib')
5
+
6
+ begin
7
+ INSTALL_MESSAGE = %q{
8
+ ========================================================================
9
+ Turkee Installation Complete.
10
+ ------------------------------------------------------------------------
11
+
12
+ For instructions on gem usage, visit:
13
+ http://github.com/aantix/turkee#readme
14
+ ========================================================================
15
+ -- Gobble, gobble.
16
+ }
17
+
18
+ require 'jeweler'
19
+ Jeweler::Tasks.new do |gem|
20
+ gem.name = "turkee"
21
+ gem.summary = "Turkee makes dealing with Amazon's Mechnical Turk a breeze."
22
+ gem.description = "Turkee will help you to create your Rails forms, post the HITs, and retrieve the user entered values from Mechanical Turk."
23
+ gem.email = "jjones@aantix.com"
24
+ gem.homepage = "http://github.com/aantix/turkee"
25
+ gem.authors = ["Jim Jones"]
26
+ gem.add_development_dependency "rspec", ">= 1.2.9"
27
+ gem.add_development_dependency "rturk", ">= 2.3.0"
28
+ gem.add_development_dependency "lockfile", ">= 1.4.3"
29
+ gem.post_install_message = INSTALL_MESSAGE
30
+ gem.require_path = 'lib'
31
+ gem.files = %w(MIT-LICENSE README.textile Rakefile init.rb) + Dir.glob("{generators,lib,spec}/**/*")
32
+
33
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
34
+ end
35
+ Jeweler::GemcutterTasks.new
36
+ rescue LoadError
37
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
38
+ end
39
+
40
+ require 'spec/rake/spectask'
41
+ Spec::Rake::SpecTask.new(:spec) do |spec|
42
+ spec.libs << 'lib' << 'spec'
43
+ spec.spec_files = FileList['spec/**/*_spec.rb']
44
+ end
45
+
46
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
47
+ spec.libs << 'lib' << 'spec'
48
+ spec.pattern = 'spec/**/*_spec.rb'
49
+ spec.rcov = true
50
+ end
51
+
52
+ task :spec => :check_dependencies
53
+
54
+ task :default => :spec
55
+
56
+ require 'rake/rdoctask'
57
+ Rake::RDocTask.new do |rdoc|
58
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
59
+
60
+ rdoc.rdoc_dir = 'rdoc'
61
+ rdoc.title = "turkee #{version}"
62
+ rdoc.rdoc_files.include('README*')
63
+ rdoc.rdoc_files.include('lib/**/*.rb')
64
+ end
@@ -0,0 +1,45 @@
1
+ // Javascript referenced from the rturk example.
2
+
3
+ // Initializes a mechanical turk form and disables the form button
4
+ // until the user has accepted the turk task.
5
+
6
+ function gup( name )
7
+ {
8
+ var regexS = "[\\?&]"+name+"=([^&#]*)";
9
+ var regex = new RegExp( regexS );
10
+ var tmpURL = window.location.href;
11
+ var results = regex.exec( tmpURL );
12
+ if( results == null )
13
+ return "";
14
+ else
15
+ return results[1];
16
+ }
17
+
18
+ //
19
+ // This method decodes the query parameters that were URL-encoded
20
+ //
21
+ function decode(strToDecode)
22
+ {
23
+ var encoded = strToDecode;
24
+ return unescape(encoded.replace(/\+/g, " "));
25
+ }
26
+
27
+ function mturk_form_init(obj_name)
28
+ {
29
+ document.getElementById('assignmentId').value = gup('assignmentId');
30
+
31
+ //
32
+ // Check if the worker is PREVIEWING the HIT or if they've ACCEPTED the HIT
33
+ //
34
+ if (gup('assignmentId') == "ASSIGNMENT_ID_NOT_AVAILABLE")
35
+ {
36
+ // If we're previewing, disable the button and give it a helpful message
37
+ document.getElementById(obj_name + '_submit').disabled = true;
38
+ document.getElementById(obj_name + '_submit').value = "You must ACCEPT the HIT before you can submit the results.";
39
+ } else {
40
+ var form = document.getElementById('mturk_form');
41
+ if (document.referrer && ( document.referrer.indexOf('workersandbox') != -1) ) {
42
+ form.action = "https://workersandbox.mturk.com/mturk/externalSubmit";
43
+ }
44
+ }
45
+ }
@@ -0,0 +1,16 @@
1
+ class CreateTurkeeImportedAssignments < ActiveRecord::Migration
2
+
3
+ def self.up
4
+ create_table "turkee_imported_assignments" do |t|
5
+ t.string "assignment_id"
6
+ t.timestamps
7
+ end
8
+
9
+ add_index :turkee_imported_assignments, :assignment_id, :unique => true
10
+ end
11
+
12
+ def self.down
13
+ drop_table :turkee_imported_assignments
14
+ end
15
+
16
+ end
@@ -0,0 +1,24 @@
1
+ class CreateTurkeeTasks < ActiveRecord::Migration
2
+
3
+ def self.up
4
+ create_table "turkee_tasks" do |t|
5
+ t.string "hit_url"
6
+ t.boolean "sandbox"
7
+ t.string "task_type"
8
+ t.text "hit_title"
9
+ t.text "hit_description"
10
+ t.string "hit_id"
11
+ t.decimal "hit_reward", :precision => 10, :scale => 2
12
+ t.integer "hit_num_assignments"
13
+ t.integer "hit_lifetime"
14
+ t.string "form_url"
15
+ t.boolean "complete"
16
+ t.timestamps
17
+ end
18
+ end
19
+
20
+ def self.down
21
+ drop_table :turkee_tasks
22
+ end
23
+
24
+ end
@@ -0,0 +1,17 @@
1
+ class TurkeeGenerator < Rails::Generator::Base
2
+
3
+ def manifest
4
+ record do |m|
5
+ m.directory File.join('public', 'javascripts')
6
+ m.template 'turkee.js', File.join('public', 'javascripts', 'turkee.js')
7
+ m.migration_template "turkee_migration.rb.erb", File.join('db', 'migrate'), :migration_file_name => 'create_turkee_tasks'
8
+ m.sleep 1 # Need this sleep so that we don't get the same migration timestamp for both migrations
9
+ m.migration_template "turkee_imported_assignments.rb.erb", File.join('db', 'migrate'), :migration_file_name => 'create_turkee_imported_assignments'
10
+ end
11
+ end
12
+
13
+ def banner
14
+ %{Usage: #{$0} #{spec.name}\nCopies turkee.js to public/javascripts/ and generates needed migrations.}
15
+ end
16
+
17
+ end
@@ -0,0 +1,20 @@
1
+ require 'turkee'
2
+
3
+ include ActionController::PolymorphicRoutes
4
+ include ActionView::Helpers::UrlHelper
5
+
6
+ # clear && rake turkee:post_hit['Test title','Test desc','Joke',3,0.05,1] --trace
7
+
8
+ namespace :turkee do
9
+ desc "Post your form to Mechanical Turk (HIT). Task takes HIT title, HIT description, model name, number of responses, reward for each response, and number of days the HIT should be valid."
10
+ task :post_hit, :title, :description, :model, :num_assignments, :reward, :lifetime, :needs => :environment do |t, args|
11
+ Turkee::TurkeeTask.create_hit(args[:title], args[:description], args[:model],
12
+ args[:num_assignments], args[:reward], args[:lifetime])
13
+ end
14
+
15
+ desc "Retrieve all results from Mechanical Turk for all open HITs."
16
+ task :get_all_results => :environment do
17
+ Turkee::TurkeeTask.process_hits
18
+ end
19
+
20
+ end
data/lib/turkee.rb ADDED
@@ -0,0 +1,223 @@
1
+ require 'rubygems'
2
+ require 'socket'
3
+ require 'lockfile'
4
+ require 'active_record'
5
+ require 'action_view'
6
+ require 'active_support'
7
+ require 'action_controller'
8
+
9
+ module Turkee
10
+
11
+ # Model simply tracks what assignments have been imported
12
+ class TurkeeImportedAssignment < ActiveRecord::Base
13
+ end
14
+
15
+ class TurkeeTask < ActiveRecord::Base
16
+ # belongs_to :task, :polymorphic => true
17
+ HIT_FRAMEHEIGHT = 1000
18
+
19
+ named_scope :unprocessed_hits, :conditions => ['complete = ?', false]
20
+
21
+ # Use this method to go out and retrieve the data for all of the posted Turk Tasks.
22
+ # Each specific TurkeeTask object (determined by task_type field) is in charge of
23
+ # accepting/rejecting the assignment and importing the data into their respective tables.
24
+ def self.process_hits(turkee_task = nil)
25
+
26
+ begin
27
+ # Using a lockfile to prevent multiple calls to Amazon.
28
+ Lockfile.new('/tmp/turk_processor.lock', :max_age => 3600, :retries => 10) do
29
+
30
+ turks = turkee_task.nil? ? TurkeeTask.unprocessed_hits : Array.new << turkee_task
31
+
32
+ turks.each do |turk|
33
+ hit = RTurk::Hit.new(turk.hit_id)
34
+
35
+ hit.assignments.each do |assignment|
36
+ next unless assignment.status == 'Submitted'
37
+ next unless TurkeeImportedAssignment.find_by_assignment_id(assignment.id).nil?
38
+
39
+ params = assignment.answers.map { |k, v| "#{CGI::escape(k)}=#{CGI::escape(v)}" }.join('&')
40
+ param_hash = Rack::Utils.parse_nested_query(params)
41
+ model = find_model(param_hash)
42
+
43
+ logger.debug "params = #{params.inspect}"
44
+ logger.debug "param_hash = #{param_hash.inspect}"
45
+ logger.debug "model = #{model.inspect}"
46
+
47
+ next if model.nil?
48
+
49
+ result = model.create(param_hash[model.to_s.underscore])
50
+
51
+ # If there's a custom approve? method, see if we should approve the submitted assignment
52
+ # otherwise just approve it by default
53
+ if result.errors.size > 0
54
+ logger.info "Errors : #{result.inspect}"
55
+ assignment.reject!('Failed to enter proper data.')
56
+ elsif result.respond_to?(:approve?)
57
+ logger.debug "Approving : #{result.inspect}"
58
+ result.approve? ? assignment.approve!('') : assignment.reject!('Rejected criteria.')
59
+ else
60
+ assignment.approve!('')
61
+ end
62
+
63
+ TurkeeImportedAssignment.create(:assignment_id => assignment.id) rescue nil
64
+
65
+ end
66
+
67
+ if hit.completed_assignments == turk.hit_num_assignments
68
+ hit.dispose!
69
+ model.hit_complete(turk) if model.respond_to?(:hit_complete)
70
+ end
71
+ end
72
+ end
73
+ rescue Lockfile::MaxTriesLockError => e
74
+ logger.info "TurkTask.process_hits is already running or the lockfile /tmp/turk_processor.lock exists from an improperly shutdown previous process. Exiting method call."
75
+ end
76
+
77
+ end
78
+
79
+ # Creates a new Mechanical Turk task on AMZN with the given title, desc, etc
80
+ def self.create_hit(host, hit_title, hit_description, typ, num_assignments, reward, lifetime)
81
+
82
+ model = Object::const_get(typ)
83
+ duration = lifetime.to_i
84
+ f_url = form_url(host, model)
85
+
86
+ h = RTurk::Hit.create(:title => hit_title) do |hit|
87
+ hit.assignments = num_assignments
88
+ hit.description = hit_description
89
+ hit.reward = reward
90
+ hit.lifetime = duration.days.seconds.to_i
91
+ hit.question(f_url, :frame_height => HIT_FRAMEHEIGHT)
92
+ # hit.qualifications.add :approval_rate, { :gt => 80 }
93
+ end
94
+
95
+ TurkeeTask.create(:sandbox => (Rails.env == 'production' ? false : true),
96
+ :hit_title => hit_title, :hit_description => hit_description,
97
+ :hit_reward => reward.to_f, :hit_num_assignments => num_assignments.to_i,
98
+ :hit_lifetime => lifetime, :form_url => f_url,
99
+ :hit_url => h.url, :hit_id => h.id,
100
+ :task_type => typ, :complete => false)
101
+
102
+ end
103
+
104
+ ##########################################################################################################
105
+ # DON'T PUSH THIS BUTTON UNLESS YOU MEAN IT. :)
106
+ def self.clear_all_turks(force = false)
107
+ # Do NOT execute this function if we're in production mode
108
+ raise "You can only clear turks in the sandbox/development environment unless you pass 'true' for the force flag." if RAILS_ENV == 'production' && !force
109
+
110
+ hits = RTurk::Hit.all_reviewable
111
+
112
+ logger.info "#{hits.size} reviewable hits. \n"
113
+
114
+ unless hits.empty?
115
+ logger.info "Approving all assignments and disposing of each hit."
116
+
117
+ hits.each do |hit|
118
+ begin
119
+ hit.expire! if (hit.status == "Assignable" || hit.status == 'Unassignable')
120
+
121
+ hit.assignments.each do |assignment|
122
+
123
+ logger.info "Assignment status : #{assignment.status}"
124
+
125
+ assignment.approve!('__clear_all_turks__approved__') if assignment.status == 'Submitted'
126
+ end
127
+
128
+ turkee_task = TurkeeTask.find_by_hit_id(hit.id)
129
+ if turkee_task
130
+ turkee_task.complete = true
131
+ turkee_task.save
132
+ end
133
+
134
+ hit.dispose!
135
+ rescue Exception => e
136
+ # Probably a service unavailable
137
+ logger.error "Exception : #{e.to_s}"
138
+ end
139
+ end
140
+ end
141
+
142
+ end
143
+
144
+ private
145
+
146
+ def logger
147
+ @logger ||= Logger.new($stderr)
148
+ end
149
+
150
+ # Method looks at the parameter and attempts to find an ActiveRecord model
151
+ # in the current app that would match the properties of one of the nested hashes
152
+ # x = {:submit = 'Create', :iteration_vote => {:iteration_id => 1}}
153
+ # The above _should_ return an IterationVote model
154
+ def self.find_model(param_hash)
155
+ param_hash.each do |k, v|
156
+ if v.is_a?(Hash)
157
+ model = Object::const_get(k.to_s.camelize) rescue next
158
+ return model if model.descends_from_active_record?
159
+ end
160
+ end
161
+ nil
162
+ end
163
+
164
+ def self.form_url(host, typ)
165
+ @app ||= ActionController::Integration::Session.new
166
+ #@app.send("new_#{typ.to_s.underscore}_url(:host => '#{host}')") # Not sure why app does respond when :host is passed...
167
+ (host + @app.send("new_#{typ.to_s.underscore}_path")) # Workaround for now. :(
168
+ end
169
+
170
+ end
171
+
172
+
173
+ module TurkeeFormHelper
174
+
175
+ # Rails 2.3.8 form_for implementation with the exception of the form action url
176
+ # will always point to the Amazon externalSubmit interface and you must pass in the
177
+ # assignment_id parameter.
178
+ def turkee_form_for(record_or_name_or_array, assignment_id, *args, &proc)
179
+ raise ArgumentError, "Missing block" unless block_given?
180
+
181
+ options = args.extract_options!
182
+
183
+ case record_or_name_or_array
184
+ when String, Symbol
185
+ object_name = record_or_name_or_array
186
+ when Array
187
+ object = record_or_name_or_array.last
188
+ object_name = ActionController::RecordIdentifier.singular_class_name(object)
189
+ apply_form_for_options!(record_or_name_or_array, options)
190
+ args.unshift object
191
+ else
192
+ object = record_or_name_or_array
193
+ object_name = ActionController::RecordIdentifier.singular_class_name(object)
194
+ apply_form_for_options!([object], options)
195
+ args.unshift object
196
+ end
197
+
198
+ # concat(form_tag(options.delete(:url) || {}, options.delete(:html) || {}))
199
+ concat(form_tag(mturk_url))
200
+ concat("<input type=\"hidden\" id=\"assignmentId\" name=\"assignmentId\" value=\"#{assignment_id}\"/>")
201
+ fields_for(object_name, *(args << options), &proc)
202
+ concat('</form>'.html_safe)
203
+ # concat('<script type="text/javascript">Event.observe(window, \'load\', function() {mturk_form_init(\''+object_name.to_s.underscore+'\')});</script>')
204
+ self
205
+ end
206
+
207
+ # Returns the external Mechanical Turk url used to post form data based on whether RTurk is cofigured
208
+ # for sandbox use or not.
209
+ def mturk_url
210
+ # Rails.env == 'production' ? "https://www.mturk.com/mturk/externalSubmit" : "https://workersandbox.mturk.com/mturk/externalSubmit"
211
+ RTurk.sandbox? ? "https://workersandbox.mturk.com/mturk/externalSubmit" : "https://www.mturk.com/mturk/externalSubmit"
212
+ end
213
+
214
+ # Returns whether the form fields should be disabled or not (based on the assignment_id)
215
+ def self.disable_form_fields?(assignment_id)
216
+ (assignment_id.nil? || assignment_id == 'ASSIGNMENT_ID_NOT_AVAILABLE')
217
+ end
218
+
219
+ end
220
+
221
+ end
222
+
223
+ ActionView::Base.send :include, Turkee::TurkeeFormHelper
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,9 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'turkee'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+
7
+ Spec::Runner.configure do |config|
8
+
9
+ end
@@ -0,0 +1,7 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Turkee" do
4
+ it "fails" do
5
+ fail "hey buddy, you should probably rename this file and start specing for real"
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,127 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: turkee
3
+ version: !ruby/object:Gem::Version
4
+ hash: 21
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 1
10
+ version: 1.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Jim Jones
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-10-14 00:00:00 -07:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rspec
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 13
30
+ segments:
31
+ - 1
32
+ - 2
33
+ - 9
34
+ version: 1.2.9
35
+ type: :development
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: rturk
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 3
46
+ segments:
47
+ - 2
48
+ - 3
49
+ - 0
50
+ version: 2.3.0
51
+ type: :development
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: lockfile
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 1
62
+ segments:
63
+ - 1
64
+ - 4
65
+ - 3
66
+ version: 1.4.3
67
+ type: :development
68
+ version_requirements: *id003
69
+ description: Turkee will help you to create your Rails forms, post the HITs, and retrieve the user entered values from Mechanical Turk.
70
+ email: jjones@aantix.com
71
+ executables: []
72
+
73
+ extensions: []
74
+
75
+ extra_rdoc_files:
76
+ - LICENSE
77
+ - README.rdoc
78
+ files:
79
+ - Rakefile
80
+ - generators/turkee/templates/turkee.js
81
+ - generators/turkee/templates/turkee_imported_assignments.rb.erb
82
+ - generators/turkee/templates/turkee_migration.rb.erb
83
+ - generators/turkee/turkee_generator.rb
84
+ - lib/tasks/turkee.rb
85
+ - lib/turkee.rb
86
+ - spec/spec.opts
87
+ - spec/spec_helper.rb
88
+ - spec/turkee_spec.rb
89
+ - LICENSE
90
+ - README.rdoc
91
+ has_rdoc: true
92
+ homepage: http://github.com/aantix/turkee
93
+ licenses: []
94
+
95
+ post_install_message: "\n ========================================================================\n Turkee Installation Complete.\n ------------------------------------------------------------------------\n\n For instructions on gem usage, visit:\n http://github.com/aantix/turkee#readme\n ========================================================================\n -- Gobble, gobble.\n "
96
+ rdoc_options:
97
+ - --charset=UTF-8
98
+ require_paths:
99
+ - lib
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ none: false
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ hash: 3
106
+ segments:
107
+ - 0
108
+ version: "0"
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
110
+ none: false
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ hash: 3
115
+ segments:
116
+ - 0
117
+ version: "0"
118
+ requirements: []
119
+
120
+ rubyforge_project:
121
+ rubygems_version: 1.3.7
122
+ signing_key:
123
+ specification_version: 3
124
+ summary: Turkee makes dealing with Amazon's Mechnical Turk a breeze.
125
+ test_files:
126
+ - spec/spec_helper.rb
127
+ - spec/turkee_spec.rb