Recalls 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +65 -0
- data/LICENSE.mkd +20 -0
- data/README.mkd +64 -0
- data/Rakefile +16 -0
- data/autotest/discover.rb +1 -0
- data/lib/faraday/multipart.rb +29 -0
- data/lib/faraday/raise_error.rb +31 -0
- data/lib/faraday/response/raise_error.rb +31 -0
- data/lib/recalls.rb +51 -0
- data/lib/recalls/client.rb +21 -0
- data/lib/recalls/client/connection.rb +36 -0
- data/lib/recalls/client/products.rb +32 -0
- data/lib/recalls/client/request.rb +37 -0
- data/lib/recalls/configuration.rb +45 -0
- data/lib/recalls/version.rb +3 -0
- data/recalls.gemspec +36 -0
- data/spec/fixtures/recalls_search_response.json +1 -0
- data/spec/helper.rb +23 -0
- data/spec/recalls_spec.rb +39 -0
- metadata +246 -0
data/.rspec
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
Recalls (0.0)
|
5
|
+
faraday (~> 0.5.3)
|
6
|
+
faraday_middleware (~> 0.3.0)
|
7
|
+
hashie (~> 0.4.0)
|
8
|
+
multi_json (~> 0.0.5)
|
9
|
+
multi_xml (~> 0.2.0)
|
10
|
+
|
11
|
+
GEM
|
12
|
+
remote: http://rubygems.org/
|
13
|
+
specs:
|
14
|
+
ZenTest (4.5.0)
|
15
|
+
addressable (2.2.5)
|
16
|
+
crack (0.1.8)
|
17
|
+
diff-lcs (1.1.2)
|
18
|
+
faraday (0.5.7)
|
19
|
+
addressable (~> 2.2.4)
|
20
|
+
multipart-post (~> 1.1.0)
|
21
|
+
rack (< 2, >= 1.1.0)
|
22
|
+
faraday_middleware (0.3.2)
|
23
|
+
faraday (~> 0.5.4)
|
24
|
+
hashie (0.4.0)
|
25
|
+
json (1.5.1)
|
26
|
+
maruku (0.6.0)
|
27
|
+
syntax (>= 1.0.0)
|
28
|
+
multi_json (0.0.5)
|
29
|
+
multi_xml (0.2.2)
|
30
|
+
multipart-post (1.1.1)
|
31
|
+
nokogiri (1.4.4)
|
32
|
+
rack (1.2.2)
|
33
|
+
rake (0.8.7)
|
34
|
+
rspec (2.5.0)
|
35
|
+
rspec-core (~> 2.5.0)
|
36
|
+
rspec-expectations (~> 2.5.0)
|
37
|
+
rspec-mocks (~> 2.5.0)
|
38
|
+
rspec-core (2.5.1)
|
39
|
+
rspec-expectations (2.5.0)
|
40
|
+
diff-lcs (~> 1.1.2)
|
41
|
+
rspec-mocks (2.5.0)
|
42
|
+
simplecov (0.4.2)
|
43
|
+
simplecov-html (~> 0.4.4)
|
44
|
+
simplecov-html (0.4.4)
|
45
|
+
syntax (1.0.0)
|
46
|
+
webmock (1.6.2)
|
47
|
+
addressable (>= 2.2.2)
|
48
|
+
crack (>= 0.1.7)
|
49
|
+
yard (0.6.8)
|
50
|
+
|
51
|
+
PLATFORMS
|
52
|
+
ruby
|
53
|
+
|
54
|
+
DEPENDENCIES
|
55
|
+
Recalls!
|
56
|
+
ZenTest (~> 4.4)
|
57
|
+
bundler (~> 1.0)
|
58
|
+
json (~> 1.4)
|
59
|
+
maruku (~> 0.6)
|
60
|
+
nokogiri (~> 1.4)
|
61
|
+
rake (~> 0.8)
|
62
|
+
rspec (~> 2.1)
|
63
|
+
simplecov (~> 0.3)
|
64
|
+
webmock (~> 1.5)
|
65
|
+
yard (~> 0.6)
|
data/LICENSE.mkd
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Code for America Laboratories
|
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.mkd
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
Recalls API
|
2
|
+
=======
|
3
|
+
A Ruby wrapper for the USA Search Product Recall API at http://search.usa.gov/api.
|
4
|
+
|
5
|
+
Does your project or organization use this gem?
|
6
|
+
------------------------------------------
|
7
|
+
Add it to the [apps](http://github.com/codeforamerica/recalls_ruby/wiki/apps) wiki!
|
8
|
+
|
9
|
+
Installation
|
10
|
+
------------
|
11
|
+
$ [sudo] gem install recalls
|
12
|
+
|
13
|
+
Usage Examples
|
14
|
+
--------------
|
15
|
+
require 'recalls'
|
16
|
+
|
17
|
+
Recalls.configure do |config|
|
18
|
+
config.api_key = 'yourkeyforpostrequests'
|
19
|
+
end
|
20
|
+
|
21
|
+
# Return product recalls with the keywords cheese
|
22
|
+
# Recalls.search(:query => "cheese")
|
23
|
+
|
24
|
+
Contributing
|
25
|
+
------------
|
26
|
+
In the spirit of [free software](http://www.fsf.org/licensing/essays/free-sw.html), **everyone** is encouraged to help improve this project.
|
27
|
+
|
28
|
+
Here are some ways *you* can contribute:
|
29
|
+
|
30
|
+
* by using alpha, beta, and prerelease versions
|
31
|
+
* by reporting bugs
|
32
|
+
* by suggesting new features
|
33
|
+
* by writing or editing documentation
|
34
|
+
* by writing specifications
|
35
|
+
* by writing code (**no patch is too small**: fix typos, add comments, clean up inconsistent whitespace)
|
36
|
+
* by refactoring code
|
37
|
+
* by resolving [issues](http://github.com/cfalabs/Recalls/issues)
|
38
|
+
* by reviewing patches
|
39
|
+
|
40
|
+
Submitting an Issue
|
41
|
+
-------------------
|
42
|
+
We use the [GitHub issue tracker](http://github.com/cfalabs/Recalls/issues) to track bugs and
|
43
|
+
features. Before submitting a bug report or feature request, check to make sure it hasn't already
|
44
|
+
been submitted. You can indicate support for an existing issuse by voting it up. When submitting a
|
45
|
+
bug report, please include a [Gist](http://gist.github.com/) that includes a stack trace and any
|
46
|
+
details that may be necessary to reproduce the bug, including your gem version, Ruby version, and
|
47
|
+
operating system. Ideally, a bug report should include a pull request with failing specs.
|
48
|
+
|
49
|
+
Submitting a Pull Request
|
50
|
+
-------------------------
|
51
|
+
1. Fork the project.
|
52
|
+
2. Create a topic branch.
|
53
|
+
3. Implement your feature or bug fix.
|
54
|
+
4. Add documentation for your feature or bug fix.
|
55
|
+
5. Run <tt>bundle exec rake doc:yard</tt>. If your changes are not 100% documented, go back to step 4.
|
56
|
+
6. Add specs for your feature or bug fix.
|
57
|
+
7. Run <tt>bundle exec rake spec</tt>. If your changes are not 100% covered, go back to step 6.
|
58
|
+
8. Commit and push your changes.
|
59
|
+
9. Submit a pull request. Please do not include changes to the gemspec, version, or history file. (If you want to create your own version for some reason, please do so in a separate commit.)
|
60
|
+
|
61
|
+
Copyright
|
62
|
+
---------
|
63
|
+
Copyright (c) 2010 Code for America Laboratories
|
64
|
+
See [LICENSE](https://github.com/cfalabs/Recalls/blob/master/LICENSE.mkd) for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
RSpec::Core::RakeTask.new(:spec)
|
6
|
+
|
7
|
+
task :default => :spec
|
8
|
+
task :test => :spec
|
9
|
+
|
10
|
+
require 'yard'
|
11
|
+
namespace :doc do
|
12
|
+
YARD::Rake::YardocTask.new do |task|
|
13
|
+
task.files = ['LICENSE.md', 'lib/**/*.rb']
|
14
|
+
task.options = ['--markup', 'markdown']
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
Autotest.add_discovery { "rspec2" }
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
module Faraday
|
5
|
+
class Request::Multipart < Faraday::Middleware
|
6
|
+
def call(env)
|
7
|
+
if env[:body].is_a?(Hash)
|
8
|
+
env[:body].each do |key, value|
|
9
|
+
if value.is_a?(File)
|
10
|
+
env[:body][key] = Faraday::UploadIO.new(value, mime_type(value), value.path)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
@app.call(env)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def mime_type(file)
|
21
|
+
case file.path
|
22
|
+
when /\.jpe?g/i then 'image/jpeg'
|
23
|
+
when /\.gif$/i then 'image/gif'
|
24
|
+
when /\.png$/i then 'image/png'
|
25
|
+
else 'application/octet-stream'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
module Faraday
|
5
|
+
class Response::RaiseError < Response::Middleware
|
6
|
+
def on_complete(response)
|
7
|
+
case response[:status].to_i
|
8
|
+
when 400
|
9
|
+
raise Open311::BadRequest, error_message(response)
|
10
|
+
when 401
|
11
|
+
raise Open311::Unauthorized, error_message(response)
|
12
|
+
when 403
|
13
|
+
raise Open311::Forbidden, error_message(response)
|
14
|
+
when 404
|
15
|
+
raise Open311::NotFound, error_message(response)
|
16
|
+
when 406
|
17
|
+
raise Open311::NotAcceptable, error_message(response)
|
18
|
+
when 500
|
19
|
+
raise Open311::InternalServerError, error_message(response)
|
20
|
+
when 502
|
21
|
+
raise Open311::BadGateway, error_message(response)
|
22
|
+
when 503
|
23
|
+
raise Open311::ServiceUnavailable, error_message(response)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def error_message(response)
|
28
|
+
"#{response[:method].to_s.upcase} #{response[:url].to_s}: #{response[:response_headers]['status']}#{(': ' + response[:body]['error']) if response[:body] && response[:body]['error']}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
module Faraday
|
5
|
+
class Response::RaiseError < Response::Middleware
|
6
|
+
def on_complete(response)
|
7
|
+
case response[:status].to_i
|
8
|
+
when 400
|
9
|
+
raise Open311::BadRequest, error_message(response)
|
10
|
+
when 401
|
11
|
+
raise Open311::Unauthorized, error_message(response)
|
12
|
+
when 403
|
13
|
+
raise Open311::Forbidden, error_message(response)
|
14
|
+
when 404
|
15
|
+
raise Open311::NotFound, error_message(response)
|
16
|
+
when 406
|
17
|
+
raise Open311::NotAcceptable, error_message(response)
|
18
|
+
when 500
|
19
|
+
raise Open311::InternalServerError, error_message(response)
|
20
|
+
when 502
|
21
|
+
raise Open311::BadGateway, error_message(response)
|
22
|
+
when 503
|
23
|
+
raise Open311::ServiceUnavailable, error_message(response)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def error_message(response)
|
28
|
+
"#{response[:method].to_s.upcase} #{response[:url].to_s}: #{response[:response_headers]['status']}#{(': ' + response[:body]['error']) if response[:body] && response[:body]['error']}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/recalls.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require ::File.expand_path('../recalls/version', __FILE__)
|
2
|
+
require ::File.expand_path('../recalls/configuration.rb', __FILE__)
|
3
|
+
require ::File.expand_path('../recalls/client', __FILE__)
|
4
|
+
|
5
|
+
module Recalls
|
6
|
+
extend Configuration
|
7
|
+
|
8
|
+
# Alias for Recalls::Client.new
|
9
|
+
#
|
10
|
+
# @return [Recalls::Client]
|
11
|
+
def self.client(options={})
|
12
|
+
Recalls::Client.new(options)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Delegate to Recalls::Client
|
16
|
+
def self.method_missing(method, *args, &block)
|
17
|
+
return super unless client.respond_to?(method)
|
18
|
+
client.send(method, *args, &block)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.respond_to?(method, include_private=false)
|
22
|
+
client.respond_to?(method, include_private) || super(method, include_private)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Custom error class for rescuing from all Recalls errors
|
26
|
+
class Error < StandardError; end
|
27
|
+
|
28
|
+
# Raised when Recalls returns a 400 HTTP status code
|
29
|
+
class BadRequest < Error; end
|
30
|
+
|
31
|
+
# Raised when Recalls returns a 401 HTTP status code
|
32
|
+
class Unauthorized < Error; end
|
33
|
+
|
34
|
+
# Raised when Recalls returns a 403 HTTP status code
|
35
|
+
class Forbidden < Error; end
|
36
|
+
|
37
|
+
# Raised when Recalls returns a 404 HTTP status code
|
38
|
+
class NotFound < Error; end
|
39
|
+
|
40
|
+
# Raised when Recalls returns a 406 HTTP status code
|
41
|
+
class NotAcceptable < Error; end
|
42
|
+
|
43
|
+
# Raised when Recalls returns a 500 HTTP status code
|
44
|
+
class InternalServerError < Error; end
|
45
|
+
|
46
|
+
# Raised when Recalls returns a 502 HTTP status code
|
47
|
+
class BadGateway < Error; end
|
48
|
+
|
49
|
+
# Raised when Recalls returns a 503 HTTP status code
|
50
|
+
class ServiceUnavailable < Error; end
|
51
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require ::File.expand_path('../client/connection', __FILE__)
|
2
|
+
require ::File.expand_path('../client/request', __FILE__)
|
3
|
+
require ::File.expand_path('../client/products.rb', __FILE__)
|
4
|
+
|
5
|
+
|
6
|
+
module Recalls
|
7
|
+
class Client
|
8
|
+
attr_accessor *Configuration::VALID_OPTIONS_KEYS
|
9
|
+
|
10
|
+
def initialize(options={})
|
11
|
+
options = Recalls.options.merge(options)
|
12
|
+
Configuration::VALID_OPTIONS_KEYS.each do |key|
|
13
|
+
send("#{key}=", options[key])
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
include Recalls::Client::Connection
|
18
|
+
include Recalls::Client::Request
|
19
|
+
include Recalls::Client::Products
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'faraday_middleware'
|
2
|
+
Dir[File.expand_path('../../../faraday/*.rb', __FILE__)].each{|file| require file}
|
3
|
+
|
4
|
+
module Recalls
|
5
|
+
class Client
|
6
|
+
# @private
|
7
|
+
module Connection
|
8
|
+
private
|
9
|
+
|
10
|
+
def connection(raw=false)
|
11
|
+
options = {
|
12
|
+
:headers => {'Accept' => 'application/json'},
|
13
|
+
:proxy => proxy,
|
14
|
+
:ssl => {:verify => false},
|
15
|
+
:url => 'http://search.usa.gov/search/recalls' + endpoint.to_s
|
16
|
+
}
|
17
|
+
|
18
|
+
Faraday::Connection.new(options) do |connection|
|
19
|
+
connection.use Faraday::Request::Multipart
|
20
|
+
unless raw
|
21
|
+
connection.use Faraday::Response::Mashify
|
22
|
+
case format.to_s.downcase
|
23
|
+
when 'json'
|
24
|
+
connection.use Faraday::Response::ParseJson
|
25
|
+
when 'xml'
|
26
|
+
connection.use Faraday::Response::ParseXml
|
27
|
+
end
|
28
|
+
end
|
29
|
+
connection.use Faraday::Response::RaiseError
|
30
|
+
connection.adapter(adapter)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Recalls
|
4
|
+
class Client
|
5
|
+
module Products
|
6
|
+
include Recalls::Client::Connection
|
7
|
+
|
8
|
+
# Returns a hash of products matching the search.
|
9
|
+
#
|
10
|
+
# @return {Hash}
|
11
|
+
# @param query
|
12
|
+
# @param start_date
|
13
|
+
# @param end_date
|
14
|
+
# @param organization opptions NHSTA, CPSC, CDC
|
15
|
+
# @param upc
|
16
|
+
# @param sort sort=date
|
17
|
+
# @param page
|
18
|
+
# @param year only for NHSTA (Traffic)
|
19
|
+
# @param make only for NHSTA (Traffic)
|
20
|
+
# @param model only for NHSTA (Traffic)
|
21
|
+
# @see http://search.usa.gov/api/recalls
|
22
|
+
# @example Returns results based upon queries
|
23
|
+
# Recalls.search(:query => "bad cheese")
|
24
|
+
|
25
|
+
def search(options = {})
|
26
|
+
options.merge!({:format => "json"})
|
27
|
+
response = get('', options) rescue "Invalid API Key"
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Recalls
|
2
|
+
class Client
|
3
|
+
module Request
|
4
|
+
def get(path, options={}, raw=false)
|
5
|
+
request(:get, path, options, raw)
|
6
|
+
end
|
7
|
+
|
8
|
+
def post(path, options={}, raw=false)
|
9
|
+
request(:post, path, options, raw)
|
10
|
+
end
|
11
|
+
|
12
|
+
def put(path, options={}, raw=false)
|
13
|
+
request(:put, path, options, raw)
|
14
|
+
end
|
15
|
+
|
16
|
+
def delete(path, options={}, raw=false)
|
17
|
+
request(:delete, path, options, raw)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def request(method, path, options, raw)
|
23
|
+
response = connection(raw).send(method) do |request|
|
24
|
+
case method
|
25
|
+
when :get, :delete
|
26
|
+
request.url(path, options)
|
27
|
+
when :post, :put
|
28
|
+
request.path = path
|
29
|
+
request.body = options unless options.empty?
|
30
|
+
end
|
31
|
+
end
|
32
|
+
raw ? response : response.body
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
|
3
|
+
module Recalls
|
4
|
+
module Configuration
|
5
|
+
VALID_OPTIONS_KEYS = [
|
6
|
+
:adapter,
|
7
|
+
:endpoint,
|
8
|
+
:user_agent,
|
9
|
+
:api_key,
|
10
|
+
:proxy,
|
11
|
+
:format].freeze
|
12
|
+
|
13
|
+
VALID_FORMATS = [:json].freeze
|
14
|
+
|
15
|
+
DEFAULT_ADAPTER = Faraday.default_adapter
|
16
|
+
DEFAULT_ENDPOINT = nil
|
17
|
+
DEFAULT_PROXY = nil
|
18
|
+
DEFAULT_FORMAT = :json
|
19
|
+
DEFAULT_API_KEY = nil.freeze
|
20
|
+
DEFAULT_USER_AGENT = "Recalls Recalls Ruby Gem #{Recalls::VERSION}".freeze
|
21
|
+
|
22
|
+
attr_accessor *VALID_OPTIONS_KEYS
|
23
|
+
|
24
|
+
def self.extended(base)
|
25
|
+
base.reset
|
26
|
+
end
|
27
|
+
|
28
|
+
def configure
|
29
|
+
yield self
|
30
|
+
end
|
31
|
+
|
32
|
+
def options
|
33
|
+
VALID_OPTIONS_KEYS.inject({}){|o,k| o.merge!(k => send(k)) }
|
34
|
+
end
|
35
|
+
|
36
|
+
def reset
|
37
|
+
self.adapter = DEFAULT_ADAPTER
|
38
|
+
self.user_agent = DEFAULT_USER_AGENT
|
39
|
+
self.endpoint = DEFAULT_ENDPOINT
|
40
|
+
self.format = DEFAULT_FORMAT
|
41
|
+
self.proxy = DEFAULT_FORMAT
|
42
|
+
self.api_key = DEFAULT_API_KEY
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/recalls.gemspec
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path("../lib/recalls/version", __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.add_development_dependency("bundler", "~> 1.0")
|
6
|
+
s.add_development_dependency("json", "~> 1.4")
|
7
|
+
s.add_development_dependency("maruku", "~> 0.6")
|
8
|
+
s.add_development_dependency("nokogiri", "~> 1.4")
|
9
|
+
s.add_development_dependency("rake", "~> 0.8")
|
10
|
+
s.add_development_dependency("rspec", "~> 2.1")
|
11
|
+
s.add_development_dependency("simplecov", "~> 0.3")
|
12
|
+
s.add_development_dependency("webmock", "~> 1.5")
|
13
|
+
s.add_development_dependency("yard", "~> 0.6")
|
14
|
+
s.add_development_dependency("ZenTest", "~> 4.4")
|
15
|
+
s.add_runtime_dependency("hashie", "~> 0.4.0")
|
16
|
+
s.add_runtime_dependency("faraday", "~> 0.5.3")
|
17
|
+
s.add_runtime_dependency("faraday_middleware", "~> 0.3.0")
|
18
|
+
s.add_runtime_dependency("multi_json", "~> 0.0.5")
|
19
|
+
s.add_runtime_dependency("multi_xml", "~> 0.2.0")
|
20
|
+
s.authors = ["Dan Melton", "Erik Michaels-Ober"]
|
21
|
+
s.summary = %q{A Ruby wrapper for the Recalls APIs.}
|
22
|
+
s.post_install_message =<<eos
|
23
|
+
Using this gem in your project or organization? Add it to the apps wiki!
|
24
|
+
https://github.com/codeforamerica/Recalls/wiki/apps
|
25
|
+
eos
|
26
|
+
s.email = ["dan@codeforamerica.org"]
|
27
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
28
|
+
s.files = `git ls-files`.split("\n")
|
29
|
+
s.homepage = "http://rubygems.org/gems/recalls"
|
30
|
+
s.name = "Recalls"
|
31
|
+
s.platform = Gem::Platform::RUBY
|
32
|
+
s.require_paths = ["lib"]
|
33
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.3.6") if s.respond_to? :required_rubygems_version=
|
34
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
35
|
+
s.version = Recalls::VERSION
|
36
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
{"success":{"total":21840,"results":[{"recall_url":"http://www.fda.gov/Safety/Recalls/ucm207989.htm","description":"H-E-B, committed to the safety of customers, is issuing a precautionary recall for H-E-B French Onion Dip. H-E-B is expanding the recall announced Thursday. In addition to the product with code dates of 4/15/2010 and 4/20/2010, new affected code dates are 4/23/2010 and 4/24/2010 in the 8 ounce, 16 ounce and 24 ounce sizes.","summary":"Consumer Alert Precautionary Recall issued for H-E-B French Onion Dip","recall_number":"cebeea25a5","organization":"CDC","recall_date":"2010-04-11"},{"recall_url":"http://www.fda.gov/Safety/Recalls/ucm207818.htm","description":"McCormick & Company, Incorporated (NYSE:MKC) has announced a voluntary recall of McCormick Fajitas Seasoning Mix, with UPC Code 5210002121 and “BEST BY” dates of JAN 16 12 AH and JAN 16 12 CH. McCormick Fajitas Seasoning Mix packages with these date codes contain undeclared wheat and milk ingredients.","summary":"Mccormick & Company Recalls Mccormick Fajitas Seasoning Mix Due To Unlabeled Wheat And Milk Ingredients","recall_number":"3cee757aca","organization":"CDC","recall_date":"2010-04-08"},{"recall_url":"http://www.fda.gov/Safety/Recalls/ucm207627.htm","description":"Del Bueno of Grandview, WA is recalling all size packages of Queso Fresco Fresh Cheese because it has the potential to be contaminated with Listeria monocytogenes, an organism which can cause serious and sometimes fatal infections in young children, frail or elderly people, and others with weakened immune systems. Although healthy individuals may suffer only short-term symptoms such as high fever, severe headache, stiffness, nausea, abdominal pain and diarrhea, Listeria infection can cause miscarriages and stillbirths among pregnant women.","summary":"Del Bueno Amends Recall of Queso Fresco Cheese Because of Possible Health Risk","recall_number":"090bbb3708","organization":"CDC","recall_date":"2010-04-06"},{"recall_url":"http://www.fda.gov/Safety/Recalls/ucm207494.htm","description":"Del Bueno of Grandview, WA is recalling 16oz. packages of Queso Fresco Fresh Cheese because it has the potential to be contaminated with Listeria monocytogenes, an organism which can cause serious and sometimes fatal infections in young children, frail or elderly people, and others with weakened immune systems. Although healthy individuals may suffer only short-term symptoms such as high fever, severe headache, stiffness, nausea, abdominal pain and diarrhea, Listeria infection can cause miscarriages and stillbirths among pregnant women.","summary":"Del Bueno Recalls Queso Fresco Because of Possible Health Risk","recall_number":"4e3e0b8c82","organization":"CDC","recall_date":"2010-04-06"},{"recall_url":"http://www.fda.gov/Safety/Recalls/ucm207588.htm","description":"The Kroger Co. said today it is recalling Kroger California Seasoning Blend Garlic Powder and Kroger Special Seasoning Blend Lemon Pepper sold in its retail stores because the Company has been made aware by a supplier that an ingredient in the product may have been contaminated with Salmonella.","summary":"Kroger Recalls Two Seasonings Due to Possible Health Risk","recall_number":"6ea2fe8c4c","organization":"CDC","recall_date":"2010-04-06"},{"recall_url":"http://www.fsis.usda.gov/News_&_Events/Recall_023_2010_Release/index.asp","description":"North American Bison Co-Op, a New Rockford, N.D., establishment is recalling approximately 25,000 pounds of whole beef heads containing tongues that may not have had the tonsils completely removed, which is not compliant with regulations that require the removal of tonsils from cattle of all ages, the U.S. Department of Agriculture's Food Safety and Inspection Service (FSIS) announced today.","summary":"North Dakota Firm Recalls Whole Beef Head Products That Contain Prohibited Materials","recall_number":"e78b0b98d6","organization":"CDC","recall_date":"2010-04-05"},{"recall_url":"http://www.fda.gov/Safety/Recalls/ucm207477.htm","description":"Whole Foods Market announced the recall of its Whole Catch Yellow fin Tuna Steaks (frozen) with a best by date of Dec 5th, 2010 because of possible elevated levels of histamine that may result in symptoms that generally appear within minutes to an hour after eating the affected fish. No other Whole Foods Market, Whole Catch, 365 or 365 Organic products are affected.","summary":"Whole Foods Market Voluntarily Recalls Frozen Whole Catch Yellow Fin Tuna Steaks Due to Possible Health Risks","recall_number":"ae7929d12f","organization":"CDC","recall_date":"2010-04-05"},{"recall_url":"http://www.fda.gov/Safety/Recalls/ucm207345.htm","description":"Chino, California (April 2, 2010) -- Golden Pacific Foods, Inc. is recalling Marco Polo Brand Shrimp Snacks sold as Original, Onion & Garlic Flavored and Bar-B-Que Flavored, because they may contain undeclared milk and soy. People who have allergies to milk and soy run the risk of serious or life-threatening reaction if they consume these products.","summary":"Golden Pacific Foods, Inc. Issues Allergy Alert for Undeclared Milk and Soy in Marco Polo Brand Shrimp Snacks","recall_number":"2d45140998","organization":"CDC","recall_date":"2010-04-04"},{"recall_url":"http://www.fsis.usda.gov/News_&_Events/Recall_022_2010_Release/index.asp","description":"Lorentz Meats, a Cannon Falls, Minn., establishment, is recalling approximately 100 pounds of ham products that may be contaminated with Listeria monocytogenes. The ham products were produced on March 12, 2010, and were distributed to retail establishments in Minneapolis/St. Paul, and the surrounding area.","summary":"Minnesota Firm Recalls Ham Products for Possible Listeria Contamination","recall_number":"ac0c5020e5","organization":"CDC","recall_date":"2010-04-04"},{"recall_url":"http://www.fda.gov/Safety/Recalls/ucm207340.htm","description":"NY GOURMET SALADS INC. of Brooklyn, NY, is recalling 60 lbs. of its 5 lb. tubs of CHICK PEA SALAD because it has the potential to be contaminated with Listeria monocytogenes, an organism which can cause serious and sometimes fatal infections in young children, frail or elderly people, and others with weakened immune systems. Although healthy individuals may suffer only short-term symptoms such as high fever, severe headache, stiffness, nausea, abdominal pain and diarrhea, Listeria infection can cause miscarriages and stillbirths among pregnant women.","summary":"NY Gourmet Salads Inc. Recalls Chick Pea Salad Because of Possible Health Risk","recall_number":"6b2bfa457d","organization":"CDC","recall_date":"2010-04-02"}]}}
|
data/spec/helper.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
SimpleCov.start do
|
3
|
+
add_group 'Recalls', 'lib/recalls'
|
4
|
+
add_group 'Faraday', 'lib/faraday'
|
5
|
+
end
|
6
|
+
|
7
|
+
require File.expand_path('../../lib/recalls', __FILE__)
|
8
|
+
require 'rspec'
|
9
|
+
require 'webmock/rspec'
|
10
|
+
|
11
|
+
require 'recalls'
|
12
|
+
|
13
|
+
RSpec.configure do |config|
|
14
|
+
config.include WebMock::API
|
15
|
+
end
|
16
|
+
|
17
|
+
def fixture_path
|
18
|
+
File.expand_path("../fixtures", __FILE__)
|
19
|
+
end
|
20
|
+
|
21
|
+
def fixture(file)
|
22
|
+
File.new(fixture_path + '/' + file)
|
23
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe Recalls do
|
4
|
+
before do
|
5
|
+
Recalls.configure do |config|
|
6
|
+
config.api_key = "badcheese"
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "search" do
|
11
|
+
context "when a search returns a success" do
|
12
|
+
before do
|
13
|
+
stub_request(:get, "http://search.usa.gov/search/recalls/?format=json").
|
14
|
+
with(:headers => {'Accept'=>'application/json'}).
|
15
|
+
to_return(:status => 200, :body => fixture('recalls_search_response.json'), :headers => {})
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should return a hash with the results" do
|
19
|
+
response = Recalls.search
|
20
|
+
response.is_a?(Hash).should be_true
|
21
|
+
response["success"]["total"].should == 21840
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context "when a search returns an error" do
|
26
|
+
before do
|
27
|
+
stub_request(:get, "http://search.usa.gov/search/recalls/?format=json").
|
28
|
+
with(:headers => {'Accept'=>'application/json'}).
|
29
|
+
to_return(:status => 401, :body => "Invalid API Key", :headers => {})
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should return an error" do
|
33
|
+
response = Recalls.search
|
34
|
+
response.is_a?(String).should be_true
|
35
|
+
response.should == "Invalid API Key"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
metadata
ADDED
@@ -0,0 +1,246 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: Recalls
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: "0.1"
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Dan Melton
|
9
|
+
- Erik Michaels-Ober
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
|
14
|
+
date: 2011-05-19 00:00:00 Z
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: bundler
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ~>
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: "1.0"
|
25
|
+
type: :development
|
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: "1.4"
|
36
|
+
type: :development
|
37
|
+
version_requirements: *id002
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: maruku
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ~>
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: "0.6"
|
47
|
+
type: :development
|
48
|
+
version_requirements: *id003
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: nokogiri
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ~>
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "1.4"
|
58
|
+
type: :development
|
59
|
+
version_requirements: *id004
|
60
|
+
- !ruby/object:Gem::Dependency
|
61
|
+
name: rake
|
62
|
+
prerelease: false
|
63
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: "0.8"
|
69
|
+
type: :development
|
70
|
+
version_requirements: *id005
|
71
|
+
- !ruby/object:Gem::Dependency
|
72
|
+
name: rspec
|
73
|
+
prerelease: false
|
74
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ~>
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: "2.1"
|
80
|
+
type: :development
|
81
|
+
version_requirements: *id006
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
name: simplecov
|
84
|
+
prerelease: false
|
85
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ~>
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: "0.3"
|
91
|
+
type: :development
|
92
|
+
version_requirements: *id007
|
93
|
+
- !ruby/object:Gem::Dependency
|
94
|
+
name: webmock
|
95
|
+
prerelease: false
|
96
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ~>
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: "1.5"
|
102
|
+
type: :development
|
103
|
+
version_requirements: *id008
|
104
|
+
- !ruby/object:Gem::Dependency
|
105
|
+
name: yard
|
106
|
+
prerelease: false
|
107
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
108
|
+
none: false
|
109
|
+
requirements:
|
110
|
+
- - ~>
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: "0.6"
|
113
|
+
type: :development
|
114
|
+
version_requirements: *id009
|
115
|
+
- !ruby/object:Gem::Dependency
|
116
|
+
name: ZenTest
|
117
|
+
prerelease: false
|
118
|
+
requirement: &id010 !ruby/object:Gem::Requirement
|
119
|
+
none: false
|
120
|
+
requirements:
|
121
|
+
- - ~>
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: "4.4"
|
124
|
+
type: :development
|
125
|
+
version_requirements: *id010
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: hashie
|
128
|
+
prerelease: false
|
129
|
+
requirement: &id011 !ruby/object:Gem::Requirement
|
130
|
+
none: false
|
131
|
+
requirements:
|
132
|
+
- - ~>
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: 0.4.0
|
135
|
+
type: :runtime
|
136
|
+
version_requirements: *id011
|
137
|
+
- !ruby/object:Gem::Dependency
|
138
|
+
name: faraday
|
139
|
+
prerelease: false
|
140
|
+
requirement: &id012 !ruby/object:Gem::Requirement
|
141
|
+
none: false
|
142
|
+
requirements:
|
143
|
+
- - ~>
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: 0.5.3
|
146
|
+
type: :runtime
|
147
|
+
version_requirements: *id012
|
148
|
+
- !ruby/object:Gem::Dependency
|
149
|
+
name: faraday_middleware
|
150
|
+
prerelease: false
|
151
|
+
requirement: &id013 !ruby/object:Gem::Requirement
|
152
|
+
none: false
|
153
|
+
requirements:
|
154
|
+
- - ~>
|
155
|
+
- !ruby/object:Gem::Version
|
156
|
+
version: 0.3.0
|
157
|
+
type: :runtime
|
158
|
+
version_requirements: *id013
|
159
|
+
- !ruby/object:Gem::Dependency
|
160
|
+
name: multi_json
|
161
|
+
prerelease: false
|
162
|
+
requirement: &id014 !ruby/object:Gem::Requirement
|
163
|
+
none: false
|
164
|
+
requirements:
|
165
|
+
- - ~>
|
166
|
+
- !ruby/object:Gem::Version
|
167
|
+
version: 0.0.5
|
168
|
+
type: :runtime
|
169
|
+
version_requirements: *id014
|
170
|
+
- !ruby/object:Gem::Dependency
|
171
|
+
name: multi_xml
|
172
|
+
prerelease: false
|
173
|
+
requirement: &id015 !ruby/object:Gem::Requirement
|
174
|
+
none: false
|
175
|
+
requirements:
|
176
|
+
- - ~>
|
177
|
+
- !ruby/object:Gem::Version
|
178
|
+
version: 0.2.0
|
179
|
+
type: :runtime
|
180
|
+
version_requirements: *id015
|
181
|
+
description:
|
182
|
+
email:
|
183
|
+
- dan@codeforamerica.org
|
184
|
+
executables: []
|
185
|
+
|
186
|
+
extensions: []
|
187
|
+
|
188
|
+
extra_rdoc_files: []
|
189
|
+
|
190
|
+
files:
|
191
|
+
- .rspec
|
192
|
+
- Gemfile
|
193
|
+
- Gemfile.lock
|
194
|
+
- LICENSE.mkd
|
195
|
+
- README.mkd
|
196
|
+
- Rakefile
|
197
|
+
- autotest/discover.rb
|
198
|
+
- lib/faraday/multipart.rb
|
199
|
+
- lib/faraday/raise_error.rb
|
200
|
+
- lib/faraday/response/raise_error.rb
|
201
|
+
- lib/recalls.rb
|
202
|
+
- lib/recalls/client.rb
|
203
|
+
- lib/recalls/client/connection.rb
|
204
|
+
- lib/recalls/client/products.rb
|
205
|
+
- lib/recalls/client/request.rb
|
206
|
+
- lib/recalls/configuration.rb
|
207
|
+
- lib/recalls/version.rb
|
208
|
+
- recalls.gemspec
|
209
|
+
- spec/fixtures/recalls_search_response.json
|
210
|
+
- spec/helper.rb
|
211
|
+
- spec/recalls_spec.rb
|
212
|
+
homepage: http://rubygems.org/gems/recalls
|
213
|
+
licenses: []
|
214
|
+
|
215
|
+
post_install_message: |
|
216
|
+
Using this gem in your project or organization? Add it to the apps wiki!
|
217
|
+
https://github.com/codeforamerica/Recalls/wiki/apps
|
218
|
+
|
219
|
+
rdoc_options: []
|
220
|
+
|
221
|
+
require_paths:
|
222
|
+
- lib
|
223
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
224
|
+
none: false
|
225
|
+
requirements:
|
226
|
+
- - ">="
|
227
|
+
- !ruby/object:Gem::Version
|
228
|
+
version: "0"
|
229
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
230
|
+
none: false
|
231
|
+
requirements:
|
232
|
+
- - ">="
|
233
|
+
- !ruby/object:Gem::Version
|
234
|
+
version: 1.3.6
|
235
|
+
requirements: []
|
236
|
+
|
237
|
+
rubyforge_project:
|
238
|
+
rubygems_version: 1.7.2
|
239
|
+
signing_key:
|
240
|
+
specification_version: 3
|
241
|
+
summary: A Ruby wrapper for the Recalls APIs.
|
242
|
+
test_files:
|
243
|
+
- spec/fixtures/recalls_search_response.json
|
244
|
+
- spec/helper.rb
|
245
|
+
- spec/recalls_spec.rb
|
246
|
+
has_rdoc:
|