ruby-macrodroid 0.8.9 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 12fa9c7d9f642140ed62656a4c3444e5c739ad2be06af2883e23e48766cd742f
4
- data.tar.gz: 6f70e2124afbcf43bd15295dfea8aaf9a0a8d6704de819acb34481082d8c905f
3
+ metadata.gz: 37e8014bb2ccd71ffd2da90197a1dd1a89c7e8e6bbbfc7ed88e9cfbff07925a1
4
+ data.tar.gz: f2d4910bb6893249e33eb7c4326ea733188ecef67ec94f808cd25ef6c97760d0
5
5
  SHA512:
6
- metadata.gz: a00b28e20a41ffbdead956eb07ad4e7fe412aa2ceb773017a709c97a4fd1307672b78405581a8e54d855d1f9cb53fe598638bc542facccde886b127e9e150d17
7
- data.tar.gz: ddcdc9689a2f202477018ab710772c834caad0e392c6d7135c0f65beb8e85dbf0144fc793e7b11db404531a1cbaf69876b2b21f7598b6baf1361ba794f7bc809
6
+ metadata.gz: 06015fe764a0450838ad49b6dbebba46afc32ec49673dbf4e1bce9b07e04aaea1850153cf2c0b1d56e740dd2cbcf4653f92878ee99680d7c3f2eaacf1fffb69e
7
+ data.tar.gz: df0c2950bcae690d137b294825c95579f8530fea24cabfe371809efff64343d4e9ffd71b5f2378c7938bc214dfc0e409892947ad03a86ef4438816fafa11000a
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -7,12 +7,7 @@
7
7
  # ## Nlp classes
8
8
  #
9
9
  # TriggersNlp ActionsNlp ConstraintsNlp
10
- #
11
- #
12
- # ## Macro class
13
- #
14
- # Macro
15
- #
10
+ #
16
11
  #
17
12
  # ## Error class
18
13
  #
@@ -31,11 +26,12 @@
31
26
  #
32
27
 
33
28
 
29
+
34
30
  require 'yaml'
35
31
  require 'rowx'
36
32
  require 'uuid'
37
- require 'glw'
38
- require 'geozone'
33
+ #require 'glw'
34
+ #require 'geozone'
39
35
  require 'geocoder'
40
36
  require 'subunit'
41
37
  require 'rxfhelper'
@@ -48,248 +44,6 @@ device
48
44
  airplane_mode is disabled
49
45
  EOF
50
46
 
51
- class TriggersNlp
52
- include AppRoutes
53
-
54
- def initialize()
55
-
56
- super()
57
- params = {}
58
- triggers(params)
59
-
60
- end
61
-
62
- def triggers(params)
63
-
64
- # e.g. at 7:30pm daily
65
- get /^(?:at )?(\d+:\d+(?:[ap]m)?) daily/i do |time, days|
66
- [TimerTrigger, {time: time,
67
- days: %w(Mon Tue Wed Thu Fri Sat Sun).join(', ')}]
68
- end
69
-
70
- get /^(?:at )?(\d+:\d+(?:[ap]m)?) (?:on )?(.*)/i do |time, days|
71
- [TimerTrigger, {time: time, days: days}]
72
- end
73
-
74
- # time.is? 'at 18:30pm on Mon or Tue'
75
- get /^time.is\? ['"](?:at )?(\d+:\d+(?:[ap]m)?) (?:on )?(.*)['"]/i do |time, days|
76
- [TimerTrigger, {time: time, days: days.gsub(' or ',', ')}]
77
- end
78
-
79
- get /^shake[ _]device\??$/i do
80
- [ShakeDeviceTrigger, {}]
81
- end
82
-
83
- get /^Flip Device (.*)$/i do |motion|
84
- facedown = motion =~ /Face Up (?:->|to) Face Down/i
85
- [FlipDeviceTrigger, {face_down: facedown }]
86
- end
87
-
88
- get /^flip_device_down\?$/i do
89
- [FlipDeviceTrigger, {face_down: true }]
90
- end
91
-
92
- get /^flip_device_up\?$/i do
93
- [FlipDeviceTrigger, {face_down: false }]
94
- end
95
-
96
- get /^Failed Login Attempt$/i do
97
- [FailedLoginTrigger, {}]
98
- end
99
-
100
- get /^failed_login?$/i do
101
- [FailedLoginTrigger, {}]
102
- end
103
-
104
- get /^Geofence (Entry|Exit) \(([^\)]+)/i do |direction, name|
105
- enter_area = direction.downcase.to_sym == :entry
106
- [GeofenceTrigger, {name: name, enter_area: enter_area}]
107
- end
108
-
109
- get /^location (entered|exited) \(([^\)]+)/i do |direction, name|
110
- enter_area = direction.downcase.to_sym == :entered
111
- [GeofenceTrigger, {name: name, enter_area: enter_area}]
112
- end
113
-
114
- # eg. Proximity Sensor (Near)
115
- #
116
- get /^Proximity Sensor \(([^\)]+)\)/i do |distance|
117
-
118
- [ProximityTrigger, {distance: distance}]
119
- end
120
-
121
-
122
-
123
- end
124
-
125
- alias find_trigger run_route
126
-
127
- def to_s(colour: false)
128
- 'TriggersNlp ' + @h.inspect
129
- end
130
-
131
- alias to_summary to_s
132
- end
133
-
134
- class ActionsNlp
135
- include AppRoutes
136
-
137
- def initialize()
138
-
139
- super()
140
- params = {}
141
- actions(params)
142
-
143
- end
144
-
145
- def actions(params)
146
-
147
- # e.g. message popup: hello world!
148
- get /^message popup: (.*)/i do |msg|
149
- [ToastAction, {msg: msg}]
150
- end
151
-
152
- # e.g. Popup Message 'hello world!'
153
- get /^Popup[ _]Message ['"]([^'"]+)/i do |msg|
154
- [ToastAction, {msg: msg}]
155
- end
156
-
157
- # e.g. Popup Message\n hello world!
158
- get /^Popup Message\n\s+(.*)/im do |msg|
159
- [ToastAction, {msg: msg}]
160
- end
161
-
162
- # e.g. Popup Message
163
- get /^Popup Message$/i do
164
- [ToastAction, {}]
165
- end
166
-
167
- # e.g. say current time
168
- get /^say current[ _]time/i do
169
- [SayTimeAction, {}]
170
- end
171
-
172
- get /^Torch :?(.*)/i do |onoffstate|
173
- state = onoffstate.downcase == 'on' ? 0 : 1
174
- [CameraFlashLightAction, {state: state}]
175
- end
176
-
177
- get /^Take Picture/i do
178
- [TakePictureAction, {}]
179
- end
180
-
181
- get /^take_picture/i do
182
- [TakePictureAction, {}]
183
- end
184
-
185
- # e.g. Display Notification: Hi there: This is the body of the message
186
- get /^Display Notification: ([^:]+): [^$]+$/i do |subject, text|
187
- [NotificationAction, {subject: subject, text: text}]
188
- end
189
-
190
-
191
- # e.g. Enable Wifi
192
- get /^(Enable|Disable) Wifi$/i do |raw_state|
193
-
194
- state = raw_state.downcase.to_sym == :enable ? 0 : 1
195
- [SetWifiAction, {state: state}]
196
-
197
- end
198
-
199
- # e.g. Play: Altair
200
- get /^Play: (.*)$/i do |name|
201
-
202
- [PlaySoundAction, {file_path: name}]
203
-
204
- end
205
-
206
- # e.g. Launch Settings
207
- get /^Launch (.*)$/i do |application|
208
-
209
- h = {
210
- application_name: application,
211
- package_to_launch: 'com.android.' + application.downcase
212
- }
213
- [LaunchActivityAction, h]
214
-
215
- end
216
-
217
- # e.g. HTTP GET http://someurl.com/something
218
- get /^HTTP GET ([^$]+)$/i do |url|
219
-
220
- [OpenWebPageAction, url_to_open: url]
221
-
222
- end
223
-
224
- # e.g. webhook entered_kitchen
225
- #
226
- get /webhook|HTTP GET/i do
227
- [OpenWebPageAction, {}]
228
- end
229
-
230
- #a: Keep Device Awake Screen On Until Disabled
231
- #
232
- get /Keep Device Awake Screen On Until Disabled/i do
233
- [KeepAwakeAction, {enabled: true, permanent: true, screen_option: 0}]
234
- end
235
-
236
-
237
- #a: Keep Device Awake Screen On 1h 1m 1s
238
- #
239
- get /Keep Device Awake Screen On ([^$]+)/i do |duration|
240
-
241
- a = duration.split.map(&:to_i)
242
- secs = Subunit.new(units={minutes:60, hours:60, seconds: 60}, a).to_i
243
-
244
- h = {
245
- permanent: true, screen_option: 0, seconds_to_stay_awake_for: secs
246
- }
247
- [KeepAwakeAction, h]
248
- end
249
-
250
- #a: Disable Keep Awake
251
- #
252
- get /Disable Keep Awake/i do
253
- [KeepAwakeAction, {enabled: false, screen_option: 0}]
254
- end
255
-
256
- #a: Disable Keep Awake
257
- #
258
- get /if (.*)/i do
259
- [IfConditionAction, {}]
260
- end
261
-
262
- end
263
-
264
- alias find_action run_route
265
-
266
-
267
- end
268
-
269
- class ConstraintsNlp
270
- include AppRoutes
271
-
272
- def initialize()
273
-
274
- super()
275
- params = {}
276
- constraints(params)
277
-
278
- end
279
-
280
- def constraints(params)
281
-
282
- get /^airplane mode (.*)/i do |state|
283
- [AirplaneModeConstraint, {enabled: (state =~ /^enabled|on$/) == 0}]
284
- end
285
-
286
- end
287
-
288
- alias find_constraint run_route
289
-
290
- end
291
-
292
-
293
47
  module Params
294
48
 
295
49
  refine Hash do
@@ -345,518 +99,23 @@ end
345
99
 
346
100
 
347
101
 
348
- class Macro
349
- using ColouredText
350
- using Params
351
-
352
- attr_reader :local_variables, :triggers, :actions, :constraints,
353
- :guid, :deviceid
354
- attr_accessor :title, :description
355
-
356
- def initialize(name=nil, geofences: nil, deviceid: nil, debug: false)
357
-
358
- @title, @geofences, @deviceid, @debug = name, geofences, deviceid, debug
359
-
360
- puts 'inside Macro#initialize' if @debug
361
-
362
- @local_variables, @triggers, @actions, @constraints = [], [], [], []
363
- @h = {}
364
-
365
- end
366
-
367
- def add(obj)
368
-
369
- if obj.kind_of? Trigger then
370
-
371
- puts 'trigger found' if @debug
372
- @triggers << obj
373
-
374
- elsif obj.kind_of? Action
375
-
376
- puts 'action found' if @debug
377
- @actions << obj
378
-
379
- elsif obj.kind_of? Constraint
380
-
381
- puts 'constraint found' if @debug
382
- @constraints << obj
383
-
384
- end
385
-
386
- end
387
-
388
- def to_h()
389
-
390
- h = {
391
- local_variables: @local_variables,
392
- m_trigger_list: @triggers.map(&:to_h),
393
- m_action_list: @actions.map(&:to_h),
394
- m_category: @category,
395
- m_constraint_list: @constraints.map(&:to_h),
396
- m_description: '',
397
- m_name: title(),
398
- m_excludeLog: false,
399
- m_GUID: guid(),
400
- m_isOrCondition: false,
401
- m_enabled: false,
402
- m_descriptionOpen: false,
403
- m_headingColor: 0
404
- }
405
-
406
- puts 'h: ' + h.inspect if @debug
407
-
408
- @h.merge(h)
409
- end
410
-
411
- def import_h(h)
412
-
413
- if @debug then
414
- puts 'inside import_h'
415
- puts 'h:' + h.inspect
416
- end
417
-
418
- @category = h[:category]
419
- @title = h[:name]
420
- @description = h[:description]
421
-
422
- # fetch the local variables
423
- if h[:local_variables].any? and h[:local_variables].first.any? then
424
-
425
- @local_variables = h[:local_variables].map do |var|
426
-
427
- val = case var[:type]
428
- when 0 # boolean
429
- var[:boolean_value]
430
- when 1 # integer
431
- var[:int_value]
432
- when 2 # string
433
- var[:string_value]
434
- when 3 # decimal
435
- var[:decimal_Value]
436
- end
437
-
438
- [var[:name], val]
439
-
440
- end.to_h
441
- end
442
-
443
- # fetch the triggers
444
- @triggers = h[:trigger_list].map do |trigger|
445
- puts 'trigger: ' + trigger.inspect
446
- #exit
447
- object(trigger.to_snake_case)
448
-
449
- end
450
-
451
- @actions = h[:action_list].map do |action|
452
- object(action.to_snake_case)
453
- end
454
- puts 'before fetch constraints' if @debug
455
- # fetch the constraints
456
- @constraints = h[:constraint_list].map do |constraint|
457
- object(constraint.to_snake_case)
458
- end
459
- puts 'after fetch constraints' if @debug
460
- @h = h
461
-
462
- %i(local_variables m_trigger_list m_action_list m_constraint_list)\
463
- .each {|x| @h[x] = [] }
464
- puts 'after @h set' if @debug
465
- @h
466
-
467
- end
468
-
469
- def import_xml(node)
470
-
471
- if @debug then
472
- puts 'inside Macro#import_xml'
473
- puts 'node: ' + node.xml.inspect
474
- end
475
-
476
- if node.element('triggers') then
477
-
478
- # level 2
479
-
480
- @title = node.attributes[:name]
481
- @category = node.attributes[:category]
482
- @description = node.attributes[:description]
483
-
484
-
485
- # get all the triggers
486
- @triggers = node.xpath('triggers/*').map do |e|
487
-
488
- puts 'e.name: ' + e.name.inspect if @debug
489
- {timer: TimerTrigger}[e.name.to_sym].new(e.attributes.to_h)
490
-
491
- end
492
-
493
- # get all the actions
494
- @actions = node.xpath('actions/*').map do |e|
495
-
496
- if e.name == 'notification' then
497
-
498
- case e.attributes[:type].to_sym
499
- when :popup
500
- e.attributes.delete :type
501
- ToastAction.new e.attributes.to_h
502
- end
503
-
504
- end
505
-
506
- end
507
-
508
- # get all the constraints
509
- @constraints = node.xpath('constraints/*').map do |e|
510
-
511
- puts 'e.name: ' + e.name.inspect if @debug
512
- {airplanemode: AirplaneModeConstraint}[e.name.to_sym].new(e.attributes.to_h)
513
-
514
- end
515
-
516
- else
517
-
518
- # Level 1
519
-
520
- puts 'import_xml: inside level 1' if @debug
521
-
522
- @title = node.text('macro') || node.attributes[:name]
523
-
524
- #@description = node.attributes[:description]
525
-
526
- tp = TriggersNlp.new
527
-
528
- @triggers = node.xpath('trigger').map do |e|
529
-
530
- r = tp.find_trigger e.text
531
-
532
- puts 'found trigger ' + r.inspect if @debug
533
-
534
- if r then
535
- if r[0] == GeofenceTrigger then
536
- GeofenceTrigger.new(r[1], geofences: @geofences)
537
- else
538
- r[0].new(r[1])
539
- end
540
- end
541
-
542
- end
543
-
544
- ap = ActionsNlp.new
545
-
546
- @actions = node.xpath('action').map do |e|
547
-
548
- puts 'action e: ' + e.xml.inspect if @debug
549
- puts 'e.text ' + e.text if @debug
550
-
551
- inner_lines = e.xpath('item/description/text()')
552
-
553
- action = if e.text.to_s.strip.empty? then
554
- inner_lines.shift.strip
555
- else
556
- e.text.strip
557
- end
558
-
559
- r = ap.find_action action
560
- puts 'found action ' + r.inspect if @debug
561
-
562
- if r then
563
-
564
- loose = inner_lines.shift
565
-
566
- raw_attributes = if loose then
567
-
568
- puts 'do something ' + loose.to_s if @debug
569
- loose.to_s
570
-
571
- else
572
-
573
- a = e.xpath('item/*')
574
-
575
- h = if a.any? then
576
- a.map {|node| [node.name.to_sym, node.text.to_s]}.to_h
577
- else
578
- {}
579
- end
580
-
581
- r[1].merge(h)
582
-
583
- end
584
- r[0].new(raw_attributes)
585
- end
586
-
587
- end
588
-
589
- cp = ConstraintsNlp.new
590
-
591
- @constraints = node.xpath('constraint').map do |e|
592
-
593
- r = cp.find_constraint e.text
594
- puts 'found constraint ' + r.inspect if @debug
595
-
596
- if r then
597
- r[0].new(r[1])
598
- end
599
-
600
- end
601
-
602
- end
603
-
604
- self
605
-
606
- end
607
-
608
- def match?(triggerx, detail={time: $env[:time]}, model=nil )
609
-
610
- if @triggers.any? {|x| x.type == triggerx and x.match?(detail, model) } then
611
-
612
- if @debug then
613
- puts 'checking constraints ...'
614
- puts '@constraints: ' + @constraints.inspect
615
- end
616
-
617
- if @constraints.all? {|x| x.match?($env.merge(detail), model) } then
618
-
619
- true
620
-
621
- else
622
-
623
- return false
624
-
625
- end
626
-
627
- end
628
-
629
- end
630
-
631
- # invokes the actions
632
- #
633
- def run()
634
- @actions.map(&:invoke)
635
- end
636
-
637
- # prepares the environment in order for triggers to test fire successfully
638
- # Used for testing
639
- #
640
- def set_env()
641
- @triggers.each(&:set_env)
642
- end
643
-
644
- def to_pc()
645
-
646
- heading = '# ' + @title
647
- heading += '\n# ' + @description if @description
648
- condition = @triggers.first.to_pc
649
- actions = @actions.map(&:to_pc).join("\n")
650
-
651
- <<EOF
652
- #{heading}
653
-
654
- if #{condition} then
655
- #{actions}
656
- end
657
- EOF
658
- end
659
-
660
- def to_s(colour: false)
661
-
662
- indent = 0 #@actions.map(&:to_s).join.lines.length > 0 ? 1 : 0
663
-
664
- a = []
665
- a << '# ' + @category + "\n" if @category
666
- a << (colour ? "m".bg_cyan.gray.bold : 'm') + ': ' + @title
667
-
668
-
669
- if @description and @description.length >= 1 then
670
- a << (colour ? "d".bg_gray.gray.bold : 'd') + ': ' \
671
- + @description.gsub(/\n/,"\n ")
672
- end
673
-
674
- if @local_variables.length >= 1 then
675
-
676
- vars = @local_variables.map do |k,v|
677
- label = colour ? 'v'.bg_magenta : 'v'
678
- label += ': '
679
- label + "%s: %s" % [k,v]
680
- end
681
-
682
- a << vars.join("\n")
683
- end
684
-
685
- a << @triggers.map do |x|
686
- s =-x.to_s(colour: colour)
687
-
688
- s2 = if s.lines.length > 1 then
689
- "\n" + s.lines.map {|x| x.prepend (' ' * (indent+1)) }.join
690
- else
691
- ' ' + s
692
- end
693
- #s.lines > 1 ? "\n" + x : x
694
- (colour ? "t".bg_red.gray.bold : 't') + ":" + s2
695
- end.join("\n")
696
-
697
- actions = @actions.map do |x|
698
-
699
-
700
- s = x.to_s(colour: colour)
701
- #puts 's: ' + s.inspect
702
-
703
-
704
-
705
- r = if indent <= 0 then
706
-
707
- lines = s.lines
708
-
709
- if lines.length > 1 then
710
- s = lines.map {|x| x.prepend (' ' * (indent+1)) }.join
711
- end
712
-
713
- s2 = s.lines.length > 1 ? "\n" + s : ' ' + s
714
-
715
- if colour then
716
- "a".bg_blue.gray.bold + ":" + s2
717
- else
718
- "a:" + s2
719
- end
720
-
721
- elsif indent > 0
722
-
723
- if s =~ /^Else/ then
724
- (' ' * (indent-1)) + "%s" % s
725
- elsif s =~ /^End/
726
- indent -= 1
727
- (' ' * indent) + "%s" % s
728
- else
729
- s2 = s.lines[0] + s.lines[1..-1].map {|x| (' ' * indent) + x }.join
730
- (' ' * indent) + "%s" % s2
731
- end
732
-
733
- end
734
-
735
- if s =~ /^(?:If|DO \/ WHILE)/i then
736
-
737
- if indent < 1 then
738
-
739
- r = if colour then
740
- "a".bg_blue.gray.bold + ":\n %s" % s
741
- else
742
- "a:\n %s" % s
743
- end
744
-
745
- indent += 1
746
- else
747
- r = (' ' * indent) + "%s" % s
748
- end
749
-
750
- indent += 1
751
- end
752
-
753
- r
754
-
755
- end.join("\n")
756
-
757
-
758
-
759
-
760
- a << actions
761
-
762
-
763
- if @constraints.any? then
764
- a << @constraints.map do |x|
765
- (colour ? "c".bg_green.gray.bold : 'c') + ": %s" % x
766
- end.join("\n")
767
- end
768
-
769
-
770
-
771
-
772
-
773
- a.join("\n") + "\n"
774
-
775
- end
776
-
777
- def to_summary(colour: false)
778
-
779
- if colour then
780
-
781
- a = [
782
- 'm'.bg_cyan.gray.bold + ': ' + @title,
783
- 't'.bg_red.gray.bold + ': ' + @triggers.map \
784
- {|x| x.to_summary(colour: false)}.join(", "),
785
- 'a'.bg_blue.gray.bold + ': ' + @actions.map \
786
- {|x| x.to_summary(colour: false)}.join(", ")
787
- ]
788
-
789
- if @constraints.any? then
790
- a << 'c'.bg_green.gray.bold + ': ' + @constraints.map \
791
- {|x| x.to_summary(colour: false)}.join(", ")
792
- end
793
-
794
- else
795
-
796
- a = [
797
- 'm: ' + @title,
798
- 't: ' + @triggers.map {|x| x.to_summary(colour: false)}.join(", "),
799
- 'a: ' + @actions.map {|x| x.to_summary(colour: false)}.join(", ")
800
- ]
801
-
802
- if @constraints.any? then
803
- a << 'c: ' + @constraints.map \
804
- {|x| x.to_summary(colour: false)}.join(", ")
805
- end
806
- end
807
-
808
-
809
-
810
- a.join("\n") + "\n"
811
-
812
- end
813
-
814
- private
815
-
816
- def guid()
817
- '-' + rand(1..9).to_s + 18.times.map { rand 9 }.join
818
- end
819
-
820
- def object(h={})
821
-
822
- puts ('inside object h:' + h.inspect).debug if @debug
823
- klass = Object.const_get h[:class_type]
824
- puts klass.inspect.highlight if $debug
825
-
826
- if klass == GeofenceTrigger then
827
- puts 'GeofenceTrigger found'.highlight if $debug
828
- GeofenceTrigger.new(h, geofences: @geofences)
829
- else
830
- puts 'before klass'
831
- h2 = h.merge( macro: self)
832
- puts 'h2: ' + h2.inspect
833
- r = klass.new h2
834
- puts 'r:' + r.inspect
835
- r
836
-
837
- end
838
-
839
- end
840
-
841
- end
842
-
843
-
844
102
  class MacroDroidError < Exception
845
103
  end
846
104
 
847
105
  class MacroDroid
106
+ include RXFHelperModule
848
107
  using ColouredText
849
108
  using Params
850
109
 
851
110
  attr_reader :macros, :geofences, :yaml
852
- attr_accessor :deviceid
111
+ attr_accessor :deviceid, :remote_url
853
112
 
854
113
  # note: The deviceid can only be found from an existing Webhook trigger,
855
114
  # generated from MacroDroid itself.
856
115
 
857
- def initialize(obj=nil, deviceid: nil, debug: false)
116
+ def initialize(obj=nil, deviceid: nil, remote_url: nil, debug: false)
858
117
 
859
- @deviceid, @debug = deviceid, debug
118
+ @deviceid, @remote_url, @debug = deviceid, remote_url, debug
860
119
 
861
120
  @geofences = {}
862
121
 
@@ -885,10 +144,16 @@ class MacroDroid
885
144
  puts 'before RowX.new' if @debug
886
145
 
887
146
  s2 = s.gsub(/^g:/,'geofence:').gsub(/^m:/,'macro:')\
888
- .gsub(/^t:/,'trigger:').gsub(/^a:/,'action:')\
889
- .gsub(/^c:/,'constraint:').gsub(/^#.*/,'')
147
+ .gsub(/^v:/,'variable:').gsub(/^t:/,'trigger:')\
148
+ .gsub(/^a:/,'action:').gsub(/^c:/,'constraint:').gsub(/^#.*/,'')
149
+
150
+ a = s2.split(/(?=^macro:)/)
890
151
 
891
- raw_macros, raw_geofences = s2.split(/(?=^macro:)/,2).reverse
152
+ raw_geofences = a.shift if a.first =~ /^geofence/
153
+ raw_macros = a.join
154
+ #raw_macros, raw_geofences .reverse
155
+
156
+ puts 'raw_macros: ' + raw_macros.inspect if @debug
892
157
 
893
158
  if raw_geofences then
894
159
 
@@ -901,6 +166,7 @@ class MacroDroid
901
166
  end
902
167
 
903
168
  xml = RowX.new(raw_macros).to_xml
169
+ puts 'xml: ' + xml if @debug
904
170
  import_rowxml(xml)
905
171
 
906
172
  elsif s =~ /^# /
@@ -954,14 +220,16 @@ class MacroDroid
954
220
 
955
221
  }
956
222
  end
223
+
224
+ def export(filepath)
225
+ FileX.write filepath, to_json
226
+ end
957
227
 
958
- def export_json()
228
+ def to_json()
959
229
 
960
230
  to_h.to_json
961
231
 
962
232
  end
963
-
964
- alias to_json export_json
965
233
 
966
234
 
967
235
  def to_h()
@@ -1063,7 +331,7 @@ class MacroDroid
1063
331
  # puts '@geofences: ' + @geofences.inspect if @debug
1064
332
 
1065
333
  m = Macro.new(geofences: @geofences.map(&:last), deviceid: @deviceid,
1066
- debug: @debug )
334
+ remote_url: @remote_url, debug: @debug )
1067
335
  m.import_h(macro)
1068
336
  m
1069
337
 
@@ -1085,7 +353,7 @@ class MacroDroid
1085
353
  @macros = doc.root.xpath('item').map do |node|
1086
354
  puts ('geofences: ' + geofences.inspect).highlight if @debug
1087
355
  Macro.new(geofences: geofences.map(&:last), deviceid: @deviceid,
1088
- debug: @debug).import_xml(node)
356
+ remote_url: @remote_url, debug: @debug).import_xml(node)
1089
357
 
1090
358
  end
1091
359
 
@@ -1107,7 +375,7 @@ class MacroDroid
1107
375
  end
1108
376
 
1109
377
  @macros = doc.root.xpath('macro').map do |node|
1110
-
378
+ puts 'node: ' + node.inspect if @debug
1111
379
  Macro.new(geofences: @geofences.map(&:last), deviceid: @deviceid,
1112
380
  debug: @debug).import_xml(node)
1113
381
 
@@ -1308,7 +576,9 @@ class DroidSim
1308
576
 
1309
577
  end
1310
578
 
579
+
1311
580
  require 'ruby-macrodroid/base'
1312
581
  require 'ruby-macrodroid/triggers'
1313
582
  require 'ruby-macrodroid/actions'
1314
583
  require 'ruby-macrodroid/constraints'
584
+ require 'ruby-macrodroid/macro'