shared_workforce 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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