crowdflower-rtfm 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,16 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+ gem "rest-client"
6
+ gem "multi_json"
7
+
8
+ # Add dependencies to develop your gem here.
9
+ # Include everything needed to run rake, tests, features, etc.
10
+ group :development do
11
+ gem "minitest", ">= 0"
12
+ gem "bundler", "~> 1.0.0"
13
+ gem "jeweler", "~> 1.8.3"
14
+ gem "simplecov", ">= 0"
15
+ gem "webmock", ">= 0"
16
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,39 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ addressable (2.2.7)
5
+ crack (0.3.1)
6
+ git (1.2.5)
7
+ jeweler (1.8.3)
8
+ bundler (~> 1.0)
9
+ git (>= 1.2.5)
10
+ rake
11
+ rdoc
12
+ json (1.7.0)
13
+ mime-types (1.18)
14
+ minitest (2.12.1)
15
+ multi_json (1.3.4)
16
+ rake (0.9.2.2)
17
+ rdoc (3.12)
18
+ json (~> 1.4)
19
+ rest-client (1.6.7)
20
+ mime-types (>= 1.16)
21
+ simplecov (0.6.2)
22
+ multi_json (~> 1.3)
23
+ simplecov-html (~> 0.5.3)
24
+ simplecov-html (0.5.3)
25
+ webmock (1.8.6)
26
+ addressable (>= 2.2.7)
27
+ crack (>= 0.1.7)
28
+
29
+ PLATFORMS
30
+ ruby
31
+
32
+ DEPENDENCIES
33
+ bundler (~> 1.0.0)
34
+ jeweler (~> 1.8.3)
35
+ minitest
36
+ multi_json
37
+ rest-client
38
+ simplecov
39
+ webmock
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 CrowdFlower
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.md ADDED
@@ -0,0 +1,45 @@
1
+ # RTFM - Real Time Foto Moderator
2
+
3
+ Real Time Foto Moderator (RTFM) is Crowdsourced Image Moderation, learn more at http://crowdflower.com/rtfm. This gem is a simple wrapper for interacting with the API. Keep your app clean!
4
+
5
+ ## Usage
6
+
7
+ ```shell
8
+ gem install crowdflower-rtfm
9
+ ```
10
+
11
+ ```ruby
12
+ require 'rubygems'
13
+ require 'crowdflower-rtfm'
14
+
15
+ RTFM.api_key = "a1b2c3d4e5f6g7h8i9j0..."
16
+ #moderate_image accepts an optional metadata hash
17
+ res = RTFM.moderate_image("http://mysite.com/images/moderateme.jpg", {:id => 123})
18
+ RTFM.retrieve_image(res["image"]["id"])
19
+ ```
20
+
21
+ ## Exceptions
22
+
23
+ All exceptions thrown by the gem itself inherit from `RTFM::Error`. Below are the possible exceptions:
24
+
25
+ * RateLimitError - (rate limit exceeded)
26
+ * PaymentError - (account is out of money)
27
+ * AccountError - (your account is not authorized for this service)
28
+ * AuthenticationError - (your API key is invalid)
29
+ * InvalidRequestError - (one of your parameters is invalid, usually url)
30
+ * APIError - (a non 200 response code was returned, see the docs)
31
+ * APIConnectionError - (a network error occured)
32
+
33
+ ## Webhook example
34
+
35
+ We've also included an example Sinatra server to consume webhooks from RTFM. You can find it at https://github.com/dolores/rtfm-ruby/tree/master/examples
36
+
37
+ # Acknowledgements
38
+
39
+ The implementation of this wrapper was inspired heavily by Stripes Ruby implementation (https://github.com/stripe/stripe-ruby). Thanks to Ross Boucher & Greg Brockman for bending RestClient to their will.
40
+
41
+ # Copyright
42
+
43
+ Copyright (c) 2012 CrowdFlower. See LICENSE.txt for
44
+ further details.
45
+
data/Rakefile ADDED
@@ -0,0 +1,35 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "crowdflower-rtfm"
18
+ gem.homepage = "http://dolores.github.com/rtfm-api"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Simple Ruby wrapper for the RTFM API}
21
+ gem.description = %Q{Real Time Foto Moderator (RTFM) is Crowdsourced Image Moderation. Keep your app clean!}
22
+ gem.email = "vanpelt@crowdflower.com"
23
+ gem.authors = ["Chris Van Pelt"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rake/testtask'
29
+ Rake::TestTask.new(:test) do |test|
30
+ test.libs << 'lib' << 'test'
31
+ test.pattern = 'test/**/test_*.rb'
32
+ test.verbose = true
33
+ end
34
+
35
+ task :default => :test
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.2
@@ -0,0 +1,73 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "crowdflower-rtfm"
8
+ s.version = "0.0.2"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Chris Van Pelt"]
12
+ s.date = "2012-05-07"
13
+ s.description = "Real Time Foto Moderator (RTFM) is Crowdsourced Image Moderation. Keep your app clean!"
14
+ s.email = "vanpelt@crowdflower.com"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.md"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ "Gemfile",
22
+ "Gemfile.lock",
23
+ "LICENSE.txt",
24
+ "README.md",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "crowdflower-rtfm.gemspec",
28
+ "examples/Gemfile",
29
+ "examples/README.md",
30
+ "examples/config.ru",
31
+ "examples/webhook.rb",
32
+ "examples/webhook_public.pem",
33
+ "lib/crowdflower-rtfm.rb",
34
+ "test/helper.rb",
35
+ "test/test_rtfm.rb"
36
+ ]
37
+ s.homepage = "http://dolores.github.com/rtfm-api"
38
+ s.licenses = ["MIT"]
39
+ s.require_paths = ["lib"]
40
+ s.rubygems_version = "1.8.10"
41
+ s.summary = "Simple Ruby wrapper for the RTFM API"
42
+
43
+ if s.respond_to? :specification_version then
44
+ s.specification_version = 3
45
+
46
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
47
+ s.add_runtime_dependency(%q<rest-client>, [">= 0"])
48
+ s.add_runtime_dependency(%q<multi_json>, [">= 0"])
49
+ s.add_development_dependency(%q<minitest>, [">= 0"])
50
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
51
+ s.add_development_dependency(%q<jeweler>, ["~> 1.8.3"])
52
+ s.add_development_dependency(%q<simplecov>, [">= 0"])
53
+ s.add_development_dependency(%q<webmock>, [">= 0"])
54
+ else
55
+ s.add_dependency(%q<rest-client>, [">= 0"])
56
+ s.add_dependency(%q<multi_json>, [">= 0"])
57
+ s.add_dependency(%q<minitest>, [">= 0"])
58
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
59
+ s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
60
+ s.add_dependency(%q<simplecov>, [">= 0"])
61
+ s.add_dependency(%q<webmock>, [">= 0"])
62
+ end
63
+ else
64
+ s.add_dependency(%q<rest-client>, [">= 0"])
65
+ s.add_dependency(%q<multi_json>, [">= 0"])
66
+ s.add_dependency(%q<minitest>, [">= 0"])
67
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
68
+ s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
69
+ s.add_dependency(%q<simplecov>, [">= 0"])
70
+ s.add_dependency(%q<webmock>, [">= 0"])
71
+ end
72
+ end
73
+
data/examples/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source :rubygems
2
+
3
+ gem "sinatra", ">= 1.3.0"
4
+ gem "multi_json"
@@ -0,0 +1,10 @@
1
+ #Sample webhook consumer
2
+
3
+ You can take the contents of this folder and put them into a new git repo. This will allows you to push the repo to heroku and have a functioning webhook.
4
+
5
+ ##Debugging
6
+
7
+ ```bash
8
+ heroku config:add LOG_LEVEL=DEBUG
9
+ heroku logs -t
10
+ ```
@@ -0,0 +1,2 @@
1
+ require './webhook'
2
+ run Sinatra::Application
@@ -0,0 +1,23 @@
1
+ require 'rubygems'
2
+ require 'sinatra'
3
+ require 'multi_json'
4
+ require 'openssl'
5
+ require 'base64'
6
+
7
+ PKey = OpenSSL::PKey::RSA.new(File.read(File.join(File.dirname(__FILE__), "webhook_public.pem")))
8
+
9
+ post "/rtfm_webhook" do
10
+ signature = env['X-CrowdFlower-Signature']
11
+ body = request.body.read
12
+ if(@public_key.verify(OpenSSL::Digest::SHA1.new, Base64.decode64(signature), body))
13
+ payload = MultiJson.load(body)
14
+ #Do something meaningful with the payload here
15
+ logger.debug "SUCCESS"
16
+ logger.debug payload
17
+ 200
18
+ else
19
+ logger.debug "FAILURE #{signature}"
20
+ logger.debug body
21
+ 401
22
+ end
23
+ end
@@ -0,0 +1,9 @@
1
+ -----BEGIN PUBLIC KEY-----
2
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0I0daumhUqIn4nIFcWEb
3
+ bTtL7F9a0d/a5d09/bnHNZcxOALjHir8iBKe3nSLRaKZDWd+MmxseD90dEbRtsvM
4
+ 9lZ5bfFnXga43IAonnTZmLbqMsUNMByLLrfthlkUsU9arRJxEWK5I4eCON2JVm9E
5
+ ruQLaNi8RqitHwGvsfiOQm2gchoMj8kOyrVvdoUldSu3VZN7AbJ+mrsmFwEfQd5h
6
+ LzqLfHBCx7YlnWVFoNC3mOzxqpzJKdL+t1mXi7ewZSsCZzEL1LdeqJ3UTpSrNIRA
7
+ DU1UB+Pi7aybUIIDWC04jmRAPRiMSg87zK9bL+oXM0QWT7Zi8/EF76ZdeIaH2YrL
8
+ cQIDAQAB
9
+ -----END PUBLIC KEY-----
@@ -0,0 +1,135 @@
1
+ require 'rubygems'
2
+ require 'openssl'
3
+ require 'rest_client'
4
+ require 'multi_json'
5
+
6
+ module RTFM
7
+ VERSION = File.read(File.join(File.dirname(__FILE__),"..","VERSION"))
8
+ @@api_key = nil
9
+ @@api_base = "https://rtfm.crowdflower.com/v1"
10
+
11
+ def self.api_key=(api_key); @@api_key = api_key; end
12
+ def self.api_key; @@api_key; end
13
+ def self.api_base=(api_base); @@api_base = api_base; end
14
+ def self.api_base; @@api_base; end
15
+ def self.api_url(url=''); @@api_base + url; end
16
+
17
+ def self.moderate_image(url, metadata = nil)
18
+ params = {:url => url}
19
+ params.merge!(:metadata => metadata) if metadata
20
+ request("/images", :post, params)
21
+ end
22
+
23
+ def self.retrieve_image(id)
24
+ request("/images/#{id}")
25
+ end
26
+
27
+ def self.request(url, method = :get, params = nil, api_key = nil, headers = {})
28
+ api_key ||= @@api_key
29
+ raise AuthenticationError.new("Please provide an API key (RTFM.api_key = <API-KEY>, your API key can be found by clicking \"APISettings\" @ http://crowdflower.com/rtfm)") unless api_key
30
+
31
+ #RestClient appends get parameters by looking for params in headers... lame
32
+ if method == :get && params
33
+ headers.merge!(:params => params)
34
+ params = nil
35
+ end
36
+
37
+ opts = {
38
+ :user => api_key,
39
+ :timeout => 30,
40
+ :url => api_url(url),
41
+ :method => method,
42
+ :headers => {
43
+ :user_agent => "RTFM/v1 RubyGem/#{VERSION}",
44
+ :accept => "application/json"
45
+ }.merge(headers),
46
+ :payload => params
47
+ }
48
+
49
+ response = RestClient::Request.execute(opts)
50
+ MultiJson.load(response.body, :symbolize_keys => true)
51
+ rescue SocketError => e
52
+ self.handle_restclient_error(e)
53
+ rescue RestClient::ExceptionWithResponse => e
54
+ rcode = e.http_code
55
+ rbody = e.http_body
56
+ if rcode && rbody
57
+ self.handle_api_error(rcode, rbody)
58
+ else
59
+ self.handle_restclient_error(e)
60
+ end
61
+ rescue RestClient::Exception, Errno::ECONNREFUSED => e
62
+ self.handle_restclient_error(e)
63
+ rescue MultiJson::DecodeError
64
+ raise APIError.new("Invalid response body: #{response.body.inspect}. (HTTP response code of #{response.code})", response.code, response.body)
65
+ end
66
+
67
+ class Error < StandardError
68
+ attr_reader :message
69
+ attr_reader :http_status
70
+ attr_reader :http_body
71
+ attr_reader :json_body
72
+
73
+ def initialize(message=nil, http_status=nil, http_body=nil, json_body=nil)
74
+ @message = message
75
+ @http_status = http_status
76
+ @http_body = http_body
77
+ @json_body = json_body
78
+ end
79
+
80
+ def to_s
81
+ status_string = @http_status.nil? ? "" : "(Status #{@http_status}) "
82
+ "#{status_string}#{@message}"
83
+ end
84
+ end
85
+
86
+ class RateLimitError < Error; end
87
+ class APIError < Error; end
88
+ class PaymentError < Error; end
89
+ class AccountError < Error; end
90
+ class AuthenticationError < Error; end
91
+ class InvalidRequestError < Error; end
92
+ class APIConnectionError < Error; end
93
+
94
+ def self.error(klass = Error, error, rcode, rbody, error_obj); klass.new(error, rcode, rbody, error_obj); end
95
+
96
+ def self.handle_api_error(rcode, rbody)
97
+ begin
98
+ error_obj = MultiJson.load(rbody, :symbolize_keys => true)
99
+ error = error_obj[:error] or raise Error.new # escape from parsing
100
+ rescue MultiJson::DecodeError, Error
101
+ raise APIError.new("Invalid response object from API: #{rbody.inspect} (HTTP response code was #{rcode})", rcode, rbody)
102
+ end
103
+
104
+ case rcode
105
+ when 503
106
+ raise error(RateLimitError, error, rcode, rbody, error_obj)
107
+ when 400, 404 then
108
+ raise error(InvalidRequestError, error, rcode, rbody, error_obj)
109
+ when 401
110
+ raise error(AuthenticationError, error, rcode, rbody, error_obj)
111
+ when 402
112
+ raise error(PaymentError, error, rcode, rbody, error_obj)
113
+ when 403
114
+ raise error(AccountError, error, rcode, rbody, error_obj)
115
+ else
116
+ raise error(APIError, error, rcode, rbody, error_obj)
117
+ end
118
+ end
119
+
120
+ def self.handle_restclient_error(e)
121
+ case e
122
+ when RestClient::ServerBrokeConnection, RestClient::RequestFailed
123
+ message = "Could not connect to RTFM (#{@@api_base}). Please check your internet connection and try again. If this problem persists, you should check RTFM's service status at https://twitter.com/cfstatus, or let us know at rtfm@crowdflower.com."
124
+ when RestClient::SSLCertificateNotVerified
125
+ message = "Could not verify RTFM's SSL certificate. Please make sure that your network is not intercepting certificates. If this problem persists, let us know at rtfm@crowdflower.com."
126
+ when SocketError
127
+ message = "Unexpected error communicating when trying to connect to RTFM. HINT: You may be seeing this message because your DNS is not working. To check, try running 'host stripe.com' from the command line."
128
+ else
129
+ message = "Unexpected error communicating with RTFM. If this problem persists, let us know at rtfm@crowdflower.com"
130
+ end
131
+ message += "\n\n(Network error: #{e.message})"
132
+ raise APIConnectionError.new(message)
133
+ end
134
+ end
135
+
data/test/helper.rb ADDED
@@ -0,0 +1,45 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ require 'simplecov'
4
+ SimpleCov.start
5
+
6
+ begin
7
+ Bundler.setup(:default, :development)
8
+ rescue Bundler::BundlerError => e
9
+ $stderr.puts e.message
10
+ $stderr.puts "Run `bundle install` to install missing gems"
11
+ exit e.status_code
12
+ end
13
+ require 'minitest/spec'
14
+ require 'minitest/autorun'
15
+ require 'webmock/minitest'
16
+
17
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
18
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
19
+ require 'rtfm'
20
+
21
+ def moderate_success_body(url, metadata = {})
22
+ MultiJson.dump(
23
+ "image" => {
24
+ "id" => 1,
25
+ "url" => url,
26
+ "metadata" => metadata
27
+ }
28
+ )
29
+ end
30
+
31
+ def retrieve_success_body(id)
32
+ MultiJson.dump(
33
+ "image" => {
34
+ "id" => id,
35
+ "url" => "http://vanpe.lt/fake.jpg",
36
+ "score" => 0.6,
37
+ "rating" => "accepted",
38
+ "state" => "completed",
39
+ "metadata" => {}
40
+ }
41
+ )
42
+ end
43
+
44
+ class MiniTest::Spec::TestCase
45
+ end
data/test/test_rtfm.rb ADDED
@@ -0,0 +1,153 @@
1
+ require 'helper'
2
+
3
+ describe RTFM do
4
+ before do
5
+ @url = "http://vanpe.lt/awesome.jpg"
6
+ RTFM.api_key = "1234"
7
+ end
8
+
9
+ describe "makes successful requests" do
10
+ it "moderates without metadata" do
11
+ stub_request(:post, "https://1234:@rtfm.crowdflower.com/v1/images").with(
12
+ :body => /awesome/,
13
+ :headers => {'User-Agent'=>"RTFM/v1 RubyGem/#{RTFM::VERSION}"}
14
+ ).to_return(:status => 200, :body => moderate_success_body(@url))
15
+ res = RTFM.moderate_image(@url)
16
+ res[:image][:id].must_equal(1)
17
+ res[:image][:metadata].must_equal({})
18
+ end
19
+
20
+ it "moderates with metadata" do
21
+ stub_request(:post, "https://1234:@rtfm.crowdflower.com/v1/images").with(
22
+ :body => /metadata\[foo\]=123/
23
+ ).to_return(:status => 200, :body => moderate_success_body(@url, {:foo => 123}))
24
+ res = RTFM.moderate_image(@url, {:foo => 123})
25
+ res[:image][:metadata].must_equal({:foo => 123})
26
+ end
27
+
28
+ it "retrieves analysis" do
29
+ stub_request(:get, "https://1234:@rtfm.crowdflower.com/v1/images/1").to_return(:status => 200, :body => retrieve_success_body(1))
30
+ res = RTFM.retrieve_image(1)
31
+ res[:image][:url].must_equal("http://vanpe.lt/fake.jpg")
32
+ res[:image][:id].must_equal(1)
33
+ end
34
+ end
35
+
36
+ describe "handles network errors" do
37
+ it "catches ERRNO" do
38
+ stub_request(:post, "https://1234:@rtfm.crowdflower.com/v1/images").to_raise(Errno::ECONNREFUSED)
39
+ error = lambda {
40
+ RTFM.moderate_image(@url)
41
+ }.must_raise(RTFM::APIConnectionError)
42
+ error.to_s.must_match /Connection refused/
43
+ end
44
+
45
+ it "catches timeout" do
46
+ #The struct is a hack to prevent an infinite loop in RestClient
47
+ stub_request(:post, "https://1234:@rtfm.crowdflower.com/v1/images").to_raise(RestClient::RequestFailed.new(OpenStruct.new(:net_http_res => nil)))
48
+ error = lambda {
49
+ RTFM.moderate_image(@url)
50
+ }.must_raise(RTFM::APIConnectionError)
51
+ error.to_s.must_match /Could not connect/
52
+ end
53
+
54
+ it "catches SocketError" do
55
+ stub_request(:post, "https://1234:@rtfm.crowdflower.com/v1/images").to_raise(SocketError)
56
+ error = lambda {
57
+ RTFM.moderate_image(@url)
58
+ }.must_raise(RTFM::APIConnectionError)
59
+ error.to_s.must_match /Network error/
60
+ end
61
+
62
+ it "handles SSL errors"
63
+ end
64
+
65
+ describe "handles API errors" do
66
+ it "prevents no API key" do
67
+ RTFM.api_key = nil
68
+ lambda {
69
+ RTFM.moderate_image(@url)
70
+ }.must_raise(RTFM::AuthenticationError)
71
+ end
72
+
73
+ it "handles bad API key" do
74
+ stub_request(:post, "https://1234:@rtfm.crowdflower.com/v1/images").to_return(
75
+ :status => 401, :body => MultiJson.dump({:error => "You're not authorized"})
76
+ )
77
+ error = lambda {
78
+ puts RTFM.moderate_image(@url)
79
+ }.must_raise(RTFM::AuthenticationError)
80
+ error.to_s.must_match /not authorized/
81
+ end
82
+
83
+ it "handles no money" do
84
+ stub_request(:post, "https://1234:@rtfm.crowdflower.com/v1/images").to_return(
85
+ :status => 402, :body => MultiJson.dump({:error => "You have no money"})
86
+ )
87
+ error = lambda {
88
+ puts RTFM.moderate_image(@url)
89
+ }.must_raise(RTFM::PaymentError)
90
+ error.to_s.must_match /no money/
91
+ end
92
+
93
+ it "handles bad account" do
94
+ stub_request(:post, "https://1234:@rtfm.crowdflower.com/v1/images").to_return(
95
+ :status => 403, :body => MultiJson.dump({:error => "You have no account"})
96
+ )
97
+ error = lambda {
98
+ puts RTFM.moderate_image(@url)
99
+ }.must_raise(RTFM::AccountError)
100
+ error.to_s.must_match /no account/
101
+ end
102
+
103
+ it "handles not found" do
104
+ stub_request(:post, "https://1234:@rtfm.crowdflower.com/v1/images").to_return(
105
+ :status => 404, :body => MultiJson.dump({:error => "Not Found"})
106
+ )
107
+ error = lambda {
108
+ puts RTFM.moderate_image(@url)
109
+ }.must_raise(RTFM::InvalidRequestError)
110
+ error.to_s.must_match /Not Found/
111
+ end
112
+
113
+ it "handles ratelimit" do
114
+ stub_request(:post, "https://1234:@rtfm.crowdflower.com/v1/images").to_return(
115
+ :status => 503, :body => MultiJson.dump({:error => "Too fast"})
116
+ )
117
+ error = lambda {
118
+ puts RTFM.moderate_image(@url)
119
+ }.must_raise(RTFM::RateLimitError)
120
+ error.to_s.must_match /Too fast/
121
+ end
122
+
123
+ it "handles malformed response on success" do
124
+ stub_request(:post, "https://1234:@rtfm.crowdflower.com/v1/images").to_return(
125
+ :status => 200, :body => "bullshit"
126
+ )
127
+ error = lambda {
128
+ puts RTFM.moderate_image(@url)
129
+ }.must_raise(RTFM::APIError)
130
+ error.to_s.must_match /bullshit/
131
+ end
132
+
133
+ it "handles malformed response on error" do
134
+ stub_request(:post, "https://1234:@rtfm.crowdflower.com/v1/images").to_return(
135
+ :status => 500, :body => "bullshit"
136
+ )
137
+ error = lambda {
138
+ puts RTFM.moderate_image(@url)
139
+ }.must_raise(RTFM::APIError)
140
+ error.to_s.must_match /bullshit/
141
+ end
142
+
143
+ it "handles malformed request" do
144
+ stub_request(:post, "https://1234:@rtfm.crowdflower.com/v1/images").to_return(
145
+ :status => 422, :body => MultiJson.dump({:error => "Bad url"})
146
+ )
147
+ error = lambda {
148
+ puts RTFM.moderate_image(@url)
149
+ }.must_raise(RTFM::APIError)
150
+ error.to_s.must_match /Bad url/
151
+ end
152
+ end
153
+ end
metadata ADDED
@@ -0,0 +1,144 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: crowdflower-rtfm
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Chris Van Pelt
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-05-07 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rest-client
16
+ requirement: &70210985936740 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70210985936740
25
+ - !ruby/object:Gem::Dependency
26
+ name: multi_json
27
+ requirement: &70210985936140 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70210985936140
36
+ - !ruby/object:Gem::Dependency
37
+ name: minitest
38
+ requirement: &70210985935640 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70210985935640
47
+ - !ruby/object:Gem::Dependency
48
+ name: bundler
49
+ requirement: &70210985935140 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 1.0.0
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70210985935140
58
+ - !ruby/object:Gem::Dependency
59
+ name: jeweler
60
+ requirement: &70210985934580 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: 1.8.3
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70210985934580
69
+ - !ruby/object:Gem::Dependency
70
+ name: simplecov
71
+ requirement: &70210985933940 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70210985933940
80
+ - !ruby/object:Gem::Dependency
81
+ name: webmock
82
+ requirement: &70210985933220 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *70210985933220
91
+ description: Real Time Foto Moderator (RTFM) is Crowdsourced Image Moderation. Keep
92
+ your app clean!
93
+ email: vanpelt@crowdflower.com
94
+ executables: []
95
+ extensions: []
96
+ extra_rdoc_files:
97
+ - LICENSE.txt
98
+ - README.md
99
+ files:
100
+ - .document
101
+ - Gemfile
102
+ - Gemfile.lock
103
+ - LICENSE.txt
104
+ - README.md
105
+ - Rakefile
106
+ - VERSION
107
+ - crowdflower-rtfm.gemspec
108
+ - examples/Gemfile
109
+ - examples/README.md
110
+ - examples/config.ru
111
+ - examples/webhook.rb
112
+ - examples/webhook_public.pem
113
+ - lib/crowdflower-rtfm.rb
114
+ - test/helper.rb
115
+ - test/test_rtfm.rb
116
+ homepage: http://dolores.github.com/rtfm-api
117
+ licenses:
118
+ - MIT
119
+ post_install_message:
120
+ rdoc_options: []
121
+ require_paths:
122
+ - lib
123
+ required_ruby_version: !ruby/object:Gem::Requirement
124
+ none: false
125
+ requirements:
126
+ - - ! '>='
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ segments:
130
+ - 0
131
+ hash: -2682891135621693422
132
+ required_rubygems_version: !ruby/object:Gem::Requirement
133
+ none: false
134
+ requirements:
135
+ - - ! '>='
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ requirements: []
139
+ rubyforge_project:
140
+ rubygems_version: 1.8.10
141
+ signing_key:
142
+ specification_version: 3
143
+ summary: Simple Ruby wrapper for the RTFM API
144
+ test_files: []