ruby-macrodroid 0.9.8 → 0.9.13

Sign up to get free protection for your applications and to get access to all the features.
@@ -34,7 +34,10 @@ module ObjectX
34
34
  r = ap.find_action action
35
35
  puts 'r: ' + r.inspect if debug
36
36
 
37
- if r[1].any? then
37
+ nested = description.element('item/description')
38
+ puts 'nested: ' + nested.inspect if debug
39
+
40
+ if r[1].any? and not nested then
38
41
 
39
42
  macro.add r[0].new(r[1])
40
43
 
@@ -44,7 +47,7 @@ module ObjectX
44
47
  #o = r[0].new([description, self]) if r
45
48
  index = macro.actions.length
46
49
  macro.add Action.new
47
- o = object_create(r[0],[description, macro]) if r
50
+ o = object_create(r[0],[description, macro, r[1]]) if r
48
51
  macro.actions[index] = o
49
52
  puts 'after o' if debug
50
53
  o
@@ -194,14 +197,15 @@ class MacroObject
194
197
  private
195
198
 
196
199
  def hashify(h)
197
- puts 'h: ' + h.inspect
200
+ #puts 'h: ' + h.inspect
198
201
  h2 = h.inject({}) do |r,x|
199
- puts 'x: ' + x.inspect #if $debug
202
+ #puts 'x: ' + x.inspect #if $debug
200
203
  key, value = x
201
- puts 'key: ' + key.inspect #if $debug
204
+ #puts 'key: ' + key.inspect #if $debug
202
205
  new_key = key.to_s.gsub(/\w_\w/){|x| x[0] + x[-1].upcase}
203
206
  new_key = new_key.prepend 'm_' unless @list.include? new_key
204
207
  new_key = 'm_SIGUID' if new_key == 'm_siguid'
208
+ new_key = 'm_SSIDList' if new_key == 'm_ssidList'
205
209
  new_val = value.is_a?(Hash) ? hashify(value) : value
206
210
  r.merge(new_key => new_val)
207
211
  end
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # file: constraintsnlp.rb
4
+
5
+
6
+ class ConstraintsNlp
7
+ include AppRoutes
8
+
9
+ def initialize()
10
+
11
+ super()
12
+ params = {}
13
+ constraints(params)
14
+
15
+ end
16
+
17
+ def constraints(params)
18
+
19
+ # Device State
20
+
21
+ get /^Device (locked|unlocked)/i do |state|
22
+ [DeviceLockedConstraint, {locked: state.downcase == 'locked'}]
23
+ end
24
+
25
+ get /^airplane mode (.*)/i do |state|
26
+ [AirplaneModeConstraint, {enabled: (state =~ /^enabled|on$/i) == 0}]
27
+ end
28
+
29
+ #
30
+
31
+ # -- MacroDroid specific -----------------------------------------------------------------------
32
+
33
+ get /^(\w+) (=) (.*)/i do |loperand, operator, roperand|
34
+
35
+ h = {
36
+ loperand: loperand,
37
+ operator: operator,
38
+ roperand: roperand
39
+ }
40
+
41
+ [MacroDroidVariableConstraint, h]
42
+
43
+ end
44
+
45
+ # -- Sensors -----------------------------------
46
+ #
47
+ get /^Light Sensor (Less|Greater) than (50.0)lx/i do |operator, val|
48
+
49
+ level, option = operator.downcase == 'less' ? [-1,0] : [1,1]
50
+
51
+ h = {
52
+ light_level: level,
53
+ light_level_float: val,
54
+ option: option
55
+ }
56
+
57
+ [LightLevelConstraint, h]
58
+ end
59
+
60
+ get /^Proximity Sensor: (Near|Far)/i do |distance|
61
+ [ProximitySensorConstraint, {near: distance.downcase == 'near'}]
62
+ end
63
+
64
+
65
+ # -- Screen and Speaker ---------------------------
66
+ #
67
+ get /^Screen (On|Off)/i do |state|
68
+ [ScreenOnOffConstraint, {screen_on: state.downcase == 'on'}]
69
+ end
70
+
71
+ end
72
+
73
+ alias find_constraint run_route
74
+
75
+ end
@@ -2,17 +2,12 @@
2
2
 
3
3
 
4
4
  # This file contains the following classes:
5
- #
6
- # ## Nlp classes
7
- #
8
- # TriggersNlp ActionsNlp ConstraintsNlp
9
- #
5
+ #
10
6
  # ## Macro class
11
7
  #
12
8
  # Macro
13
9
 
14
10
 
15
-
16
11
  VAR_TYPES = {
17
12
  String: [2, :string_value],
18
13
  TrueClass: [0, :boolean_value],
@@ -22,446 +17,6 @@ VAR_TYPES = {
22
17
  }
23
18
 
24
19
 
25
-
26
- class TriggersNlp
27
- include AppRoutes
28
- using ColouredText
29
-
30
- def initialize(macro=nil)
31
-
32
- super()
33
- params = {macro: macro}
34
- triggers(params)
35
-
36
- end
37
-
38
- def triggers(params)
39
-
40
- # -- Battery/Power ---------------------------------------------
41
-
42
- get /^Power Connected: (Wired \([^\)]+\))/i do |s|
43
-
44
- h = {
45
- power_connected_options: [true, true, true],
46
- has_set_usb_option: true,
47
- power_connected: true
48
- }
49
-
50
- a = ['Wired (Fast Charge)', 'Wireless', 'Wired (Slow Charge)']
51
-
52
- puts ('s: ' + s.inspect).debug
53
-
54
- options = s.downcase.split(/ \+ /)
55
- puts ('options: ' + options.inspect).debug
56
-
57
- h[:power_connected_options] = a.map {|x| options.include? x.downcase }
58
-
59
- [ExternalPowerTrigger, h]
60
- end
61
-
62
- get /^Power Connected: Any/i do |s|
63
-
64
- h = {
65
- power_connected_options: [true, true, true],
66
- has_set_usb_option: true,
67
- power_connected: true
68
- }
69
-
70
- [ExternalPowerTrigger, h]
71
- end
72
-
73
- # -- Device Events ----------------------------------------------------
74
-
75
- get /^Screen[ _](On|Off)/i do |state|
76
- [ScreenOnOffTrigger, {screen_on: state.downcase == 'on'}]
77
- end
78
-
79
- # e.g. at 7:30pm daily
80
- get /^(?:at )?(\d+:\d+(?:[ap]m)?) daily/i do |time, days|
81
- [TimerTrigger, {time: time,
82
- days: %w(Mon Tue Wed Thu Fri Sat Sun).join(', ')}]
83
- end
84
-
85
- get /^(?:at )?(\d+:\d+(?:[ap]m)?) (?:on )?(.*)/i do |time, days|
86
- [TimerTrigger, {time: time, days: days}]
87
- end
88
-
89
- # time.is? 'at 18:30pm on Mon or Tue'
90
- get /^time.is\? ['"](?:at )?(\d+:\d+(?:[ap]m)?) (?:on )?(.*)['"]/i do |time, days|
91
- [TimerTrigger, {time: time, days: days.gsub(' or ',', ')}]
92
- end
93
-
94
- get /^shake[ _]device\??$/i do
95
- [ShakeDeviceTrigger, {}]
96
- end
97
-
98
- get /^Flip Device (.*)$/i do |motion|
99
- facedown = motion =~ /Face Up (?:->|to) Face Down/i
100
- [FlipDeviceTrigger, {face_down: facedown }]
101
- end
102
-
103
- get /^flip_device_down\?$/i do
104
- [FlipDeviceTrigger, {face_down: true }]
105
- end
106
-
107
- get /^flip_device_up\?$/i do
108
- [FlipDeviceTrigger, {face_down: false }]
109
- end
110
-
111
- get /^Failed Login Attempt$/i do
112
- [FailedLoginTrigger, {}]
113
- end
114
-
115
- get /^failed_login?$/i do
116
- [FailedLoginTrigger, {}]
117
- end
118
-
119
- get /^Geofence (Entry|Exit) \(([^\)]+)/i do |direction, name|
120
- enter_area = direction.downcase.to_sym == :entry
121
- [GeofenceTrigger, {name: name, enter_area: enter_area}]
122
- end
123
-
124
- get /^location (entered|exited) \(([^\)]+)/i do |direction, name|
125
- enter_area = direction.downcase.to_sym == :entered
126
- [GeofenceTrigger, {name: name, enter_area: enter_area}]
127
- end
128
-
129
- # eg. Proximity Sensor (Near)
130
- #
131
- get /^Proximity Sensor \(([^\)]+)\)/i do |distance|
132
-
133
- [ProximityTrigger, {distance: distance}]
134
- end
135
-
136
- # eg. Proximity near
137
- #
138
- get /^Proximity (near|far|slow wave|fast wave)/i do |distance|
139
-
140
- [ProximityTrigger, {distance: distance}]
141
- end
142
-
143
- get /^WebHook \(Url\)/i do
144
- [WebHookTrigger, params]
145
- end
146
-
147
- get /^WebHook/i do
148
- [WebHookTrigger, params]
149
- end
150
-
151
- get /^wh/i do
152
- [WebHookTrigger, params]
153
- end
154
-
155
- # MacroDroid specific ---------------------------------------------------------------
156
-
157
- get /^EmptyTrigger$/i do
158
- [EmptyTrigger, params]
159
- end
160
-
161
- end
162
-
163
- alias find_trigger run_route
164
-
165
- def to_s(colour: false)
166
- 'TriggersNlp ' + @h.inspect
167
- end
168
-
169
- alias to_summary to_s
170
- end
171
-
172
- class ActionsNlp
173
- include AppRoutes
174
-
175
- def initialize(macro=nil)
176
-
177
- super()
178
-
179
- params = {macro: macro}
180
- actions(params)
181
-
182
- end
183
-
184
- def actions(params)
185
-
186
- # -- Connectivity ------------------------------------------------------
187
-
188
- get /^(Enable|Disable) HotSpot/i do |state|
189
- enable, state = if state.downcase == 'enable' then
190
- [true, 0]
191
- else
192
- [false, 1]
193
- end
194
- [SetHotspotAction, {turn_wifi_on: enable, state: state }]
195
- end
196
-
197
- # e.g. message popup: hello world!
198
- get /^message popup: (.*)/i do |msg|
199
- [ToastAction, {msg: msg}]
200
- end
201
-
202
- # e.g. Popup Message 'hello world!'
203
- get /^Popup[ _]Message ['"]([^'"]+)/i do |msg|
204
- [ToastAction, {msg: msg}]
205
- end
206
-
207
- # e.g. Popup Message\n hello world!
208
- get /^Popup Message\n\s+(.*)/im do |msg|
209
- [ToastAction, {msg: msg}]
210
- end
211
-
212
- # e.g. Popup Message
213
- get /^Popup Message$/i do
214
- [ToastAction, {}]
215
- end
216
-
217
- # e.g. say current time
218
- get /^say current[ _]time/i do
219
- [SayTimeAction, {}]
220
- end
221
-
222
- get /^Torch :?(.*)/i do |onoffstate|
223
- state = %w(on off toggle).index onoffstate.downcase
224
- [CameraFlashLightAction, {state: state}]
225
- end
226
-
227
- get /^Take Picture/i do
228
- [TakePictureAction, {}]
229
- end
230
-
231
- get /^take_picture/i do
232
- [TakePictureAction, {}]
233
- end
234
-
235
- # -- DEVICE ACTIONS ------------------------------------------------------
236
-
237
- get /^Speak text \(([^\)]+)\)/i do |text|
238
- [SpeakTextAction, {text: text}]
239
- end
240
-
241
- get /^Speak text ['"]([^'"]+)/i do |text|
242
- [SpeakTextAction, {text: text}]
243
- end
244
-
245
- get /^Speak text$/i do |text|
246
- [SpeakTextAction, {}]
247
- end
248
-
249
- get /^Vibrate \(([^\)]+)/i do |pattern|
250
- [VibrateAction, {pattern: pattern}]
251
- end
252
-
253
- get /^Vibrate$/i do |pattern|
254
- [VibrateAction, {pattern: 'short buzz'}]
255
- end
256
-
257
- # e.g. Display Notification: Hi there: This is the body of the message
258
- get /^Display Notification: ([^:]+): [^$]+$/i do |subject, text|
259
- [NotificationAction, {subject: subject, text: text}]
260
- end
261
-
262
-
263
- # e.g. Enable Wifi
264
- get /^(Enable|Disable) Wifi$/i do |raw_state|
265
-
266
- state = raw_state.downcase.to_sym == :enable ? 0 : 1
267
- [SetWifiAction, {state: state}]
268
-
269
- end
270
-
271
- # e.g. Play: Altair
272
- get /^Play: (.*)$/i do |name|
273
-
274
- [PlaySoundAction, {file_path: name}]
275
-
276
- end
277
-
278
- # e.g. Launch Settings
279
- get /^Launch (.*)$/i do |application|
280
-
281
- h = {
282
- application_name: application,
283
- package_to_launch: 'com.android.' + application.downcase
284
- }
285
- [LaunchActivityAction, h]
286
-
287
- end
288
-
289
- # e.g. HTTP GET http://someurl.com/something
290
- get /^HTTP GET ([^$]+)$/i do |url|
291
-
292
- [OpenWebPageAction, url_to_open: url]
293
-
294
- end
295
-
296
- get /^HTTP GET$/i do
297
-
298
- [OpenWebPageAction, {}]
299
-
300
- end
301
-
302
- # e.g. webhook entered_kitchen
303
- #
304
- get /(?:webhook|HTTP GET) ([^$]+)$/i do |s|
305
- key = s =~ /^http/ ? :url_to_open : :identifier
306
- [OpenWebPageAction, {key => s}]
307
- end
308
-
309
- #
310
- get /^WebHook \(Url\)/i do
311
- [OpenWebPageAction, {}]
312
- end
313
-
314
- # e.g. webhook entered_kitchen
315
- #
316
- get /^webhook$/i do
317
- [OpenWebPageAction, {}, params[:macro]]
318
- end
319
-
320
- # -- Location ---------------------------------------------------------
321
-
322
- get /^Force Location Update$/i do
323
- [ForceLocationUpdateAction, params]
324
- end
325
-
326
- get /^Share Location$/i do
327
- [ShareLocationAction, {}]
328
- end
329
-
330
- #a: Keep Device Awake Screen On Until Disabled
331
- #
332
- get /Keep Device Awake Screen On Until Disabled/i do
333
- [KeepAwakeAction, {enabled: true, permanent: true, screen_option: 0}]
334
- end
335
-
336
-
337
- #a: Keep Device Awake Screen On 1h 1m 1s
338
- #
339
- get /Keep Device Awake Screen On ([^$]+)/i do |duration|
340
-
341
- a = duration.split.map(&:to_i)
342
- secs = Subunit.new(units={minutes:60, hours:60, seconds: 60}, a).to_i
343
-
344
- h = {
345
- permanent: true, screen_option: 0, seconds_to_stay_awake_for: secs
346
- }
347
- [KeepAwakeAction, h]
348
- end
349
-
350
- get /Keep Device Awake$/i do
351
- [KeepAwakeAction, {}]
352
- end
353
-
354
- #a: Disable Keep Awake
355
- #
356
- get /Disable Keep Awake/i do
357
- [KeepAwakeAction, {enabled: false, screen_option: 0}]
358
- end
359
-
360
- #e.g a: if Airplane mode enabled
361
- #
362
- get /if (.*)/i do
363
- [IfConditionAction, {}]
364
- end
365
-
366
- get /else/i do
367
- [ElseAction, {}]
368
- end
369
-
370
- get /End If/i do
371
- [EndIfAction, {}]
372
- end
373
-
374
- # -- MacroDroid Specific ------------------------------------------------
375
- #
376
- get /^Set Variable$/i do
377
- [SetVariableAction, {}]
378
- end
379
-
380
- # -- Screen ------------------------------------------------
381
- #
382
- get /^Screen (On|Off)$/i do |state|
383
- [ScreenOnAction, {screen_off: state.downcase == 'off'}]
384
- end
385
-
386
- end
387
-
388
- alias find_action run_route
389
-
390
-
391
- end
392
-
393
- class ConstraintsNlp
394
- include AppRoutes
395
-
396
- def initialize()
397
-
398
- super()
399
- params = {}
400
- constraints(params)
401
-
402
- end
403
-
404
- def constraints(params)
405
-
406
- # Device State
407
-
408
- get /^Device (locked|unlocked)/i do |state|
409
- [DeviceLockedConstraint, {locked: state.downcase == 'locked'}]
410
- end
411
-
412
- get /^airplane mode (.*)/i do |state|
413
- [AirplaneModeConstraint, {enabled: (state =~ /^enabled|on$/i) == 0}]
414
- end
415
-
416
- #
417
-
418
- # -- MacroDroid specific -----------------------------------------------------------------------
419
-
420
- get /^(\w+) (=) (\[?\w+\]?)/i do |loperand, operator, roperand|
421
-
422
- h = {
423
- loperand: loperand,
424
- operator: operator,
425
- roperand: roperand
426
- }
427
-
428
- [MacroDroidVariableConstraint, h]
429
-
430
- end
431
-
432
- # -- Sensors -----------------------------------
433
- #
434
- get /^Light Sensor (Less|Greater) than (50.0)lx/i do |operator, val|
435
-
436
- level, option = operator.downcase == 'less' ? [-1,0] : [1,1]
437
-
438
- h = {
439
- light_level: level,
440
- light_level_float: val,
441
- option: option
442
- }
443
-
444
- [LightLevelConstraint, h]
445
- end
446
-
447
- get /^Proximity Sensor: (Near|Far)/i do |distance|
448
- [ProximitySensorConstraint, {near: distance.downcase == 'near'}]
449
- end
450
-
451
-
452
- # -- Screen and Speaker ---------------------------
453
- #
454
- get /^Screen (On|Off)/i do |state|
455
- [ScreenOnOffConstraint, {screen_on: state.downcase == 'on'}]
456
- end
457
-
458
- end
459
-
460
- alias find_constraint run_route
461
-
462
- end
463
-
464
-
465
20
  class MacroError < Exception
466
21
  end
467
22
 
@@ -471,19 +26,21 @@ class Macro
471
26
  include ObjectX
472
27
 
473
28
  attr_reader :local_variables, :triggers, :actions, :constraints,
474
- :guid, :deviceid
29
+ :guid, :deviceid, :parent
475
30
  attr_accessor :title, :description, :remote_url, :picture_path
476
31
 
477
32
  def initialize(name=nil, geofences: nil, deviceid: nil, remote_url: nil, \
478
- picture_path: nil, debug: false)
33
+ picture_path: nil, parent: nil, debug: false)
479
34
 
480
35
  @title, @geofences, @deviceid, @debug = name, geofences, deviceid, debug
481
- @remote_url, @picture_path = remote_url, picture_path
36
+ @remote_url, @picture_path, @parent = remote_url, picture_path, parent
482
37
 
483
38
  puts 'inside Macro#initialize' if @debug
484
39
 
485
40
  @local_variables, @triggers, @actions, @constraints = {}, [], [], []
486
41
  @h = {}
42
+ @guid = generate_guid()
43
+ @enabled = true
487
44
 
488
45
  end
489
46
 
@@ -509,6 +66,18 @@ class Macro
509
66
  end
510
67
 
511
68
  end
69
+
70
+ def disable()
71
+ @enabled = false
72
+ end
73
+
74
+ def enable()
75
+ @enabled = true
76
+ end
77
+
78
+ def enabled?()
79
+ @enabled
80
+ end
512
81
 
513
82
  def to_h()
514
83
 
@@ -525,9 +94,9 @@ class Macro
525
94
  m_description: '',
526
95
  m_name: title(),
527
96
  m_excludeLog: false,
528
- m_GUID: guid(),
97
+ m_GUID: @guid,
529
98
  m_isOrCondition: false,
530
- m_enabled: true,
99
+ m_enabled: @enabled,
531
100
  m_descriptionOpen: false,
532
101
  m_headingColor: 0
533
102
  }
@@ -544,6 +113,7 @@ class Macro
544
113
  puts 'h:' + h.inspect
545
114
  end
546
115
 
116
+ @guid = h[:guid]
547
117
  @category = h[:category]
548
118
  @title = h[:name]
549
119
  @description = h[:description]
@@ -698,7 +268,7 @@ class Macro
698
268
  r = tp.find_trigger trigger
699
269
  puts 'r: ' + r.inspect if @debug
700
270
  #o = r[0].new([description, self]) if r
701
- o = object_create(r[0], [description, self]) if r
271
+ o = object_create(r[0], [description, self, r[1]]) if r
702
272
  puts 'after o' if @debug
703
273
  o
704
274
 
@@ -744,7 +314,6 @@ class Macro
744
314
 
745
315
  end
746
316
 
747
-
748
317
 
749
318
  ap = ActionsNlp.new self
750
319
 
@@ -918,8 +487,6 @@ EOF
918
487
  s = x.to_s(colour: colour)
919
488
  #puts 's: ' + s.inspect
920
489
 
921
-
922
-
923
490
  r = if indent <= 0 then
924
491
 
925
492
  lines = s.lines
@@ -972,9 +539,6 @@ EOF
972
539
 
973
540
  end.join("\n")
974
541
 
975
-
976
-
977
-
978
542
  a << actions
979
543
 
980
544
 
@@ -985,10 +549,6 @@ EOF
985
549
  end.join("\n")
986
550
  end
987
551
 
988
-
989
-
990
-
991
-
992
552
  a.join("\n") + "\n"
993
553
 
994
554
  end
@@ -1032,8 +592,8 @@ EOF
1032
592
 
1033
593
  private
1034
594
 
1035
- def guid()
1036
- '-' + rand(1..9).to_s + 18.times.map { rand 9 }.join
595
+ def generate_guid()
596
+ ('-' + rand(1..9).to_s + 18.times.map { rand 9 }.join).to_i
1037
597
  end
1038
598
 
1039
599
  def object(h={})
@@ -1055,9 +615,6 @@ EOF
1055
615
 
1056
616
  end
1057
617
 
1058
- end
1059
-
1060
-
1061
-
618
+ end
1062
619
 
1063
620
  end