Recalls 0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in gem_template.gemspec
4
+ gemspec
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
@@ -0,0 +1,3 @@
1
+ module Recalls
2
+ VERSION = "0.1"
3
+ 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: