ruby-macrodroid 0.8.9 → 0.8.10
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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +1 -3
- data/lib/ruby-macrodroid.rb +5 -502
- data/lib/ruby-macrodroid/actions.rb +3 -0
- data/lib/ruby-macrodroid/macro.rb +514 -0
- metadata +3 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b820bff4fbf40858e39fb86dcf5cca3c511fec1285c6ef642469f0222ae7858e
|
4
|
+
data.tar.gz: abea1d50f38024c84dcca885487915a6f878427d0f5504c98ce818976231eb8c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6f64c76e11c1b581e8e86bbddbcfec090e90c5673ecc72d64deeb542452a870252dc30a066f699f5ea1b682147f241d2518341b34cfefe6d5e70aacbe4cf22e6
|
7
|
+
data.tar.gz: b3e6b695cca7a0c10c14b4bde58c927504cc2f5e722ba2ca83fb9c905d51369b1a0912134a523ae4a3f6546dbf9e826585fddb6a56fa02799e2d72fcbd37a6d0
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
@@ -1,3 +1 @@
|
|
1
|
-
|
2
|
-
�����L'NK��D�qf�H�k�w�+ԐP]�\�X9��x��w���1wj{S9�fWDgc�6s��Yr�=�ų��UB�,�Q.�z�R�R\C���jC��탿Ru�����3����j�a+�������>�tv׳��[��Ѐ�0^
|
3
|
-
d[m6��N�e��HvLv
|
1
|
+
�����Qt�;�����Ɠ�5���
|
data/lib/ruby-macrodroid.rb
CHANGED
@@ -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'
|
@@ -345,500 +341,6 @@ end
|
|
345
341
|
|
346
342
|
|
347
343
|
|
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
344
|
|
843
345
|
|
844
346
|
class MacroDroidError < Exception
|
@@ -901,6 +403,7 @@ class MacroDroid
|
|
901
403
|
end
|
902
404
|
|
903
405
|
xml = RowX.new(raw_macros).to_xml
|
406
|
+
puts 'xml: ' + xml if @debug
|
904
407
|
import_rowxml(xml)
|
905
408
|
|
906
409
|
elsif s =~ /^# /
|
@@ -0,0 +1,514 @@
|
|
1
|
+
# file: ruby-macrodroid/macro.rb
|
2
|
+
|
3
|
+
|
4
|
+
# This file contains the following classes:
|
5
|
+
#
|
6
|
+
# ## Macro class
|
7
|
+
#
|
8
|
+
# Macro
|
9
|
+
|
10
|
+
class Macro
|
11
|
+
using ColouredText
|
12
|
+
using Params
|
13
|
+
|
14
|
+
attr_reader :local_variables, :triggers, :actions, :constraints,
|
15
|
+
:guid, :deviceid
|
16
|
+
attr_accessor :title, :description
|
17
|
+
|
18
|
+
def initialize(name=nil, geofences: nil, deviceid: nil, debug: false)
|
19
|
+
|
20
|
+
@title, @geofences, @deviceid, @debug = name, geofences, deviceid, debug
|
21
|
+
|
22
|
+
puts 'inside Macro#initialize' if @debug
|
23
|
+
|
24
|
+
@local_variables, @triggers, @actions, @constraints = [], [], [], []
|
25
|
+
@h = {}
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
def add(obj)
|
30
|
+
|
31
|
+
if obj.kind_of? Trigger then
|
32
|
+
|
33
|
+
puts 'trigger found' if @debug
|
34
|
+
@triggers << obj
|
35
|
+
|
36
|
+
elsif obj.kind_of? Action
|
37
|
+
|
38
|
+
puts 'action found' if @debug
|
39
|
+
@actions << obj
|
40
|
+
|
41
|
+
elsif obj.kind_of? Constraint
|
42
|
+
|
43
|
+
puts 'constraint found' if @debug
|
44
|
+
@constraints << obj
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_h()
|
51
|
+
|
52
|
+
h = {
|
53
|
+
local_variables: @local_variables,
|
54
|
+
m_trigger_list: @triggers.map(&:to_h),
|
55
|
+
m_action_list: @actions.map(&:to_h),
|
56
|
+
m_category: @category,
|
57
|
+
m_constraint_list: @constraints.map(&:to_h),
|
58
|
+
m_description: '',
|
59
|
+
m_name: title(),
|
60
|
+
m_excludeLog: false,
|
61
|
+
m_GUID: guid(),
|
62
|
+
m_isOrCondition: false,
|
63
|
+
m_enabled: false,
|
64
|
+
m_descriptionOpen: false,
|
65
|
+
m_headingColor: 0
|
66
|
+
}
|
67
|
+
|
68
|
+
puts 'h: ' + h.inspect if @debug
|
69
|
+
|
70
|
+
@h.merge(h)
|
71
|
+
end
|
72
|
+
|
73
|
+
def import_h(h)
|
74
|
+
|
75
|
+
if @debug then
|
76
|
+
puts 'inside import_h'
|
77
|
+
puts 'h:' + h.inspect
|
78
|
+
end
|
79
|
+
|
80
|
+
@category = h[:category]
|
81
|
+
@title = h[:name]
|
82
|
+
@description = h[:description]
|
83
|
+
|
84
|
+
# fetch the local variables
|
85
|
+
if h[:local_variables].any? and h[:local_variables].first.any? then
|
86
|
+
|
87
|
+
@local_variables = h[:local_variables].map do |var|
|
88
|
+
|
89
|
+
val = case var[:type]
|
90
|
+
when 0 # boolean
|
91
|
+
var[:boolean_value]
|
92
|
+
when 1 # integer
|
93
|
+
var[:int_value]
|
94
|
+
when 2 # string
|
95
|
+
var[:string_value]
|
96
|
+
when 3 # decimal
|
97
|
+
var[:decimal_Value]
|
98
|
+
end
|
99
|
+
|
100
|
+
[var[:name], val]
|
101
|
+
|
102
|
+
end.to_h
|
103
|
+
end
|
104
|
+
|
105
|
+
# fetch the triggers
|
106
|
+
@triggers = h[:trigger_list].map do |trigger|
|
107
|
+
puts 'trigger: ' + trigger.inspect
|
108
|
+
#exit
|
109
|
+
object(trigger.to_snake_case)
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
@actions = h[:action_list].map do |action|
|
114
|
+
object(action.to_snake_case)
|
115
|
+
end
|
116
|
+
puts 'before fetch constraints' if @debug
|
117
|
+
# fetch the constraints
|
118
|
+
@constraints = h[:constraint_list].map do |constraint|
|
119
|
+
object(constraint.to_snake_case)
|
120
|
+
end
|
121
|
+
puts 'after fetch constraints' if @debug
|
122
|
+
@h = h
|
123
|
+
|
124
|
+
%i(local_variables m_trigger_list m_action_list m_constraint_list)\
|
125
|
+
.each {|x| @h[x] = [] }
|
126
|
+
puts 'after @h set' if @debug
|
127
|
+
@h
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
def import_xml(node)
|
132
|
+
|
133
|
+
if @debug then
|
134
|
+
puts 'inside Macro#import_xml'
|
135
|
+
puts 'node: ' + node.xml.inspect
|
136
|
+
end
|
137
|
+
|
138
|
+
if node.element('triggers') then
|
139
|
+
|
140
|
+
# level 2
|
141
|
+
|
142
|
+
@title = node.attributes[:name]
|
143
|
+
@category = node.attributes[:category]
|
144
|
+
@description = node.attributes[:description]
|
145
|
+
|
146
|
+
|
147
|
+
# get all the triggers
|
148
|
+
@triggers = node.xpath('triggers/*').map do |e|
|
149
|
+
|
150
|
+
puts 'e.name: ' + e.name.inspect if @debug
|
151
|
+
{timer: TimerTrigger}[e.name.to_sym].new(e.attributes.to_h)
|
152
|
+
|
153
|
+
end
|
154
|
+
|
155
|
+
# get all the actions
|
156
|
+
@actions = node.xpath('actions/*').map do |e|
|
157
|
+
|
158
|
+
if e.name == 'notification' then
|
159
|
+
|
160
|
+
case e.attributes[:type].to_sym
|
161
|
+
when :popup
|
162
|
+
e.attributes.delete :type
|
163
|
+
ToastAction.new e.attributes.to_h
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|
169
|
+
|
170
|
+
# get all the constraints
|
171
|
+
@constraints = node.xpath('constraints/*').map do |e|
|
172
|
+
|
173
|
+
puts 'e.name: ' + e.name.inspect if @debug
|
174
|
+
{airplanemode: AirplaneModeConstraint}[e.name.to_sym].new(e.attributes.to_h)
|
175
|
+
|
176
|
+
end
|
177
|
+
|
178
|
+
else
|
179
|
+
|
180
|
+
# Level 1
|
181
|
+
|
182
|
+
puts 'import_xml: inside level 1' if @debug
|
183
|
+
|
184
|
+
@title = node.text('macro') || node.attributes[:name]
|
185
|
+
|
186
|
+
#@description = node.attributes[:description]
|
187
|
+
|
188
|
+
tp = TriggersNlp.new
|
189
|
+
|
190
|
+
@triggers = node.xpath('trigger').map do |e|
|
191
|
+
|
192
|
+
r = tp.find_trigger e.text
|
193
|
+
|
194
|
+
puts 'found trigger ' + r.inspect if @debug
|
195
|
+
|
196
|
+
if r then
|
197
|
+
if r[0] == GeofenceTrigger then
|
198
|
+
GeofenceTrigger.new(r[1], geofences: @geofences)
|
199
|
+
else
|
200
|
+
r[0].new(r[1])
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
end
|
205
|
+
|
206
|
+
ap = ActionsNlp.new
|
207
|
+
|
208
|
+
@actions = node.xpath('action').flat_map do |e|
|
209
|
+
|
210
|
+
puts 'action e: ' + e.xml.inspect if @debug
|
211
|
+
puts 'e.text ' + e.text if @debug
|
212
|
+
|
213
|
+
item = e.element('item')
|
214
|
+
if item then
|
215
|
+
|
216
|
+
if item.element('description') then
|
217
|
+
|
218
|
+
item.xpath('description').map do |description|
|
219
|
+
|
220
|
+
inner_lines = description.text.to_s.strip.lines
|
221
|
+
puts 'inner_lines: ' + inner_lines.inspect if @debug
|
222
|
+
|
223
|
+
action = if e.text.to_s.strip.empty? then
|
224
|
+
inner_lines.shift.strip
|
225
|
+
else
|
226
|
+
e.text.strip
|
227
|
+
end
|
228
|
+
|
229
|
+
r = ap.find_action action
|
230
|
+
r[0].new(description) if r
|
231
|
+
|
232
|
+
end
|
233
|
+
|
234
|
+
else
|
235
|
+
|
236
|
+
action = e.text.strip
|
237
|
+
r = ap.find_action action
|
238
|
+
|
239
|
+
a = e.xpath('item/*')
|
240
|
+
|
241
|
+
h = if a.any? then
|
242
|
+
a.map {|node| [node.name.to_sym, node.text.to_s]}.to_h
|
243
|
+
else
|
244
|
+
{}
|
245
|
+
end
|
246
|
+
|
247
|
+
r = ap.find_action action
|
248
|
+
r[0].new(h) if r
|
249
|
+
|
250
|
+
end
|
251
|
+
|
252
|
+
else
|
253
|
+
|
254
|
+
action = e.text.strip
|
255
|
+
r = ap.find_action action
|
256
|
+
r[0].new(r[1]) if r
|
257
|
+
|
258
|
+
end
|
259
|
+
|
260
|
+
end
|
261
|
+
|
262
|
+
cp = ConstraintsNlp.new
|
263
|
+
|
264
|
+
@constraints = node.xpath('constraint').map do |e|
|
265
|
+
|
266
|
+
r = cp.find_constraint e.text
|
267
|
+
puts 'found constraint ' + r.inspect if @debug
|
268
|
+
|
269
|
+
if r then
|
270
|
+
r[0].new(r[1])
|
271
|
+
end
|
272
|
+
|
273
|
+
end
|
274
|
+
|
275
|
+
end
|
276
|
+
|
277
|
+
self
|
278
|
+
|
279
|
+
end
|
280
|
+
|
281
|
+
def match?(triggerx, detail={time: $env[:time]}, model=nil )
|
282
|
+
|
283
|
+
if @triggers.any? {|x| x.type == triggerx and x.match?(detail, model) } then
|
284
|
+
|
285
|
+
if @debug then
|
286
|
+
puts 'checking constraints ...'
|
287
|
+
puts '@constraints: ' + @constraints.inspect
|
288
|
+
end
|
289
|
+
|
290
|
+
if @constraints.all? {|x| x.match?($env.merge(detail), model) } then
|
291
|
+
|
292
|
+
true
|
293
|
+
|
294
|
+
else
|
295
|
+
|
296
|
+
return false
|
297
|
+
|
298
|
+
end
|
299
|
+
|
300
|
+
end
|
301
|
+
|
302
|
+
end
|
303
|
+
|
304
|
+
# invokes the actions
|
305
|
+
#
|
306
|
+
def run()
|
307
|
+
@actions.map(&:invoke)
|
308
|
+
end
|
309
|
+
|
310
|
+
# prepares the environment in order for triggers to test fire successfully
|
311
|
+
# Used for testing
|
312
|
+
#
|
313
|
+
def set_env()
|
314
|
+
@triggers.each(&:set_env)
|
315
|
+
end
|
316
|
+
|
317
|
+
def to_pc()
|
318
|
+
|
319
|
+
heading = '# ' + @title
|
320
|
+
heading += '\n# ' + @description if @description
|
321
|
+
condition = @triggers.first.to_pc
|
322
|
+
actions = @actions.map(&:to_pc).join("\n")
|
323
|
+
|
324
|
+
<<EOF
|
325
|
+
#{heading}
|
326
|
+
|
327
|
+
if #{condition} then
|
328
|
+
#{actions}
|
329
|
+
end
|
330
|
+
EOF
|
331
|
+
end
|
332
|
+
|
333
|
+
def to_s(colour: false)
|
334
|
+
|
335
|
+
indent = 0 #@actions.map(&:to_s).join.lines.length > 0 ? 1 : 0
|
336
|
+
|
337
|
+
a = []
|
338
|
+
a << '# ' + @category + "\n" if @category
|
339
|
+
a << (colour ? "m".bg_cyan.gray.bold : 'm') + ': ' + @title
|
340
|
+
|
341
|
+
|
342
|
+
if @description and @description.length >= 1 then
|
343
|
+
a << (colour ? "d".bg_gray.gray.bold : 'd') + ': ' \
|
344
|
+
+ @description.gsub(/\n/,"\n ")
|
345
|
+
end
|
346
|
+
|
347
|
+
if @local_variables.length >= 1 then
|
348
|
+
|
349
|
+
vars = @local_variables.map do |k,v|
|
350
|
+
label = colour ? 'v'.bg_magenta : 'v'
|
351
|
+
label += ': '
|
352
|
+
label + "%s: %s" % [k,v]
|
353
|
+
end
|
354
|
+
|
355
|
+
a << vars.join("\n")
|
356
|
+
end
|
357
|
+
|
358
|
+
a << @triggers.map do |x|
|
359
|
+
s =-x.to_s(colour: colour)
|
360
|
+
|
361
|
+
s2 = if s.lines.length > 1 then
|
362
|
+
"\n" + s.lines.map {|x| x.prepend (' ' * (indent+1)) }.join
|
363
|
+
else
|
364
|
+
' ' + s
|
365
|
+
end
|
366
|
+
#s.lines > 1 ? "\n" + x : x
|
367
|
+
(colour ? "t".bg_red.gray.bold : 't') + ":" + s2
|
368
|
+
end.join("\n")
|
369
|
+
|
370
|
+
actions = @actions.map do |x|
|
371
|
+
|
372
|
+
|
373
|
+
s = x.to_s(colour: colour)
|
374
|
+
#puts 's: ' + s.inspect
|
375
|
+
|
376
|
+
|
377
|
+
|
378
|
+
r = if indent <= 0 then
|
379
|
+
|
380
|
+
lines = s.lines
|
381
|
+
|
382
|
+
if lines.length > 1 then
|
383
|
+
s = lines.map {|x| x.prepend (' ' * (indent+1)) }.join
|
384
|
+
end
|
385
|
+
|
386
|
+
s2 = s.lines.length > 1 ? "\n" + s : ' ' + s
|
387
|
+
|
388
|
+
if colour then
|
389
|
+
"a".bg_blue.gray.bold + ":" + s2
|
390
|
+
else
|
391
|
+
"a:" + s2
|
392
|
+
end
|
393
|
+
|
394
|
+
elsif indent > 0
|
395
|
+
|
396
|
+
if s =~ /^Else/ then
|
397
|
+
(' ' * (indent-1)) + "%s" % s
|
398
|
+
elsif s =~ /^End/
|
399
|
+
indent -= 1
|
400
|
+
(' ' * indent) + "%s" % s
|
401
|
+
else
|
402
|
+
s2 = s.lines[0] + s.lines[1..-1].map {|x| (' ' * indent) + x }.join
|
403
|
+
(' ' * indent) + "%s" % s2
|
404
|
+
end
|
405
|
+
|
406
|
+
end
|
407
|
+
|
408
|
+
if s =~ /^(?:If|DO \/ WHILE)/i then
|
409
|
+
|
410
|
+
if indent < 1 then
|
411
|
+
|
412
|
+
r = if colour then
|
413
|
+
"a".bg_blue.gray.bold + ":\n %s" % s
|
414
|
+
else
|
415
|
+
"a:\n %s" % s
|
416
|
+
end
|
417
|
+
|
418
|
+
indent += 1
|
419
|
+
else
|
420
|
+
r = (' ' * indent) + "%s" % s
|
421
|
+
end
|
422
|
+
|
423
|
+
indent += 1
|
424
|
+
end
|
425
|
+
|
426
|
+
r
|
427
|
+
|
428
|
+
end.join("\n")
|
429
|
+
|
430
|
+
|
431
|
+
|
432
|
+
|
433
|
+
a << actions
|
434
|
+
|
435
|
+
|
436
|
+
if @constraints.any? then
|
437
|
+
a << @constraints.map do |x|
|
438
|
+
(colour ? "c".bg_green.gray.bold : 'c') + ": %s" % x
|
439
|
+
end.join("\n")
|
440
|
+
end
|
441
|
+
|
442
|
+
|
443
|
+
|
444
|
+
|
445
|
+
|
446
|
+
a.join("\n") + "\n"
|
447
|
+
|
448
|
+
end
|
449
|
+
|
450
|
+
def to_summary(colour: false)
|
451
|
+
|
452
|
+
if colour then
|
453
|
+
|
454
|
+
a = [
|
455
|
+
'm'.bg_cyan.gray.bold + ': ' + @title,
|
456
|
+
't'.bg_red.gray.bold + ': ' + @triggers.map \
|
457
|
+
{|x| x.to_summary(colour: false)}.join(", "),
|
458
|
+
'a'.bg_blue.gray.bold + ': ' + @actions.map \
|
459
|
+
{|x| x.to_summary(colour: false)}.join(", ")
|
460
|
+
]
|
461
|
+
|
462
|
+
if @constraints.any? then
|
463
|
+
a << 'c'.bg_green.gray.bold + ': ' + @constraints.map \
|
464
|
+
{|x| x.to_summary(colour: false)}.join(", ")
|
465
|
+
end
|
466
|
+
|
467
|
+
else
|
468
|
+
|
469
|
+
a = [
|
470
|
+
'm: ' + @title,
|
471
|
+
't: ' + @triggers.map {|x| x.to_summary(colour: false)}.join(", "),
|
472
|
+
'a: ' + @actions.map {|x| x.to_summary(colour: false)}.join(", ")
|
473
|
+
]
|
474
|
+
|
475
|
+
if @constraints.any? then
|
476
|
+
a << 'c: ' + @constraints.map \
|
477
|
+
{|x| x.to_summary(colour: false)}.join(", ")
|
478
|
+
end
|
479
|
+
end
|
480
|
+
|
481
|
+
|
482
|
+
|
483
|
+
a.join("\n") + "\n"
|
484
|
+
|
485
|
+
end
|
486
|
+
|
487
|
+
private
|
488
|
+
|
489
|
+
def guid()
|
490
|
+
'-' + rand(1..9).to_s + 18.times.map { rand 9 }.join
|
491
|
+
end
|
492
|
+
|
493
|
+
def object(h={})
|
494
|
+
|
495
|
+
puts ('inside object h:' + h.inspect).debug if @debug
|
496
|
+
klass = Object.const_get h[:class_type]
|
497
|
+
puts klass.inspect.highlight if $debug
|
498
|
+
|
499
|
+
if klass == GeofenceTrigger then
|
500
|
+
puts 'GeofenceTrigger found'.highlight if $debug
|
501
|
+
GeofenceTrigger.new(h, geofences: @geofences)
|
502
|
+
else
|
503
|
+
puts 'before klass'
|
504
|
+
h2 = h.merge( macro: self)
|
505
|
+
puts 'h2: ' + h2.inspect
|
506
|
+
r = klass.new h2
|
507
|
+
puts 'r:' + r.inspect
|
508
|
+
r
|
509
|
+
|
510
|
+
end
|
511
|
+
|
512
|
+
end
|
513
|
+
|
514
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-macrodroid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Robertson
|
@@ -35,7 +35,7 @@ cert_chain:
|
|
35
35
|
NZ2kdBIUDnAM24e0/wXdVxg4HnsZbdymxyzMQ4P5pKYcpI6oisBxI37p/Xy+wAg3
|
36
36
|
SBHno3GEuuD8ZWj24IMJpfbp
|
37
37
|
-----END CERTIFICATE-----
|
38
|
-
date: 2020-09-
|
38
|
+
date: 2020-09-28 00:00:00.000000000 Z
|
39
39
|
dependencies:
|
40
40
|
- !ruby/object:Gem::Dependency
|
41
41
|
name: glw
|
@@ -186,6 +186,7 @@ files:
|
|
186
186
|
- lib/ruby-macrodroid.rb
|
187
187
|
- lib/ruby-macrodroid/actions.rb
|
188
188
|
- lib/ruby-macrodroid/base.rb
|
189
|
+
- lib/ruby-macrodroid/macro.rb
|
189
190
|
- lib/ruby-macrodroid/triggers.rb
|
190
191
|
homepage: https://github.com/jrobertson/ruby-macrodroid
|
191
192
|
licenses:
|
metadata.gz.sig
CHANGED
Binary file
|