cs 0.1.1beta → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -7,10 +7,11 @@ module CS
7
7
  include HTTParty
8
8
 
9
9
  attr_accessor :response_body, :response_code, :response_headers, :errors
10
- attr_reader :session_id
10
+ attr_reader :session_id, :api_key
11
11
 
12
- def initialize(base_uri = nil)
12
+ def initialize(base_uri = nil, api_key = nil)
13
13
  self.base_uri = base_uri
14
+ @api_key = api_key
14
15
  @session_id = nil
15
16
  reset
16
17
  end
@@ -22,10 +23,23 @@ module CS
22
23
  @response_body
23
24
  end
24
25
 
26
+ def process_api_key(path)
27
+ return path if @api_key.nil?
28
+
29
+ if URI(path).query.nil?
30
+ path += "?API_KEY=#{@api_key}"
31
+ else
32
+ path += "&API_KEY=#{@api_key}"
33
+ end
34
+
35
+ path
36
+ end
37
+
25
38
  def get(path, query={}, headers = {})
26
39
  execute do
27
40
  headers = default_headers.merge(headers)
28
41
  options = {query: query, headers: headers}
42
+ path = process_api_key(path)
29
43
  self.class.get(path, options)
30
44
  end
31
45
  end
@@ -66,7 +80,7 @@ module CS
66
80
  header = self.class.default_options[:headers] || {}
67
81
  header.merge!({"Content-Type" => "application/json"})
68
82
  if @session_id
69
- header.merge!('X-SESSION_ID' => self.session_id)
83
+ header = header.merge('X-SESSION_ID' => self.session_id)
70
84
  end
71
85
  header
72
86
  end
@@ -79,18 +93,19 @@ module CS
79
93
  @session_id = session_id
80
94
  end
81
95
 
82
-
83
96
  # login to commonsense
84
97
  # @return [String] session_id
85
- def login(username, password)
86
- password = Digest::MD5.hexdigest password
98
+ def login(username, password, digest=true)
99
+ if digest
100
+ password = Digest::MD5.hexdigest password
101
+ end
87
102
  post('/login.json', {:username => username, :password => password})
88
103
 
89
104
  if @response_code == 200
90
105
  self.session_id = response_body['session_id']
91
106
  else
92
107
  self.session_id = false
93
- errors = [response_body['error']]
108
+ @errors = [response_body['error']]
94
109
  end
95
110
 
96
111
  session_id
@@ -104,6 +119,7 @@ module CS
104
119
  end
105
120
 
106
121
  def parse_response
122
+ return unless @response_body
107
123
  @response_code = @response_body.response.code.to_i
108
124
  @response_headers = @response_body.headers
109
125
  if @response_code >= 400
@@ -0,0 +1,29 @@
1
+ require 'yaml'
2
+
3
+ module CS
4
+ module CLI
5
+ class Config
6
+ @@config = {}
7
+ @@loaded = false
8
+ @@file = ""
9
+
10
+ def self.load_config(file="#{ENV['HOME']}/.cs.yml")
11
+ @@file = file
12
+ @@config = YAML.load_file(file)
13
+ @@loaded = true
14
+ end
15
+
16
+ def self.get(key=nil)
17
+ if !@@loaded
18
+ STDERR.puts("WARNING could not load '#{@@file}'. Is it exists ?")
19
+ end
20
+
21
+ if key.nil?
22
+ return @@config
23
+ else
24
+ return @@config[key.to_s]
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,7 @@
1
+ module CS
2
+ ##
3
+ # Module to handle Collection
4
+ module Collection
5
+
6
+ end
7
+ end
@@ -0,0 +1,62 @@
1
+ require 'delegate'
2
+
3
+ module CS
4
+ module Collection
5
+ class SensorDataCollection < SimpleDelegator
6
+ attr_accessor :session
7
+ attr_accessor :batch_size
8
+
9
+ def initialize(session=nil)
10
+ self.session = session
11
+ @batch_size = 1000
12
+ super([])
13
+ end
14
+
15
+ def save!
16
+ check_session!
17
+
18
+ # group batch
19
+ self.each_slice(@batch_size) do |batch|
20
+ body = process_batch(batch)
21
+ @session.post(get_url, body)
22
+ end
23
+ end
24
+
25
+ ##
26
+ # Given array of sensor data it will group the data by sensor_id
27
+ # and construct payload for multiple sensor upload
28
+ def process_batch(batch)
29
+ sensors = {}
30
+ batch.each do |point|
31
+ next if point.nil? || point.sensor_id.nil?
32
+ sensor_id = point.sensor_id
33
+
34
+ if !sensors[sensor_id]
35
+ sensors[sensor_id] = {
36
+ sensor_id: sensor_id,
37
+ data: []
38
+ }
39
+ end
40
+
41
+ sensors[sensor_id][:data].push(point.to_cs_value)
42
+ end
43
+
44
+ retval = []
45
+ sensors.each do |k, v|
46
+ retval.push(v)
47
+ end
48
+
49
+ {sensors: retval}
50
+ end
51
+
52
+ def get_url
53
+ "/sensors/data.json"
54
+ end
55
+
56
+ private
57
+ def check_session!
58
+ raise Error::SessionEmptyError unless @session
59
+ end
60
+ end
61
+ end
62
+ end
@@ -1,4 +1,6 @@
1
1
  require 'cs/serializer'
2
+ require 'set'
3
+
2
4
  module CS
3
5
  module EndPoint
4
6
  include CS::Serializer
@@ -0,0 +1,16 @@
1
+ module CS
2
+ module EndPoint
3
+ class Notification
4
+ include EndPoint
5
+
6
+ attribute :type, :text, :destination
7
+
8
+ resources "notifications"
9
+ resource "notification"
10
+
11
+ def initialize(hash={})
12
+ from_hash(hash)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -26,8 +26,8 @@ module CS
26
26
  end
27
27
  end
28
28
 
29
- # overide Endpoint#to_parameters
30
- def to_parameters
29
+
30
+ def to_cs_value
31
31
  param = self.to_h(false)
32
32
  if param[:data_type] == "json"
33
33
  if param[:data_structure] && !param[:data_structure].kind_of?(String)
@@ -35,12 +35,40 @@ module CS
35
35
  end
36
36
  end
37
37
 
38
- {sensor: param}
38
+ param
39
+ end
40
+
41
+ # overide Endpoint#to_parameters
42
+ def to_parameters
43
+ {sensor: to_cs_value}
39
44
  end
40
45
 
41
46
  def data
42
47
  Relation::SensorDataRelation.new(self.id, self.session)
43
48
  end
49
+
50
+ # Copy data from other sensor
51
+ #
52
+ # example :
53
+ #
54
+ # source = client.sensors.find(1234)
55
+ # destination = clint.sensors.find(2345)
56
+ #
57
+ # destination.copy_data(source, start_date: 12345, end_date: 12350)
58
+ #
59
+ def copy_data(sensor, parameters={})
60
+ source = sensor.data
61
+ parameters.each do |k,v|
62
+ source.send(k.to_sym, v)
63
+ end
64
+
65
+ collection = self.data.collection
66
+ source.each do |point|
67
+ collection.push self.data.build(date: point.date, value: point.value)
68
+ end
69
+
70
+ collection.save!
71
+ end
44
72
  end
45
73
  end
46
74
  end
@@ -26,7 +26,7 @@ module CS
26
26
  resources "data"
27
27
  resource "data"
28
28
 
29
- def to_parameters
29
+ def to_cs_value
30
30
  param = self.to_h(false)
31
31
  param.delete(:sensor_id)
32
32
  value = param[:value]
@@ -35,7 +35,12 @@ module CS
35
35
  end
36
36
 
37
37
  param[:date] = CS::Time.new(date).to_f if param[:date]
38
- {data: [param]}
38
+
39
+ param
40
+ end
41
+
42
+ def to_parameters
43
+ {data: [to_cs_value]}
39
44
  end
40
45
 
41
46
  def date_human
@@ -0,0 +1,16 @@
1
+ module CS
2
+ module EndPoint
3
+ class Trigger
4
+ include EndPoint
5
+
6
+ attribute :name, :expression, :inactivity, :creation_date
7
+
8
+ resources "triggers"
9
+ resource "trigger"
10
+
11
+ def initialize(hash={})
12
+ from_hash(hash)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -45,7 +45,7 @@ module CS
45
45
  end
46
46
 
47
47
  def get_data(params={})
48
- get_data!(params) rescue nil
48
+ get_data!(params)
49
49
  end
50
50
 
51
51
  def all
@@ -94,7 +94,6 @@ module CS
94
94
  end
95
95
 
96
96
  def last
97
- total = count
98
97
  resource = get_single_resource(page: count - 1)
99
98
  parse_single_resource(resource)
100
99
  end
@@ -146,7 +145,7 @@ module CS
146
145
  options[:page] = self.page
147
146
  data = get_data(options)
148
147
 
149
- data = data[resource_class.resources_name]
148
+ data = data[resource_class.resources_name] unless data.nil?
150
149
  if !data.nil? && !data.empty?
151
150
  yield data
152
151
  self.page += 1
@@ -0,0 +1,20 @@
1
+ module CS
2
+ module Relation
3
+ class NotificationRelation
4
+ include Relation
5
+
6
+ parameter :page, Integer, default: 0, required: true
7
+ parameter :per_page, Integer, default: 1000, required: true, maximum: 1000
8
+ parameter :total, Boolean
9
+
10
+ private
11
+ def resource_class
12
+ EndPoint::Notification
13
+ end
14
+
15
+ def get_url
16
+ "/notifications.json"
17
+ end
18
+ end
19
+ end
20
+ end
@@ -50,6 +50,14 @@ module CS
50
50
  parse_single_resource(data)
51
51
  end
52
52
 
53
+ def start_date(date)
54
+ from(date)
55
+ end
56
+
57
+ def end_date(date)
58
+ to(date)
59
+ end
60
+
53
61
  def from(start_date)
54
62
  param_option = self.class.parameters[:start_date]
55
63
  self.start_date = process_param_time(:start_date, start_date, param_option)
@@ -62,6 +70,10 @@ module CS
62
70
  self
63
71
  end
64
72
 
73
+ def collection
74
+ Collection::SensorDataCollection.new(session)
75
+ end
76
+
65
77
  private
66
78
  def resource_class
67
79
  EndPoint::SensorData
@@ -100,6 +100,23 @@ module CS
100
100
  self.select { |sensor| sensor.name =~ regex }
101
101
  end
102
102
 
103
+ def triggers()
104
+ Relation::SensorTriggersRelation.new(@session)
105
+ end
106
+
107
+ # Create new sensor with properties from other sensor
108
+ #
109
+ # example :
110
+ #
111
+ # client.sensors.clone_from(client.sensors.find(123))
112
+ def clone_from(other_sensor)
113
+ sensor = EndPoint::Sensor.new(other_sensor.to_cs_value)
114
+ sensor.id = nil
115
+ sensor.session = self.session
116
+
117
+ sensor
118
+ end
119
+
103
120
  private
104
121
  def resource_class
105
122
  EndPoint::Sensor
@@ -109,5 +126,15 @@ module CS
109
126
  "/sensors.json"
110
127
  end
111
128
  end
129
+
130
+ class SensorTriggersRelation
131
+ include Relation
132
+
133
+ parameter :page, Integer, default: 0, required: true
134
+
135
+ def get_url
136
+ "/sensors/triggers.json"
137
+ end
138
+ end
112
139
  end
113
140
  end
@@ -0,0 +1,21 @@
1
+ module CS
2
+ module Relation
3
+ class TriggerRelation
4
+ include Relation
5
+
6
+ parameter :page, Integer, default: 0, required: true
7
+ parameter :per_page, Integer, default: 1000, required: true, maximum: 1000
8
+ parameter :total, Boolean
9
+
10
+
11
+ private
12
+ def resource_class
13
+ EndPoint::Trigger
14
+ end
15
+
16
+ def get_url
17
+ "/triggers.json"
18
+ end
19
+ end
20
+ end
21
+ end
@@ -13,9 +13,9 @@ module CS
13
13
 
14
14
  # login to commonsense
15
15
  # @return [String] session_id
16
- def login(username, password)
16
+ def login(username, password, digest=true)
17
17
  @auth_proxy = CS::Auth::HTTP.new(@base_uri)
18
- @auth_proxy.login(username, password)
18
+ @auth_proxy.login(username, password, digest)
19
19
  end
20
20
 
21
21
  def oauth(consumer_key, consumer_secret, access_token, access_token_secret)
@@ -28,11 +28,20 @@ module CS
28
28
  auth_proxy.session_id
29
29
  end
30
30
 
31
+ def api_key
32
+ auth_proxy.api_key
33
+ end
34
+
31
35
  def session_id=(session_id)
32
36
  @auth_proxy = CS::Auth::HTTP.new(@base_uri)
33
37
  @auth_proxy.session_id = session_id
34
38
  end
35
39
 
40
+ def api_key=(api_key)
41
+ @api_key = api_key
42
+ @auth_proxy = CS::Auth::HTTP.new(@base_uri, api_key)
43
+ end
44
+
36
45
  def auth_proxy
37
46
  raise 'The session is not logged in' unless @auth_proxy
38
47
  @auth_proxy
@@ -55,18 +64,25 @@ module CS
55
64
  logger.info("")
56
65
  logger.info("#{type} #{path}")
57
66
  logger.debug("headers: #{headers.inspect}")
58
- logger.info("parameters: #{body.inspect}")
67
+ if ["POST", "PUT"].include?(type)
68
+ logger.debug("request: #{body.inspect}")
69
+ else
70
+ logger.info("request: #{body.inspect}")
71
+ end
59
72
  end
60
73
 
61
- def log_response
62
- logger.info("response: #{self.response_code}")
63
- logger.debug("body: #{self.response_body}")
74
+ def log_response(elapsed)
75
+ logger.info("result: #{self.response_code} in #{elapsed}ms")
76
+ logger.debug("response: #{self.response_body}")
64
77
  end
65
78
 
66
79
  def execute(type, path, body, headers, &block)
80
+ start_time = Time.now
67
81
  log_request(type, path, body, headers) if logger
68
82
  response = retry_on_509 { yield }
69
- log_response if logger
83
+
84
+ elapsed = (Time.now - start_time) * 1000.0
85
+ log_response(elapsed) if logger
70
86
 
71
87
  response
72
88
  end
@@ -146,7 +162,12 @@ module CS
146
162
  end
147
163
 
148
164
  def to_s
149
- "\"#{self.session_id}\""
165
+ if session_id
166
+ return "SESSION_ID \"#{session_id}\""
167
+ elsif api_key
168
+ return "API_KEY \"#{api_key}\""
169
+ end
170
+ return ""
150
171
  end
151
172
 
152
173
  def inspect