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.
Files changed (36) hide show
  1. data/.gitignore +21 -0
  2. data/Gemfile +10 -0
  3. data/LICENSE +22 -0
  4. data/README.md +132 -0
  5. data/Rakefile +7 -0
  6. data/cs.gemspec +22 -0
  7. data/lib/commonsense-ruby-lib.rb +127 -0
  8. data/lib/commonsense-ruby-lib/auth/http.rb +117 -0
  9. data/lib/commonsense-ruby-lib/auth/oauth.rb +101 -0
  10. data/lib/commonsense-ruby-lib/end_point.rb +276 -0
  11. data/lib/commonsense-ruby-lib/end_point/group.rb +28 -0
  12. data/lib/commonsense-ruby-lib/end_point/sensor.rb +36 -0
  13. data/lib/commonsense-ruby-lib/end_point/sensor_data.rb +70 -0
  14. data/lib/commonsense-ruby-lib/end_point/user.rb +50 -0
  15. data/lib/commonsense-ruby-lib/error.rb +51 -0
  16. data/lib/commonsense-ruby-lib/relation.rb +233 -0
  17. data/lib/commonsense-ruby-lib/relation/sensor_data_relation.rb +116 -0
  18. data/lib/commonsense-ruby-lib/relation/sensor_relation.rb +162 -0
  19. data/lib/commonsense-ruby-lib/serializer.rb +20 -0
  20. data/lib/commonsense-ruby-lib/session.rb +105 -0
  21. data/lib/commonsense-ruby-lib/version.rb +3 -0
  22. data/spec/features/sensor_data_management_spec.rb +4 -0
  23. data/spec/features/sensor_management_spec.rb +105 -0
  24. data/spec/features/user_management_spec.rb +70 -0
  25. data/spec/lib/commonsense-ruby-lib/end_point/sensor_data_spec.rb +68 -0
  26. data/spec/lib/commonsense-ruby-lib/end_point/sensor_spec.rb +98 -0
  27. data/spec/lib/commonsense-ruby-lib/end_point/user_spec.rb +36 -0
  28. data/spec/lib/commonsense-ruby-lib/end_point_spec.rb +190 -0
  29. data/spec/lib/commonsense-ruby-lib/relation/sensor_data_relation_spec.rb +444 -0
  30. data/spec/lib/commonsense-ruby-lib/relation/sensor_relation_spec.rb +165 -0
  31. data/spec/lib/commonsense-ruby-lib/session_spec.rb +43 -0
  32. data/spec/lib/commonsense-ruby-lib_spec.rb +51 -0
  33. data/spec/spec_helper.rb +40 -0
  34. data/spec/support/spec_config.yml.sample +6 -0
  35. data/spec/support/vcr.rb +5 -0
  36. 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