kegbot_api 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +24 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +9 -0
  5. data/.yardopts +1 -0
  6. data/CHANGELOG.md +18 -0
  7. data/Gemfile +4 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +178 -0
  10. data/Rakefile +1 -0
  11. data/kegbot_api.gemspec +30 -0
  12. data/lib/kegbot_api.rb +7 -0
  13. data/lib/kegbot_api/client.rb +39 -0
  14. data/lib/kegbot_api/client_helpers.rb +33 -0
  15. data/lib/kegbot_api/errors.rb +17 -0
  16. data/lib/kegbot_api/nouns/beverage.rb +23 -0
  17. data/lib/kegbot_api/nouns/drink.rb +32 -0
  18. data/lib/kegbot_api/nouns/image.rb +22 -0
  19. data/lib/kegbot_api/nouns/keg.rb +45 -0
  20. data/lib/kegbot_api/nouns/keg_size.rb +21 -0
  21. data/lib/kegbot_api/nouns/remote_rest_noun.rb +49 -0
  22. data/lib/kegbot_api/nouns/rest_noun.rb +36 -0
  23. data/lib/kegbot_api/nouns/rest_noun_attributes.rb +119 -0
  24. data/lib/kegbot_api/nouns/session.rb +32 -0
  25. data/lib/kegbot_api/nouns/tap.rb +31 -0
  26. data/lib/kegbot_api/rest_response.rb +76 -0
  27. data/lib/kegbot_api/version.rb +3 -0
  28. data/spec/beverage_spec.rb +44 -0
  29. data/spec/drink_spec.rb +88 -0
  30. data/spec/drinks.http +5416 -0
  31. data/spec/drinks_614.http +68 -0
  32. data/spec/drinks_999999.http +18 -0
  33. data/spec/example_1.rb +40 -0
  34. data/spec/example_2.rb +28 -0
  35. data/spec/examples_spec.rb +37 -0
  36. data/spec/image_spec.rb +33 -0
  37. data/spec/keg_spec.rb +131 -0
  38. data/spec/kegs.http +144 -0
  39. data/spec/kegs_4.http +46 -0
  40. data/spec/kegs_999999.http +18 -0
  41. data/spec/session_spec.rb +73 -0
  42. data/spec/sessions.http +601 -0
  43. data/spec/sessions_65.http +23 -0
  44. data/spec/sessions_999999.http +18 -0
  45. data/spec/spec_helper.rb +34 -0
  46. data/spec/tap_spec.rb +134 -0
  47. data/spec/taps.http +96 -0
  48. metadata +209 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 18e3dfc1d6222d9c0b416ee462558e52fcc2bc4f
4
+ data.tar.gz: aa9ee8559db9fbfcacff6e02dd05404b690260d9
5
+ SHA512:
6
+ metadata.gz: 1770d0e990bd6258a7c772eba65c0833a91e72c4ecc8e532780779f9a1b79c2c8cb486e0af0a92d47c337e627fc46625f2fba1733c0edc64b40cc033779eec17
7
+ data.tar.gz: 914fa3fd62521aaedcb15daf14af94127cfdfc8bc1fd3dbdd24d41a17b27263a0196bf94f64b1a5a2da0d5bc9892fca4672d680b1242506d0bf5e63cccd63adb
@@ -0,0 +1,24 @@
1
+ *~
2
+
3
+ # /temp* files used for prototyping + hacks. usually temp.rb
4
+ /temp*
5
+
6
+ # Default GEM .gitignore
7
+
8
+ *.gem
9
+ *.rbc
10
+ .bundle
11
+ .config
12
+ .yardoc
13
+ Gemfile.lock
14
+ InstalledFiles
15
+ _yardoc
16
+ coverage
17
+ doc/
18
+ lib/bundler/man
19
+ pkg
20
+ rdoc
21
+ spec/reports
22
+ test/tmp
23
+ test/version_tmp
24
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
@@ -0,0 +1,9 @@
1
+ rvm:
2
+ - 1.9.3-p194 # Ruby version on Ubuntu
3
+ - 1.9.3 # Latest in 1.9.3 series
4
+ - 2.0.0 # Latest in 2.0.0 series
5
+ - 2.1.1 # Latest
6
+ before_script:
7
+ - gem install bundler --version "~> 1.5"
8
+ - bundle install
9
+ script: bundle exec rspec -fd
@@ -0,0 +1 @@
1
+ - README.md CHANGELOG.md
@@ -0,0 +1,18 @@
1
+ # Changelog
2
+
3
+ ## Version 0.0.1 (Feb 28, 2014)
4
+
5
+ #### Added
6
+
7
+ * Initial working version
8
+ # Added REST nouns (and associations):
9
+ * Session
10
+ * Keg
11
+ * Type
12
+ * Image
13
+ * Size
14
+ * Tap
15
+ * Keg
16
+ * Drink
17
+ * Keg
18
+ * Session
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in kegbot_api.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Eric Webb
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,178 @@
1
+ # KegbotApi
2
+
3
+ [Kegbot](https://kegbot.org/) Server [REST API](https://kegbot.org/docs/api/) client implemented in Ruby.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'kegbot_api'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install kegbot_api
18
+
19
+ ## Usage
20
+
21
+ Using the `KegbotApi` is pretty straight-forward.
22
+
23
+ ### Example 1
24
+
25
+ ``` ruby
26
+ require 'kegbot_api'
27
+
28
+ #
29
+ # Example use of the KegbotApi
30
+ #
31
+
32
+ client = KegbotApi::Client.new "http://demo.kegbot.org/api"
33
+
34
+ puts "KegbotApi Demo"
35
+ puts "http://demo.kegbot.org/api"
36
+ puts "--------------"
37
+
38
+ taps = client.Tap.all
39
+
40
+ puts "Taps: #{taps.length}"
41
+ puts "--------------"
42
+
43
+ taps.each_with_index do |tap, index|
44
+ puts "Tap #{index + 1}"
45
+ puts tap.name
46
+ puts "Online? #{tap.online?}"
47
+
48
+ if tap.online?
49
+ puts "On Tap: #{tap.keg.name}"
50
+
51
+ puts "Remaining: #{tap.keg.volume_ml_remaining}ml of #{tap.keg.volume_ml}ml"
52
+ puts '%.0f%' % tap.keg.percent_full
53
+ end
54
+
55
+ puts "--------------"
56
+ end
57
+
58
+ # Or you can find resources by ID...for example: Keg 1
59
+
60
+ puts "GET /kegs/1"
61
+ tap = client.Keg.find(1)
62
+
63
+ [:id, :name, :size_name, :volume_ml_remaining, :percent_full, :online?].each do |name|
64
+ puts "#{name} = #{tap.send(name)}"
65
+ end
66
+ ```
67
+
68
+ produces output:
69
+
70
+ ``` text
71
+ KegbotApi Demo
72
+ http://demo.kegbot.org/api
73
+ --------------
74
+ Taps: 2
75
+ --------------
76
+ Tap 1
77
+ Main Tap
78
+ Online? true
79
+ On Tap: Drake's 1500
80
+ Remaining: 21796.9ml of 58673.9ml
81
+ 37%
82
+ --------------
83
+ Tap 2
84
+ Second Tap
85
+ Online? true
86
+ On Tap: Anchor Steam
87
+ Remaining: 21005.9ml of 58673.9ml
88
+ 36%
89
+ --------------
90
+ GET /kegs/1
91
+ id = 1
92
+ name = Drake's Blonde
93
+ size_name = half-barrel
94
+ volume_ml_remaining = 80.90000000000146
95
+ percent_full = 0.13788072720579586
96
+ online? = false
97
+ ```
98
+
99
+ Source is at [`spec/example_1.rb`](spec/example_1.rb)
100
+
101
+ ### Example 2
102
+
103
+ ``` ruby
104
+ require 'kegbot_api'
105
+
106
+ #
107
+ # REST endpoints and their corresponding KegbotApi classes/methods
108
+ #
109
+
110
+ client = KegbotApi::Client.new "http://demo.kegbot.org/api"
111
+
112
+ # /drinks
113
+ client.Drink.all
114
+
115
+ # /drinks/ID
116
+ client.Drink.find(1)
117
+
118
+ # /taps
119
+ client.Tap.all
120
+
121
+ # /kegs
122
+ client.Keg.all
123
+
124
+ # /kegs/ID
125
+ client.Keg.find(1)
126
+
127
+ # /sessions
128
+ client.Session.all
129
+
130
+ # /sessions/ID
131
+ client.Session.find(1)
132
+ ```
133
+
134
+ Source is at [`spec/example_2.rb`](spec/example_2.rb)
135
+
136
+
137
+ For more examples, see the rspec test cases in the [`spec` directory](spec)
138
+
139
+ ## Limitations
140
+
141
+ The [Kegbot Server REST API specification](https://kegbot.org/docs/api/) is in flux (as mentioned on the specification page). As such, things might break. Open an issue, or even better, a pull request!
142
+
143
+ The Kegbot Server REST API specification is a bit out of date to what the server actually returns...as such, when in doubt, hit the REST URL directly and see what you see: eg: http://demo.kegbot.org/api/taps
144
+
145
+ Currently, the API is for unauthenticated and read-only content: `taps`, `kegs`, and `drinks` endpoints and their sub-objects `beverage`, `image`. The following are not fully implemented yet:
146
+
147
+ * GET `/taps/ID`
148
+ * GET `/kegs/ID/drinks`
149
+ * GET `/kegs/ID/sessions`
150
+ * GET `/users`
151
+ * GET `/users/ID`
152
+ * GET `/users/ID/drinks`
153
+ * GET `/users/ID/auth-tokens`
154
+ * GET `/thermo-sensors`
155
+ * All POST Endpoints
156
+
157
+ That being said, the API is complete for querying most information from a Kegbot server.
158
+
159
+ ## Version History
160
+
161
+ See [CHANGELOG.md](CHANGELOG.md) for a complete version history.
162
+
163
+ ## Branch Convention
164
+
165
+ * `master`
166
+ * Latest stable version
167
+ * `develop`
168
+ * Bleeding edge development
169
+ * `wip*`
170
+ * Work in progress (WIP). Should not be used unless you absolutely know what you're doing.
171
+
172
+ ## Contributing
173
+
174
+ 1. Fork it ( https://github.com/kegbot/kegbot_ruby_api/fork )
175
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
176
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
177
+ 4. Push to the branch (`git push origin my-new-feature`)
178
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'kegbot_api/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "kegbot_api"
8
+ spec.version = KegbotApi::VERSION
9
+ spec.authors = ["Eric Webb"]
10
+ spec.email = ["opensource@collectivegenius.net"]
11
+ spec.summary = "Kegbot REST API implementation in Ruby"
12
+ spec.description = "Kegbot REST API implementation in Ruby"
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ .reject { |path| path.match /\A\.idea\// } # Ignore .idea/ IntelliJ project directory
18
+ .reject { |path| path.match /\A[^\/]+\.iml/ } # Ignore *.iml IntelliJ module file
19
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.5"
24
+ spec.add_development_dependency "rake"
25
+ spec.add_development_dependency "rspec", "~> 2.14"
26
+ spec.add_development_dependency "wwtd"
27
+ spec.add_development_dependency "fakeweb", "~> 1.3"
28
+ spec.add_development_dependency "yard", "0.8.7.3"
29
+ spec.add_development_dependency "activesupport", "~> 4.0"
30
+ end
@@ -0,0 +1,7 @@
1
+ require "kegbot_api/version"
2
+ require "kegbot_api/errors"
3
+ require "kegbot_api/client"
4
+
5
+ module KegbotApi
6
+ # Your code goes here...
7
+ end
@@ -0,0 +1,39 @@
1
+ require 'kegbot_api/client_helpers'
2
+ require 'kegbot_api/nouns/keg'
3
+ require 'kegbot_api/nouns/tap'
4
+ require 'kegbot_api/nouns/drink'
5
+ require 'kegbot_api/nouns/session'
6
+ require 'kegbot_api/nouns/beverage'
7
+ require 'kegbot_api/nouns/image'
8
+ require 'kegbot_api/nouns/keg_size'
9
+
10
+ module KegbotApi
11
+ # Represents a connection to a specific Kegbot REST server
12
+ #
13
+ # Because a program my want to access multiple Kegbot REST APIs servers from the same program, you can create a {Client}
14
+ # instance appropriate for each server. To get an instance of a REST noun ({Drink}, {Keg}, {Tap}, etc.) connected to
15
+ # this client, use the appropriate methods below. {#Drink}
16
+ class Client
17
+ include ClientHelpers
18
+
19
+ attr_accessor :base_url
20
+
21
+ # @param base_url [String] base URL for the REST server (ie: http://demo.kegbot.org/api)
22
+ # @param options [Hash] (currently unused)
23
+ def initialize(base_url, options = {})
24
+ self.base_url = base_url
25
+ end
26
+
27
+ # @!macro [attach] rest_noun
28
+ # @!method $1
29
+ # @return [$1] $1 class (specialized for this specific client instance)
30
+ noun Drink
31
+ noun Tap
32
+ noun Keg
33
+ noun Session
34
+ noun Session
35
+ noun Beverage
36
+ noun Image
37
+ noun KegSize
38
+ end
39
+ end
@@ -0,0 +1,33 @@
1
+ require 'active_support/concern'
2
+
3
+ module KegbotApi
4
+ # Helper methods to be extended from {Client}
5
+ module ClientHelpers
6
+ extend ActiveSupport::Concern
7
+
8
+ # Returns RestNoun subclass by name
9
+ # @param [String, Symbol] noun name, ie: +Drink+, +Tap+
10
+ # @return [RestNoun] noun configured for this client
11
+ # @visibility private
12
+ def noun_class(name)
13
+ self.send(name)
14
+ end
15
+
16
+ module ClassMethods
17
+ # Creates a method with the same name as the specified `klass`, returning a new instance of the klass specialized
18
+ # for this {Client} instance.
19
+ # @param [Class] klass a class instance (ie: {Drink}, {Keg}, etc.)
20
+ # @visibility private
21
+ def noun(klass)
22
+ short_name = klass.name.split('::').last
23
+
24
+ define_method(short_name) do
25
+ klazz = klass.clone
26
+ klazz.client = self
27
+
28
+ klazz
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,17 @@
1
+ module KegbotApi
2
+ # Base error of all KegbotApi errors
3
+ class Error < StandardError
4
+ end
5
+
6
+ # Raised when a feature isn't implemented
7
+ class NotImplementedError < Error
8
+ end
9
+
10
+ # Raises when a specific resource is not found
11
+ class NotFoundError < Error
12
+ end
13
+
14
+ # Raised when an input (user or server) isn't appropriate/expected.
15
+ class InvalidInputError < Error
16
+ end
17
+ end
@@ -0,0 +1,23 @@
1
+ require 'kegbot_api/nouns/rest_noun'
2
+
3
+ module KegbotApi
4
+ # Beverage information (as returned with a {Keg} instance)
5
+ class Beverage < RemoteRestNoun
6
+ id :id
7
+ string :name
8
+ float :abv
9
+ has_one :image
10
+
11
+ def to_s
12
+ "#<#{self.class.to_s}:#{"0x%x" % object_id} @id=#{self.id.inspect}>"
13
+ end
14
+
15
+ def self.to_s
16
+ self.client ? "KegbotApi::Beverage<#{self.client.base_url}>" : super
17
+ end
18
+
19
+ def self.inspect
20
+ to_s
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,32 @@
1
+ require 'kegbot_api/nouns/remote_rest_noun'
2
+
3
+ module KegbotApi
4
+ class Drink < RemoteRestNoun
5
+ id :id
6
+ float :volume_ml
7
+ time :time
8
+ integer :duration
9
+ has_one :keg
10
+ has_one :session
11
+
12
+ def self.all
13
+ list(get("#{self.client.base_url}/drinks"))
14
+ end
15
+
16
+ def self.find(id, *args)
17
+ one(get("#{self.client.base_url}/drinks/#{id}"))
18
+ end
19
+
20
+ def to_s
21
+ "#<#{self.class.to_s}:#{"0x%x" % object_id} @id=#{self.id.inspect}>"
22
+ end
23
+
24
+ def self.to_s
25
+ self.client ? "KegbotApi::Drink<#{self.client.base_url}>" : super
26
+ end
27
+
28
+ def self.inspect
29
+ to_s
30
+ end
31
+ end
32
+ end