cs 0.1.0beta3 → 0.1.0

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 (57) hide show
  1. checksums.yaml +7 -0
  2. data/.travis.yml +8 -0
  3. data/Gemfile +22 -6
  4. data/README.md +15 -4
  5. data/cs.gemspec +7 -7
  6. data/lib/{commonsense-ruby-lib.rb → cs.rb} +80 -31
  7. data/lib/{commonsense-ruby-lib → cs}/auth/http.rb +52 -33
  8. data/lib/{commonsense-ruby-lib → cs}/auth/oauth.rb +28 -28
  9. data/lib/cs/collection.rb +7 -0
  10. data/lib/cs/collection/sensor_data_collection.rb +61 -0
  11. data/lib/{commonsense-ruby-lib → cs}/end_point.rb +36 -24
  12. data/lib/cs/end_point/group.rb +26 -0
  13. data/lib/cs/end_point/notification.rb +16 -0
  14. data/lib/{commonsense-ruby-lib → cs}/end_point/sensor.rb +22 -6
  15. data/lib/{commonsense-ruby-lib → cs}/end_point/sensor_data.rb +17 -6
  16. data/lib/cs/end_point/trigger.rb +16 -0
  17. data/lib/{commonsense-ruby-lib → cs}/end_point/user.rb +8 -4
  18. data/lib/{commonsense-ruby-lib → cs}/error.rb +7 -1
  19. data/lib/cs/parameter_processor.rb +99 -0
  20. data/lib/cs/relation.rb +244 -0
  21. data/lib/cs/relation/group_relation.rb +24 -0
  22. data/lib/cs/relation/notification_relation.rb +20 -0
  23. data/lib/{commonsense-ruby-lib → cs}/relation/sensor_data_relation.rb +7 -52
  24. data/lib/{commonsense-ruby-lib → cs}/relation/sensor_relation.rb +28 -55
  25. data/lib/cs/relation/trigger_relation.rb +21 -0
  26. data/lib/cs/relation/user_relation.rb +20 -0
  27. data/lib/{commonsense-ruby-lib → cs}/serializer.rb +1 -1
  28. data/lib/cs/session.rb +170 -0
  29. data/lib/cs/time.rb +45 -0
  30. data/lib/cs/version.rb +3 -0
  31. data/spec/features/sensor_management_spec.rb +146 -45
  32. data/spec/features/user_management_spec.rb +94 -22
  33. data/spec/lib/cs/collection/sensor_data_collection_spec.rb +27 -0
  34. data/spec/lib/cs/end_point/group_spec.rb +120 -0
  35. data/spec/lib/cs/end_point/sensor_data_spec.rb +110 -0
  36. data/spec/lib/{commonsense-ruby-lib → cs}/end_point/sensor_spec.rb +6 -6
  37. data/spec/lib/{commonsense-ruby-lib → cs}/end_point/user_spec.rb +14 -7
  38. data/spec/lib/{commonsense-ruby-lib → cs}/end_point_spec.rb +25 -12
  39. data/spec/lib/cs/relation/group_relation_spec.rb +103 -0
  40. data/spec/lib/cs/relation/sensor_data_relation_spec.rb +184 -0
  41. data/spec/lib/cs/relation/sensor_relation_spec.rb +192 -0
  42. data/spec/lib/cs/relation/user_relation_spec.rb +81 -0
  43. data/spec/lib/cs/relation_spec.rb +151 -0
  44. data/spec/lib/cs/session_spec.rb +91 -0
  45. data/spec/lib/cs/time_spec.rb +71 -0
  46. data/spec/lib/cs_spec.rb +85 -0
  47. data/spec/spec_helper.rb +6 -26
  48. metadata +69 -86
  49. data/lib/commonsense-ruby-lib/end_point/group.rb +0 -28
  50. data/lib/commonsense-ruby-lib/relation.rb +0 -233
  51. data/lib/commonsense-ruby-lib/session.rb +0 -105
  52. data/lib/commonsense-ruby-lib/version.rb +0 -3
  53. data/spec/lib/commonsense-ruby-lib/end_point/sensor_data_spec.rb +0 -68
  54. data/spec/lib/commonsense-ruby-lib/relation/sensor_data_relation_spec.rb +0 -444
  55. data/spec/lib/commonsense-ruby-lib/relation/sensor_relation_spec.rb +0 -165
  56. data/spec/lib/commonsense-ruby-lib/session_spec.rb +0 -43
  57. data/spec/lib/commonsense-ruby-lib_spec.rb +0 -51
@@ -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
@@ -1,15 +1,15 @@
1
1
  require 'digest/md5'
2
2
 
3
- module CommonSense
3
+ module CS
4
4
  module EndPoint
5
5
  class User
6
6
  include EndPoint
7
7
 
8
- resources :users
9
- resource :user
8
+ resources "users"
9
+ resource "user"
10
10
 
11
11
  attribute :email, :username, :name, :surname, :address, :zipcode,
12
- :country, :mobile, :uuid, :openid, :password
12
+ :country, :mobile, :UUID, :openid, :password
13
13
 
14
14
  def initialize(hash={})
15
15
  if hash[:password]
@@ -38,6 +38,10 @@ module CommonSense
38
38
  current_user
39
39
  end
40
40
 
41
+ def save!(options={})
42
+ raise Error::ClientError, "No session found. use Client#new_user instead" unless @session
43
+ super(options)
44
+ end
41
45
 
42
46
  # get groups that this users belongs to
43
47
  def groups
@@ -1,4 +1,4 @@
1
- module CommonSense
1
+ module CS
2
2
  module Error
3
3
  class Error < ::RuntimeError
4
4
  def initialize(message = "")
@@ -6,6 +6,12 @@ module CommonSense
6
6
  end
7
7
  end
8
8
 
9
+ class ClientError < Error
10
+ def initialize(message = "Invalid uses of the library : #{self.class}")
11
+ super(message)
12
+ end
13
+ end
14
+
9
15
  class ResourceIdError < Error
10
16
  def initialize(message = "No id found for Resrouce: #{self.class}")
11
17
  super(message)
@@ -0,0 +1,99 @@
1
+ module CS
2
+ module ParameterProcessor
3
+ def process_alias!(params)
4
+ return if self.class.parameters_alias.nil?
5
+
6
+ aliases = params.select { |param| self.class.parameters_alias.include?(param) }
7
+ aliases.each do |alias_to, value|
8
+ alias_for = self.class.parameters_alias[alias_to]
9
+ params[alias_for] = value
10
+ params.delete(alias_to)
11
+ end
12
+ end
13
+
14
+ def process_valid_values(name, value, param_option)
15
+ return value unless param_option[:valid_values]
16
+
17
+ if param_option[:valid_values].include?(value)
18
+ value
19
+ elsif !value.nil?
20
+ raise ArgumentError, "Invalid value for parameter '#{name}'"
21
+ end
22
+ end
23
+
24
+ def process_default_value(name, value, param_option)
25
+ value.nil? ? param_option[:default] : value
26
+ end
27
+
28
+
29
+ def process_param(name, value, param_option)
30
+ retval = value
31
+
32
+ # this should be refactored to it's own classes
33
+ retval = process_param_integer(name, value, param_option) if param_option[:type] == Integer
34
+ retval = process_param_boolean(name, value, param_option) if param_option[:type] == Boolean
35
+ retval = process_param_string(name, value, param_option) if param_option[:type] == String
36
+ retval = process_param_time(name, value, param_option) if param_option[:type] == Time
37
+ retval
38
+ end
39
+
40
+ def process_param_integer(name, value, param_option)
41
+ if value.kind_of?(Integer)
42
+ retval = value
43
+ retval = process_valid_values(name, value, param_option) if param_option[:valid_values]
44
+ maximum = param_option[:maximum]
45
+ retval = maximum if maximum && retval > maximum
46
+ end
47
+
48
+ retval = process_default_value(name, retval, param_option)
49
+
50
+ if !value.nil? && !value.kind_of?(Integer)
51
+ raise ArgumentError, "Received non Integer value for parameter '#{name}'"
52
+ end
53
+
54
+ retval
55
+ end
56
+
57
+ def process_param_boolean(name, value, param_option)
58
+ retval = nil
59
+
60
+ if value.nil?
61
+ retval = param_option[:default] ? param_option[:default] : nil
62
+ elsif [0, "0", false, "false"].include?(value)
63
+ retval = 0
64
+ else
65
+ retval = 1
66
+ end
67
+
68
+ retval
69
+ end
70
+
71
+ def process_param_string(name, value, param_option)
72
+ retval = value
73
+ retval = process_valid_values(name, value, param_option) if param_option[:valid_values]
74
+ retval = process_default_value(name, retval, param_option)
75
+
76
+ retval
77
+ end
78
+
79
+ # This method prosess assignment for properties with datatype Time.
80
+ # There are 3 type that is valid for this properties:
81
+ #
82
+ # * **Time**
83
+ # * **Numeric**. It will convert this to ruby {Time}
84
+ # * **Obejct that respond to #to_time** and return ruby {Time}
85
+ #
86
+ def process_param_time(name, value, param_option)
87
+ retval = value
88
+
89
+ if !value.nil?
90
+ retval = CS::Time.new(value)
91
+ end
92
+
93
+ retval = process_default_value(name, retval, param_option)
94
+ retval = process_valid_values(name, value, param_option) if param_option[:valid_values]
95
+
96
+ retval
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,244 @@
1
+ module CS
2
+ module Boolean; end
3
+ module Relation
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 initialize(session=nil)
14
+ @session = session
15
+ end
16
+
17
+ # Create a new Endpoint object.
18
+ #
19
+ # example:
20
+ #
21
+ # sensor = client.sensors.build
22
+ def build(attributes={})
23
+ resource = resource_class.new(attributes)
24
+ resource.session = self.session
25
+ resource
26
+ end
27
+
28
+ def get_data!(params={})
29
+ check_session!
30
+ options = get_options(params)
31
+ session.get(get_url, options)
32
+ end
33
+
34
+ def limit(num)
35
+ @limit = num
36
+ return self
37
+ end
38
+
39
+ def parameter(name)
40
+ self.instance_variable_get("@#{name}")
41
+ end
42
+
43
+ def parameters
44
+ self.class.parameters
45
+ end
46
+
47
+ def get_data(params={})
48
+ get_data!(params)
49
+ end
50
+
51
+ def all
52
+ self.to_a
53
+ end
54
+
55
+ def count
56
+ check_session!
57
+ resource = get_single_resource
58
+ resource["total"] if resource
59
+ end
60
+
61
+ def find_or_new(attribute)
62
+ check_session!
63
+
64
+ self.each do |resource|
65
+ found = true
66
+ attribute.each do |key, value|
67
+ if resource.parameter(key) != value
68
+ found = false
69
+ break
70
+ end
71
+ end
72
+
73
+ return resource if found
74
+ end
75
+
76
+ resource = resource_class.new(attribute)
77
+ resource.session = self.session
78
+ resource
79
+ end
80
+
81
+ def find_or_create!(attribute)
82
+ resource = find_or_new(attribute)
83
+ resource.save! if resource.id.nil?
84
+ resource
85
+ end
86
+
87
+ def find_or_create(attribute)
88
+ find_or_create!(attribute) rescue nil
89
+ end
90
+
91
+ def first
92
+ resource = get_single_resource
93
+ parse_single_resource(resource)
94
+ end
95
+
96
+ def last
97
+ resource = get_single_resource(page: count - 1)
98
+ parse_single_resource(resource)
99
+ end
100
+
101
+ def inspect
102
+ entries = to_a.take(11).map!(&:inspect)
103
+ entries[10] = '...' if entries.size == 11
104
+
105
+ "#<#{self.class.name} [#{entries.join(", \n")}]>"
106
+ end
107
+
108
+ def get_options(input={})
109
+ options = {}
110
+
111
+ self.class.parameters.each do |name, param_option|
112
+ value = self.parameter(name) # get value from object
113
+ value = input[name] if input.has_key?(name) # override
114
+
115
+ value = process_param(name, value, param_option)
116
+ value = value.to_f if value.kind_of?(Time)
117
+
118
+ options[name] = value if value
119
+ end
120
+
121
+ options
122
+ end
123
+
124
+ def where(params={})
125
+ process_alias!(params)
126
+ params.keep_if {|k| self.class.parameters[k]}
127
+
128
+ params.each do |name,value|
129
+ param_option = self.class.parameters[name]
130
+
131
+ value = process_param(name, value, param_option)
132
+ self.send("#{name}=", value)
133
+ end
134
+
135
+ self
136
+ end
137
+
138
+ def each_batch(params={}, &block)
139
+ check_session!
140
+ options = get_options(params)
141
+
142
+ self.page ||= 0;
143
+
144
+ begin
145
+ options[:page] = self.page
146
+ data = get_data(options)
147
+
148
+ data = data[resource_class.resources_name] unless data.nil?
149
+ if !data.nil? && !data.empty?
150
+ yield data
151
+ self.page += 1
152
+ end
153
+ end while data && data.size == self.per_page
154
+ end
155
+
156
+ def each(&block)
157
+ counter = 0
158
+ self.each_batch do |data|
159
+ data.each do |data_point|
160
+ resource = resource_class.new(data_point)
161
+ resource.session = session
162
+ yield resource
163
+ counter += 1
164
+
165
+ return if @limit && @limit == counter
166
+ end
167
+ end
168
+ end
169
+
170
+ module ClassMethod
171
+ def parameter(name, type, *args)
172
+ attr_accessor name
173
+ self.parameters ||= {}
174
+
175
+ param = {type: type}
176
+ param.merge!(args[0]) unless args.empty?
177
+
178
+ self.class_eval %{
179
+ def #{name}
180
+ if @#{name}.nil? && (default = self.class.parameters[:#{name}][:default])
181
+ @#{name} = default
182
+ end
183
+
184
+ @#{name}
185
+ end
186
+ }
187
+
188
+ self.parameters[name] = param
189
+ end
190
+
191
+ def parameter_alias(name, name_alias)
192
+ attr_accessor name
193
+ self.parameters_alias ||= {}
194
+ self.parameters_alias[name] = name_alias
195
+ end
196
+
197
+ def parameters_alias=(parameters_alias)
198
+ @parameters_alias = parameters_alias
199
+ end
200
+
201
+ def parameters_alias
202
+ @parameters_alias
203
+ end
204
+
205
+ def parameters=(parameters)
206
+ @parameters = parameters
207
+ end
208
+
209
+ def parameters
210
+ @parameters
211
+ end
212
+ end
213
+
214
+ protected
215
+ def self.included(base)
216
+ base.send(:include, Enumerable)
217
+ base.send(:include, ParameterProcessor)
218
+ base.extend(ClassMethod)
219
+ base.class_eval do
220
+ attr_accessor :session
221
+ end
222
+ end
223
+
224
+ def resource_class
225
+ raise Error::NotImplementedError, "resource_class is not implemented for class : #{self.class}"
226
+ end
227
+
228
+ def parse_single_resource(data)
229
+ resources = data[resource_class.resources_name]
230
+ if !resources.empty?
231
+ resource = resource_class.new(resources[0])
232
+ resource.session = self.session
233
+
234
+ return resource
235
+ end
236
+ end
237
+
238
+ def get_single_resource(params={})
239
+ options = get_options.merge!({ page: 0, per_page: 1 })
240
+ options.merge!(params)
241
+ get_data(options)
242
+ end
243
+ end
244
+ end
@@ -0,0 +1,24 @@
1
+ module CS
2
+ module Relation
3
+ class GroupRelation
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 :public, Boolean
9
+ parameter :total, Boolean
10
+ parameter :sort, String, valid_values: ["ASC", "DESC"]
11
+ parameter :sort_field, String, valid_values: ["id", "username", "email", "public", "description", "name"]
12
+
13
+
14
+ private
15
+ def resource_class
16
+ EndPoint::Group
17
+ end
18
+
19
+ def get_url
20
+ "/groups.json"
21
+ end
22
+ end
23
+ end
24
+ end
@@ -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