lelylan-rb 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. data/.gitignore +26 -0
  2. data/CHANGELOG.md +5 -0
  3. data/Gemfile +7 -0
  4. data/Guardfile +5 -0
  5. data/LICENSE.md +1 -0
  6. data/README.md +218 -0
  7. data/Rakefile +21 -0
  8. data/lelylan_rb.gemspec +36 -0
  9. data/lib/faraday/response/raise_http_error.rb +35 -0
  10. data/lib/lelylan.rb +26 -0
  11. data/lib/lelylan/authentication.rb +11 -0
  12. data/lib/lelylan/client.rb +47 -0
  13. data/lib/lelylan/client/categories.rb +112 -0
  14. data/lib/lelylan/client/consumptions.rb +93 -0
  15. data/lib/lelylan/client/devices.rb +211 -0
  16. data/lib/lelylan/client/functions.rb +118 -0
  17. data/lib/lelylan/client/histories.rb +42 -0
  18. data/lib/lelylan/client/locations.rb +92 -0
  19. data/lib/lelylan/client/properties.rb +115 -0
  20. data/lib/lelylan/client/statuses.rb +110 -0
  21. data/lib/lelylan/client/types.rb +109 -0
  22. data/lib/lelylan/configuration.rb +65 -0
  23. data/lib/lelylan/connection.rb +33 -0
  24. data/lib/lelylan/error.rb +34 -0
  25. data/lib/lelylan/request.rb +70 -0
  26. data/lib/lelylan/version.rb +15 -0
  27. data/spec/faraday/response_spec.rb +37 -0
  28. data/spec/fixtures/categories.json +7 -0
  29. data/spec/fixtures/category.json +7 -0
  30. data/spec/fixtures/consumption.json +11 -0
  31. data/spec/fixtures/consumptions.json +11 -0
  32. data/spec/fixtures/device.json +25 -0
  33. data/spec/fixtures/devices.json +25 -0
  34. data/spec/fixtures/function.json +15 -0
  35. data/spec/fixtures/functions.json +15 -0
  36. data/spec/fixtures/histories.json +16 -0
  37. data/spec/fixtures/history.json +16 -0
  38. data/spec/fixtures/location.json +55 -0
  39. data/spec/fixtures/locations.json +18 -0
  40. data/spec/fixtures/oauth2/refresh.json +6 -0
  41. data/spec/fixtures/oauth2/token.json +6 -0
  42. data/spec/fixtures/pending.json +12 -0
  43. data/spec/fixtures/properties.json +9 -0
  44. data/spec/fixtures/property.json +9 -0
  45. data/spec/fixtures/status.json +24 -0
  46. data/spec/fixtures/statuses.json +24 -0
  47. data/spec/fixtures/type.json +94 -0
  48. data/spec/fixtures/types.json +88 -0
  49. data/spec/helper.rb +71 -0
  50. data/spec/lelylan/client/categories_spec.rb +178 -0
  51. data/spec/lelylan/client/consumptions_spec.rb +150 -0
  52. data/spec/lelylan/client/devices_spec.rb +342 -0
  53. data/spec/lelylan/client/functions_spec.rb +184 -0
  54. data/spec/lelylan/client/histories_spec.rb +64 -0
  55. data/spec/lelylan/client/locations_spec.rb +155 -0
  56. data/spec/lelylan/client/properties_spec.rb +184 -0
  57. data/spec/lelylan/client/statuses_spec.rb +184 -0
  58. data/spec/lelylan/client/types_spec.rb +184 -0
  59. data/spec/lelylan/client_spec.rb +32 -0
  60. data/spec/lelylan/oauth2_spec.rb +54 -0
  61. data/spec/lelylan_spec.rb +32 -0
  62. metadata +351 -0
@@ -0,0 +1,26 @@
1
+ *.gem
2
+ *.rbc
3
+ *.swp
4
+ *.tmproj
5
+ *.DS_Store
6
+ *~
7
+ .\#*
8
+ .bundle
9
+ .config
10
+ .yardoc
11
+ .yardopts
12
+ .rvmrc
13
+ Gemfile.lock
14
+ InstalledFiles
15
+ \#*
16
+ _yardoc
17
+ coverage
18
+ doc/
19
+ lib/bundler/man
20
+ pkg
21
+ rdoc
22
+ spec/reports
23
+ test/tmp
24
+ test/version_tmp
25
+ tmp
26
+ tmtags
@@ -0,0 +1,5 @@
1
+ # Changelog
2
+
3
+ ## v0.1.0 ()
4
+
5
+ First version Ruby wrapper for Lelylan API
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ platforms :jruby do
4
+ gem "jruby-openssl", "~> 0.7"
5
+ end
6
+
7
+ gemspec
@@ -0,0 +1,5 @@
1
+ guard 'rspec', cli: '--format Fuubar --color', all_after_pass: false, :version => 2 do
2
+ watch(%r{^spec/.+_spec\.rb})
3
+ watch(%r{^lib/(.+)\.rb}) { |m| "spec/#{m[1]}_spec.rb" }
4
+ watch('spec/spec_helper.rb') { "spec" }
5
+ end
@@ -0,0 +1 @@
1
+ Copyright (c) 2013 Lelylan
@@ -0,0 +1,218 @@
1
+ # Lelylan Ruby Gem
2
+
3
+ Ruby client library for [Lelylan API](http://dev.lelylan.com)
4
+
5
+
6
+ ## Requirements
7
+
8
+ Ruby client library is tested against MRI 1.9.3.
9
+
10
+
11
+ ## Installation
12
+
13
+ Install gem using Bundler.
14
+
15
+ gem 'lelylan-rb', require: 'lelylan'
16
+
17
+ Development version.
18
+
19
+ gem 'lelylan-rb', require: 'lelylan', git: 'https://github.com/lelylan/lelylan-rb', branch: 'dev'
20
+
21
+
22
+ ## Resources
23
+
24
+ * [Ruby gem documentation](http://rdoc.info/gems/lelylan-rb)
25
+ * [Lelylan API](http://dev.lelylan.com)
26
+
27
+
28
+ ## Getting started
29
+
30
+ Require gems.
31
+
32
+ require 'rubygems'
33
+ require 'lelylan-rb'
34
+
35
+
36
+ ### Create the access token
37
+
38
+ Create a client (uses the [OAuth2 gem](https://github.com/intridea/oauth2/)).
39
+
40
+ oauth = OAuth2::Client.new(client_id, client_secret, site: site)
41
+
42
+ Redirect the application to the Lelylan authorization page.
43
+
44
+ redirect oauth.auth_code.authorize_url(redirect_uri: redirect_uri)
45
+
46
+ Create the access token. The params[:code] contains the authorization
47
+ code created from Lelylan and sent to the redirect_uri.
48
+
49
+ token = oauth.auth_code.get_token(params[:code], redirect_uri: redirect_uri)
50
+
51
+ ### Create the Lelylan client.
52
+
53
+ client = Lelylan::Client.new(token: token)
54
+
55
+ ### Access Lelylan API
56
+
57
+ Get 10 devices.
58
+
59
+ client.devices(per: 10)
60
+
61
+ Get a device based on its URI.
62
+
63
+ client.device('http://api.lelylan.com/devices/:id')
64
+
65
+ Search a device based on its name.
66
+
67
+ client.devices(name: 'Dimmer').first
68
+
69
+ Create a device (in this case we suppose the type is a dimmer)
70
+
71
+ device = client.create_device(name: 'Closet dimmer', type_uri: dimmer.uri)
72
+
73
+ Execute a function.
74
+
75
+ client.execute(device.uri, function.uri)
76
+
77
+ Get a public type based on its URI. Remember, when a resource is public the client
78
+ with a token is not needed.
79
+
80
+ Lelylan.type('http://api.lelylan.com/types/:id')
81
+
82
+
83
+ ## More examples
84
+
85
+ For more examples check out the [ruby gem documentation](http://rdoc.info/gems/lelylan-rb).
86
+
87
+ * [Device examples](docs/Lelylan/Client/Devices)
88
+ * [Consumption examples](docs/Lelylan/Client/Consumptions)
89
+ * [Hisotry examples](docs/Lelylan/Client/Histories)
90
+ * [Types examples](docs/Lelylan/Client/Types)
91
+ * [Properties examples](docs/Lelylan/Client/Properties)
92
+ * [Functions examples](docs/Lelylan/Client/Functions)
93
+ * [Statuses examples](docs/Lelylan/Client/Statuses)
94
+ * [Categories examples](docs/Lelylan/Client/Categories)
95
+ * [Locations examples](docs/Lelylan/Client/Locations)
96
+
97
+ ## Authorization flows
98
+
99
+ Lelylan support four OAuth2 authorization flows.
100
+
101
+ ### Authorization code flows
102
+
103
+ oauth = OAuth2::Client.new(client_id, client_secret, site: site)
104
+ redirect oauth.auth_code.authorize_url(redirect_uri: redirect_uri)
105
+ token = oauth.auth_code.get_token(params[:code], redirect_uri: redirect_uri)
106
+
107
+ ### Implicit grant flow
108
+
109
+ oauth = OAuth2::Client.new(client_id, client_secret, site: site)
110
+ redirect oauth.auth_code.authorize_url(redirect_uri: redirect_uri)
111
+ token = OAuth2::AccessToken.from_kvform(client, params)
112
+
113
+ ### Resource owner password credentials flow
114
+
115
+ oauth = OAuth2::Client.new(client_id, client_secret, site: site)
116
+ token = oauth.password.get_token('email', 'password')
117
+
118
+ ### Client credentials flow
119
+
120
+ token = oauth.client_credentials.get_token
121
+
122
+ All access tokens, when expired, are automatically refreshed.
123
+
124
+
125
+ ## Settings
126
+
127
+ ### API endpoint
128
+
129
+ Configuration block.
130
+
131
+ Lelylan.configure { |c| c.endpoint = 'https://lelylan.yourhouse.com' }
132
+ @client = Lelylan::Client.new(token: token)
133
+
134
+ Client instance.
135
+
136
+ @client = Lelylan::Client.new(token: token)
137
+ @client.endpoint = 'https://lelylan.yourhouse.com'
138
+
139
+
140
+ ## Errors
141
+
142
+ Exceptions are raised when a 4xx or 5xx status code is returned.
143
+
144
+ Lelylan::BadRequest # 400
145
+ Lelylan::Unauthorized # 401
146
+ Lelylan::NotFound # 404
147
+ Lelylan::NotValid # 422
148
+ Lelylan::InternalServerError # 500
149
+ Lelylan::BadGateway # 502
150
+ Lelylan::ServiceUnavailable # 503
151
+
152
+
153
+ Through the error message attribute you can access the error information.
154
+
155
+ begin
156
+ @type = Lelylan::Type.type("https://type.lelylan.com/types/not_existing_uri")
157
+ rescue Lelylan::NotFound => e
158
+ puts "The resource #{e.message.error.uri} was not found"
159
+ end
160
+
161
+ Learn more about the [error response structure](http://dev.lelylan.com/rest/core/#errors).
162
+
163
+
164
+ ## Contributing
165
+
166
+ Fork the repo on github and send a pull requests with topic branches. Do not forget to
167
+ provide specs to your contribution.
168
+
169
+
170
+ ### Running specs
171
+
172
+ * Fork and clone the repository.
173
+ * Run `gem install bundler` to get the latest for the gemset.
174
+ * Run `bundle install` for dependencies.
175
+ * Run `bundle exec guard` and press enter to execute all specs.
176
+
177
+
178
+ ## Spec guidelines
179
+
180
+ Follow [rspec best practices](https://docs.google.com/document/d/1gi00-wwPaLk5VvoAJhBVNh9Htw4Rwmj-Ut88T4M2MwI/edit?hl=en#) guidelines.
181
+
182
+
183
+ ## Coding guidelines
184
+
185
+ Follow [github](https://github.com/styleguide/) guidelines.
186
+
187
+
188
+ ## Feedback
189
+
190
+ Use the [issue tracker](http://github.com/lelylan/lelylan-rb/issues) for bugs.
191
+ [Mail](mailto:touch@lelylan.com) or [Tweet](http://twitter.com/lelylan) us for any idea that can improve the project.
192
+
193
+
194
+ ## Links
195
+
196
+ * [GIT Repository](http://github.com/lelylan/lelylan-rb)
197
+ * [Lelylan Dev Center](http://dev.lelylan.com)
198
+ * [Lelylan Site](http://lelylan.com)
199
+
200
+
201
+ ## Authors
202
+
203
+ [Andrea Reginato](http://twitter.com/andreareginato)
204
+
205
+
206
+ ## Contributors
207
+
208
+ Special thanks to the following people for submitting patches.
209
+
210
+
211
+ ## Changelog
212
+
213
+ See [CHANGELOG](people/blob/master/CHANGELOG.md)
214
+
215
+
216
+ ## Copyright
217
+
218
+ Copyright (c) 2013 [Lelylan](http://lelylan.com). See [LICENSE](people/blob/master/LICENSE.md) for details.
@@ -0,0 +1,21 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task :test => :spec
8
+ task :default => :spec
9
+
10
+ namespace :doc do
11
+ require 'yard'
12
+ YARD::Rake::YardocTask.new do |task|
13
+ task.files = ['README.md', 'CHANGELOG.md', 'lib/lelylan/client/**/*.rb']
14
+ task.options = [
15
+ '--plugin', 'yard-tomdoc',
16
+ '--markup-provider', 'redcarpet',
17
+ '--markup', 'markdown',
18
+ '--output-dir', 'doc'
19
+ ]
20
+ end
21
+ end
@@ -0,0 +1,36 @@
1
+ # encoding: utf-8
2
+ require File.expand_path('../lib/lelylan/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.add_dependency 'addressable', '~> 2.2'
6
+ gem.add_dependency 'oauth2', '~> 0.8'
7
+ gem.add_dependency 'faraday', '~> 0.8'
8
+ gem.add_dependency 'faraday_middleware', '~> 0.8'
9
+ gem.add_dependency 'hashie', '~> 1.2'
10
+ gem.add_dependency 'multi_json', '~> 1.3'
11
+ gem.add_development_dependency 'json'
12
+ gem.add_development_dependency 'maruku'
13
+ gem.add_development_dependency 'rake'
14
+ gem.add_development_dependency 'rspec'
15
+ gem.add_development_dependency 'simplecov'
16
+ gem.add_development_dependency 'webmock'
17
+ gem.add_development_dependency 'guard-rspec'
18
+ gem.add_development_dependency 'fuubar'
19
+ gem.add_development_dependency 'growl'
20
+ gem.add_development_dependency 'yard'
21
+ gem.add_development_dependency 'yard-tomdoc'
22
+ gem.add_development_dependency 'redcarpet'
23
+ gem.add_development_dependency 'github-markup'
24
+ gem.authors = ["Andrea Reginato"]
25
+ gem.description = %q{Ruby wrapper for Lelylan API}
26
+ gem.email = ['touch@lelylan.com']
27
+ gem.files = `git ls-files`.split("\n")
28
+ gem.homepage = 'https://github.com/lelylan/lelylan-rb'
29
+ gem.name = 'lelylan-rb'
30
+ gem.platform = Gem::Platform::RUBY
31
+ gem.require_paths = ['lib']
32
+ gem.required_rubygems_version = Gem::Requirement.new('>= 1.3.6')
33
+ gem.summary = gem.description
34
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
35
+ gem.version = Lelylan::Version
36
+ end
@@ -0,0 +1,35 @@
1
+ require 'faraday'
2
+ require 'multi_json'
3
+
4
+ module Faraday
5
+ class Response::RaiseHttpError < Response::Middleware
6
+ def on_complete(response)
7
+ case response[:status].to_i
8
+ when 400
9
+ raise Lelylan::BadRequest, error_message(response)
10
+ when 401
11
+ raise Lelylan::Unauthorized, error_message(response)
12
+ when 403
13
+ raise Lelylan::Forbidden, error_message(response)
14
+ when 404
15
+ raise Lelylan::NotFound, error_message(response)
16
+ when 406
17
+ raise Lelylan::NotAcceptable, error_message(response)
18
+ when 422
19
+ raise Lelylan::UnprocessableEntity, error_message(response)
20
+ when 500
21
+ raise Lelylan::InternalServerError, error_message(response)
22
+ when 501
23
+ raise Lelylan::NotImplemented, error_message(response)
24
+ when 502
25
+ raise Lelylan::BadGateway, error_message(response)
26
+ when 503
27
+ raise Lelylan::ServiceUnavailable, error_message(response)
28
+ end
29
+ end
30
+
31
+ def error_message(response)
32
+ response[:body]
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,26 @@
1
+ require 'lelylan/configuration'
2
+ require 'lelylan/client'
3
+ require 'lelylan/error'
4
+ require 'oauth2'
5
+
6
+ module Lelylan
7
+ extend Configuration
8
+
9
+ class << self
10
+
11
+ # Alias for Lelylan::Client.new
12
+ def new(options={})
13
+ Lelylan::Client.new(options)
14
+ end
15
+
16
+ # Delegate to Lelylan::Client.new
17
+ def method_missing(method, *args, &block)
18
+ return super unless new.respond_to?(method)
19
+ new.send(method, *args, &block)
20
+ end
21
+
22
+ def respond_to?(method, include_private=false)
23
+ new.respond_to?(method, include_private) || super(method, include_private)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,11 @@
1
+ module Lelylan
2
+ module Authentication
3
+ def authentication
4
+ token ? { token: token } : {}
5
+ end
6
+
7
+ def authenticated?
8
+ !authentication.empty?
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,47 @@
1
+ require 'lelylan/authentication'
2
+ require 'lelylan/connection'
3
+ require 'lelylan/request'
4
+
5
+ require 'lelylan/client/devices'
6
+ require 'lelylan/client/consumptions'
7
+ require 'lelylan/client/histories'
8
+ require 'lelylan/client/types'
9
+ require 'lelylan/client/properties'
10
+ require 'lelylan/client/functions'
11
+ require 'lelylan/client/statuses'
12
+ require 'lelylan/client/categories'
13
+ require 'lelylan/client/locations'
14
+
15
+ module Lelylan
16
+ class Client
17
+ attr_accessor(*Configuration::VALID_OPTIONS_KEYS)
18
+
19
+ def initialize(options={})
20
+ options = Lelylan.options.merge(options)
21
+ Configuration::VALID_OPTIONS_KEYS.each do |key|
22
+ send("#{key}=", options[key])
23
+ end
24
+ end
25
+
26
+ # helper method
27
+ def find_id(uri)
28
+ Addressable::URI.parse(uri).basename
29
+ end
30
+
31
+ # structure related
32
+ include Lelylan::Authentication
33
+ include Lelylan::Connection
34
+ include Lelylan::Request
35
+
36
+ # client related
37
+ include Lelylan::Client::Devices
38
+ include Lelylan::Client::Consumptions
39
+ include Lelylan::Client::Histories
40
+ include Lelylan::Client::Types
41
+ include Lelylan::Client::Properties
42
+ include Lelylan::Client::Functions
43
+ include Lelylan::Client::Statuses
44
+ include Lelylan::Client::Categories
45
+ include Lelylan::Client::Locations
46
+ end
47
+ end