lelylan-rb 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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