cs 0.1.0beta3
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.
- data/.gitignore +21 -0
- data/Gemfile +10 -0
- data/LICENSE +22 -0
- data/README.md +132 -0
- data/Rakefile +7 -0
- data/cs.gemspec +22 -0
- data/lib/commonsense-ruby-lib.rb +127 -0
- data/lib/commonsense-ruby-lib/auth/http.rb +117 -0
- data/lib/commonsense-ruby-lib/auth/oauth.rb +101 -0
- data/lib/commonsense-ruby-lib/end_point.rb +276 -0
- data/lib/commonsense-ruby-lib/end_point/group.rb +28 -0
- data/lib/commonsense-ruby-lib/end_point/sensor.rb +36 -0
- data/lib/commonsense-ruby-lib/end_point/sensor_data.rb +70 -0
- data/lib/commonsense-ruby-lib/end_point/user.rb +50 -0
- data/lib/commonsense-ruby-lib/error.rb +51 -0
- data/lib/commonsense-ruby-lib/relation.rb +233 -0
- data/lib/commonsense-ruby-lib/relation/sensor_data_relation.rb +116 -0
- data/lib/commonsense-ruby-lib/relation/sensor_relation.rb +162 -0
- data/lib/commonsense-ruby-lib/serializer.rb +20 -0
- data/lib/commonsense-ruby-lib/session.rb +105 -0
- data/lib/commonsense-ruby-lib/version.rb +3 -0
- data/spec/features/sensor_data_management_spec.rb +4 -0
- data/spec/features/sensor_management_spec.rb +105 -0
- data/spec/features/user_management_spec.rb +70 -0
- data/spec/lib/commonsense-ruby-lib/end_point/sensor_data_spec.rb +68 -0
- data/spec/lib/commonsense-ruby-lib/end_point/sensor_spec.rb +98 -0
- data/spec/lib/commonsense-ruby-lib/end_point/user_spec.rb +36 -0
- data/spec/lib/commonsense-ruby-lib/end_point_spec.rb +190 -0
- data/spec/lib/commonsense-ruby-lib/relation/sensor_data_relation_spec.rb +444 -0
- data/spec/lib/commonsense-ruby-lib/relation/sensor_relation_spec.rb +165 -0
- data/spec/lib/commonsense-ruby-lib/session_spec.rb +43 -0
- data/spec/lib/commonsense-ruby-lib_spec.rb +51 -0
- data/spec/spec_helper.rb +40 -0
- data/spec/support/spec_config.yml.sample +6 -0
- data/spec/support/vcr.rb +5 -0
- metadata +175 -0
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
|
3
|
+
module CommonSense
|
4
|
+
module EndPoint
|
5
|
+
class User
|
6
|
+
include EndPoint
|
7
|
+
|
8
|
+
resources :users
|
9
|
+
resource :user
|
10
|
+
|
11
|
+
attribute :email, :username, :name, :surname, :address, :zipcode,
|
12
|
+
:country, :mobile, :uuid, :openid, :password
|
13
|
+
|
14
|
+
def initialize(hash={})
|
15
|
+
if hash[:password]
|
16
|
+
hash[:password] = Digest::MD5.hexdigest(hash[:password])
|
17
|
+
end
|
18
|
+
super(hash)
|
19
|
+
end
|
20
|
+
|
21
|
+
def password=(plain_text)
|
22
|
+
@password = Digest::MD5.hexdigest(plain_text)
|
23
|
+
end
|
24
|
+
|
25
|
+
def password_hashed=(hash)
|
26
|
+
self.password = hash
|
27
|
+
end
|
28
|
+
|
29
|
+
def current_user
|
30
|
+
res = session.get('/users/current.json', )
|
31
|
+
return nil unless res && res["user"]
|
32
|
+
|
33
|
+
from_hash(res["user"])
|
34
|
+
self
|
35
|
+
end
|
36
|
+
|
37
|
+
def reload
|
38
|
+
current_user
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
# get groups that this users belongs to
|
43
|
+
def groups
|
44
|
+
group = Group.new
|
45
|
+
group.session = session
|
46
|
+
group.groups
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module CommonSense
|
2
|
+
module Error
|
3
|
+
class Error < ::RuntimeError
|
4
|
+
def initialize(message = "")
|
5
|
+
super(message)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class ResourceIdError < Error
|
10
|
+
def initialize(message = "No id found for Resrouce: #{self.class}")
|
11
|
+
super(message)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class ResourcesError < Error
|
16
|
+
def initialize(message = "'resources' is not set for class: #{self.class}")
|
17
|
+
super(message)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class ResourceError < Error
|
22
|
+
def initialize(message = "'resource' is not set for class: #{self.class}")
|
23
|
+
super(message)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class ResponseError < Error
|
28
|
+
def initialize(message = "Error Response from CommonSense")
|
29
|
+
super(message)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class SessionEmptyError < Error
|
34
|
+
def initialize(message = "There is no Session found")
|
35
|
+
super(message)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class RelationError < Error
|
40
|
+
def initialize(message = "Error when setting up relation")
|
41
|
+
super(message)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class NotImplementedError < Error
|
46
|
+
def initialize(message = "There is unimplemented method")
|
47
|
+
super(message)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,233 @@
|
|
1
|
+
module CommonSense
|
2
|
+
module Relation
|
3
|
+
module Boolean; end
|
4
|
+
|
5
|
+
def check_session!
|
6
|
+
raise Error::SessionEmptyError unless @session
|
7
|
+
end
|
8
|
+
|
9
|
+
def get_url
|
10
|
+
raise Error::NotImplementedError, "the class #{self.class} does not respond to 'get_url' "
|
11
|
+
end
|
12
|
+
|
13
|
+
def get_data!(params={})
|
14
|
+
check_session!
|
15
|
+
options = get_options(params)
|
16
|
+
session.get(get_url, options)
|
17
|
+
end
|
18
|
+
|
19
|
+
def parameter(name)
|
20
|
+
self.instance_variable_get("@#{name}")
|
21
|
+
end
|
22
|
+
|
23
|
+
def get_options(params)
|
24
|
+
options = {}
|
25
|
+
|
26
|
+
params.each do |k,v|
|
27
|
+
param_option = self.class.parameters[k]
|
28
|
+
|
29
|
+
value = v
|
30
|
+
value = process_param_integer(k, v, param_option) if param_option[:type] == Integer
|
31
|
+
value = process_param_boolean(k, v, param_option) if param_option[:type] == Boolean
|
32
|
+
value = process_param_string(k, v, param_option) if param_option[:type] == String
|
33
|
+
|
34
|
+
if value.kind_of?(Time)
|
35
|
+
value = value.to_f
|
36
|
+
end
|
37
|
+
|
38
|
+
options[k] = value
|
39
|
+
end
|
40
|
+
|
41
|
+
options
|
42
|
+
end
|
43
|
+
|
44
|
+
def get_data(params={})
|
45
|
+
get_data!(params) rescue nil
|
46
|
+
end
|
47
|
+
|
48
|
+
def all
|
49
|
+
self.to_a
|
50
|
+
end
|
51
|
+
|
52
|
+
def count
|
53
|
+
check_session!
|
54
|
+
resource = get_single_resource
|
55
|
+
resource["total"] if resource
|
56
|
+
end
|
57
|
+
|
58
|
+
def first
|
59
|
+
resource = get_single_resource
|
60
|
+
parse_single_resource(resource)
|
61
|
+
end
|
62
|
+
|
63
|
+
def last
|
64
|
+
total = count
|
65
|
+
resource = get_single_resource(page: count - 1)
|
66
|
+
parse_single_resource(resource)
|
67
|
+
end
|
68
|
+
|
69
|
+
def inspect
|
70
|
+
inspection = self.class.parameters.collect {|k,v| "#{k}: #{parameter(k).inspect}"}.compact.join(", ")
|
71
|
+
"#<#{self.class} #{inspection}>"
|
72
|
+
end
|
73
|
+
|
74
|
+
def where(params={})
|
75
|
+
process_alias!(params)
|
76
|
+
params.keep_if {|k| self.class.parameters[k]}
|
77
|
+
|
78
|
+
params.each do |k,v|
|
79
|
+
param_option = self.class.parameters[k]
|
80
|
+
|
81
|
+
value = process_param_integer(k, v, param_option) if param_option[:type] == Integer
|
82
|
+
value = process_param_boolean(k, v, param_option) if param_option[:type] == Boolean
|
83
|
+
value = process_param_string(k, v, param_option) if param_option[:type] == String
|
84
|
+
value = process_param_time(k, v, param_option) if param_option[:type] == Time
|
85
|
+
|
86
|
+
self.send("#{k}=", value)
|
87
|
+
end
|
88
|
+
|
89
|
+
self
|
90
|
+
end
|
91
|
+
|
92
|
+
module ClassMethod
|
93
|
+
def parameter(name, type, *args)
|
94
|
+
attr_accessor name
|
95
|
+
self.parameters ||= {}
|
96
|
+
|
97
|
+
param = {type: type}
|
98
|
+
unless args.empty?
|
99
|
+
param.merge!(args[0])
|
100
|
+
end
|
101
|
+
|
102
|
+
self.parameters[name] = param
|
103
|
+
end
|
104
|
+
|
105
|
+
def parameter_alias(name, name_alias)
|
106
|
+
attr_accessor name
|
107
|
+
self.parameters_alias ||= {}
|
108
|
+
self.parameters_alias[name] = name_alias
|
109
|
+
end
|
110
|
+
|
111
|
+
def parameters_alias=(parameters_alias)
|
112
|
+
@parameters_alias = parameters_alias
|
113
|
+
end
|
114
|
+
|
115
|
+
def parameters_alias
|
116
|
+
@parameters_alias
|
117
|
+
end
|
118
|
+
|
119
|
+
def parameters=(parameters)
|
120
|
+
@parameters = parameters
|
121
|
+
end
|
122
|
+
|
123
|
+
def parameters
|
124
|
+
@parameters
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
protected
|
129
|
+
def self.included(base)
|
130
|
+
base.send(:include, Enumerable)
|
131
|
+
base.extend(ClassMethod)
|
132
|
+
base.class_eval do
|
133
|
+
attr_accessor :session
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def parse_single_resource(resource)
|
138
|
+
raise Error::NotImplementedError, "parse_single_resource is not implemented for class : #{self.class}"
|
139
|
+
end
|
140
|
+
|
141
|
+
def get_single_resource(params={})
|
142
|
+
raise Error::NotImplementedError, "get_single_resource is not implemented for class : #{self.class}"
|
143
|
+
end
|
144
|
+
|
145
|
+
def process_alias!(params)
|
146
|
+
return if self.class.parameters_alias.nil?
|
147
|
+
|
148
|
+
aliases = params.select { |param| self.class.parameters_alias.include?(param) }
|
149
|
+
aliases.each do |alias_to, value|
|
150
|
+
alias_for = self.class.parameters_alias[alias_to]
|
151
|
+
params[alias_for] = value
|
152
|
+
params.delete(alias_to)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
|
157
|
+
def process_valid_values(name, value, param_option)
|
158
|
+
return value unless param_option[:valid_values]
|
159
|
+
|
160
|
+
if param_option[:valid_values].include?(value)
|
161
|
+
value
|
162
|
+
elsif !value.nil?
|
163
|
+
raise ArgumentError, "Invalid value for parameter '#{name}'"
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
167
|
+
|
168
|
+
def process_default_value(name, value, param_option)
|
169
|
+
value.nil? ? param_option[:default] : value
|
170
|
+
end
|
171
|
+
|
172
|
+
def process_param_integer(name, value, param_option)
|
173
|
+
if value.kind_of?(Integer)
|
174
|
+
retval = value
|
175
|
+
retval = process_valid_values(name, value, param_option) if param_option[:valid_values]
|
176
|
+
end
|
177
|
+
|
178
|
+
retval = process_default_value(name, retval, param_option)
|
179
|
+
|
180
|
+
if !value.nil? && !value.kind_of?(Integer)
|
181
|
+
raise ArgumentError, "Received non Integer value for parameter '#{name}'"
|
182
|
+
end
|
183
|
+
|
184
|
+
retval
|
185
|
+
end
|
186
|
+
|
187
|
+
def process_param_boolean(name, value, param_option)
|
188
|
+
retval = nil
|
189
|
+
|
190
|
+
if value.nil?
|
191
|
+
retval = param_option[:default] ? param_option[:default] : nil
|
192
|
+
elsif [0, "0", false, "false"].include?(value)
|
193
|
+
retval = 0
|
194
|
+
else
|
195
|
+
retval = 1
|
196
|
+
end
|
197
|
+
|
198
|
+
retval
|
199
|
+
end
|
200
|
+
|
201
|
+
def process_param_string(name, value, param_option)
|
202
|
+
retval = value
|
203
|
+
retval = process_valid_values(name, value, param_option) if param_option[:valid_values]
|
204
|
+
retval = process_default_value(name, retval, param_option)
|
205
|
+
|
206
|
+
retval
|
207
|
+
end
|
208
|
+
|
209
|
+
# This method prosess assignment for properties with datatype Time.
|
210
|
+
# There are 3 type that is valid for this properties:
|
211
|
+
#
|
212
|
+
# * **Time**
|
213
|
+
# * **Numeric**. It will convert this to ruby {Time}
|
214
|
+
# * **Obejct that respond to #to_time** and return ruby {Time}
|
215
|
+
#
|
216
|
+
def process_param_time(name, value, param_option)
|
217
|
+
retval = value
|
218
|
+
|
219
|
+
if !value.nil? && !value.kind_of?(Time)
|
220
|
+
if value.kind_of?(Numeric)
|
221
|
+
retval = Time.at(retval)
|
222
|
+
else
|
223
|
+
retval = value.to_time
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
retval = process_default_value(name, retval, param_option)
|
228
|
+
retval = process_valid_values(name, value, param_option) if param_option[:valid_values]
|
229
|
+
|
230
|
+
retval
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
module CommonSense
|
2
|
+
module Relation
|
3
|
+
class SensorDataRelation
|
4
|
+
include Relation
|
5
|
+
|
6
|
+
parameter :page, Integer, default: 0
|
7
|
+
parameter :per_page, Integer, default: 1000, maximum: 1000
|
8
|
+
parameter :start_date, Time
|
9
|
+
parameter :end_date, Time
|
10
|
+
parameter :date, Time
|
11
|
+
parameter :last, Boolean
|
12
|
+
parameter :sort, String, valid_values: ["ASC", "DESC"]
|
13
|
+
parameter :interval, Integer, valid_values: [604800, 86400, 3600, 1800, 600, 300, 60]
|
14
|
+
parameter :sensor_id, String
|
15
|
+
parameter_alias :from, :start_date
|
16
|
+
parameter_alias :to, :end_date
|
17
|
+
|
18
|
+
include Enumerable
|
19
|
+
|
20
|
+
def initialize(sensor_id, session=nil)
|
21
|
+
self.sensor_id = sensor_id
|
22
|
+
self.session = session
|
23
|
+
page = 0
|
24
|
+
per_page = 1000
|
25
|
+
end
|
26
|
+
|
27
|
+
def get_url
|
28
|
+
"/sensors/#{self.sensor_id}/data.json"
|
29
|
+
end
|
30
|
+
|
31
|
+
def build(attributes={})
|
32
|
+
data = EndPoint::SensorData.new
|
33
|
+
data.sensor_id = self.sensor_id
|
34
|
+
data.session = self.session
|
35
|
+
data
|
36
|
+
end
|
37
|
+
|
38
|
+
def each_batch(params={}, &block)
|
39
|
+
check_session!
|
40
|
+
options = get_options(params)
|
41
|
+
|
42
|
+
page = self.page || 0;
|
43
|
+
begin
|
44
|
+
options[:page] = page
|
45
|
+
data = get_data(options)
|
46
|
+
|
47
|
+
data = data["data"]
|
48
|
+
if !data.empty?
|
49
|
+
yield data
|
50
|
+
|
51
|
+
page += 1
|
52
|
+
end
|
53
|
+
|
54
|
+
end while data.size == self.per_page
|
55
|
+
end
|
56
|
+
|
57
|
+
def each(&block)
|
58
|
+
self.each_batch do |data|
|
59
|
+
data.each do |data_point|
|
60
|
+
sensor_data = EndPoint::SensorData.new(data_point)
|
61
|
+
sensor_data.sensor_id = self.sensor_id
|
62
|
+
sensor_data.session = session
|
63
|
+
yield sensor_data
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def count
|
69
|
+
retval = 0
|
70
|
+
each_batch do |data|
|
71
|
+
retval += data.size
|
72
|
+
end
|
73
|
+
|
74
|
+
retval
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
def first
|
79
|
+
data = get_data!(page:0, per_page: 1, sort: "ASC")
|
80
|
+
parse_single_resource(data)
|
81
|
+
end
|
82
|
+
|
83
|
+
def last
|
84
|
+
data = get_data!(page:0, per_page: 1, sort: "DESC")
|
85
|
+
parse_single_resource(data)
|
86
|
+
end
|
87
|
+
|
88
|
+
def from(start_date)
|
89
|
+
param_option = self.class.parameters[:start_date]
|
90
|
+
self.start_date = process_param_time(:start_date, start_date, param_option)
|
91
|
+
self
|
92
|
+
end
|
93
|
+
|
94
|
+
def to(end_date)
|
95
|
+
param_option = self.class.parameters[:end_date]
|
96
|
+
self.end_date = process_param_time(:end_date, end_date, param_option)
|
97
|
+
self
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
def parse_single_resource(data)
|
102
|
+
data = data["data"]
|
103
|
+
data_point = data[0]
|
104
|
+
|
105
|
+
sensor_data = nil
|
106
|
+
if !data.empty?
|
107
|
+
sensor_data = EndPoint::SensorData.new(data_point)
|
108
|
+
sensor_data.sensor_id = self.sensor_id
|
109
|
+
sensor_data.session = session
|
110
|
+
end
|
111
|
+
|
112
|
+
sensor_data
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|