ruby-macrodroid 0.9.8 → 0.9.13

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.
@@ -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