cs 0.1.0beta3

Sign up to get free protection for your applications and to get access to all the features.
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