lifx-http 0.2.0
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.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +87 -0
- data/LICENSE +23 -0
- data/README.md +51 -0
- data/bin/lifx-http +31 -0
- data/doc.png +0 -0
- data/lib/lifx-http.rb +192 -0
- data/lib/lifx-http/method_override.rb +29 -0
- data/lib/lifx-http/version.rb +3 -0
- data/lifx-http.gemspec +30 -0
- data/start.sh +3 -0
- metadata +170 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 865b3dc88e318a175a2150d10de44183d9ea9c39
|
4
|
+
data.tar.gz: 2b34e96d9020ddd814fa3b7ebee607784e3e5296
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7cee8f7b1766ab4ed48ddeefb97a2e12f7aaf2d86ab6ad183ed14c508c509ab048dc6d0cbb020d64153a0646df5ae22a61f6835c9ac8b4ed614edfaf59fcbbe4
|
7
|
+
data.tar.gz: 5296e1ca15be060808e0beac32416e329ce592a2a7e599c448af18cd436409e7ad1b86ce77e17902c88c45c587b32c21120a107e3c70ee3ee1f1e1f69c0c739a
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
lifx-http (0.2.0)
|
5
|
+
grape (~> 0.6)
|
6
|
+
grape-entity (~> 0.4)
|
7
|
+
grape-swagger (~> 0.7)
|
8
|
+
lifx (= 0.4.5)
|
9
|
+
rack (~> 1.5)
|
10
|
+
rack-cors (~> 0.2)
|
11
|
+
|
12
|
+
GEM
|
13
|
+
remote: https://rubygems.org/
|
14
|
+
specs:
|
15
|
+
activesupport (4.0.4)
|
16
|
+
i18n (~> 0.6, >= 0.6.9)
|
17
|
+
minitest (~> 4.2)
|
18
|
+
multi_json (~> 1.3)
|
19
|
+
thread_safe (~> 0.1)
|
20
|
+
tzinfo (~> 0.3.37)
|
21
|
+
atomic (1.1.16)
|
22
|
+
axiom-types (0.1.1)
|
23
|
+
descendants_tracker (~> 0.0.4)
|
24
|
+
ice_nine (~> 0.11.0)
|
25
|
+
thread_safe (~> 0.3, >= 0.3.1)
|
26
|
+
bindata (2.0.0)
|
27
|
+
builder (3.2.2)
|
28
|
+
coercible (1.0.0)
|
29
|
+
descendants_tracker (~> 0.0.1)
|
30
|
+
configatron (3.0.2)
|
31
|
+
descendants_tracker (0.0.4)
|
32
|
+
thread_safe (~> 0.3, >= 0.3.1)
|
33
|
+
equalizer (0.0.9)
|
34
|
+
grape (0.6.1)
|
35
|
+
activesupport
|
36
|
+
builder
|
37
|
+
hashie (>= 1.2.0)
|
38
|
+
multi_json (>= 1.3.2)
|
39
|
+
multi_xml (>= 0.5.2)
|
40
|
+
rack (>= 1.3.0)
|
41
|
+
rack-accept
|
42
|
+
rack-mount
|
43
|
+
virtus (>= 1.0.0)
|
44
|
+
grape-entity (0.4.1)
|
45
|
+
activesupport
|
46
|
+
multi_json (>= 1.3.2)
|
47
|
+
grape-swagger (0.7.2)
|
48
|
+
grape (>= 0.2.0)
|
49
|
+
grape-entity (>= 0.3.0)
|
50
|
+
kramdown (>= 1.3.1)
|
51
|
+
hashie (2.0.5)
|
52
|
+
i18n (0.6.9)
|
53
|
+
ice_nine (0.11.0)
|
54
|
+
kramdown (1.3.3)
|
55
|
+
lifx (0.4.5)
|
56
|
+
bindata (~> 2.0)
|
57
|
+
configatron (~> 3.0)
|
58
|
+
timers (~> 1.0)
|
59
|
+
yell (~> 2.0)
|
60
|
+
minitest (4.7.5)
|
61
|
+
multi_json (1.9.2)
|
62
|
+
multi_xml (0.5.5)
|
63
|
+
rack (1.5.2)
|
64
|
+
rack-accept (0.4.5)
|
65
|
+
rack (>= 0.4)
|
66
|
+
rack-cors (0.2.9)
|
67
|
+
rack-mount (0.8.3)
|
68
|
+
rack (>= 1.0.0)
|
69
|
+
rake (10.2.2)
|
70
|
+
thread_safe (0.3.1)
|
71
|
+
atomic (>= 1.1.7, < 2)
|
72
|
+
timers (1.1.0)
|
73
|
+
tzinfo (0.3.39)
|
74
|
+
virtus (1.0.2)
|
75
|
+
axiom-types (~> 0.1)
|
76
|
+
coercible (~> 1.0)
|
77
|
+
descendants_tracker (~> 0.0.3)
|
78
|
+
equalizer (~> 0.0.9)
|
79
|
+
yell (2.0.4)
|
80
|
+
|
81
|
+
PLATFORMS
|
82
|
+
ruby
|
83
|
+
|
84
|
+
DEPENDENCIES
|
85
|
+
bundler (~> 1.3)
|
86
|
+
lifx-http!
|
87
|
+
rake (~> 10.1)
|
data/LICENSE
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
Copyright (c) 2014 Jack "chendo" Chen
|
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.
|
23
|
+
|
data/README.md
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# LIFX HTTP API
|
2
|
+
|
3
|
+
[](https://rubygems.org/gems/lifx-http)
|
4
|
+
|
5
|
+
This is an **unofficial** JSON RESTful API service for controlling LIFX devices. This API adds some reliability that the [LIFX gem](https://github.com/LIFX/lifx-gem) does not include.
|
6
|
+
|
7
|
+
## Requirements
|
8
|
+
|
9
|
+
* Ruby 2.0+
|
10
|
+
* Tested on OS X Mavericks, but should work for other *nix platforms.
|
11
|
+
|
12
|
+
## Usage
|
13
|
+
|
14
|
+
* Install the gem: `gem install lifx-http`
|
15
|
+
* Run in foreground (no daemonizing yet): `lifx-http`
|
16
|
+
* Test if working: `curl http://localhost:56780/lights.json`
|
17
|
+
* Toggle all lights: `curl -XPUT http://localhost:56780/lights/all/toggle`
|
18
|
+
* Set all lights to green:
|
19
|
+
* URL params: `curl -XPUT http://localhost:56780/lights/all/color?hue=120&saturation=1&brightness=1&duration=2 -d ''`
|
20
|
+
* JSON body: `curl -XPUT http://localhost:56780/lights/all/color -H "Content-Type: application/json" -d '{"hue": 120, "saturation": 1, "brightness": 1, "duration":2}'`
|
21
|
+
* Override method by setting `_method`: `curl http://localhost:56780/lights/all/color?hue=120&saturation=1&brightness=1&duration=2&_method=put`
|
22
|
+
|
23
|
+
|
24
|
+
## API
|
25
|
+
|
26
|
+
* `selector` is either:
|
27
|
+
* `all` for all lights
|
28
|
+
* `label:[label]` for light with label `label`
|
29
|
+
* `tag:[tag]` for lights with tag `tag`
|
30
|
+
* `[light_id]` for light with id `light_id`
|
31
|
+
* `GET /lights` - Lists all lights
|
32
|
+
* `GET /lights/{selector}` - Lists lights matching `selector`
|
33
|
+
* `PUT /lights/{selector}/on` - Turns lights matching `selector` on
|
34
|
+
* `PUT /lights/{selector}/off` - Turns lights matching `selector` off
|
35
|
+
* `PUT /lights/{selector}/toggle` - Toggle lights matching `selector`. If any lights in `selector` is on, it will turn them off
|
36
|
+
* `PUT /lights/{selector}/color` - Sets the color for lights matching `selector`. Color data can be passed as URL parameters or form parameters (JSON)
|
37
|
+
* `PUT /lights/{light_id}/label` - Changes the label of light with id `light_id`
|
38
|
+
* `POST /lights/{light_id}/tag` - Adds a tag to the light
|
39
|
+
* `DELETE /lights/{light_id}/tag` - Removes a tag from the light
|
40
|
+
|
41
|
+
## Documentation
|
42
|
+
|
43
|
+
This API is documented using [Swagger](https://github.com/wordnik/swagger-ui).
|
44
|
+
To view documentation and play with the API, start the API server locally, then visit http://swagger.wordnik.com and put `http://localhost:3000/swagger_doc.json` in the first text box, then hit `Explore`.
|
45
|
+
|
46
|
+
You should see something like this:
|
47
|
+

|
48
|
+
|
49
|
+
## License
|
50
|
+
|
51
|
+
MIT. See [LICENSE](LICENSE)
|
data/bin/lifx-http
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "lifx-http"
|
3
|
+
require "rack/cors"
|
4
|
+
require "lifx-http/method_override"
|
5
|
+
require "webrick"
|
6
|
+
require "optparse"
|
7
|
+
|
8
|
+
options = {
|
9
|
+
port: 56780
|
10
|
+
}
|
11
|
+
OptionParser.new do |parser|
|
12
|
+
parser.banner = "Usage: lifx-http [options]"
|
13
|
+
parser.version = LIFXHTTP::VERSION
|
14
|
+
parser.on("-p PORT", "--port PORT", "Specify the port to run lifx-http on. Defaults to #{options[:port]}") do |port|
|
15
|
+
options[:port] = port.to_i
|
16
|
+
end
|
17
|
+
end.parse!
|
18
|
+
|
19
|
+
app = Rack::Builder.new do
|
20
|
+
use LIFXHTTP::MethodOverride
|
21
|
+
use Rack::Cors do
|
22
|
+
allow do
|
23
|
+
origins '*'
|
24
|
+
resource '*', headers: :any, methods: [:get, :post, :put, :delete, :options]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
run LIFXHTTP::API
|
29
|
+
end
|
30
|
+
|
31
|
+
Rack::Handler::WEBrick.run(app, Port: options[:port])
|
data/doc.png
ADDED
Binary file
|
data/lib/lifx-http.rb
ADDED
@@ -0,0 +1,192 @@
|
|
1
|
+
require 'grape'
|
2
|
+
require 'grape-entity'
|
3
|
+
require 'grape-swagger'
|
4
|
+
require 'lifx'
|
5
|
+
|
6
|
+
LIFX::Client.lan.discover
|
7
|
+
|
8
|
+
module LIFXHTTP
|
9
|
+
class API < Grape::API
|
10
|
+
module Entities
|
11
|
+
class Light < Grape::Entity
|
12
|
+
format_with(:iso_timestamp) { |dt| dt.iso8601 }
|
13
|
+
expose :id
|
14
|
+
expose :label do |light, options|
|
15
|
+
light.label(fetch: false)
|
16
|
+
end
|
17
|
+
expose :site_id
|
18
|
+
expose :tags
|
19
|
+
expose :on do |light, options|
|
20
|
+
light.on?(fetch: false)
|
21
|
+
end
|
22
|
+
expose :color
|
23
|
+
expose :last_seen
|
24
|
+
expose :seconds_since_seen
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
format :json
|
29
|
+
default_format :json
|
30
|
+
helpers do
|
31
|
+
def lifx
|
32
|
+
@lifx ||= LIFX::Client.lan
|
33
|
+
end
|
34
|
+
|
35
|
+
def ensure_light_target!
|
36
|
+
error!('Must target a single light', 400) unless @target.is_a?(LIFX::Light)
|
37
|
+
end
|
38
|
+
|
39
|
+
def present_target(target)
|
40
|
+
if target.is_a?(LIFX::LightCollection)
|
41
|
+
present target.to_a, with: Entities::Light
|
42
|
+
else
|
43
|
+
present target, with: Entities::Light
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def set_power(target, state)
|
48
|
+
if target.is_a?(LIFX::LightCollection)
|
49
|
+
wait_until -> { target.to_a.all? { |light| light.power(fetch: false) == state} }, retry_interval: 1, timeout: 10 do
|
50
|
+
target.set_power(state)
|
51
|
+
target.refresh
|
52
|
+
end
|
53
|
+
else
|
54
|
+
target.set_power!(state)
|
55
|
+
end
|
56
|
+
rescue Timeout::Error
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
def wait_until(condition_proc, timeout: 5, retry_interval: 0.5, &action_block)
|
61
|
+
Timeout.timeout(timeout) do
|
62
|
+
while !condition_proc.call
|
63
|
+
action_block.call if action_block
|
64
|
+
sleep(retry_interval)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
desc "List of all known lights"
|
71
|
+
get "lights" do
|
72
|
+
present_target(lifx.lights.lights)
|
73
|
+
end
|
74
|
+
|
75
|
+
resources :lights do
|
76
|
+
params do
|
77
|
+
requires :selector, type: String, desc: "Can be 'all', 'label:[label]', 'tag:[tag]' and '[light id]'"
|
78
|
+
end
|
79
|
+
|
80
|
+
namespace ":selector" do
|
81
|
+
after_validation do
|
82
|
+
selector = params[:selector]
|
83
|
+
case selector
|
84
|
+
when /^tag:(.+)$/
|
85
|
+
@target = lifx.lights.with_tag($1)
|
86
|
+
when /^label:(.+)$/
|
87
|
+
@target = lifx.lights.with_label($1)
|
88
|
+
when /^all$/
|
89
|
+
@target = lifx.lights
|
90
|
+
else
|
91
|
+
@target = lifx.lights.with_id(selector)
|
92
|
+
end
|
93
|
+
|
94
|
+
if @target.nil?
|
95
|
+
error! "Could not resolve selector: selector", 404
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
desc "Returns light(s) based on selector"
|
100
|
+
get do
|
101
|
+
present_target(@target)
|
102
|
+
end
|
103
|
+
|
104
|
+
desc "Turn light(s) on"
|
105
|
+
put :on do
|
106
|
+
set_power(@target, :on)
|
107
|
+
present_target(@target)
|
108
|
+
end
|
109
|
+
|
110
|
+
desc "Turn light(s) off"
|
111
|
+
put :off do
|
112
|
+
set_power(@target, :off)
|
113
|
+
present_target(@target)
|
114
|
+
end
|
115
|
+
|
116
|
+
desc "Toggle light(s) power state. Will turn lights off if any are on."
|
117
|
+
put :toggle do
|
118
|
+
if @target.is_a?(LIFX::LightCollection)
|
119
|
+
on = @target.to_a.any? { |light| light.on? }
|
120
|
+
desired_state = on ? :off : :on
|
121
|
+
set_power(@target, desired_state)
|
122
|
+
present_target(@target)
|
123
|
+
else
|
124
|
+
desired_state = @target.on? ? :off : :on
|
125
|
+
set_power(@target, desired_state)
|
126
|
+
present_target(@target)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
desc "Set colour of light(s)"
|
131
|
+
params do
|
132
|
+
requires :hue, type: Float, desc: "Hue: 0-360"
|
133
|
+
requires :saturation, type: Float, desc: "Saturation: 0-1"
|
134
|
+
requires :brightness, type: Float, desc: "Brightness: 0-1"
|
135
|
+
optional :kelvin, type: Integer, default: 3_500, desc: "Kelvin: 2500-10000. Defaults to 3500"
|
136
|
+
optional :duration, type: Float, default: 1, desc: "Duration in seconds. Defaults to 1.0"
|
137
|
+
end
|
138
|
+
put :color do
|
139
|
+
color = LIFX::Color.hsbk(
|
140
|
+
params[:hue],
|
141
|
+
params[:saturation],
|
142
|
+
params[:brightness],
|
143
|
+
params[:kelvin]
|
144
|
+
)
|
145
|
+
lifx.sync { 3.times { @target.set_color(color, duration: params[:duration]) } } # Retry
|
146
|
+
present_target(@target)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
params do
|
151
|
+
requires :light_id, type: String, desc: "Light ID"
|
152
|
+
end
|
153
|
+
namespace ":light_id" do
|
154
|
+
after_validation do
|
155
|
+
@target = lifx.lights.with_id(params[:light_id])
|
156
|
+
if @target.nil?
|
157
|
+
error!("Could not find light with ID: #{params[:light_id]}", 404)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
desc "Sets label on light"
|
161
|
+
params do
|
162
|
+
requires :label, type: String, regexp: /^.{,32}$/, desc: "Label"
|
163
|
+
end
|
164
|
+
put :label do
|
165
|
+
ensure_light_target!
|
166
|
+
present_target(@target.set_label(params[:label]))
|
167
|
+
end
|
168
|
+
|
169
|
+
desc "Adds a tag a light"
|
170
|
+
params do
|
171
|
+
requires :tag, type: String, regexp: /^.{1,32}$/, desc: "Tag"
|
172
|
+
end
|
173
|
+
post :tag do
|
174
|
+
ensure_light_target!
|
175
|
+
present_target(@target.add_tag(params[:tag]))
|
176
|
+
end
|
177
|
+
|
178
|
+
desc "Removes a tag from a light"
|
179
|
+
params do
|
180
|
+
requires :tag, type: String, regexp: /^.{1,32}$/, desc: "Tag"
|
181
|
+
end
|
182
|
+
delete :tag do
|
183
|
+
ensure_light_target!
|
184
|
+
present_target(@target.remove_tag(params[:tag]))
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
add_swagger_documentation(markdown: true)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
require "lifx-http/version"
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module LIFXHTTP
|
2
|
+
class MethodOverride
|
3
|
+
HTTP_METHODS = %w(GET HEAD PUT POST DELETE OPTIONS PATCH LINK UNLINK)
|
4
|
+
|
5
|
+
METHOD_OVERRIDE_PARAM_KEY = "_method".freeze
|
6
|
+
HTTP_METHOD_OVERRIDE_HEADER = "HTTP_X_HTTP_METHOD_OVERRIDE".freeze
|
7
|
+
|
8
|
+
def initialize(app)
|
9
|
+
@app = app
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(env)
|
13
|
+
method = method_override(env)
|
14
|
+
if HTTP_METHODS.include?(method)
|
15
|
+
env["rack.methodoverride.original_method"] = env["REQUEST_METHOD"]
|
16
|
+
env["REQUEST_METHOD"] = method
|
17
|
+
end
|
18
|
+
|
19
|
+
@app.call(env)
|
20
|
+
end
|
21
|
+
|
22
|
+
def method_override(env)
|
23
|
+
req = Rack::Request.new(env)
|
24
|
+
method = req.params[METHOD_OVERRIDE_PARAM_KEY] ||
|
25
|
+
env[HTTP_METHOD_OVERRIDE_HEADER]
|
26
|
+
method.to_s.upcase
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lifx-http.gemspec
ADDED
@@ -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 'lifx-http/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "lifx-http"
|
8
|
+
spec.version = LIFXHTTP::VERSION
|
9
|
+
spec.authors = ["Jack Chen (chendo)"]
|
10
|
+
spec.email = ["github+lifx-http@chen.do"]
|
11
|
+
spec.description = %q{A HTTP API for LIFX.}
|
12
|
+
spec.summary = %q{A HTTP API for interacting with LIFX devices.}
|
13
|
+
spec.homepage = "https://github.com/chendo/lifx-http"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/).reject { |f| f =~ /^script\// }
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
spec.required_ruby_version = ">= 2.0"
|
21
|
+
|
22
|
+
spec.add_dependency "rack", "~> 1.5"
|
23
|
+
spec.add_dependency "rack-cors", "~> 0.2"
|
24
|
+
spec.add_dependency "lifx", "= 0.4.5"
|
25
|
+
spec.add_dependency "grape", "~> 0.6"
|
26
|
+
spec.add_dependency "grape-entity", "~> 0.4"
|
27
|
+
spec.add_dependency "grape-swagger", "~> 0.7"
|
28
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
29
|
+
spec.add_development_dependency "rake", "~> 10.1"
|
30
|
+
end
|
data/start.sh
ADDED
metadata
ADDED
@@ -0,0 +1,170 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: lifx-http
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jack Chen (chendo)
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-03-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rack
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.5'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rack-cors
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.2'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.2'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: lifx
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.4.5
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.4.5
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: grape
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.6'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.6'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: grape-entity
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.4'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.4'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: grape-swagger
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.7'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.7'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: bundler
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '1.3'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '1.3'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rake
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '10.1'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '10.1'
|
125
|
+
description: A HTTP API for LIFX.
|
126
|
+
email:
|
127
|
+
- github+lifx-http@chen.do
|
128
|
+
executables:
|
129
|
+
- lifx-http
|
130
|
+
extensions: []
|
131
|
+
extra_rdoc_files: []
|
132
|
+
files:
|
133
|
+
- ".gitignore"
|
134
|
+
- Gemfile
|
135
|
+
- Gemfile.lock
|
136
|
+
- LICENSE
|
137
|
+
- README.md
|
138
|
+
- bin/lifx-http
|
139
|
+
- doc.png
|
140
|
+
- lib/lifx-http.rb
|
141
|
+
- lib/lifx-http/method_override.rb
|
142
|
+
- lib/lifx-http/version.rb
|
143
|
+
- lifx-http.gemspec
|
144
|
+
- start.sh
|
145
|
+
homepage: https://github.com/chendo/lifx-http
|
146
|
+
licenses:
|
147
|
+
- MIT
|
148
|
+
metadata: {}
|
149
|
+
post_install_message:
|
150
|
+
rdoc_options: []
|
151
|
+
require_paths:
|
152
|
+
- lib
|
153
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
154
|
+
requirements:
|
155
|
+
- - ">="
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '2.0'
|
158
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
159
|
+
requirements:
|
160
|
+
- - ">="
|
161
|
+
- !ruby/object:Gem::Version
|
162
|
+
version: '0'
|
163
|
+
requirements: []
|
164
|
+
rubyforge_project:
|
165
|
+
rubygems_version: 2.2.2
|
166
|
+
signing_key:
|
167
|
+
specification_version: 4
|
168
|
+
summary: A HTTP API for interacting with LIFX devices.
|
169
|
+
test_files: []
|
170
|
+
has_rdoc:
|