ruby-macrodroid 0.8.8 → 0.9.0

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: 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'