ruby-macrodroid 0.8.8 → 0.9.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
  SHA256:
3
- metadata.gz: 24d851b05dbc6ecfd52b146846a6bbe935a06d30bfdf523c0550bd18c701b93b
4
- data.tar.gz: 97171c71818bc1d0ce3ed70dc790f3464170e18f8ff62b5b3ff47b66f40c49d0
3
+ metadata.gz: 6f4d8a484f60935d656a2ac7973ca917709201955fe55897ce27d2430cb8ec93
4
+ data.tar.gz: d886539a6623877a521969d869d8d4b5690191795ffa6710dc0df5149b123707
5
5
  SHA512:
6
- metadata.gz: a9187782e93e70a758e50a07c49812d5bb915dab37bb108d174157a76d76cc2b625b766665ad5ac3f47c7d12d3ac8082b291966aa36c114d4d573ddf38e567b3
7
- data.tar.gz: 7514ffbe6a9b4c063fe278c685ce0a860b4d28a1945d4819faa65b081395b701b5dab657a3d7764b87689f230c74d7c14051e563ad4360937ade7f78466ac3a3
6
+ metadata.gz: 5d6251c0656a7ff30a252bc3ef38dcdd27da42ef278f34e07d4d03d07a2d11a7bab346e39330d76d17d69dd5f8d2d6091f89a81e691b1c47d7513013781e0524
7
+ data.tar.gz: bd12b85b6ef51759358f4c7e44e5671a1f69119d156ba25806eeb287e67da4f6cd50aca09940e6b4e5c0e3b9b96475be4dde49ce7f8a01694634e764e45fe343
Binary file
data.tar.gz.sig CHANGED
@@ -1,2 +1,2 @@
1
- \�-��1g(3�&�oԓz�7R�,$�ǝ�_�gb����
2
- ���;t1ӎ���M��(Y棸����s_��*A� ���mX�l4}Mݩ�{������ꉻ;��
1
+ #�[fb��f
2
+ ϱ�>�Q
@@ -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'
@@ -51,10 +47,10 @@ EOF
51
47
  class TriggersNlp
52
48
  include AppRoutes
53
49
 
54
- def initialize()
50
+ def initialize(macro=nil)
55
51
 
56
52
  super()
57
- params = {}
53
+ params = {macro: macro}
58
54
  triggers(params)
59
55
 
60
56
  end
@@ -117,7 +113,18 @@ class TriggersNlp
117
113
 
118
114
  [ProximityTrigger, {distance: distance}]
119
115
  end
116
+
117
+ get /^WebHook \(Url\)/i do
118
+ [WebHookTrigger, params]
119
+ end
120
120
 
121
+ get /^WebHook/i do
122
+ [WebHookTrigger, params]
123
+ end
124
+
125
+ get /^wh/i do
126
+ [WebHookTrigger, params]
127
+ end
121
128
 
122
129
 
123
130
  end
@@ -134,10 +141,10 @@ end
134
141
  class ActionsNlp
135
142
  include AppRoutes
136
143
 
137
- def initialize()
144
+ def initialize(macro=nil)
138
145
 
139
146
  super()
140
- params = {}
147
+ params = {macro: macro}
141
148
  actions(params)
142
149
 
143
150
  end
@@ -170,7 +177,7 @@ class ActionsNlp
170
177
  end
171
178
 
172
179
  get /^Torch :?(.*)/i do |onoffstate|
173
- state = onoffstate.downcase == 'on' ? 0 : 1
180
+ state = %w(on off toggle).index onoffstate.downcase
174
181
  [CameraFlashLightAction, {state: state}]
175
182
  end
176
183
 
@@ -223,8 +230,20 @@ class ActionsNlp
223
230
 
224
231
  # e.g. webhook entered_kitchen
225
232
  #
226
- get /webhook|HTTP GET/i do
227
- [OpenWebPageAction, {}]
233
+ get /(?:webhook|HTTP GET) ([^$]+)$/i do |s|
234
+ key = s =~ /^http/ ? :url_to_open : :identifier
235
+ [OpenWebPageAction, {key => s}]
236
+ end
237
+
238
+ #
239
+ get /^WebHook \(Url\)/i do
240
+ [OpenWebPageAction, params]
241
+ end
242
+
243
+ # e.g. webhook entered_kitchen
244
+ #
245
+ get /^webhook$/i do
246
+ [OpenWebPageAction, params]
228
247
  end
229
248
 
230
249
  #a: Keep Device Awake Screen On Until Disabled
@@ -253,11 +272,15 @@ class ActionsNlp
253
272
  [KeepAwakeAction, {enabled: false, screen_option: 0}]
254
273
  end
255
274
 
256
- #a: Disable Keep Awake
275
+ #e.g a: if Airplane mode enabled
257
276
  #
258
277
  get /if (.*)/i do
259
278
  [IfConditionAction, {}]
260
- end
279
+ end
280
+
281
+ get /End If/i do
282
+ [EndIfAction, {}]
283
+ end
261
284
 
262
285
  end
263
286
 
@@ -280,7 +303,7 @@ class ConstraintsNlp
280
303
  def constraints(params)
281
304
 
282
305
  get /^airplane mode (.*)/i do |state|
283
- [AirplaneModeConstraint, {enabled: (state =~ /^enabled|on$/) == 0}]
306
+ [AirplaneModeConstraint, {enabled: (state =~ /^enabled|on$/i) == 0}]
284
307
  end
285
308
 
286
309
  end
@@ -345,495 +368,25 @@ end
345
368
 
346
369
 
347
370
 
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
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
663
- actions = @actions.map do |x|
664
-
665
- s = x.to_s(colour: colour)
666
- if s.lines.length > 1 then
667
- lines = s.lines
668
- s = lines[0] + lines[1..-1].map {|x| x.prepend (' ' * indent) }.join
669
- end
670
-
671
- r = if indent <= 0 then
672
-
673
- if colour then
674
- "a".bg_blue.gray.bold + ": %s" % s
675
- else
676
- "a: %s" % s
677
- end
678
-
679
- elsif indent > 0
680
-
681
- if s =~ /^Else/ then
682
- (' ' * (indent-1)) + "%s" % s
683
- elsif s =~ /^End/
684
- indent -= 1
685
- (' ' * indent) + "%s" % s
686
- else
687
- (' ' * indent) + "%s" % s
688
- end
689
-
690
- end
691
-
692
- if s =~ /^(?:If|DO \/ WHILE)/i then
693
-
694
- if indent < 1 then
695
-
696
- r = if colour then
697
- "a".bg_blue.gray.bold + ":\n %s" % s
698
- else
699
- "a:\n %s" % s
700
- end
701
-
702
- indent += 1
703
- else
704
- r = (' ' * indent) + "%s" % s
705
- end
706
-
707
- indent += 1
708
- end
709
-
710
- r
711
-
712
- end.join("\n")
713
-
714
- a = []
715
- a << '# ' + @category + "\n" if @category
716
- a << (colour ? "m".bg_cyan.gray.bold : 'm') + ': ' + @title
717
-
718
-
719
- if @description and @description.length >= 1 then
720
- a << (colour ? "d".bg_gray.gray.bold : 'd') + ': ' \
721
- + @description.gsub(/\n/,"\n ")
722
- end
723
-
724
- if @local_variables.length >= 1 then
725
-
726
- vars = @local_variables.map do |k,v|
727
- label = colour ? 'v'.bg_magenta : 'v'
728
- label += ': '
729
- label + "%s: %s" % [k,v]
730
- end
731
-
732
- a << vars.join("\n")
733
- end
734
-
735
- a << @triggers.map {|x| (colour ? "t".bg_red.gray.bold : 't') \
736
- + ": %s" % x}.join("\n")
737
- a << actions
738
-
739
-
740
- if @constraints.any? then
741
- a << @constraints.map do |x|
742
- (colour ? "c".bg_green.gray.bold : 'c') + ": %s" % x
743
- end.join("\n")
744
- end
745
-
746
-
747
-
748
-
749
-
750
- a.join("\n") + "\n"
751
-
752
- end
753
-
754
- def to_summary(colour: false)
755
-
756
- if colour then
757
-
758
- a = [
759
- 'm'.bg_cyan.gray.bold + ': ' + @title,
760
- 't'.bg_red.gray.bold + ': ' + @triggers.map \
761
- {|x| x.to_summary(colour: false)}.join(", "),
762
- 'a'.bg_blue.gray.bold + ': ' + @actions.map \
763
- {|x| x.to_summary(colour: false)}.join(", ")
764
- ]
765
-
766
- if @constraints.any? then
767
- a << 'c'.bg_green.gray.bold + ': ' + @constraints.map \
768
- {|x| x.to_summary(colour: false)}.join(", ")
769
- end
770
-
771
- else
772
-
773
- a = [
774
- 'm: ' + @title,
775
- 't: ' + @triggers.map {|x| x.to_summary(colour: false)}.join(", "),
776
- 'a: ' + @actions.map {|x| x.to_summary(colour: false)}.join(", ")
777
- ]
778
-
779
- if @constraints.any? then
780
- a << 'c: ' + @constraints.map \
781
- {|x| x.to_summary(colour: false)}.join(", ")
782
- end
783
- end
784
-
785
-
786
-
787
- a.join("\n") + "\n"
788
-
789
- end
790
-
791
- private
792
-
793
- def guid()
794
- '-' + rand(1..9).to_s + 18.times.map { rand 9 }.join
795
- end
796
-
797
- def object(h={})
798
-
799
- puts ('inside object h:' + h.inspect).debug if @debug
800
- klass = Object.const_get h[:class_type]
801
- puts klass.inspect.highlight if $debug
802
-
803
- if klass == GeofenceTrigger then
804
- puts 'GeofenceTrigger found'.highlight if $debug
805
- GeofenceTrigger.new(h, geofences: @geofences)
806
- else
807
- puts 'before klass'
808
- h2 = h.merge( macro: self)
809
- puts 'h2: ' + h2.inspect
810
- r = klass.new h2
811
- puts 'r:' + r.inspect
812
- r
813
-
814
- end
815
-
816
- end
817
-
818
- end
819
371
 
820
372
 
821
373
  class MacroDroidError < Exception
822
374
  end
823
375
 
824
376
  class MacroDroid
377
+ include RXFHelperModule
825
378
  using ColouredText
826
379
  using Params
827
380
 
828
381
  attr_reader :macros, :geofences, :yaml
829
- attr_accessor :deviceid
382
+ attr_accessor :deviceid, :remote_url
830
383
 
831
384
  # note: The deviceid can only be found from an existing Webhook trigger,
832
385
  # generated from MacroDroid itself.
833
386
 
834
- def initialize(obj=nil, deviceid: nil, debug: false)
387
+ def initialize(obj=nil, deviceid: nil, remote_url: nil, debug: false)
835
388
 
836
- @deviceid, @debug = deviceid, debug
389
+ @deviceid, @remote_url, @debug = deviceid, remote_url, debug
837
390
 
838
391
  @geofences = {}
839
392
 
@@ -862,10 +415,16 @@ class MacroDroid
862
415
  puts 'before RowX.new' if @debug
863
416
 
864
417
  s2 = s.gsub(/^g:/,'geofence:').gsub(/^m:/,'macro:')\
865
- .gsub(/^t:/,'trigger:').gsub(/^a:/,'action:')\
866
- .gsub(/^c:/,'constraint:').gsub(/^#.*/,'')
418
+ .gsub(/^v:/,'variable:').gsub(/^t:/,'trigger:')\
419
+ .gsub(/^a:/,'action:').gsub(/^c:/,'constraint:').gsub(/^#.*/,'')
420
+
421
+ a = s2.split(/(?=^macro:)/)
867
422
 
868
- raw_macros, raw_geofences = s2.split(/(?=^macro:)/,2).reverse
423
+ raw_geofences = a.shift if a.first =~ /^geofence/
424
+ raw_macros = a.join
425
+ #raw_macros, raw_geofences .reverse
426
+
427
+ puts 'raw_macros: ' + raw_macros.inspect if @debug
869
428
 
870
429
  if raw_geofences then
871
430
 
@@ -878,6 +437,7 @@ class MacroDroid
878
437
  end
879
438
 
880
439
  xml = RowX.new(raw_macros).to_xml
440
+ puts 'xml: ' + xml if @debug
881
441
  import_rowxml(xml)
882
442
 
883
443
  elsif s =~ /^# /
@@ -931,14 +491,16 @@ class MacroDroid
931
491
 
932
492
  }
933
493
  end
494
+
495
+ def export(filepath)
496
+ FileX.write filepath, to_json
497
+ end
934
498
 
935
- def export_json()
499
+ def to_json()
936
500
 
937
501
  to_h.to_json
938
502
 
939
503
  end
940
-
941
- alias to_json export_json
942
504
 
943
505
 
944
506
  def to_h()
@@ -1040,7 +602,7 @@ class MacroDroid
1040
602
  # puts '@geofences: ' + @geofences.inspect if @debug
1041
603
 
1042
604
  m = Macro.new(geofences: @geofences.map(&:last), deviceid: @deviceid,
1043
- debug: @debug )
605
+ remote_url: @remote_url, debug: @debug )
1044
606
  m.import_h(macro)
1045
607
  m
1046
608
 
@@ -1062,7 +624,7 @@ class MacroDroid
1062
624
  @macros = doc.root.xpath('item').map do |node|
1063
625
  puts ('geofences: ' + geofences.inspect).highlight if @debug
1064
626
  Macro.new(geofences: geofences.map(&:last), deviceid: @deviceid,
1065
- debug: @debug).import_xml(node)
627
+ remote_url: @remote_url, debug: @debug).import_xml(node)
1066
628
 
1067
629
  end
1068
630
 
@@ -1084,7 +646,7 @@ class MacroDroid
1084
646
  end
1085
647
 
1086
648
  @macros = doc.root.xpath('macro').map do |node|
1087
-
649
+ puts 'node: ' + node.inspect if @debug
1088
650
  Macro.new(geofences: @geofences.map(&:last), deviceid: @deviceid,
1089
651
  debug: @debug).import_xml(node)
1090
652
 
@@ -1285,7 +847,9 @@ class DroidSim
1285
847
 
1286
848
  end
1287
849
 
850
+
1288
851
  require 'ruby-macrodroid/base'
1289
852
  require 'ruby-macrodroid/triggers'
1290
853
  require 'ruby-macrodroid/actions'
1291
854
  require 'ruby-macrodroid/constraints'
855
+ require 'ruby-macrodroid/macro'