shared_workforce 0.1.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.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in hci.gemspec
4
+ gemspec
data/README.rdoc ADDED
File without changes
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+
6
+ task :default => 'spec:unit'
7
+
8
+ namespace :spec do
9
+ desc "Run unit specs"
10
+ RSpec::Core::RakeTask.new('unit') do |t|
11
+ t.pattern = 'spec/**/*_spec.rb'
12
+ end
13
+ end
@@ -0,0 +1,9 @@
1
+ require 'shared_workforce/exceptions'
2
+ require 'shared_workforce/client'
3
+ require 'shared_workforce/version'
4
+ require 'shared_workforce/task'
5
+ require 'shared_workforce/task_request'
6
+ require 'shared_workforce/task_result'
7
+ require 'shared_workforce/task_response'
8
+ require 'shared_workforce/end_point'
9
+ require 'shared_workforce/frameworks/rails' if defined?(Rails)
@@ -0,0 +1,34 @@
1
+ module SharedWorkforce
2
+ class Client
3
+
4
+ @http_end_point = "http://hci.heroku.com"
5
+ @load_path = "tasks"
6
+
7
+ class << self
8
+ attr_accessor :api_key
9
+ attr_accessor :load_path
10
+ attr_accessor :http_end_point
11
+ attr_accessor :callback_host
12
+ attr_accessor :callback_path
13
+
14
+ def version
15
+ SharedWorkforce::VERSION
16
+ end
17
+
18
+ def load!
19
+ Dir[File.join(load_path, "*.rb")].each do |file|
20
+ load file
21
+ end
22
+ end
23
+
24
+ def callback_url
25
+ callback_host + '/' + callback_path
26
+ end
27
+
28
+ def callback_path
29
+ "hci_task_result"
30
+ end
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,34 @@
1
+ module SharedWorkforce
2
+ class EndPoint
3
+
4
+ def initialize(app)
5
+ @app = app
6
+ end
7
+
8
+ def call(env)
9
+ if env["PATH_INFO"] =~ /^\/#{Client.callback_path}/
10
+ process_request(env)
11
+ else
12
+ @app.call(env)
13
+ end
14
+
15
+ end
16
+
17
+ private
18
+
19
+ def process_request(env)
20
+ req = Rack::Request.new(env)
21
+ body = JSON.parse(req.body.read)
22
+ puts "processing task callback"
23
+ puts body.inspect
24
+ SharedWorkforce::TaskResult.new(body).process!
25
+
26
+ [ 200,
27
+ { "Content-Type" => "text/html",
28
+ "Content-Length" => "0" },
29
+ [""]
30
+ ]
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,4 @@
1
+ module SharedWorkforce
2
+ class Error < RuntimeError; end
3
+ class ConfigurationError < Error; end
4
+ end
@@ -0,0 +1,13 @@
1
+ if defined?(ActionController::Metal)
2
+ class Railtie < Rails::Railtie
3
+ initializer :load_hci do |app|
4
+ SharedWorkforce::Client.load_path = Rails.root + SharedWorkforce::Client.load_path
5
+ SharedWorkforce::Client.load!
6
+ end
7
+ end
8
+ else
9
+ Rails.configuration.after_initialize do
10
+ SharedWorkforce::Client.load_path = Rails.root + SharedWorkforce::Client.load_path
11
+ SharedWorkforce::Client.load!
12
+ end
13
+ end
@@ -0,0 +1,95 @@
1
+ module SharedWorkforce
2
+ class Task
3
+
4
+ class << self
5
+
6
+ attr_accessor :tasks
7
+
8
+ def tasks
9
+ @tasks ||= {}
10
+ end
11
+
12
+ def define(name, &block)
13
+ raise ConfigurationError, "Please set your SharedWorkforce api key with SharedWorkforce::Client.api_key = 'your-api-key-here'" unless Client.api_key
14
+ raise ConfigurationError, "Please set your callback URL with SharedWorkforce::Client.callback_host = 'www.your-domain-name.com'" unless Client.callback_host
15
+
16
+ task = self.new
17
+ task.name = name
18
+ yield task
19
+ self.tasks[name] = task
20
+ end
21
+
22
+ def request(name, options)
23
+ @tasks[name].request(options)
24
+ end
25
+
26
+ def cancel(name, options)
27
+ @tasks[name].cancel(options)
28
+ end
29
+
30
+ def find(name)
31
+ self.tasks[name]
32
+ end
33
+
34
+ def clear!
35
+ @tasks = {}
36
+ end
37
+
38
+ end
39
+
40
+ attr_accessor :name
41
+ attr_accessor :directions
42
+ attr_accessor :image_url
43
+ attr_accessor :answer_options
44
+ attr_accessor :answer_type
45
+ attr_accessor :responses_required
46
+ attr_accessor :replace # whether tasks with the same resource id and name should be overwritten
47
+
48
+ def replace
49
+ @replace ||= false
50
+ end
51
+
52
+ def request(options)
53
+ task_request = TaskRequest.new(self, options)
54
+ task_request.create
55
+ end
56
+
57
+ def cancel(options)
58
+ task_request = TaskRequest.new(self, options)
59
+ task_request.cancel
60
+ end
61
+
62
+ def to_hash
63
+ {
64
+ :name=>name,
65
+ :directions => directions,
66
+ :image_url => image_url,
67
+ :answer_options => answer_options,
68
+ :responses_required => responses_required,
69
+ :answer_type => answer_type.to_s,
70
+ :callback_url => Client.callback_url,
71
+ :replace => replace
72
+ }
73
+ end
74
+
75
+ # Callbacks
76
+
77
+ def on_completion(&block)
78
+ @on_complete_proc = block
79
+ end
80
+
81
+ def complete!(results)
82
+ @on_complete_proc.call(results) if @on_complete_proc
83
+ end
84
+
85
+ def on_failure(&block)
86
+ @on_failure_proc = block
87
+ end
88
+
89
+ def fail!(results)
90
+ @on_failure_proc.call(results) if @on_failure_proc
91
+ end
92
+
93
+
94
+ end
95
+ end
@@ -0,0 +1,27 @@
1
+ require 'rest_client'
2
+ require 'json'
3
+ module SharedWorkforce
4
+ class TaskRequest
5
+
6
+ def initialize(task, params)
7
+ @task = task
8
+ @params = params
9
+ @http_end_point = Client.http_end_point
10
+ end
11
+
12
+ def create
13
+ RestClient.post("#{@http_end_point}/tasks", *request_params)
14
+ end
15
+
16
+ def cancel
17
+ RestClient.post("#{@http_end_point}/tasks/cancel", *request_params)
18
+ end
19
+
20
+ private
21
+
22
+ def request_params
23
+ [{:task=>@task.to_hash.merge(@params).merge(:callback_url=>Client.callback_url), :api_key=>Client.api_key}.to_json, {:content_type => :json, :accept => :json}]
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,17 @@
1
+ module SharedWorkforce
2
+ class TaskResponse
3
+
4
+ def self.create_collection_from_array(ary)
5
+ ary.collect {|r| TaskResponse.new(r) }
6
+ end
7
+
8
+ attr_accessor :answer, :callback_params, :username
9
+
10
+ def initialize(params)
11
+ @answer = params['answer']
12
+ @callback_params = params['callback_params']
13
+ @username = params['username']
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,32 @@
1
+ module SharedWorkforce
2
+ class TaskResult
3
+
4
+ attr_accessor :callback_params
5
+ attr_accessor :responses
6
+ attr_accessor :name
7
+ attr_accessor :status
8
+
9
+ def initialize(params)
10
+ self.callback_params = params['callback_params']
11
+ self.responses = TaskResponse.create_collection_from_array(params['responses'])
12
+ self.name = params['name']
13
+ end
14
+
15
+ def answers
16
+ responses.map(&:answer).flatten
17
+ end
18
+
19
+ def usernames
20
+ responses.map(&:username).flatten
21
+ end
22
+
23
+ def process!
24
+ if task = Task.find(name)
25
+ task.complete!(self)
26
+ else
27
+ raise "The task #{name} could not be found"
28
+ end
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,4 @@
1
+ module SharedWorkforce
2
+ VERSION = "0.1.0"
3
+
4
+ end
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "shared_workforce/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "shared_workforce"
7
+ s.version = SharedWorkforce::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Sam Oliver"]
10
+ s.email = ["sam@samoliver.com"]
11
+ s.homepage = "http://github.com/pigment/shared_workforce"
12
+ s.summary = %q{Shared Workforce Client}
13
+ s.description = %q{Shared Workforce is a service and simple API for human intelligence tasks}
14
+
15
+ s.rubyforge_project = "shared_workforce_client"
16
+
17
+ s.add_dependency "rest-client"
18
+ s.add_dependency "json"
19
+ s.add_development_dependency "rspec", ">= 1.2.9"
20
+ s.add_development_dependency "webmock"
21
+
22
+ s.files = `git ls-files`.split("\n")
23
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
24
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
25
+ s.require_paths = ["lib"]
26
+ end
data/spec/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,16 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Client" do
4
+ it "should load tasks" do
5
+ SharedWorkforce::Client.load_path = File.dirname(__FILE__) + '/tasks'
6
+ SharedWorkforce::Client.load!
7
+
8
+ SharedWorkforce::Task.find("Approve photo").should_not == nil
9
+ end
10
+
11
+ it "should return the current version number" do
12
+ SharedWorkforce::Client.version.should == SharedWorkforce::VERSION
13
+ end
14
+ end
15
+
16
+
@@ -0,0 +1,20 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'shared_workforce'
4
+ require 'rspec'
5
+ require 'rspec/autorun'
6
+ require 'webmock/rspec'
7
+
8
+ RSpec.configure do |config|
9
+ config.color_enabled = true
10
+ config.after :each do
11
+ SharedWorkforce::Task.clear!
12
+ end
13
+
14
+ config.before :each do
15
+ SharedWorkforce::Client.api_key = "test-api-key"
16
+ SharedWorkforce::Client.callback_host = "www.example.com"
17
+ end
18
+ end
19
+
20
+
@@ -0,0 +1,126 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "TaskRequest" do
4
+
5
+ it "should invoke a task request" do
6
+
7
+ task = SharedWorkforce::Task.define "Approve photo" do |h|
8
+
9
+ h.directions = "Please classify this photo by choosing the appropriate tickboxes."
10
+ h.image_url = "http://www.google.com/logo.png"
11
+ h.answer_type = "tags"
12
+ h.answer_options = ['Obscenity', 'Nudity', 'Blurry', 'Upside down or sideways', 'Contains more than one person in the foreground', 'Has people in the background', 'Contains children']
13
+ h.responses_required = 3
14
+ h.replace = false
15
+
16
+ h.on_completion do |result|
17
+ puts "Complete"
18
+ end
19
+
20
+ h.on_failure do |result|
21
+ puts "Failed"
22
+ end
23
+
24
+ end
25
+
26
+ task_request = SharedWorkforce::TaskRequest.new(task, :callback_params=>{:resource_id=>'1234'})
27
+
28
+ stub_request(:post, "hci.heroku.com/tasks")
29
+ task_request.create
30
+ a_request(:post, "http://hci.heroku.com/tasks").with(:body=>{'task'=>
31
+ {
32
+ 'name'=>"Approve photo",
33
+ 'directions'=>"Please classify this photo by choosing the appropriate tickboxes.",
34
+ 'image_url'=>"http://www.google.com/logo.png",
35
+ 'answer_options'=> ['Obscenity', 'Nudity', 'Blurry', 'Upside down or sideways', 'Contains more than one person in the foreground', 'Has people in the background', 'Contains children'],
36
+ 'responses_required'=>3,
37
+ 'answer_type'=>'tags',
38
+ 'callback_url'=>"#{SharedWorkforce::Client.callback_host}/hci_task_result",
39
+ 'callback_params'=>{'resource_id'=>'1234'},
40
+ 'replace'=>false
41
+ }, :api_key=>'test-api-key'}).should have_been_made.once
42
+
43
+ end
44
+
45
+
46
+ it "should invoke a task cancellation" do
47
+
48
+ task = SharedWorkforce::Task.define "Approve photo" do |h|
49
+
50
+ h.directions = "Please classify this photo by choosing the appropriate tickboxes."
51
+ h.image_url = "http://www.google.com/logo.png"
52
+ h.answer_type = "tags"
53
+ h.answer_options = ['Obscenity', 'Nudity', 'Blurry', 'Upside down or sideways', 'Contains more than one person in the foreground', 'Has people in the background', 'Contains children']
54
+ h.responses_required = 3
55
+ h.replace = false
56
+
57
+ h.on_completion do |result|
58
+ puts "Complete"
59
+ end
60
+
61
+ h.on_failure do |result|
62
+ puts "Failed"
63
+ end
64
+
65
+ end
66
+
67
+ task_request = SharedWorkforce::TaskRequest.new(task, :callback_params=>{:resource_id=>'1234'})
68
+
69
+ stub_request(:post, "hci.heroku.com/tasks/cancel")
70
+ task_request.cancel
71
+ a_request(:post, "http://hci.heroku.com/tasks/cancel").with(:body=>{'task'=>
72
+ {
73
+ 'name'=>"Approve photo",
74
+ 'directions'=>"Please classify this photo by choosing the appropriate tickboxes.",
75
+ 'image_url'=>"http://www.google.com/logo.png",
76
+ 'answer_options'=> ['Obscenity', 'Nudity', 'Blurry', 'Upside down or sideways', 'Contains more than one person in the foreground', 'Has people in the background', 'Contains children'],
77
+ 'responses_required'=>3,
78
+ 'answer_type'=>'tags',
79
+ 'callback_url'=>"#{SharedWorkforce::Client.callback_host}/hci_task_result",
80
+ 'callback_params'=>{'resource_id'=>'1234'},
81
+ 'replace'=>false
82
+ }, :api_key=>'test-api-key'}).should have_been_made.once
83
+
84
+ end
85
+
86
+ it "should allow options to be overridden when making the request" do
87
+
88
+ task = SharedWorkforce::Task.define "Approve photo" do |h|
89
+
90
+ h.directions = "Please classify this photo by choosing the appropriate tickboxes."
91
+ h.image_url = "http://www.google.com/logo.png"
92
+ h.answer_type = "tags"
93
+ h.answer_options = ['Obscenity', 'Nudity', 'Blurry', 'Upside down or sideways', 'Contains more than one person in the foreground', 'Has people in the background', 'Contains children']
94
+ h.responses_required = 3
95
+
96
+ h.on_completion do |result|
97
+ puts "Complete"
98
+ end
99
+
100
+ h.on_failure do |result|
101
+ puts "Failed"
102
+ end
103
+
104
+ end
105
+
106
+ task_request = SharedWorkforce::TaskRequest.new(task, {:callback_params=>{:resource_id=>'1234'}, :image_url=>"http://www.example.com/image.jpg"})
107
+
108
+ stub_request(:post, "hci.heroku.com/tasks")
109
+ task_request.create
110
+ a_request(:post, "http://hci.heroku.com/tasks").with(:body=>{'task'=>
111
+ {
112
+ 'name'=>"Approve photo",
113
+ 'directions'=>"Please classify this photo by choosing the appropriate tickboxes.",
114
+ 'image_url'=>"http://www.example.com/image.jpg",
115
+ 'answer_options'=> ['Obscenity', 'Nudity', 'Blurry', 'Upside down or sideways', 'Contains more than one person in the foreground', 'Has people in the background', 'Contains children'],
116
+ 'responses_required'=>3,
117
+ 'answer_type'=>'tags',
118
+ 'callback_url'=>"#{SharedWorkforce::Client.callback_host}/hci_task_result",
119
+ 'callback_params'=>{'resource_id'=>'1234'},
120
+ 'replace'=>false,
121
+ }, :api_key=>'test-api-key'}).should have_been_made.once
122
+ end
123
+
124
+ end
125
+
126
+
@@ -0,0 +1,15 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "TaskResponse" do
4
+ it "should create responses from an array" do
5
+ r = SharedWorkforce::TaskResponse.create_collection_from_array([{'answer'=>'answer 1'}, {'answer'=>'answer 2'}])
6
+ r[0].answer.should == "answer 1"
7
+ r[1].answer.should == "answer 2"
8
+ end
9
+
10
+ it "should accept and store a username" do
11
+ r = SharedWorkforce::TaskResponse.create_collection_from_array([{'answer'=>'answer 1', 'username'=>'bilbo'}, {'answer'=>'answer 2', 'username'=>'frodo'}])
12
+ r[0].username.should == "bilbo"
13
+ r[1].username.should == "frodo"
14
+ end
15
+ end
@@ -0,0 +1,40 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "TaskResult" do
4
+
5
+ it "should invoke a tasks complete callback" do
6
+
7
+ resources = {}
8
+ resources['1'] = OpenStruct.new(:approved=>false)
9
+ resources['2'] = OpenStruct.new(:approved=>false)
10
+ resources['3'] = OpenStruct.new(:approved=>false)
11
+
12
+ task = SharedWorkforce::Task.define("Approve photo") do |h|
13
+
14
+ h.on_completion do |result|
15
+ if result.responses.first.answer == 'yes'
16
+ resources[result.callback_params['resource_id']].approved = true
17
+ end
18
+ end
19
+
20
+ end
21
+
22
+ SharedWorkforce::TaskResult.new({'callback_params'=>{'resource_id' => '2'}, 'responses'=>[{'answer'=>'yes'}], 'name'=>"Approve photo"}).process!
23
+
24
+ resources['1'].approved.should == false
25
+ resources['2'].approved.should == true
26
+ resources['3'].approved.should == false
27
+
28
+ end
29
+
30
+ it "should collect the answers" do
31
+ r = SharedWorkforce::TaskResult.new({'callback_params'=>{'resource_id' => '2'}, 'responses'=>[{'answer'=>'yes'}, {'answer'=>'no'}, {'answer'=>'yes'}], 'name'=>"Approve photo"})
32
+ r.answers.should == ['yes', 'no', 'yes']
33
+ end
34
+
35
+ it "should collect the usernames" do
36
+ r = SharedWorkforce::TaskResult.new({'callback_params'=>{'resource_id' => '2'}, 'responses'=>[{'answer'=>'yes', 'username'=>'bilbo'}, {'answer'=>'no', 'username'=>'frodo'}, {'answer'=>'yes', 'username'=>'sam'}], 'name'=>"Approve photo"})
37
+ r.usernames.should == ['bilbo', 'frodo', 'sam']
38
+ end
39
+
40
+ end
data/spec/task_spec.rb ADDED
@@ -0,0 +1,108 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Task" do
4
+ it "should define a task" do
5
+
6
+ SharedWorkforce::Task.define "Approve photo" do |h|
7
+
8
+ h.directions = "Please classify this photo by choosing the appropriate tickboxes."
9
+ h.image_url = "http://www.google.com/logo.png"
10
+ h.answer_options = ['Obscenity', 'Nudity', 'Blurry', 'Upside down or sideways', 'Contains more than one person in the foreground', 'Has people in the background', 'Contains children']
11
+ h.responses_required = 3
12
+
13
+ h.on_completion do |result|
14
+ puts "Complete"
15
+ end
16
+
17
+ h.on_failure do |result|
18
+ puts "Failed"
19
+ end
20
+
21
+ end
22
+
23
+ SharedWorkforce::Task.tasks.first[1].directions.should == "Please classify this photo by choosing the appropriate tickboxes."
24
+
25
+ end
26
+
27
+ it "should run a completion callback" do
28
+
29
+ object = OpenStruct.new(:test=>nil)
30
+
31
+ task = SharedWorkforce::Task.define "Approve photo" do |h|
32
+
33
+ h.on_completion do |result|
34
+ object.test = "Complete"
35
+ end
36
+
37
+ end
38
+
39
+ object.test.should == nil
40
+ task.complete!({})
41
+ object.test.should == "Complete"
42
+ end
43
+
44
+ it "should run a failure callback" do
45
+
46
+ object = OpenStruct.new(:test=>nil)
47
+
48
+ task = SharedWorkforce::Task.define "Approve photo" do |h|
49
+
50
+ h.on_failure do |result|
51
+ object.test = "Failed"
52
+ end
53
+
54
+ end
55
+
56
+ object.test.should == nil
57
+ task.fail!({})
58
+ object.test.should == "Failed"
59
+ end
60
+
61
+ it "should not raise an error if there is no callback defined" do
62
+ lambda {
63
+ task = SharedWorkforce::Task.define("Approve photo") { }
64
+ task.fail!({})
65
+ }.should_not raise_error
66
+ end
67
+
68
+ it "should request a task" do
69
+ task = SharedWorkforce::Task.define("Approve photo") { }
70
+ task.should_receive(:request).with(:request_id=>'123')
71
+ SharedWorkforce::Task.request("Approve photo", :request_id=>'123')
72
+ end
73
+
74
+ it "should cancel a task" do
75
+ task = SharedWorkforce::Task.define("Approve photo") { }
76
+ task.should_receive(:request).with(:request_id=>'123')
77
+ SharedWorkforce::Task.request("Approve photo", :request_id=>'123')
78
+
79
+ task.should_receive(:cancel).with(:request_id=>'123')
80
+ SharedWorkforce::Task.cancel("Approve photo", :request_id=>'123')
81
+ end
82
+
83
+ it "should find a task" do
84
+ SharedWorkforce::Task.define("Approve photo") { }
85
+ SharedWorkforce::Task.define("Check profile text") { }
86
+ SharedWorkforce::Task.define("Check content") { }
87
+
88
+
89
+ SharedWorkforce::Task.find("Check profile text").name.should == "Check profile text"
90
+
91
+ end
92
+
93
+ it "should raise a ConfigurationError if a callback host is not set" do
94
+ SharedWorkforce::Client.callback_host = nil
95
+ lambda {
96
+ SharedWorkforce::Task.define("Approve photo") { }
97
+ }.should raise_error SharedWorkforce::ConfigurationError
98
+ end
99
+
100
+ it "should raise a ConfigurationError if an API key is not set" do
101
+ SharedWorkforce::Client.api_key = nil
102
+ lambda {
103
+ SharedWorkforce::Task.define("Approve photo") { }
104
+ }.should raise_error SharedWorkforce::ConfigurationError
105
+ end
106
+ end
107
+
108
+
@@ -0,0 +1,16 @@
1
+ SharedWorkforce::Task.define "Approve photo" do |h|
2
+
3
+ h.directions = "Please classify this photo by choosing the appropriate tickboxes."
4
+ h.image_url = "http://www.google.com/logo.png"
5
+ h.answer_options = ['Obscenity', 'Nudity', 'Blurry', 'Upside down or sideways', 'Contains more than one person in the foreground', 'Has people in the background', 'Contains children']
6
+ h.responses_required = 3
7
+
8
+ h.on_completion do |result|
9
+ puts "Complete"
10
+ end
11
+
12
+ h.on_failure do |result|
13
+ puts "Failed"
14
+ end
15
+
16
+ end
metadata ADDED
@@ -0,0 +1,128 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: shared_workforce
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.0
6
+ platform: ruby
7
+ authors:
8
+ - Sam Oliver
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-04-13 00:00:00 +01:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: rest-client
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: "0"
25
+ type: :runtime
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: json
29
+ prerelease: false
30
+ requirement: &id002 !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: "0"
36
+ type: :runtime
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: rspec
40
+ prerelease: false
41
+ requirement: &id003 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 1.2.9
47
+ type: :development
48
+ version_requirements: *id003
49
+ - !ruby/object:Gem::Dependency
50
+ name: webmock
51
+ prerelease: false
52
+ requirement: &id004 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ type: :development
59
+ version_requirements: *id004
60
+ description: Shared Workforce is a service and simple API for human intelligence tasks
61
+ email:
62
+ - sam@samoliver.com
63
+ executables: []
64
+
65
+ extensions: []
66
+
67
+ extra_rdoc_files: []
68
+
69
+ files:
70
+ - .gitignore
71
+ - Gemfile
72
+ - README.rdoc
73
+ - Rakefile
74
+ - lib/shared_workforce.rb
75
+ - lib/shared_workforce/client.rb
76
+ - lib/shared_workforce/end_point.rb
77
+ - lib/shared_workforce/exceptions.rb
78
+ - lib/shared_workforce/frameworks/rails.rb
79
+ - lib/shared_workforce/task.rb
80
+ - lib/shared_workforce/task_request.rb
81
+ - lib/shared_workforce/task_response.rb
82
+ - lib/shared_workforce/task_result.rb
83
+ - lib/shared_workforce/version.rb
84
+ - shared_workforce.gemspec
85
+ - spec/.rspec
86
+ - spec/client_spec.rb
87
+ - spec/spec_helper.rb
88
+ - spec/task_request_spec.rb
89
+ - spec/task_response_spec.rb
90
+ - spec/task_result_spec.rb
91
+ - spec/task_spec.rb
92
+ - spec/tasks/approve_photo.rb
93
+ has_rdoc: true
94
+ homepage: http://github.com/pigment/shared_workforce
95
+ licenses: []
96
+
97
+ post_install_message:
98
+ rdoc_options: []
99
+
100
+ require_paths:
101
+ - lib
102
+ required_ruby_version: !ruby/object:Gem::Requirement
103
+ none: false
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: "0"
108
+ required_rubygems_version: !ruby/object:Gem::Requirement
109
+ none: false
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: "0"
114
+ requirements: []
115
+
116
+ rubyforge_project: shared_workforce_client
117
+ rubygems_version: 1.5.3
118
+ signing_key:
119
+ specification_version: 3
120
+ summary: Shared Workforce Client
121
+ test_files:
122
+ - spec/client_spec.rb
123
+ - spec/spec_helper.rb
124
+ - spec/task_request_spec.rb
125
+ - spec/task_response_spec.rb
126
+ - spec/task_result_spec.rb
127
+ - spec/task_spec.rb
128
+ - spec/tasks/approve_photo.rb