houdini-rails 0.1.5 → 0.1.6
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/Rakefile +3 -2
- data/VERSION +1 -1
- data/app/controllers/houdini/postbacks_controller.rb +4 -3
- data/config/routes.rb +1 -1
- data/houdini-rails.gemspec +10 -8
- data/lib/houdini-rails.rb +10 -1
- data/lib/houdini-rails/base.rb +11 -5
- data/lib/houdini-rails/model.rb +11 -11
- data/lib/houdini-rails/task.rb +3 -4
- data/spec/controllers/houdini/postbacks_controller_spec.rb +7 -7
- data/spec/integration/postbacks_test.rb +2 -2
- data/spec/lib/base_spec.rb +30 -0
- data/spec/rails_app/app/models/post.rb +8 -9
- data/spec/rails_app/app/views/posts/houdini_template.html.erb +6 -0
- data/spec/rails_app/config/environment.rb +0 -1
- metadata +22 -9
- data/spec/rails_app/app/views/posts/houdini_template.html.haml +0 -6
data/Rakefile
CHANGED
@@ -20,12 +20,13 @@ begin
|
|
20
20
|
require 'jeweler'
|
21
21
|
Jeweler::Tasks.new do |gem|
|
22
22
|
gem.name = "houdini-rails"
|
23
|
-
gem.summary = %Q{Rails
|
24
|
-
gem.description = %Q{Rails
|
23
|
+
gem.summary = %Q{Rails engine for interacting with the Houdini Mechanical Turk API}
|
24
|
+
gem.description = %Q{Rails engine for interacting with the Houdini Mechanical Turk API}
|
25
25
|
gem.email = "chris@chrisconley.me"
|
26
26
|
gem.homepage = "http://github.com/chrisconley/houdini-rails"
|
27
27
|
gem.authors = ["Chris Conley"]
|
28
28
|
gem.add_development_dependency "spec", ">= 1.3.0"
|
29
|
+
gem.add_dependency "tilt", ">= 1.0.1"
|
29
30
|
end
|
30
31
|
Jeweler::GemcutterTasks.new
|
31
32
|
rescue LoadError
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.6
|
@@ -1,8 +1,9 @@
|
|
1
1
|
class Houdini::PostbacksController < ApplicationController
|
2
|
+
protect_from_forgery :except => [:create]
|
2
3
|
def create
|
3
|
-
|
4
|
-
|
5
|
-
if
|
4
|
+
object_class = params[:object_class].classify.constantize
|
5
|
+
object = object_class.find(params[:object_id])
|
6
|
+
if object.process_postback(request.request_parameters)
|
6
7
|
render :json => {:success => true}
|
7
8
|
else
|
8
9
|
render :json => {:success => false}, :status => 422
|
data/config/routes.rb
CHANGED
@@ -3,5 +3,5 @@ ActionController::Routing::Routes.draw do |map|
|
|
3
3
|
:name_prefix => 'houdini_',
|
4
4
|
:controller => 'houdini/postbacks',
|
5
5
|
:only => [:create],
|
6
|
-
:path_prefix => "houdini/:
|
6
|
+
:path_prefix => "houdini/:object_class/:object_id/:task_name"
|
7
7
|
end
|
data/houdini-rails.gemspec
CHANGED
@@ -5,12 +5,12 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{houdini-rails}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.6"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Chris Conley"]
|
12
|
-
s.date = %q{2010-08-
|
13
|
-
s.description = %q{Rails
|
12
|
+
s.date = %q{2010-08-16}
|
13
|
+
s.description = %q{Rails engine for interacting with the Houdini Mechanical Turk API}
|
14
14
|
s.email = %q{chris@chrisconley.me}
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"README"
|
@@ -31,12 +31,13 @@ Gem::Specification.new do |s|
|
|
31
31
|
"rails/init.rb",
|
32
32
|
"spec/controllers/houdini/postbacks_controller_spec.rb",
|
33
33
|
"spec/integration/postbacks_test.rb",
|
34
|
+
"spec/lib/base_spec.rb",
|
34
35
|
"spec/rails_app/README",
|
35
36
|
"spec/rails_app/Rakefile",
|
36
37
|
"spec/rails_app/app/controllers/application_controller.rb",
|
37
38
|
"spec/rails_app/app/helpers/application_helper.rb",
|
38
39
|
"spec/rails_app/app/models/post.rb",
|
39
|
-
"spec/rails_app/app/views/posts/houdini_template.html.
|
40
|
+
"spec/rails_app/app/views/posts/houdini_template.html.erb",
|
40
41
|
"spec/rails_app/config/boot.rb",
|
41
42
|
"spec/rails_app/config/database.yml",
|
42
43
|
"spec/rails_app/config/environment.rb",
|
@@ -53,9 +54,6 @@ Gem::Specification.new do |s|
|
|
53
54
|
"spec/rails_app/db/migrate/20100517231810_create_posts.rb",
|
54
55
|
"spec/rails_app/db/seeds.rb",
|
55
56
|
"spec/rails_app/doc/README_FOR_APP",
|
56
|
-
"spec/rails_app/log/development.log",
|
57
|
-
"spec/rails_app/log/production.log",
|
58
|
-
"spec/rails_app/log/server.log",
|
59
57
|
"spec/rails_app/public/404.html",
|
60
58
|
"spec/rails_app/public/422.html",
|
61
59
|
"spec/rails_app/public/500.html",
|
@@ -87,10 +85,11 @@ Gem::Specification.new do |s|
|
|
87
85
|
s.rdoc_options = ["--charset=UTF-8"]
|
88
86
|
s.require_paths = ["lib"]
|
89
87
|
s.rubygems_version = %q{1.3.6}
|
90
|
-
s.summary = %q{Rails
|
88
|
+
s.summary = %q{Rails engine for interacting with the Houdini Mechanical Turk API}
|
91
89
|
s.test_files = [
|
92
90
|
"spec/controllers/houdini/postbacks_controller_spec.rb",
|
93
91
|
"spec/integration/postbacks_test.rb",
|
92
|
+
"spec/lib/base_spec.rb",
|
94
93
|
"spec/rails_app/app/controllers/application_controller.rb",
|
95
94
|
"spec/rails_app/app/helpers/application_helper.rb",
|
96
95
|
"spec/rails_app/app/models/post.rb",
|
@@ -117,11 +116,14 @@ Gem::Specification.new do |s|
|
|
117
116
|
|
118
117
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
119
118
|
s.add_development_dependency(%q<spec>, [">= 1.3.0"])
|
119
|
+
s.add_runtime_dependency(%q<tilt>, [">= 1.0.1"])
|
120
120
|
else
|
121
121
|
s.add_dependency(%q<spec>, [">= 1.3.0"])
|
122
|
+
s.add_dependency(%q<tilt>, [">= 1.0.1"])
|
122
123
|
end
|
123
124
|
else
|
124
125
|
s.add_dependency(%q<spec>, [">= 1.3.0"])
|
126
|
+
s.add_dependency(%q<tilt>, [">= 1.0.1"])
|
125
127
|
end
|
126
128
|
end
|
127
129
|
|
data/lib/houdini-rails.rb
CHANGED
@@ -1,6 +1,15 @@
|
|
1
1
|
require 'net/http'
|
2
2
|
require 'uri'
|
3
3
|
|
4
|
+
require 'tilt'
|
5
|
+
|
4
6
|
require 'houdini-rails/base'
|
5
7
|
require 'houdini-rails/model'
|
6
|
-
require 'houdini-rails/task'
|
8
|
+
require 'houdini-rails/task'
|
9
|
+
|
10
|
+
module Houdini
|
11
|
+
# Convenience method
|
12
|
+
def self.perform!(task_name, object)
|
13
|
+
object.send_to_houdini(task_name)
|
14
|
+
end
|
15
|
+
end
|
data/lib/houdini-rails/base.rb
CHANGED
@@ -1,15 +1,21 @@
|
|
1
1
|
module Houdini
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
Undefined = Class.new(NameError)
|
3
|
+
RequestError = Class.new(NameError)
|
4
|
+
AuthenticationError = Class.new(NameError)
|
5
5
|
|
6
|
+
class Base
|
6
7
|
def self.request(api, params)
|
7
8
|
validate_constants
|
8
9
|
return ["200", '{success:"true"}'] if HOST == 'test'
|
9
10
|
url = URI.parse("http://#{HOST}/api/v0/#{api}/tasks/")
|
10
11
|
response, body = Net::HTTP.post_form(url, params)
|
11
|
-
|
12
|
-
|
12
|
+
|
13
|
+
raise(AuthenticationError, "invalid api key") if response.code == '403'
|
14
|
+
if response.code != "200"
|
15
|
+
raise RequestError, "The request to houdini failed with code #{response.code}: #{body}"
|
16
|
+
end
|
17
|
+
|
18
|
+
[response, body]
|
13
19
|
end
|
14
20
|
|
15
21
|
private
|
data/lib/houdini-rails/model.rb
CHANGED
@@ -12,30 +12,30 @@ module Houdini
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
def send_to_houdini
|
15
|
+
def send_to_houdini(task_name)
|
16
|
+
# TODO: look up task when multiple tasks per model are implemented
|
16
17
|
result = Houdini::Base.request(houdini_task.api,
|
17
18
|
:api_key => Houdini::KEY,
|
18
|
-
:identifier => houdini_task.
|
19
|
+
:identifier => houdini_task.name,
|
19
20
|
:price => houdini_task.price,
|
20
21
|
:title => houdini_task.title,
|
21
22
|
:form_html => generate_form_html(houdini_task.form_template),
|
22
23
|
:postback_url => houdini_postbacks_url(self.class.name, self.id, self.houdini_task.name, :host => Houdini::RAILS_HOST))
|
23
|
-
|
24
|
+
|
25
|
+
call_after_submit
|
24
26
|
end
|
25
27
|
|
26
28
|
def process_postback(answer)
|
27
|
-
self.send(houdini_task.
|
29
|
+
self.send(houdini_task.on_task_completion, answer)
|
28
30
|
end
|
29
31
|
|
30
|
-
def
|
31
|
-
self.send(houdini_task.
|
32
|
+
def call_after_submit
|
33
|
+
self.send(houdini_task.after_submit) if houdini_task.after_submit
|
32
34
|
end
|
33
35
|
|
34
|
-
def generate_form_html(
|
35
|
-
|
36
|
-
template
|
37
|
-
haml_engine = Haml::Engine.new(template)
|
38
|
-
haml_engine.render(Object.new, self.class.name.underscore => self)
|
36
|
+
def generate_form_html(template_path)
|
37
|
+
template = Tilt.new(File.join(RAILS_ROOT, template_path))
|
38
|
+
template.render(self, self.class.name.downcase.to_sym => self)
|
39
39
|
end
|
40
40
|
end
|
41
41
|
end
|
data/lib/houdini-rails/task.rb
CHANGED
@@ -1,18 +1,17 @@
|
|
1
1
|
module Houdini
|
2
2
|
class Task
|
3
|
-
attr_accessor :name, :api, :on, :if, :
|
3
|
+
attr_accessor :name, :api, :on, :if, :price, :title, :form_template, :after_submit, :on_task_completion
|
4
4
|
|
5
5
|
def initialize(name, options)
|
6
6
|
@name = name
|
7
7
|
@api = "simple" # options[:strategy]
|
8
8
|
@on = options[:on] || :after_create
|
9
9
|
@if = options[:if] || true
|
10
|
-
@identifier = options[:identifier] || name
|
11
10
|
@price = options[:price]
|
12
11
|
@title = options[:title]
|
13
12
|
@form_template = options[:form_template]
|
14
|
-
@
|
15
|
-
@
|
13
|
+
@after_submit = options[:after_submit]
|
14
|
+
@on_task_completion = options[:on_task_completion] || :update_attributes
|
16
15
|
end
|
17
16
|
end
|
18
17
|
end
|
@@ -6,22 +6,22 @@ end
|
|
6
6
|
|
7
7
|
describe Houdini::PostbacksController do
|
8
8
|
before do
|
9
|
-
@
|
10
|
-
Foo.stub!(:find).and_return(@
|
11
|
-
@
|
9
|
+
@object = mock_model(Foo)
|
10
|
+
Foo.stub!(:find).and_return(@object)
|
11
|
+
@object.stub!(:process_postback)
|
12
12
|
end
|
13
13
|
|
14
14
|
def do_post
|
15
|
-
post :create, :
|
15
|
+
post :create, :object_class => 'foo', :object_id => '1', :task_name => 'review_image'
|
16
16
|
end
|
17
17
|
|
18
|
-
it "should find the
|
19
|
-
Foo.should_receive(:find).with("1").and_return(@
|
18
|
+
it "should find the object" do
|
19
|
+
Foo.should_receive(:find).with("1").and_return(@object)
|
20
20
|
do_post
|
21
21
|
end
|
22
22
|
|
23
23
|
it "should process the answer" do
|
24
|
-
@
|
24
|
+
@object.should_receive(:process_postback)
|
25
25
|
do_post
|
26
26
|
end
|
27
27
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'spec/test_helper'
|
2
2
|
|
3
3
|
class PostbacksTest < ActionController::IntegrationTest
|
4
|
-
def
|
4
|
+
def test_should_send_to_houdini_and_receive_postback
|
5
5
|
post = Post.create(:image_url => 'http://google.com', :flagged => nil)
|
6
|
-
visit 'houdini/post/1/review_image/postbacks', :post, :
|
6
|
+
visit 'houdini/post/1/review_image/postbacks', :post, :flagged => "yes"
|
7
7
|
assert_response :success
|
8
8
|
assert_equal true, post.reload.flagged
|
9
9
|
assert_equal Time.now.to_date, post.houdini_request_sent_at.to_date
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Houdini::Base do
|
4
|
+
it "should raise a Houdini::AuthenticationError" do
|
5
|
+
response = mock('Response')
|
6
|
+
response.stub!(:code).and_return('403')
|
7
|
+
Net::HTTP.stub!(:post_form).and_return([response, ''])
|
8
|
+
|
9
|
+
lambda { Houdini::Base.request('simple', {}) }.should raise_error(Houdini::AuthenticationError)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should raise a Houdini::RequestError" do
|
13
|
+
response = mock('Response')
|
14
|
+
response.stub!(:code).and_return('422')
|
15
|
+
Net::HTTP.stub!(:post_form).and_return([response, ''])
|
16
|
+
|
17
|
+
lambda { Houdini::Base.request('simple', {}) }.should raise_error(Houdini::RequestError)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should not raise a error" do
|
21
|
+
response = mock('Response')
|
22
|
+
response.stub!(:code).and_return('200')
|
23
|
+
Net::HTTP.stub!(:post_form).and_return([response, ''])
|
24
|
+
|
25
|
+
lambda { Houdini::Base.request('simple', {}) }.should_not raise_error()
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
end
|
@@ -1,25 +1,24 @@
|
|
1
1
|
class Post < ActiveRecord::Base
|
2
2
|
include Houdini::Model
|
3
3
|
|
4
|
-
houdini :
|
5
|
-
:identifier => 'image_moderation',
|
4
|
+
houdini :image_moderation,
|
6
5
|
:title => 'Moderate Image',
|
7
|
-
:form_template =>
|
8
|
-
:
|
9
|
-
:
|
6
|
+
:form_template => 'app/views/posts/houdini_template.html.erb',
|
7
|
+
:after_submit => :update_houdini_attributes,
|
8
|
+
:on_task_completion => :process_image_moderation_answer,
|
10
9
|
:price => '0.01'
|
11
10
|
|
12
11
|
after_create :moderate_image, :if => :image_url
|
13
12
|
|
14
13
|
def moderate_image
|
15
|
-
|
14
|
+
Houdini.perform!(:image_moderation, self)
|
16
15
|
end
|
17
16
|
|
18
|
-
def update_houdini_attributes
|
17
|
+
def update_houdini_attributes
|
19
18
|
update_attribute(:houdini_request_sent_at, Time.now)
|
20
19
|
end
|
21
20
|
|
22
|
-
def process_image_moderation_answer(
|
23
|
-
update_attribute(:flagged, true) if
|
21
|
+
def process_image_moderation_answer(params)
|
22
|
+
update_attribute(:flagged, true) if params[:flagged] == 'yes'
|
24
23
|
end
|
25
24
|
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
version: 0.1.
|
8
|
+
- 6
|
9
|
+
version: 0.1.6
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Chris Conley
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-08-
|
17
|
+
date: 2010-08-16 00:00:00 -04:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -31,7 +31,21 @@ dependencies:
|
|
31
31
|
version: 1.3.0
|
32
32
|
type: :development
|
33
33
|
version_requirements: *id001
|
34
|
-
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: tilt
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 1
|
43
|
+
- 0
|
44
|
+
- 1
|
45
|
+
version: 1.0.1
|
46
|
+
type: :runtime
|
47
|
+
version_requirements: *id002
|
48
|
+
description: Rails engine for interacting with the Houdini Mechanical Turk API
|
35
49
|
email: chris@chrisconley.me
|
36
50
|
executables: []
|
37
51
|
|
@@ -55,12 +69,13 @@ files:
|
|
55
69
|
- rails/init.rb
|
56
70
|
- spec/controllers/houdini/postbacks_controller_spec.rb
|
57
71
|
- spec/integration/postbacks_test.rb
|
72
|
+
- spec/lib/base_spec.rb
|
58
73
|
- spec/rails_app/README
|
59
74
|
- spec/rails_app/Rakefile
|
60
75
|
- spec/rails_app/app/controllers/application_controller.rb
|
61
76
|
- spec/rails_app/app/helpers/application_helper.rb
|
62
77
|
- spec/rails_app/app/models/post.rb
|
63
|
-
- spec/rails_app/app/views/posts/houdini_template.html.
|
78
|
+
- spec/rails_app/app/views/posts/houdini_template.html.erb
|
64
79
|
- spec/rails_app/config/boot.rb
|
65
80
|
- spec/rails_app/config/database.yml
|
66
81
|
- spec/rails_app/config/environment.rb
|
@@ -77,9 +92,6 @@ files:
|
|
77
92
|
- spec/rails_app/db/migrate/20100517231810_create_posts.rb
|
78
93
|
- spec/rails_app/db/seeds.rb
|
79
94
|
- spec/rails_app/doc/README_FOR_APP
|
80
|
-
- spec/rails_app/log/development.log
|
81
|
-
- spec/rails_app/log/production.log
|
82
|
-
- spec/rails_app/log/server.log
|
83
95
|
- spec/rails_app/public/404.html
|
84
96
|
- spec/rails_app/public/422.html
|
85
97
|
- spec/rails_app/public/500.html
|
@@ -135,10 +147,11 @@ rubyforge_project:
|
|
135
147
|
rubygems_version: 1.3.6
|
136
148
|
signing_key:
|
137
149
|
specification_version: 3
|
138
|
-
summary: Rails
|
150
|
+
summary: Rails engine for interacting with the Houdini Mechanical Turk API
|
139
151
|
test_files:
|
140
152
|
- spec/controllers/houdini/postbacks_controller_spec.rb
|
141
153
|
- spec/integration/postbacks_test.rb
|
154
|
+
- spec/lib/base_spec.rb
|
142
155
|
- spec/rails_app/app/controllers/application_controller.rb
|
143
156
|
- spec/rails_app/app/helpers/application_helper.rb
|
144
157
|
- spec/rails_app/app/models/post.rb
|