helium-ruby 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -0
  3. data/README.md +3 -3
  4. data/docs/Helium.html +4 -4
  5. data/docs/Helium/Client.html +9 -9
  6. data/docs/Helium/Client/Elements.html +8 -110
  7. data/docs/Helium/Client/Http.html +31 -33
  8. data/docs/Helium/Client/Labels.html +38 -218
  9. data/docs/Helium/Client/Organizations.html +1 -1
  10. data/docs/Helium/Client/Sensors.html +30 -214
  11. data/docs/Helium/Client/Users.html +1 -1
  12. data/docs/Helium/ClientError.html +153 -0
  13. data/docs/Helium/Cursor.html +8 -8
  14. data/docs/Helium/DataPoint.html +9 -9
  15. data/docs/Helium/Element.html +16 -79
  16. data/docs/Helium/Error.html +267 -0
  17. data/docs/Helium/InvalidApiKey.html +157 -0
  18. data/docs/Helium/Label.html +29 -133
  19. data/docs/Helium/Organization.html +8 -8
  20. data/docs/Helium/Resource.html +717 -43
  21. data/docs/Helium/Sensor.html +31 -132
  22. data/docs/Helium/User.html +8 -8
  23. data/docs/Helium/Utils.html +1 -1
  24. data/docs/_index.html +33 -4
  25. data/docs/class_list.html +1 -1
  26. data/docs/file.README.html +4 -4
  27. data/docs/index.html +4 -4
  28. data/docs/method_list.html +112 -144
  29. data/docs/top-level-namespace.html +1 -1
  30. data/lib/helium.rb +1 -0
  31. data/lib/helium/client.rb +3 -3
  32. data/lib/helium/client/elements.rb +10 -27
  33. data/lib/helium/client/http.rb +38 -19
  34. data/lib/helium/client/labels.rb +7 -53
  35. data/lib/helium/client/sensors.rb +5 -54
  36. data/lib/helium/cursor.rb +6 -6
  37. data/lib/helium/data_point.rb +5 -5
  38. data/lib/helium/element.rb +7 -8
  39. data/lib/helium/error.rb +28 -0
  40. data/lib/helium/label.rb +3 -11
  41. data/lib/helium/organization.rb +4 -4
  42. data/lib/helium/resource.rb +103 -5
  43. data/lib/helium/sensor.rb +13 -15
  44. data/lib/helium/user.rb +4 -4
  45. data/lib/helium/version.rb +1 -1
  46. metadata +6 -2
@@ -102,7 +102,7 @@
102
102
  </div>
103
103
 
104
104
  <div id="footer">
105
- Generated on Mon Aug 22 15:52:19 2016 by
105
+ Generated on Wed Aug 24 13:22:50 2016 by
106
106
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
107
107
  0.9.3 (ruby-2.3.1).
108
108
  </div>
@@ -3,6 +3,7 @@ require 'json'
3
3
  require 'date'
4
4
 
5
5
  require "helium/version"
6
+ require "helium/error"
6
7
  require "helium/utils"
7
8
  require "helium/client"
8
9
  require "helium/cursor"
@@ -17,9 +17,9 @@ module Helium
17
17
 
18
18
  attr_accessor :api_key
19
19
 
20
- def initialize(api_key:, debug: false)
21
- @api_key = api_key
22
- @debug = debug
20
+ def initialize(opts = {})
21
+ @api_key = opts.fetch(:api_key)
22
+ @debug = opts.fetch(:debug, false)
23
23
  end
24
24
 
25
25
  def inspect
@@ -2,40 +2,23 @@ module Helium
2
2
  class Client
3
3
  module Elements
4
4
  def elements
5
- response = get('/element')
6
- elements_data = JSON.parse(response.body)["data"]
7
-
8
- elements = elements_data.map do |element_data|
9
- Element.new(client: self, params: element_data)
10
- end
11
-
12
- return elements
5
+ Element.all(client: self)
13
6
  end
14
7
 
15
8
  def element(id)
16
- response = get("/element/#{id}")
17
- element_data = JSON.parse(response.body)["data"]
18
-
19
- return Element.new(client: self, params: element_data)
9
+ Element.find(id, client: self)
20
10
  end
21
11
 
22
- def update_element(element, name:)
23
- path = "/element/#{element.id}"
24
-
25
- body = {
26
- data: {
27
- attributes: {
28
- name: name
29
- },
30
- id: element.id,
31
- type: "element"
32
- }
33
- }
12
+ def element_sensors(element)
13
+ path = "/element/#{element.id}?include=sensor"
14
+ response = get(path)
15
+ sensors_data = JSON.parse(response.body)["included"]
34
16
 
35
- response = patch(path, body: body)
36
- element_data = JSON.parse(response.body)["data"]
17
+ sensors = sensors_data.map do |sensor|
18
+ Sensor.new(client: self, params: sensor)
19
+ end
37
20
 
38
- return Element.new(client: self, params: element_data)
21
+ return sensors
39
22
  end
40
23
  end
41
24
  end
@@ -11,28 +11,27 @@ module Helium
11
11
  'User-Agent' => 'helium-ruby'
12
12
  }
13
13
 
14
- def get(path = nil, url: nil, params: {})
15
- request = generate_request(path, url: url, method: :get, params: params)
16
- run(request)
14
+ def get(path, opts = {})
15
+ run(path, :get, opts)
17
16
  end
18
17
 
19
- def paginated_get(path, klass:, params: {})
18
+ def paginated_get(path, opts = {})
19
+ klass = opts.fetch(:klass)
20
+ params = opts.fetch(:params, {})
21
+
20
22
  Cursor.new(client: self, path: path, klass: klass, params: params)
21
23
  end
22
24
 
23
- def post(path, body: {})
24
- request = generate_request(path, method: :post, body: body)
25
- run(request)
25
+ def post(path, opts = {})
26
+ run(path, :post, opts)
26
27
  end
27
28
 
28
- def patch(path, body: {})
29
- request = generate_request(path, method: :patch, body: body)
30
- run(request)
29
+ def patch(path, opts = {})
30
+ run(path, :patch, opts)
31
31
  end
32
32
 
33
33
  def delete(path)
34
- request = generate_request(path, method: :delete)
35
- response = run(request)
34
+ response = run(path, :delete)
36
35
  response.code == 204
37
36
  end
38
37
 
@@ -44,9 +43,24 @@ module Helium
44
43
  })
45
44
  end
46
45
 
47
- def generate_request(path = nil, url: nil, method:, params: {}, body: {})
48
- path = path.gsub(/^\//, '') if path
49
- url ||= "#{PROTOCOL}://#{HOST}/v#{API_VERSION}/#{path}"
46
+ def run(path, method, opts = {})
47
+ request = generate_request(path, opts.merge(method: method))
48
+ response = run_request(request)
49
+ return response
50
+ end
51
+
52
+ def generate_request(path, opts = {})
53
+ method = opts.fetch(:method)
54
+ params = opts.fetch(:params, {})
55
+ body = opts.fetch(:body, {})
56
+
57
+
58
+ url = if path =~ /^http/
59
+ path
60
+ else
61
+ path = path.gsub(/^\//, '')
62
+ "#{PROTOCOL}://#{HOST}/v#{API_VERSION}/#{path}"
63
+ end
50
64
 
51
65
  Typhoeus::Request.new(url, {
52
66
  method: method,
@@ -56,19 +70,24 @@ module Helium
56
70
  })
57
71
  end
58
72
 
59
- def run(request)
73
+ def run_request(request)
60
74
  request.run()
61
75
 
76
+ response = request.response
77
+
62
78
  if debug?
63
79
  method = request.options[:method]
64
80
  puts "#{method.upcase} #{request.url} #{request.response.code} #{request.response.total_time}"
65
81
  # puts request.response.body
66
82
  end
67
83
 
68
- # TODO error handling
69
- # halt(request.response.code, "Helium Get Failed: #{request.response.code.to_s}") unless request.response.code.between?(200,399)\
84
+ halt(response) unless response.code.between?(200,399)
85
+
86
+ return response
87
+ end
70
88
 
71
- return request.response
89
+ def halt(response)
90
+ raise Helium::Error.from_response(response)
72
91
  end
73
92
  end
74
93
  end
@@ -2,63 +2,15 @@ module Helium
2
2
  class Client
3
3
  module Labels
4
4
  def labels
5
- response = get('/label')
6
- labels_data = JSON.parse(response.body)["data"]
7
-
8
- labels = labels_data.map do |label_data|
9
- Label.new(client: self, params: label_data)
10
- end
11
-
12
- return labels
5
+ Label.all(client: self)
13
6
  end
14
7
 
15
8
  def label(id)
16
- response = get("/label/#{id}")
17
- label_data = JSON.parse(response.body)["data"]
18
-
19
- return Label.new(client: self, params: label_data)
20
- end
21
-
22
- def new_label(name:)
23
- path = "/label"
24
-
25
- body = {
26
- data: {
27
- attributes: {
28
- name: name
29
- },
30
- type: "label"
31
- }
32
- }
33
-
34
- response = post(path, body: body)
35
- label_data = JSON.parse(response.body)["data"]
36
-
37
- return Label.new(client: self, params: label_data)
9
+ Label.find(id, client: self)
38
10
  end
39
11
 
40
- def update_label(label, name:)
41
- path = "/label/#{label.id}"
42
-
43
- body = {
44
- data: {
45
- attributes: {
46
- name: name
47
- },
48
- id: label.id,
49
- type: "label"
50
- }
51
- }
52
-
53
- response = patch(path, body: body)
54
- label_data = JSON.parse(response.body)["data"]
55
-
56
- return Label.new(client: self, params: label_data)
57
- end
58
-
59
- def delete_label(label)
60
- path = "/label/#{label.id}"
61
- delete(path)
12
+ def create_label(attributes)
13
+ Label.create(attributes, client: self)
62
14
  end
63
15
 
64
16
  def label_sensors(label)
@@ -73,7 +25,9 @@ module Helium
73
25
  return sensors
74
26
  end
75
27
 
76
- def update_label_sensors(label, sensors: [])
28
+ def update_label_sensors(label, opts = {})
29
+ sensors = opts.fetch(:sensors, [])
30
+
77
31
  path = "/label/#{label.id}/relationships/sensor"
78
32
 
79
33
  sensors = Array(sensors)
@@ -2,21 +2,11 @@ module Helium
2
2
  class Client
3
3
  module Sensors
4
4
  def sensors
5
- response = get('/sensor')
6
- sensors_data = JSON.parse(response.body)["data"]
7
-
8
- sensors = sensors_data.map do |sensor_data|
9
- Sensor.new(client: self, params: sensor_data)
10
- end
11
-
12
- return sensors
5
+ Sensor.all(client: self)
13
6
  end
14
7
 
15
8
  def sensor(id)
16
- response = get("/sensor/#{id}")
17
- sensor_data = JSON.parse(response.body)["data"]
18
-
19
- return Sensor.new(client: self, params: sensor_data)
9
+ Sensor.find(id, client: self)
20
10
  end
21
11
 
22
12
  def sensor_timeseries(sensor, opts = {})
@@ -29,53 +19,14 @@ module Helium
29
19
  "filter[end]" => datetime_to_iso(opts.fetch(:end_time, nil)),
30
20
  "agg[type]" => opts.fetch(:aggtype),
31
21
  "agg[size]" => opts.fetch(:aggsize)
32
- }.delete_if { |key, value| value.to_s.empty? }
22
+ }.delete_if { |_key, value| value.to_s.empty? }
33
23
 
34
24
  paginated_get(path, klass: Helium::DataPoint, params: params)
35
25
  end
36
26
 
37
- def new_sensor(name:)
38
- path = "/sensor"
39
-
40
- body = {
41
- data: {
42
- attributes: {
43
- name: name
44
- },
45
- type: "sensor"
46
- }
47
- }
48
-
49
- response = post(path, body: body)
50
- sensor_data = JSON.parse(response.body)["data"]
51
-
52
- return Sensor.new(client: self, params: sensor_data)
53
- end
54
-
55
- def update_sensor(sensor, name:)
56
- path = "/sensor/#{sensor.id}"
57
-
58
- body = {
59
- data: {
60
- attributes: {
61
- name: name
62
- },
63
- id: sensor.id,
64
- type: "sensor"
65
- }
66
- }
67
-
68
- response = patch(path, body: body)
69
- sensor_data = JSON.parse(response.body)["data"]
70
-
71
- return Sensor.new(client: self, params: sensor_data)
27
+ def create_sensor(attributes)
28
+ Sensor.create(attributes, client: self)
72
29
  end
73
-
74
- def delete_sensor(sensor)
75
- path = "/sensor/#{sensor.id}"
76
- delete(path)
77
- end
78
-
79
30
  end
80
31
  end
81
32
  end
@@ -2,11 +2,11 @@ module Helium
2
2
  class Cursor
3
3
  include Enumerable
4
4
 
5
- def initialize(client:, path:, klass:, params: {})
6
- @client = client
7
- @path = path
8
- @klass = klass
9
- @params = params
5
+ def initialize(opts = {})
6
+ @client = opts.fetch(:client)
7
+ @path = opts.fetch(:path)
8
+ @klass = opts.fetch(:klass)
9
+ @params = opts.fetch(:params, {})
10
10
 
11
11
  @collection = []
12
12
  @next_link = nil
@@ -37,7 +37,7 @@ module Helium
37
37
 
38
38
  def fetch_next_page
39
39
  if @next_link
40
- response = @client.get(url: @next_link)
40
+ response = @client.get(@next_link)
41
41
  else
42
42
  response = @client.get(@path, params: @params)
43
43
  end
@@ -2,12 +2,12 @@ module Helium
2
2
  class DataPoint < Resource
3
3
  attr_reader :timestamp, :value, :port
4
4
 
5
- def initialize(client:, params:)
6
- super(client: client, params: params)
5
+ def initialize(opts = {})
6
+ super(opts)
7
7
 
8
- @timestamp = params.dig("attributes", "timestamp")
9
- @value = params.dig("attributes", "value")
10
- @port = params.dig("attributes", "port")
8
+ @timestamp = @params.dig("attributes", "timestamp")
9
+ @value = @params.dig("attributes", "value")
10
+ @port = @params.dig("attributes", "port")
11
11
  end
12
12
 
13
13
  def timestamp
@@ -2,17 +2,16 @@ module Helium
2
2
  class Element < Resource
3
3
  attr_reader :name, :mac, :versions
4
4
 
5
- def initialize(client:, params:)
6
- super(client: client, params: params)
5
+ def initialize(opts = {})
6
+ super(opts)
7
7
 
8
- @name = params.dig("attributes", "name")
9
- @mac = params.dig("meta", "mac")
10
- @versions = params.dig("meta", "versions")
8
+ @name = @params.dig("attributes", "name")
9
+ @mac = @params.dig("meta", "mac")
10
+ @versions = @params.dig("meta", "versions")
11
11
  end
12
12
 
13
- # TODO these kinds of methods should be generalized into a Resource object
14
- def update(name:)
15
- @client.update_element(self, name: name)
13
+ def sensors
14
+ @client.element_sensors(self)
16
15
  end
17
16
 
18
17
  # TODO can probably generalize this a bit more
@@ -0,0 +1,28 @@
1
+ module Helium
2
+ # Custom error class for rescuing from Helium API errors
3
+ class Error < StandardError
4
+
5
+ # Returns the appropriate Helium::Error subclass based on status and
6
+ # response message
7
+ #
8
+ # @param [Typhoeus::Response] response
9
+ # @return [Helium::Error]
10
+ def self.from_response(response)
11
+ status = response.code
12
+ message = JSON.parse(response.body)["errors"].first["detail"]
13
+
14
+ klass = case status
15
+ when 401 then Helium::InvalidApiKey
16
+ else self
17
+ end
18
+
19
+ klass.new(message)
20
+ end
21
+ end
22
+
23
+ # Raised on errors in the 400-499 range
24
+ class ClientError < Error; end
25
+
26
+ # Raised when Helium returns a 401 error
27
+ class InvalidApiKey < ClientError; end
28
+ end
@@ -2,18 +2,10 @@ module Helium
2
2
  class Label < Resource
3
3
  attr_reader :name
4
4
 
5
- def initialize(client:, params:)
6
- super(client: client, params: params)
5
+ def initialize(opts = {})
6
+ super(opts)
7
7
 
8
- @name = params.dig("attributes", "name")
9
- end
10
-
11
- def update(name:)
12
- @client.update_label(self, name: name)
13
- end
14
-
15
- def destroy
16
- @client.delete_label(self)
8
+ @name = @params.dig("attributes", "name")
17
9
  end
18
10
 
19
11
  # TODO: would be nice to wrap this in a proxy collection, that way