machineshop 0.0.4 → 1.0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5d54f636ead5b398e7076611d3aafa0fe4edacbd
4
- data.tar.gz: 75a98f285a8c2b9b0d571e269e470048f869bbc5
3
+ metadata.gz: 5398a18d7fa06b98439cd8fb269584d75470e086
4
+ data.tar.gz: 79a3b0359fd318cb575793e235b3c9d874e049ea
5
5
  SHA512:
6
- metadata.gz: ffd6bca5ec40d674a5a7143e68b7307948427bba658e7c9a8597e52e182806dd6fb7fe67317c31b24873ca7e795e93c02121894c29ab4fa4ea1d48bf35108e21
7
- data.tar.gz: 183d8bc7b1065c036d26cd89a371faddfb62c13246f9ae3015eea5f3db8805dc7ade18425403834d31fb30cddbcdaa239d34e41219bbe910f3a6264c00e51ca9
6
+ metadata.gz: 91f0b27d60bc49ebd22a466b5522ecc449e0f3ab4d533c18d0c4a856fb69ba2e593c9938831efd16b0704ca16a37cda0452782ba0f048aaafeba707e470d2f10
7
+ data.tar.gz: 06609725eaf1067089ece7db9bbe045b11a13af8b821e86305bcc484749645730ba6688c2d35be197f595ea5fa2c0089617b7c1ec23ca269960a2c94642e4202
data/Gemfile CHANGED
@@ -3,6 +3,7 @@ source 'https://rubygems.org'
3
3
  # Specify your gem's dependencies in machineshop.gemspec
4
4
  gemspec
5
5
 
6
- gem "mysql"
6
+ # gem "mysql"
7
7
  gem "activerecord"
8
- gem "awesome_print"
8
+ gem "awesome_print"
9
+ gem 'will_paginate'
@@ -1,5 +1,8 @@
1
1
  require "machineshop/version"
2
2
 
3
+ # require 'awesome_print'
4
+ # require 'will_paginate'
5
+
3
6
  require 'cgi'
4
7
  require 'set'
5
8
  require 'openssl'
@@ -11,7 +14,7 @@ require 'multi_json'
11
14
  #configurations
12
15
  require 'machineshop/configuration'
13
16
  #database
14
- # require 'machineshop/database'
17
+ require 'machineshop/database'
15
18
 
16
19
  # API operations
17
20
  require 'machineshop/api_operations/create'
@@ -24,6 +27,11 @@ require 'machineshop/api_operations/update'
24
27
  require 'machineshop/machineshop_object'
25
28
  require 'machineshop/api_resource'
26
29
  require 'machineshop/device_instance'
30
+
31
+ require 'machineshop/data_sources'
32
+ require 'machineshop/data_source_types'
33
+
34
+
27
35
  require 'machineshop/device'
28
36
  require 'machineshop/machineshop_object'
29
37
  require 'machineshop/mapping'
@@ -31,7 +39,8 @@ require 'machineshop/meter'
31
39
  require 'machineshop/report'
32
40
  require 'machineshop/customer'
33
41
  require 'machineshop/rule'
34
- require 'machineshop/user'
42
+ # require 'machineshop/user'
43
+ require 'machineshop/users'
35
44
  require 'machineshop/utility'
36
45
  require 'machineshop/json'
37
46
  require 'machineshop/util'
@@ -43,14 +52,15 @@ require 'machineshop/errors/invalid_request_error'
43
52
  require 'machineshop/errors/authentication_error'
44
53
  require 'machineshop/errors/api_connection_error'
45
54
 
46
- # require 'machineshop/models/people'
55
+ #Models
56
+ require 'machineshop/models/api_request'
57
+ # require 'machineshop/models/device_cache'
47
58
 
48
59
 
49
60
  module MachineShop
50
61
  class << self
51
62
  # @@api_base_url = 'http://api.machineshop.io/api/v0'
52
- @@api_base_url = 'http://stage.services.machineshop.io/api/v0'
53
- # @@api_base_url = 'https://services.machineshop.io/api/v0'
63
+ @@api_base_url = 'http://stage.services.machineshop.io/api/v1'
54
64
 
55
65
  #configs starts
56
66
  attr_writer :configuration
@@ -102,63 +112,81 @@ module MachineShop
102
112
  end
103
113
 
104
114
  def platform_request(url, auth_token, body_hash=nil, http_verb=:get )
105
- puts "body_hash: #{body_hash}"
106
- opts = nil
107
- api_uri = api_base_url + url
108
- headers = self.headers(auth_token)
109
- if http_verb == :get
110
- if (body_hash && !body_hash.empty?)
111
- uri = Addressable::URI.new
112
- uri.query_values = body_hash
113
- api_uri += "?" + uri.query
114
- end
115
+ rbody=nil
116
+ cachedContent = :true
117
+ # ApiRequest.cache(url,MachineShop.configuration.expiry_time)
118
+ if http_verb==:get
115
119
 
116
- opts = {
117
- :method => :get,
118
- :url => api_uri,
119
- :headers => headers,
120
- :open_timeout => 30,
121
- :timeout => 80
122
- }
120
+ if db_connected?
121
+ ApiRequest.cache(url, auth_token, MachineShop.configuration.expiry_time) do
123
122
 
124
- else
125
- opts = {
126
- :method => http_verb,
127
- :url => api_uri,
128
- :headers => headers,
129
- :open_timeout => 30,
130
- :payload => MachineShop::JSON.dump(body_hash),
131
- :timeout => 80
132
- }
123
+ rbody = get_from_cache(url,body_hash,auth_token)
124
+ rcode="200"
125
+ end
126
+ end
133
127
 
134
128
  end
129
+ if (rbody.nil? || rbody.empty?)
130
+ cachedContent=:false
131
+ opts = nil
132
+ api_uri = api_base_url + url
133
+ headers = self.headers(auth_token)
134
+ if http_verb == :get
135
+ if (body_hash && !body_hash.empty?)
136
+ uri = Addressable::URI.new
137
+ uri.query_values = body_hash
138
+ api_uri += "?" + uri.query
139
+ end
140
+
141
+ opts = {
142
+ :method => :get,
143
+ :url => api_uri,
144
+ :headers => headers,
145
+ :open_timeout => 30,
146
+ :timeout => 80
147
+ }
135
148
 
136
- puts "request params: #{opts} "
137
-
138
- begin
139
- response = execute_request(opts)
140
- rescue SocketError => e
141
- self.handle_restclient_error(e)
142
- rescue NoMethodError => e
143
- # Work around RestClient bug
144
- if e.message =~ /\WRequestFailed\W/
145
- e = APIConnectionError.new('Unexpected HTTP response code')
146
- self.handle_restclient_error(e)
147
149
  else
148
- raise
150
+ opts = {
151
+ :method => http_verb,
152
+ :url => api_uri,
153
+ :headers => headers,
154
+ :open_timeout => 30,
155
+ :payload => MachineShop::JSON.dump(body_hash),
156
+ :timeout => 80
157
+ }
158
+
149
159
  end
150
- rescue RestClient::ExceptionWithResponse => e
151
- if rcode = e.http_code and rbody = e.http_body
152
- self.handle_api_error(rcode, rbody)
153
- else
160
+
161
+ begin
162
+ response = execute_request(opts)
163
+
164
+ rescue SocketError => e
165
+ self.handle_restclient_error(e)
166
+ rescue NoMethodError => e
167
+ # Work around RestClient bug
168
+ if e.message =~ /\WRequestFailed\W/
169
+ e = APIConnectionError.new('Unexpected HTTP response code')
170
+ self.handle_restclient_error(e)
171
+ else
172
+ raise
173
+ end
174
+ rescue RestClient::ExceptionWithResponse => e
175
+ if rcode = e.http_code and rbody = e.http_body
176
+ self.handle_api_error(rcode, rbody)
177
+ else
178
+ self.handle_restclient_error(e)
179
+ end
180
+ rescue RestClient::Exception, Errno::ECONNREFUSED => e
154
181
  self.handle_restclient_error(e)
155
182
  end
156
- rescue RestClient::Exception, Errno::ECONNREFUSED => e
157
- self.handle_restclient_error(e)
183
+
184
+ rbody = response.body
185
+ rcode = response.code
158
186
  end
159
187
 
160
- rbody = response.body
161
- rcode = response.code
188
+
189
+
162
190
 
163
191
  begin
164
192
  # Would use :symbolize_names => true, but apparently there is
@@ -166,7 +194,7 @@ module MachineShop
166
194
  resp = MachineShop::JSON.load(rbody)
167
195
  resp ||= {}
168
196
  resp = Util.symbolize_names(resp)
169
-
197
+ save_into_cache(url,resp,auth_token) if (http_verb == :get && cachedContent==:false)
170
198
  resp.merge!({:http_code => rcode}) if resp.is_a?(Hash)
171
199
  return resp
172
200
  rescue MultiJson::DecodeError
@@ -225,11 +253,219 @@ module MachineShop
225
253
  message = "Unexpected error communicating with MachineShop"
226
254
  end
227
255
  message += "\n\n(Network error: #{e.message})"
228
- # puts "error message string : #{message}"
229
256
  raise APIConnectionError.new(message)
230
257
  end
231
258
 
232
259
 
260
+ # Check if the class with the variable exists
261
+ def class_exists?(class_name)
262
+ klass = class_name.constantize
263
+ return klass.is_a?(Class)
264
+ rescue NameError =>e
265
+ return false
266
+ end
267
+
268
+
269
+ #get the classname from url and get the record if exists
270
+
271
+ #Check if db_connected
272
+ def db_connected?
273
+ db_connected = true
274
+ begin
275
+ MachineShop::Database.new
276
+ rescue DatabaseError =>e
277
+ db_connected= false
278
+ rescue SchemaError =>e
279
+ # db_connected=true
280
+ end
281
+
282
+ db_connected
283
+ end
284
+
285
+
286
+ def save_into_cache(url, data,auth_token)
287
+ if db_connected?
288
+
289
+ id=nil
290
+ splitted = url.split('/')
291
+ klass = splitted[-1]
292
+ if /[0-9]/.match(klass)
293
+ id=splitted[-1]
294
+ if splitted[-3]=="rule"
295
+ klass="rule"
296
+ else
297
+ klass = splitted[-2]
298
+ end
299
+ end
300
+
301
+ klass = klass.capitalize+"Cache"
302
+ modelClass ||= (Object.const_set klass, Class.new(ActiveRecord::Base))
303
+ modelClass.inheritance_column = :_type_disabled
304
+ #Because 'type' is reserved for storing the class in case of inheritance and our array has "TYPE" key
305
+
306
+ if ActiveRecord::Base.connection.table_exists? CGI.escape(klass.pluralize.underscore)
307
+ if data.class ==Hash
308
+
309
+ findId = data[:_id] || data["_id"]
310
+ @activeObject = modelClass.find_by(_id: findId) || modelClass.new
311
+
312
+ data.each do |k,v|
313
+
314
+ val=nil
315
+ if v.class==Array
316
+ val = v.to_json
317
+ elsif v.class==Hash
318
+ val = v.to_json
319
+ else
320
+ val=v
321
+ end
322
+ if @activeObject.has_attribute?(k)
323
+ @activeObject.send("#{k}=",val)
324
+ end
325
+ @activeObject.save
326
+ end
327
+
328
+
329
+ else
330
+ data.each do |data_arr|
331
+ if data_arr
332
+ if data_arr.first.class==String && data_arr.class==Array
333
+ @activeObject = modelClass.find_by(rule_condition: data_arr.select{|k| k.include?("rule_condition")}) || modelClass.new
334
+ data_arr.each do |k|
335
+ if k.include?("rule_condition")
336
+ @activeObject.rule_condition = k
337
+ else
338
+ @activeObject.rule_description=k
339
+ end
340
+ end
341
+ else
342
+ if data_arr.class!=String
343
+ findId = data_arr[:_id] || data_arr["_id"]
344
+ @activeObject = modelClass.find_by(_id: findId) || modelClass.new
345
+ data_arr.each do |k,v|
346
+ val=nil
347
+ if v.class==Array
348
+ val = v.to_json
349
+ elsif v.class==Hash
350
+ val = v.to_json
351
+ else
352
+ val=v
353
+ end
354
+
355
+ #check if the database has the particular field to store
356
+ if @activeObject.has_attribute?(k)
357
+ @activeObject.send("#{k}=",val)
358
+ end
359
+
360
+ end
361
+ end
362
+ end
363
+ end
364
+ @activeObject.send("auth_token=",auth_token)
365
+ @activeObject.save
366
+ end
367
+ end
368
+ end
369
+ end
370
+
371
+ end
372
+
373
+
374
+
375
+ def get_from_cache(url, body_hash,auth_token)
376
+ result =Array.new
377
+ if db_connected?
378
+
379
+ id=nil
380
+ splitted = url.split('/')
381
+ klass = splitted[-1]
382
+
383
+
384
+ if /[0-9]/.match(klass)
385
+ id=splitted[-1]
386
+
387
+ if splitted[-3]=="rule"
388
+ klass="rule"
389
+ else
390
+ klass = splitted[-2]
391
+ end
392
+
393
+ end
394
+
395
+ klass = klass.capitalize+"Cache"
396
+
397
+ modelClass = Object.const_set klass, Class.new(ActiveRecord::Base)
398
+ modelClass.inheritance_column = :_type_disabled
399
+
400
+ data_exist=false
401
+ if ActiveRecord::Base.connection.table_exists? CGI.escape(klass.pluralize.underscore)
402
+ resp= nil
403
+ if id
404
+ resp = modelClass.find_by(_id: id, auth_token: auth_token)
405
+ data_exist=true if resp
406
+ else
407
+ # pagination = body_hash.select{|k| k==:per_page || k==:page} if body_hash
408
+ resp = modelClass.where(parse_query_string(body_hash,auth_token))
409
+ data_exist = true if resp.exists?
410
+ end
411
+
412
+ if data_exist
413
+ if(klass.include?("rule_condition"))
414
+ resp.each do |rTemp|
415
+ temp = Array.new
416
+ temp.push rTemp["rule_description"]
417
+ temp.push rTemp["rule_condition"]
418
+ result << temp
419
+ end
420
+ result = result.to_json(:except=>[:id]) if result
421
+ else
422
+ result = resp.to_json(:except=>[:id]) if resp
423
+ end
424
+
425
+ end
426
+ end
427
+ end
428
+ return result
429
+ end
430
+
431
+ QUERY_STRING_BLACKLIST = [
432
+ 'page',
433
+ 'per_page'
434
+ ]
435
+
436
+ def parse_query_string(query_params,auth_token)
437
+
438
+ search_parms = {}
439
+ if query_params
440
+ params = Hash[query_params.map{ |k, v| [k.to_s, v] }]
441
+ operators = ["gt", "gte", "lt", "lte"]
442
+
443
+ xs = params.reject { |k,_| QUERY_STRING_BLACKLIST.include?(k) }
444
+ xs.each do |key,value|
445
+ tokens = key.split('_')
446
+ if tokens.nil? || tokens.length == 1
447
+ search_parms[key] = value
448
+ else
449
+ token_length = tokens[tokens.length-1].length-1
450
+ if operators.include?(tokens[tokens.length-1])
451
+ operator = "$" + tokens[tokens.length-1]
452
+ new_key = key[0,key.length-token_length-2].to_sym
453
+ search_parms[new_key] = { operator => value }
454
+ elsif tokens[tokens.length-1] == "between" && value.split("_").length > 1
455
+ new_key = key[0,key.length-token_length-2].to_sym
456
+ vals = value.split("_")
457
+ search_parms[new_key] = {"$gte" => vals[0], "$lte" => vals[1]}
458
+ else
459
+ search_parms[key] = value
460
+ end
461
+ end
462
+ end
463
+ end
464
+ #append auth_token = auth_token part as well
465
+ search_parms['auth_token']=auth_token
466
+ search_parms
467
+ end
468
+
233
469
 
234
470
  end
235
471
  end
@@ -4,7 +4,7 @@ module MachineShop
4
4
 
5
5
  def initialize
6
6
  #default values
7
- @expiry_time=6
7
+ @expiry_time=0
8
8
  @enable_caching = true
9
9
  end
10
10
  end
@@ -0,0 +1,28 @@
1
+ module MachineShop
2
+ class DataSourceTypes < APIResource
3
+ include MachineShop::APIOperations::List
4
+ include MachineShop::APIOperations::Create
5
+ include MachineShop::APIOperations::Delete
6
+
7
+
8
+ def create_data_source(params)
9
+ params.merge!({:data_source_type => self.id})
10
+ DataSources.create(params, @auth_token)
11
+ end
12
+
13
+ def create_email_data_source(params)
14
+ params.merge!({:data_source_type => self.id})
15
+ MachineShop.post(email_data_source_url, @auth_token, params)
16
+ end
17
+
18
+ private
19
+ def self.url
20
+ '/platform/data_source_types'
21
+ end
22
+
23
+ def email_data_source_url
24
+ '/platform/email_data_sources'
25
+ end
26
+
27
+ end
28
+ end