brewery_db 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +2 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +5 -0
  5. data/CHANGELOG.md +15 -0
  6. data/README.md +81 -29
  7. data/Rakefile +5 -0
  8. data/brewery_db.gemspec +6 -5
  9. data/lib/brewery_db.rb +15 -19
  10. data/lib/brewery_db/client.rb +19 -7
  11. data/lib/brewery_db/collection.rb +42 -0
  12. data/lib/brewery_db/config.rb +7 -6
  13. data/lib/brewery_db/mash.rb +18 -0
  14. data/lib/brewery_db/middleware/error_handler.rb +28 -0
  15. data/lib/brewery_db/request.rb +27 -0
  16. data/lib/brewery_db/resource.rb +16 -22
  17. data/lib/brewery_db/resources/beers.rb +2 -2
  18. data/lib/brewery_db/resources/breweries.rb +2 -2
  19. data/lib/brewery_db/resources/brewery.rb +16 -0
  20. data/lib/brewery_db/resources/categories.rb +2 -2
  21. data/lib/brewery_db/resources/glassware.rb +2 -2
  22. data/lib/brewery_db/resources/search.rb +1 -1
  23. data/lib/brewery_db/resources/styles.rb +2 -2
  24. data/lib/brewery_db/response.rb +26 -12
  25. data/lib/brewery_db/version.rb +1 -1
  26. data/lib/brewery_db/web_hook.rb +32 -0
  27. data/spec/brewery_db/client_spec.rb +41 -30
  28. data/spec/brewery_db/config_spec.rb +25 -28
  29. data/spec/brewery_db/{response_spec.rb → mash_spec.rb} +1 -1
  30. data/spec/brewery_db/middleware/error_handler_spec.rb +49 -0
  31. data/spec/brewery_db/resource_spec.rb +35 -22
  32. data/spec/brewery_db/resources/beers_spec.rb +10 -82
  33. data/spec/brewery_db/resources/breweries_spec.rb +10 -54
  34. data/spec/brewery_db/resources/brewery_spec.rb +27 -0
  35. data/spec/brewery_db/resources/categories_spec.rb +10 -38
  36. data/spec/brewery_db/resources/glassware_spec.rb +10 -36
  37. data/spec/brewery_db/resources/search_spec.rb +19 -61
  38. data/spec/brewery_db/resources/styles_spec.rb +10 -72
  39. data/spec/brewery_db/web_hook_spec.rb +79 -0
  40. data/spec/fixtures/BreweryDB_Resource/_get/a_list_of_resources/can_be_enumerated.yml +515 -0
  41. data/spec/fixtures/BreweryDB_Resource/_get/a_not_found_request/raises_an_exception.yml +38 -0
  42. data/spec/fixtures/BreweryDB_Resource/_get/a_not_found_request/sets_the_exception_message_to_the_error_message_in_the_response.yml +38 -0
  43. data/spec/fixtures/BreweryDB_Resource/_get/an_OK_request/name/.yml +54 -0
  44. data/spec/fixtures/BreweryDB_Resources_Beers/_all/fetches_all_of_the_beers_at_once.yml +889 -0
  45. data/spec/fixtures/BreweryDB_Resources_Beers/_find/fetches_only_the_beer_asked_for.yml +61 -0
  46. data/spec/fixtures/BreweryDB_Resources_Breweries/_all/fetches_all_of_the_breweries_at_once.yml +430 -0
  47. data/spec/fixtures/BreweryDB_Resources_Breweries/_find/fetches_only_the_brewery_asked_for.yml +57 -0
  48. data/spec/fixtures/BreweryDB_Resources_Categories/_all/fetches_all_of_the_cagtegories_at_once.yml +49 -0
  49. data/spec/fixtures/BreweryDB_Resources_Categories/_find/fetches_only_the_category_asked_for.yml +39 -0
  50. data/spec/fixtures/BreweryDB_Resources_Glassware/_all/fetches_all_of_the_glassware_at_once.yml +45 -0
  51. data/spec/fixtures/BreweryDB_Resources_Glassware/_find/fetches_only_the_glassware_asked_for.yml +39 -0
  52. data/spec/fixtures/BreweryDB_Resources_Search/_all/fetches_all_of_the_search_results_at_once.yml +1132 -0
  53. data/spec/fixtures/BreweryDB_Resources_Styles/_all/fetches_all_of_the_styles_at_once.yml +1866 -0
  54. data/spec/fixtures/BreweryDB_Resources_Styles/_find/fetches_only_the_style_asked_for.yml +50 -0
  55. data/spec/spec_helper.rb +4 -4
  56. data/spec/support/shared/a_resource.rb +3 -9
  57. data/spec/support/vcr.rb +6 -1
  58. metadata +82 -42
  59. data/spec/brewery_db_spec.rb +0 -18
  60. data/spec/fixtures/beers.yml +0 -445
  61. data/spec/fixtures/breweries.yml +0 -409
  62. data/spec/fixtures/categories.yml +0 -102
  63. data/spec/fixtures/glassware.yml +0 -65
  64. data/spec/fixtures/search.yml +0 -314
  65. data/spec/fixtures/styles.yml +0 -317
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MjQzMTM3ZWNlM2JhODRkM2FkMDU2MDAzOWVkNzUwOGFkOWU1OTY5OA==
5
+ data.tar.gz: !binary |-
6
+ ZGM5NmZmMmE1MDcyYWUyMjFkODZkMmFlYjNiNjI5NTM0Y2JkMGUyZA==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ OGIxYmNhNjNlMWZiNGZhYzE0MzdjYjM4MzQ5YmYzMTUwNDRiOWM2YzczNDdl
10
+ ZDRkZjQzNmNjOThjNGY5YzkzZmNmMzRjYzViMTAzZWJiNWY1Yzk3ZDA2M2Ey
11
+ OTQwNjkyNTkzMjE0YTY3MzE1ZjA3OWZhYjRiYjlmMDg3NGQzZDY=
12
+ data.tar.gz: !binary |-
13
+ NjBiYjUxZGRmNTdmMjEyYTNjY2U0ZmMzYjQ5YTUxNjEyMThiNDAwNTBhMjY4
14
+ YjQzOGJhZWJlMmM4YWY4NzdiZDE4ZmI5ZGMxMWJlM2ZmZjY4OTAzMWFmMTdj
15
+ MzI2NGY4ZTNjYTYwMDcyZGJjYTljYmQ3NGU2NTA2MTNhMzJiYjg=
data/.gitignore CHANGED
@@ -3,6 +3,7 @@
3
3
  *.swp
4
4
  .bundle
5
5
  .config
6
+ .rbenv-version
6
7
  .rvmrc
7
8
  .yardoc
8
9
  Gemfile.lock
@@ -15,6 +16,7 @@ lib/bundler/man
15
16
  pkg
16
17
  rdoc
17
18
  spec/reports
19
+ tags
18
20
  test/tmp
19
21
  test/version_tmp
20
22
  tmp
data/.rspec CHANGED
@@ -1,2 +1,4 @@
1
1
  --color
2
2
  --format progress
3
+
4
+ -r pry
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ script: bundle exec rspec
3
+ rvm:
4
+ - 1.9.2
5
+ - 1.9.3
data/CHANGELOG.md ADDED
@@ -0,0 +1,15 @@
1
+ # Changelog
2
+
3
+ ## BreweryDB 0.0.2 (Unreleased)
4
+
5
+ * Raise exceptions on unsuccessful responses
6
+ * Return the data directly on successful responses ([Steven Harman][stevenharman])
7
+ * Add support for `brewery/:id/beers` endpoint ([Steven Harman][stevenharman])
8
+ * Require `faraday_middleare` ~> 0.8 ([Steven Harman][stevenharman])
9
+ * Add support for handling webhook parameters ([Steven Harman][stevenharman])
10
+
11
+ ## BreweryDB 0.0.1
12
+
13
+ * Initial release
14
+
15
+ [stevenharman]: http://github.com/stevenharman
data/README.md CHANGED
@@ -1,6 +1,11 @@
1
1
  # BreweryDB
2
2
 
3
- A Ruby library for interfacing with the [BreweryDB][] API.
3
+ [![Build Status][travis]][travis-web]
4
+
5
+ [travis]: https://secure.travis-ci.org/tylerhunt/brewery_db.png
6
+ [travis-web]: http://travis-ci.org/tylerhunt/brewery_db
7
+
8
+ A Ruby library for using the [BreweryDB][] API.
4
9
 
5
10
  [brewerydb]: http://www.brewerydb.com/
6
11
 
@@ -29,55 +34,94 @@ one, you may [request one here][api-key].
29
34
 
30
35
  [api-key]: http://www.brewerydb.com/developers
31
36
 
32
- Use the following method to configure your API key:
37
+ You can use the following method to configure your API key:
33
38
 
34
39
  ``` ruby
35
- BreweryDB.configure do |config|
40
+ brewery_db = BreweryDB::Client.new do |config|
36
41
  config.api_key = API_KEY
37
42
  end
38
43
  ```
39
44
 
40
- If you'd like to use multiple instance of the API with different keys, you may
41
- instantiate the `BreweryDB::Client` directly and treat those instances the same
42
- as the `BreweryDB` module:
45
+
46
+ ## Usage
47
+
48
+ Once an API key has been set, resources can be called on the client instance.
43
49
 
44
50
  ``` ruby
45
- brewery_db = BreweryDB::Client.new
51
+ brewery_db.beers.all(abv: '5.5')
52
+ brewery_db.beers.find('vYlBZQ')
46
53
 
47
- brewery_db.configure do |config|
48
- config.api_key = API_KEY
49
- end
54
+ brewery_db.breweries.all(established: 2006)
55
+ brewery_db.breweries.find('d1zSa7')
56
+
57
+ brewery_db.brewery('d1zSa7').beers
58
+
59
+ brewery_db.categories.all
60
+ brewery_db.categories.find(1)
61
+
62
+ brewery_db.glassware.all
63
+ brewery_db.glassware.find(1)
64
+
65
+ brewery_db.search.all(q: 'IPA')
66
+ brewery_db.search.beers(q: 'IPA')
67
+ brewery_db.search.breweries(q: 'IPA')
68
+ brewery_db.search.guilds(q: 'IPA')
69
+ brewery_db.search.events(q: 'IPA')
70
+
71
+ brewery_db.styles.all
72
+ brewery_db.styles.find(1)
50
73
  ```
51
74
 
75
+ ### WebHooks
52
76
 
53
- ## Usage
77
+ The BreweryDB API also provides [WebHooks][webhooks] which can be use to:
54
78
 
55
- Once the API key has been configured, resources may be called off the module
56
- directly or off your client instances:
79
+ > keep your local data stores in sync with the main BreweryDB API. Instead of
80
+ > having to constantly query the API, webhooks will send you a message when
81
+ > something changes.
57
82
 
58
- ``` ruby
59
- BreweryDB.beers.all(abv: '5.5')
60
- BreweryDB.beers.find('vYlBZQ')
83
+ This library provides a simple abstraction over the data posted by those
84
+ webhooks.
85
+
86
+ ```ruby
87
+ webhook = BreweryDB::WebHook.new(webhook_params_hash)
88
+ ```
89
+
90
+ #### Validating a WebHook
91
+
92
+ The `webhook_params_hash` should contain the `key`, `nonce`, `action`, etc.
93
+ sent as the payload of the webhook. A `BreweryDB::WebHook` object can validate
94
+ the posted data by SHA1 hashing your API key with the `nonce` value and
95
+ comparing it to the `key` value (as per the [docs][webhooks]).
96
+
97
+ ```ruby
98
+ webhook.valid?(API_KEY) #=> true or false
99
+ ```
61
100
 
62
- BreweryDB.breweries.all(established: 2006)
63
- BreweryDB.breweries.find('d1zSa7')
101
+ #### Idiomatic wrapper over WebHook parameters
64
102
 
65
- BreweryDB.categories.all
66
- BreweryDB.categories.find(1)
103
+ The `BreweryDB::WebHook` object also provides an idiomatic Ruby wrapper over
104
+ the parameters. For example, one of the parameters posted in a webhook is
105
+ `attributeId`, which is the BreweryDB id for a brewery, beer, etc. This
106
+ parameter is exposed by an instance of `BreweryDB::WebHook` via
67
107
 
68
- BreweryDB.glassware.all
69
- BreweryDB.glassware.find(1)
108
+ ```ruby
109
+ webhook.attribute_id #=> 'x6bRxw'
110
+ ```
70
111
 
71
- BreweryDB.search.all(q: 'IPA')
72
- BreweryDB.search.beers(q: 'IPA')
73
- BreweryDB.search.breweries(q: 'IPA')
74
- BreweryDB.search.guilds(q: 'IPA')
75
- BreweryDB.search.events(q: 'IPA')
112
+ The full list of parameters available are:
76
113
 
77
- BreweryDB.styles.all
78
- BreweryDB.styles.find(1)
114
+ ```ruby
115
+ webhook.action #=> 'insert'
116
+ webhook.attribute #=> 'beer'
117
+ webhook.attribute_id #=> 'x6bRxw'
118
+ webhook.key #=> 'some-long-key-value-here'
119
+ webhook.nonce #=> 'some-long-nonce-value-here'
120
+ webhook.sub_action #=> 'none'
121
+ webhook.timestamp #=> '1350573527'
79
122
  ```
80
123
 
124
+ [webhooks]: http://developer.pintlabs.com/brewerydb/webhooks/
81
125
 
82
126
  ## Contributing
83
127
 
@@ -88,6 +132,14 @@ BreweryDB.styles.find(1)
88
132
  5. Create a new Pull Request.
89
133
 
90
134
 
135
+ ## Contributors
136
+
137
+ Thanks to the following people who have contributed patches or helpful
138
+ suggestions:
139
+
140
+ * [Steven Harman](https://github.com/stevenharman)
141
+
142
+
91
143
  ## Copyright
92
144
 
93
145
  Copyright © 2012 Tyler Hunt. See LICENSE for details.
data/Rakefile CHANGED
@@ -1,3 +1,8 @@
1
1
  #!/usr/bin/env rake
2
2
 
3
3
  require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
data/brewery_db.gemspec CHANGED
@@ -3,16 +3,17 @@ require './lib/brewery_db/version'
3
3
  Gem::Specification.new do |gem|
4
4
  gem.name = 'brewery_db'
5
5
  gem.version = BreweryDB::VERSION
6
- gem.summary = 'A Ruby library for interfacing with the BreweryDB API.'
6
+ gem.summary = 'A Ruby library for using the BreweryDB API.'
7
7
  gem.homepage = 'http://github.com/tylerhunt/brewery_db'
8
- gem.author = 'Tyler Hunt'
8
+ gem.authors = ['Tyler Hunt', 'Steven Harman']
9
9
 
10
10
  gem.required_ruby_version = '>= 1.9'
11
11
 
12
12
  gem.add_dependency 'faraday', '~> 0.8.0'
13
- gem.add_dependency 'faraday_middleware'
14
- gem.add_dependency 'hashie', '~> 1.1'
15
- gem.add_development_dependency 'rspec', '~> 2.0'
13
+ gem.add_dependency 'faraday_middleware', '~> 0.8'
14
+ gem.add_dependency 'hashie', '>= 1.1', '< 3'
15
+ gem.add_development_dependency 'pry'
16
+ gem.add_development_dependency 'rspec', '~> 2.11'
16
17
  gem.add_development_dependency 'vcr', '~> 2.0'
17
18
 
18
19
  gem.files = `git ls-files`.split($\)
data/lib/brewery_db.rb CHANGED
@@ -1,36 +1,32 @@
1
1
  require 'brewery_db/version'
2
2
 
3
3
  module BreweryDB
4
+ Error = Class.new(StandardError)
5
+ BadRequest = Class.new(Error)
6
+ NotFound = Class.new(Error)
7
+ RateLimitExceeded = Class.new(Error)
8
+ Unauthorized = Class.new(Error)
9
+
4
10
  autoload :Client, 'brewery_db/client'
11
+ autoload :Collection, 'brewery_db/collection'
5
12
  autoload :Config, 'brewery_db/config'
13
+ autoload :Mash, 'brewery_db/mash'
14
+ autoload :Request, 'brewery_db/request'
6
15
  autoload :Resource, 'brewery_db/resource'
7
16
  autoload :Response, 'brewery_db/response'
17
+ autoload :WebHook, 'brewery_db/web_hook'
18
+
19
+ module Middleware
20
+ autoload :ErrorHandler, 'brewery_db/middleware/error_handler'
21
+ end
8
22
 
9
23
  module Resources
10
24
  autoload :Beers, 'brewery_db/resources/beers'
11
25
  autoload :Breweries, 'brewery_db/resources/breweries'
26
+ autoload :Brewery, 'brewery_db/resources/brewery'
12
27
  autoload :Categories, 'brewery_db/resources/categories'
13
28
  autoload :Glassware, 'brewery_db/resources/glassware'
14
29
  autoload :Search, 'brewery_db/resources/search'
15
30
  autoload :Styles, 'brewery_db/resources/styles'
16
31
  end
17
-
18
- extend self
19
-
20
- def respond_to?(method, include_private=false)
21
- super || client.respond_to?(method, include_private)
22
- end
23
-
24
- def method_missing(method, *args, &block)
25
- if client.respond_to?(method)
26
- client.send(method, *args, &block)
27
- else
28
- super
29
- end
30
- end
31
-
32
- def client
33
- @client ||= Client.new
34
- end
35
- private :client
36
32
  end
@@ -1,36 +1,48 @@
1
1
  module BreweryDB
2
2
  class Client
3
+ def initialize(&block)
4
+ configure(&block) if block_given?
5
+ end
6
+
3
7
  def config
4
8
  @config ||= Config.new
5
9
  end
6
10
 
7
11
  def configure
8
12
  yield(config)
9
- config
13
+ self
10
14
  end
11
15
 
12
16
  def beers
13
- @beers ||= Resources::Beers.new(self)
17
+ @beers ||= Resources::Beers.new(config)
18
+ end
19
+
20
+ # Builds a new instance of the brewery resource.
21
+ #
22
+ # @param id [String] the brewery ID
23
+ # @return <Resources::Breweries> an instance of the brewery resource
24
+ def brewery(id)
25
+ Resources::Brewery.new(config, id: id)
14
26
  end
15
27
 
16
28
  def breweries
17
- @breweries ||= Resources::Breweries.new(self)
29
+ @breweries ||= Resources::Breweries.new(config)
18
30
  end
19
31
 
20
32
  def categories
21
- @categories ||= Resources::Categories.new(self)
33
+ @categories ||= Resources::Categories.new(config)
22
34
  end
23
35
 
24
36
  def glassware
25
- @glassware ||= Resources::Glassware.new(self)
37
+ @glassware ||= Resources::Glassware.new(config)
26
38
  end
27
39
 
28
40
  def search
29
- @search ||= Resources::Search.new(self)
41
+ @search ||= Resources::Search.new(config)
30
42
  end
31
43
 
32
44
  def styles
33
- @styles ||= Resources::Styles.new(self)
45
+ @styles ||= Resources::Styles.new(config)
34
46
  end
35
47
  end
36
48
  end
@@ -0,0 +1,42 @@
1
+ module BreweryDB
2
+ class Collection
3
+ include Enumerable
4
+
5
+ BATCH_SIZE = 50
6
+
7
+ attr_reader :size
8
+ alias length size
9
+
10
+ def initialize(response)
11
+ self.response = response
12
+ end
13
+
14
+ def count(*args, &block)
15
+ # The Ruby documentation is wrong, and Enumerable#count no longer calls
16
+ # #size, so let's make sure it's used here when no arguments are given.
17
+ if args.empty? && !block_given?
18
+ size
19
+ else
20
+ super
21
+ end
22
+ end
23
+
24
+ def each
25
+ return to_enum unless block_given?
26
+
27
+ while @collection.any?
28
+ @collection.each { |element| yield(element) }
29
+ break if @collection.size < BATCH_SIZE
30
+ self.response = @response.next_page
31
+ end
32
+ end
33
+
34
+ def response=(response)
35
+ @response = response
36
+ @collection = Array(response.data) || []
37
+ @size = response.count || 0
38
+ @page_count = response.page_count
39
+ end
40
+ private :response=
41
+ end
42
+ end
@@ -2,19 +2,20 @@ require 'faraday'
2
2
 
3
3
  module BreweryDB
4
4
  class Config
5
- ADAPTER = Faraday.default_adapter
6
- ENDPOINT = 'http://api.brewerydb.com/v2'
7
- MIDDLEWARE = []
5
+ BASE_URI = 'http://api.brewerydb.com/v2'
8
6
  USER_AGENT = "BreweryDB Ruby Gem #{BreweryDB::VERSION}"
7
+ TIMEOUT = 60
9
8
 
10
9
  attr_accessor :adapter
11
10
  attr_accessor :api_key
12
- attr_accessor :endpoint
11
+ attr_accessor :base_uri
12
+ attr_accessor :timeout
13
13
  attr_accessor :user_agent
14
14
 
15
15
  def initialize
16
- self.adapter = ADAPTER
17
- self.endpoint = ENDPOINT
16
+ self.adapter = Faraday.default_adapter
17
+ self.base_uri = BASE_URI
18
+ self.timeout = TIMEOUT
18
19
  self.user_agent = USER_AGENT
19
20
  end
20
21
  end
@@ -0,0 +1,18 @@
1
+ require 'hashie'
2
+
3
+ module BreweryDB
4
+ class Mash < Hashie::Mash
5
+ def convert_key(key)
6
+ key = key.to_s.dup
7
+ key.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
8
+ key.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
9
+ key.tr('-', '_').downcase
10
+ end
11
+ protected :convert_key
12
+
13
+ def convert_value(value, duping=false)
14
+ value.is_a?(String) ? super.gsub("\r\n", "\n") : super
15
+ end
16
+ protected :convert_value
17
+ end
18
+ end