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 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 plugin for interacting with the Houdini Mechanical Turk API}
24
- gem.description = %Q{Rails plugin for interacting with the Houdini Mechanical Turk API}
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.5
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
- subject_class = params[:subject_class].classify.constantize
4
- subject = subject_class.find(params[:subject_id])
5
- if subject.process_postback(params[:answer])
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
@@ -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/:subject_class/:subject_id/:task_name"
6
+ :path_prefix => "houdini/:object_class/:object_id/:task_name"
7
7
  end
@@ -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.5"
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-09}
13
- s.description = %q{Rails plugin for interacting with the Houdini Mechanical Turk API}
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.haml",
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 plugin for interacting with the Houdini Mechanical Turk API}
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
 
@@ -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
@@ -1,15 +1,21 @@
1
1
  module Houdini
2
- class Base
3
- Undefined = Class.new(NameError)
4
- HoudiniRequestError = Class.new(NameError)
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
- raise HoudiniRequestError, "The request to houdini failed with code #{response.code}: #{body}" if response.code != "200"
12
- [response.code, body]
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
@@ -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.identifier,
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
- call_on_submit(*result)
24
+
25
+ call_after_submit
24
26
  end
25
27
 
26
28
  def process_postback(answer)
27
- self.send(houdini_task.on_postback, answer)
29
+ self.send(houdini_task.on_task_completion, answer)
28
30
  end
29
31
 
30
- def call_on_submit(response, body)
31
- self.send(houdini_task.on_submit, response, body) if houdini_task.on_submit
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(template)
35
- #TODO: look into including Rails::Renderer
36
- template = File.read(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
@@ -1,18 +1,17 @@
1
1
  module Houdini
2
2
  class Task
3
- attr_accessor :name, :api, :on, :if, :identifier, :price, :title, :form_template, :on_submit, :on_postback
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
- @on_submit = options[:on_submit]
15
- @on_postback = options[:on_postback] || :update_attributes
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
- @subject = mock_model(Foo)
10
- Foo.stub!(:find).and_return(@subject)
11
- @subject.stub!(:process_postback)
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, :subject_class => 'foo', :subject_id => '1', :task_name => 'review_image'
15
+ post :create, :object_class => 'foo', :object_id => '1', :task_name => 'review_image'
16
16
  end
17
17
 
18
- it "should find the subject" do
19
- Foo.should_receive(:find).with("1").and_return(@subject)
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
- @subject.should_receive(:process_postback)
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 test_should_do_something
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, :answer => {:flagged => "yes"}
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 :moderates_image,
5
- :identifier => 'image_moderation',
4
+ houdini :image_moderation,
6
5
  :title => 'Moderate Image',
7
- :form_template => File.join(RAILS_ROOT, 'app/views/posts/houdini_template.html.haml'),
8
- :on_submit => :update_houdini_attributes,
9
- :on_postback => :process_image_moderation_answer,
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
- send_to_houdini
14
+ Houdini.perform!(:image_moderation, self)
16
15
  end
17
16
 
18
- def update_houdini_attributes(response, body)
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(answer)
23
- update_attribute(:flagged, true) if answer[:flagged] == 'yes'
21
+ def process_image_moderation_answer(params)
22
+ update_attribute(:flagged, true) if params[:flagged] == 'yes'
24
23
  end
25
24
  end
@@ -0,0 +1,6 @@
1
+ <h2>Should this image be flagged?</h2>
2
+
3
+ <img src="<%= post.image_url %>">
4
+
5
+ <input type="radio" name="flagged" value="yes", class="required">Yes</input>
6
+ <input type="radio" name="flagged" value="no", class="required">No</input>
@@ -13,7 +13,6 @@ class TestGemLocator < Rails::Plugin::Locator
13
13
  end
14
14
 
15
15
  Rails::Initializer.run do |config|
16
- config.gem 'haml'
17
16
  config.time_zone = 'UTC'
18
17
  config.plugin_locators << TestGemLocator
19
18
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 1
8
- - 5
9
- version: 0.1.5
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-09 00:00:00 -04:00
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
- description: Rails plugin for interacting with the Houdini Mechanical Turk API
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.haml
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 plugin for interacting with the Houdini Mechanical Turk API
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
@@ -1,6 +0,0 @@
1
- %h2 Should this image be flagged?
2
-
3
- %img{:src => post.image_url}
4
-
5
- %input{:type => 'radio', :name => 'flagged', :value => 'yes', :class => 'required'} Yes
6
- %input{:type => 'radio', :name => 'flagged', :value => 'no', :class => 'required'} No