ruby-macrodroid 0.9.1 → 0.9.2
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 +0 -0
- data/lib/ruby-macrodroid.rb +6 -5
- data/lib/ruby-macrodroid/actions.rb +72 -28
- data/lib/ruby-macrodroid/base.rb +21 -15
- data/lib/ruby-macrodroid/macro.rb +413 -58
- data/lib/ruby-macrodroid/triggers.rb +15 -9
- metadata +2 -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: d378de53e069fe32854e621ab9b72b08a0785f99957f57cf4933d650287be069
|
4
|
+
data.tar.gz: 856870eab31f6fffd85f55f1a61315dbec075f9bcbe89b8111e15eca5a064b54
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 42ec4a29e2a2976767cd62eaa3630388acd4777a07ea72ba95549d2ba0f184d8e8e8fb433385d1610c796c4bcecd9dc613372f702fe9c15e626c0717d26a13ab
|
7
|
+
data.tar.gz: 7fec30fda5d214a892b703ba5cf9ea3e1c9d0b6a5d7bf72221c6fa286558807d7f629c7fc0f6c0b858161873dc2e1a3323c7598fc3c61788848f72e848cabea8
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/lib/ruby-macrodroid.rb
CHANGED
@@ -38,6 +38,7 @@ require 'rxfhelper'
|
|
38
38
|
require 'chronic_cron'
|
39
39
|
|
40
40
|
|
41
|
+
|
41
42
|
MODEL =<<EOF
|
42
43
|
device
|
43
44
|
connectivity
|
@@ -73,16 +74,16 @@ module Params
|
|
73
74
|
end
|
74
75
|
|
75
76
|
# turns keys from snake_case to CamelCase
|
76
|
-
def
|
77
|
+
def to_camelcase(h=self)
|
77
78
|
|
78
79
|
h.inject({}) do |r,x|
|
79
80
|
|
80
81
|
key, value = x
|
81
82
|
|
82
83
|
val = if value.is_a?(Hash) then
|
83
|
-
|
84
|
+
to_camelcase(value)
|
84
85
|
elsif value.is_a?(Array) and value.first.is_a? Hash
|
85
|
-
value.map {|row|
|
86
|
+
value.map {|row| to_camelcase(row)}
|
86
87
|
else
|
87
88
|
value
|
88
89
|
end
|
@@ -165,7 +166,7 @@ class MacroDroid
|
|
165
166
|
|
166
167
|
end
|
167
168
|
|
168
|
-
xml = RowX.new(raw_macros).to_xml
|
169
|
+
xml = RowX.new(raw_macros, allow_lonely_keyfield: true).to_xml
|
169
170
|
puts 'xml: ' + xml if @debug
|
170
171
|
import_rowxml(xml)
|
171
172
|
|
@@ -240,7 +241,7 @@ class MacroDroid
|
|
240
241
|
},
|
241
242
|
macro_list: @macros.map(&:to_h)
|
242
243
|
}
|
243
|
-
@h.merge(h).
|
244
|
+
@h.merge(h).to_camelcase
|
244
245
|
|
245
246
|
end
|
246
247
|
|
@@ -145,12 +145,15 @@ class OpenWebPageAction < ApplicationAction
|
|
145
145
|
|
146
146
|
def initialize(obj={}, macro=nil)
|
147
147
|
|
148
|
+
# puts 'obj: ' + obj[0].xml.inspect
|
149
|
+
|
148
150
|
h = if obj.is_a? Hash then
|
149
151
|
|
150
152
|
obj
|
151
153
|
|
152
154
|
elsif obj.is_a? Array
|
153
|
-
|
155
|
+
|
156
|
+
puts 'obj: ' + obj.inspect if $debug
|
154
157
|
e, macro = obj
|
155
158
|
|
156
159
|
a = e.xpath('item/*')
|
@@ -166,41 +169,54 @@ class OpenWebPageAction < ApplicationAction
|
|
166
169
|
|
167
170
|
end
|
168
171
|
|
169
|
-
puts 'h:' + h.inspect if
|
172
|
+
puts 'h:' + h.inspect if $debug
|
170
173
|
|
171
|
-
h[:url_to_open] = h[:url] if h[:url] and h[:url].length > 1
|
174
|
+
#h[:url_to_open] = h[:url] if h[:url] and h[:url].length > 1
|
172
175
|
|
173
176
|
options = {
|
174
|
-
variable_to_save_response: {:
|
175
|
-
|
176
|
-
excludeFromLog: false,
|
177
|
+
variable_to_save_response: {:string_value=>"", :name=>"coords",
|
178
|
+
decimal_value: 0.0, isLocal: true, m_boolean_value: false,
|
179
|
+
excludeFromLog: false, int_value: 0, type: 2},
|
177
180
|
url_to_open: '',
|
178
181
|
http_get: true,
|
179
182
|
disable_url_encode: false,
|
180
183
|
block_next_action: false
|
181
184
|
}
|
182
185
|
|
183
|
-
|
184
|
-
|
186
|
+
return super(options.merge h) if h[:url_to_open]
|
187
|
+
|
188
|
+
if h[:macro].remote_url.nil? and (h[:url].nil? or h[:url].empty?) then
|
185
189
|
raise OpenWebPageActionError, 'remote_url not found'
|
186
190
|
end
|
187
191
|
|
188
|
-
if
|
189
|
-
|
192
|
+
url = if h[:url] and h[:url].length > 1 then
|
193
|
+
|
194
|
+
h[:url]
|
195
|
+
|
196
|
+
elsif h2 and h[:macro].remote_url and h[:identifier]
|
197
|
+
|
198
|
+
"%s/%s" % [h[:macro].remote_url.sub(/\/$/,''), h[:identifier]]
|
199
|
+
|
200
|
+
elsif (h[:identifier].nil? or h[:identifier].empty?)
|
190
201
|
|
191
202
|
h[:url_to_open] = h[:macro].remote_url.sub(/\/$/,'') + '/' +
|
192
|
-
h[:macro].title.downcase.gsub(/ +/,'-')
|
203
|
+
h[:macro].title.downcase.gsub(/ +/,'-')
|
193
204
|
|
194
|
-
|
205
|
+
end
|
206
|
+
|
207
|
+
if h2 then
|
195
208
|
|
196
|
-
url = "%s/%s" % [h[:macro].remote_url.sub(/\/$/,''), h[:identifier]]
|
197
209
|
h2.delete :identifier
|
198
|
-
url
|
199
|
-
URI.escape(h2.map {|key,value| "%s=%s" % [key, value]}.join('&'))
|
200
|
-
h[:url_to_open] = url
|
210
|
+
h2.delete :url
|
201
211
|
|
202
|
-
|
212
|
+
if h2.any? then
|
213
|
+
url += '?' + \
|
214
|
+
URI.escape(h2.map {|key,value| "%s=%s" % [key, value]}.join('&'))
|
215
|
+
end
|
216
|
+
|
217
|
+
end
|
203
218
|
|
219
|
+
h[:url_to_open] = url
|
204
220
|
super(options.merge h)
|
205
221
|
|
206
222
|
end
|
@@ -1338,7 +1354,7 @@ class ForceLocationUpdateAction < LocationAction
|
|
1338
1354
|
end
|
1339
1355
|
|
1340
1356
|
def to_s(colour: false, indent: 0)
|
1341
|
-
'
|
1357
|
+
'Force Location Update' #+ @h.inspect
|
1342
1358
|
end
|
1343
1359
|
|
1344
1360
|
alias to_summary to_s
|
@@ -1359,26 +1375,34 @@ end
|
|
1359
1375
|
#
|
1360
1376
|
class ShareLocationAction < LocationAction
|
1361
1377
|
|
1362
|
-
def initialize(
|
1378
|
+
def initialize(obj=nil)
|
1363
1379
|
|
1364
|
-
|
1380
|
+
h = if obj.is_a? Hash then
|
1381
|
+
obj
|
1382
|
+
elsif obj.is_a? Array
|
1383
|
+
e, macro = obj
|
1384
|
+
{variable: macro.set_var(e.text('item/description').to_s)}
|
1385
|
+
|
1386
|
+
end
|
1387
|
+
|
1388
|
+
#super()
|
1365
1389
|
|
1366
1390
|
options = {
|
1367
1391
|
email: '',
|
1368
|
-
variable: {:
|
1369
|
-
:
|
1370
|
-
:
|
1392
|
+
variable: {:string_value=>"", :name=>"",
|
1393
|
+
:decimal_value=>0.0, :is_local=>true, :boolean_value=>false,
|
1394
|
+
:exclude_from_log=>false, :int_value=>0, :type=>2},
|
1371
1395
|
sim_id: 0,
|
1372
1396
|
output_channel: 5,
|
1373
1397
|
old_variable_format: true
|
1374
1398
|
}
|
1375
|
-
|
1399
|
+
#options[:variable].merge! h
|
1376
1400
|
super(options.merge h)
|
1377
1401
|
|
1378
1402
|
end
|
1379
1403
|
|
1380
1404
|
def to_s(colour: false, indent: 0)
|
1381
|
-
@s = 'Share Location' + "\
|
1405
|
+
@s = 'Share Location' + "\n" + @h[:variable][:name] # + @h.inspect
|
1382
1406
|
super()
|
1383
1407
|
end
|
1384
1408
|
|
@@ -1573,7 +1597,15 @@ end
|
|
1573
1597
|
#
|
1574
1598
|
class SetVariableAction < Action
|
1575
1599
|
|
1576
|
-
def initialize(
|
1600
|
+
def initialize(obj=nil)
|
1601
|
+
|
1602
|
+
h = if obj.is_a? Hash then
|
1603
|
+
obj
|
1604
|
+
elsif obj.is_a? Array
|
1605
|
+
e, macro = obj
|
1606
|
+
node = e.element('item/*')
|
1607
|
+
macro.set_var node.name, node.value.to_s
|
1608
|
+
end
|
1577
1609
|
|
1578
1610
|
options = {
|
1579
1611
|
:user_prompt=>true,
|
@@ -1581,9 +1613,21 @@ class SetVariableAction < Action
|
|
1581
1613
|
:user_prompt_show_cancel=>true,
|
1582
1614
|
:user_prompt_stop_after_cancel=>true,
|
1583
1615
|
:user_prompt_title=>"Word reverse",
|
1584
|
-
:name => 'word'
|
1616
|
+
:name => 'word',
|
1617
|
+
:false_label=>"False", :int_expression=>false, :int_random=>false,
|
1618
|
+
:int_random_max=>0, :int_random_min=>0, :int_value_decrement=>false,
|
1619
|
+
:int_value_increment=>false, :new_boolean_value=>false,
|
1620
|
+
:new_double_value=>0.0, :new_int_value=>0,
|
1621
|
+
:new_string_value=>"[battery]", :true_label=>"True",
|
1622
|
+
:user_prompt=>false, :user_prompt_show_cancel=>true,
|
1623
|
+
:user_prompt_stop_after_cancel=>true,
|
1624
|
+
:variable=>{
|
1625
|
+
:exclude_from_log=>false, :is_local=>true,
|
1626
|
+
:boolean_value=>false, :decimal_value=>0.0,
|
1627
|
+
:int_value=>0, :name=>"foo", :string_value=>"52", :type=>2
|
1628
|
+
}
|
1585
1629
|
}
|
1586
|
-
super(h)
|
1630
|
+
super(options.merge h)
|
1587
1631
|
|
1588
1632
|
end
|
1589
1633
|
|
data/lib/ruby-macrodroid/base.rb
CHANGED
@@ -34,19 +34,7 @@ class MacroObject
|
|
34
34
|
|
35
35
|
def to_h()
|
36
36
|
|
37
|
-
|
38
|
-
|
39
|
-
h2 = h.inject({}) do |r,x|
|
40
|
-
puts 'x: ' + x.inspect if @debug
|
41
|
-
key, value = x
|
42
|
-
puts 'key: ' + key.inspect if @debug
|
43
|
-
new_key = key.to_s.gsub(/\w_\w/){|x| x[0] + x[-1].upcase}
|
44
|
-
new_key = new_key.prepend 'm_' unless @list.include? new_key
|
45
|
-
new_key = 'm_SIGUID' if new_key == 'm_siguid'
|
46
|
-
r.merge(new_key => value)
|
47
|
-
end
|
48
|
-
|
49
|
-
h2.merge('m_classType' => self.class.to_s)
|
37
|
+
hashify(@h)
|
50
38
|
|
51
39
|
end
|
52
40
|
|
@@ -98,13 +86,31 @@ class MacroObject
|
|
98
86
|
|
99
87
|
def object(h={})
|
100
88
|
|
101
|
-
puts ('inside object h:' + h.inspect).debug if
|
89
|
+
puts ('inside object h:' + h.inspect).debug if $debug
|
102
90
|
klass = Object.const_get h[:class_type]
|
103
91
|
puts klass.inspect.highlight if $debug
|
104
92
|
|
105
93
|
klass.new h
|
106
94
|
|
107
|
-
end
|
95
|
+
end
|
96
|
+
|
97
|
+
private
|
98
|
+
|
99
|
+
def hashify(h)
|
100
|
+
|
101
|
+
h2 = h.inject({}) do |r,x|
|
102
|
+
puts 'x: ' + x.inspect if $debug
|
103
|
+
key, value = x
|
104
|
+
puts 'key: ' + key.inspect if $debug
|
105
|
+
new_key = key.to_s.gsub(/\w_\w/){|x| x[0] + x[-1].upcase}
|
106
|
+
new_key = new_key.prepend 'm_' unless @list.include? new_key
|
107
|
+
new_key = 'm_SIGUID' if new_key == 'm_siguid'
|
108
|
+
new_val = value.is_a?(Hash) ? hashify(value) : value
|
109
|
+
r.merge(new_key => new_val)
|
110
|
+
end
|
111
|
+
|
112
|
+
h2.merge('m_classType' => self.class.to_s)
|
113
|
+
end
|
108
114
|
|
109
115
|
end
|
110
116
|
|
@@ -3,6 +3,10 @@
|
|
3
3
|
|
4
4
|
# This file contains the following classes:
|
5
5
|
#
|
6
|
+
# ## Nlp classes
|
7
|
+
#
|
8
|
+
# TriggersNlp ActionsNlp ConstraintsNlp
|
9
|
+
#
|
6
10
|
# ## Macro class
|
7
11
|
#
|
8
12
|
# Macro
|
@@ -12,11 +16,330 @@
|
|
12
16
|
VAR_TYPES = {
|
13
17
|
String: [2, :string_value],
|
14
18
|
TrueClass: [0, :boolean_value],
|
15
|
-
|
19
|
+
FalseClass: [0, :boolean_value],
|
16
20
|
Integer: [1, :int_value],
|
17
21
|
Float: [3, :decimal_value]
|
18
22
|
}
|
19
23
|
|
24
|
+
class TriggersNlp
|
25
|
+
include AppRoutes
|
26
|
+
|
27
|
+
def initialize(macro=nil)
|
28
|
+
|
29
|
+
super()
|
30
|
+
params = {macro: macro}
|
31
|
+
triggers(params)
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
def triggers(params)
|
36
|
+
|
37
|
+
# e.g. at 7:30pm daily
|
38
|
+
get /^(?:at )?(\d+:\d+(?:[ap]m)?) daily/i do |time, days|
|
39
|
+
[TimerTrigger, {time: time,
|
40
|
+
days: %w(Mon Tue Wed Thu Fri Sat Sun).join(', ')}]
|
41
|
+
end
|
42
|
+
|
43
|
+
get /^(?:at )?(\d+:\d+(?:[ap]m)?) (?:on )?(.*)/i do |time, days|
|
44
|
+
[TimerTrigger, {time: time, days: days}]
|
45
|
+
end
|
46
|
+
|
47
|
+
# time.is? 'at 18:30pm on Mon or Tue'
|
48
|
+
get /^time.is\? ['"](?:at )?(\d+:\d+(?:[ap]m)?) (?:on )?(.*)['"]/i do |time, days|
|
49
|
+
[TimerTrigger, {time: time, days: days.gsub(' or ',', ')}]
|
50
|
+
end
|
51
|
+
|
52
|
+
get /^shake[ _]device\??$/i do
|
53
|
+
[ShakeDeviceTrigger, {}]
|
54
|
+
end
|
55
|
+
|
56
|
+
get /^Flip Device (.*)$/i do |motion|
|
57
|
+
facedown = motion =~ /Face Up (?:->|to) Face Down/i
|
58
|
+
[FlipDeviceTrigger, {face_down: facedown }]
|
59
|
+
end
|
60
|
+
|
61
|
+
get /^flip_device_down\?$/i do
|
62
|
+
[FlipDeviceTrigger, {face_down: true }]
|
63
|
+
end
|
64
|
+
|
65
|
+
get /^flip_device_up\?$/i do
|
66
|
+
[FlipDeviceTrigger, {face_down: false }]
|
67
|
+
end
|
68
|
+
|
69
|
+
get /^Failed Login Attempt$/i do
|
70
|
+
[FailedLoginTrigger, {}]
|
71
|
+
end
|
72
|
+
|
73
|
+
get /^failed_login?$/i do
|
74
|
+
[FailedLoginTrigger, {}]
|
75
|
+
end
|
76
|
+
|
77
|
+
get /^Geofence (Entry|Exit) \(([^\)]+)/i do |direction, name|
|
78
|
+
enter_area = direction.downcase.to_sym == :entry
|
79
|
+
[GeofenceTrigger, {name: name, enter_area: enter_area}]
|
80
|
+
end
|
81
|
+
|
82
|
+
get /^location (entered|exited) \(([^\)]+)/i do |direction, name|
|
83
|
+
enter_area = direction.downcase.to_sym == :entered
|
84
|
+
[GeofenceTrigger, {name: name, enter_area: enter_area}]
|
85
|
+
end
|
86
|
+
|
87
|
+
# eg. Proximity Sensor (Near)
|
88
|
+
#
|
89
|
+
get /^Proximity Sensor \(([^\)]+)\)/i do |distance|
|
90
|
+
|
91
|
+
[ProximityTrigger, {distance: distance}]
|
92
|
+
end
|
93
|
+
|
94
|
+
# eg. Proximity near
|
95
|
+
#
|
96
|
+
get /^Proximity (near|far|slow wave|fast wave)/i do |distance|
|
97
|
+
|
98
|
+
[ProximityTrigger, {distance: distance}]
|
99
|
+
end
|
100
|
+
|
101
|
+
get /^WebHook \(Url\)/i do
|
102
|
+
[WebHookTrigger, params]
|
103
|
+
end
|
104
|
+
|
105
|
+
get /^WebHook/i do
|
106
|
+
[WebHookTrigger, params]
|
107
|
+
end
|
108
|
+
|
109
|
+
get /^wh/i do
|
110
|
+
[WebHookTrigger, params]
|
111
|
+
end
|
112
|
+
|
113
|
+
# MacroDroid specific ---------------------------------------------------------------
|
114
|
+
|
115
|
+
get /^EmptyTrigger$/i do
|
116
|
+
[EmptyTrigger, params]
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
alias find_trigger run_route
|
122
|
+
|
123
|
+
def to_s(colour: false)
|
124
|
+
'TriggersNlp ' + @h.inspect
|
125
|
+
end
|
126
|
+
|
127
|
+
alias to_summary to_s
|
128
|
+
end
|
129
|
+
|
130
|
+
class ActionsNlp
|
131
|
+
include AppRoutes
|
132
|
+
|
133
|
+
def initialize(macro=nil)
|
134
|
+
|
135
|
+
super()
|
136
|
+
params = {macro: macro}
|
137
|
+
actions(params)
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
def actions(params)
|
142
|
+
|
143
|
+
# e.g. message popup: hello world!
|
144
|
+
get /^message popup: (.*)/i do |msg|
|
145
|
+
[ToastAction, {msg: msg}]
|
146
|
+
end
|
147
|
+
|
148
|
+
# e.g. Popup Message 'hello world!'
|
149
|
+
get /^Popup[ _]Message ['"]([^'"]+)/i do |msg|
|
150
|
+
[ToastAction, {msg: msg}]
|
151
|
+
end
|
152
|
+
|
153
|
+
# e.g. Popup Message\n hello world!
|
154
|
+
get /^Popup Message\n\s+(.*)/im do |msg|
|
155
|
+
[ToastAction, {msg: msg}]
|
156
|
+
end
|
157
|
+
|
158
|
+
# e.g. Popup Message
|
159
|
+
get /^Popup Message$/i do
|
160
|
+
[ToastAction, {}]
|
161
|
+
end
|
162
|
+
|
163
|
+
# e.g. say current time
|
164
|
+
get /^say current[ _]time/i do
|
165
|
+
[SayTimeAction, {}]
|
166
|
+
end
|
167
|
+
|
168
|
+
get /^Torch :?(.*)/i do |onoffstate|
|
169
|
+
state = %w(on off toggle).index onoffstate.downcase
|
170
|
+
[CameraFlashLightAction, {state: state}]
|
171
|
+
end
|
172
|
+
|
173
|
+
get /^Take Picture/i do
|
174
|
+
[TakePictureAction, {}]
|
175
|
+
end
|
176
|
+
|
177
|
+
get /^take_picture/i do
|
178
|
+
[TakePictureAction, {}]
|
179
|
+
end
|
180
|
+
|
181
|
+
# -- DEVICE ACTIONS ------------------------------------------------------
|
182
|
+
|
183
|
+
get /^Speak text \(([^\)]+)\)/i do |text|
|
184
|
+
[SpeakTextAction, {text: text}]
|
185
|
+
end
|
186
|
+
|
187
|
+
get /^Speak text ['"]([^'"]+)/i do |text|
|
188
|
+
[SpeakTextAction, {text: text}]
|
189
|
+
end
|
190
|
+
|
191
|
+
get /^Speak text$/i do |text|
|
192
|
+
[SpeakTextAction, {}]
|
193
|
+
end
|
194
|
+
|
195
|
+
# e.g. Display Notification: Hi there: This is the body of the message
|
196
|
+
get /^Display Notification: ([^:]+): [^$]+$/i do |subject, text|
|
197
|
+
[NotificationAction, {subject: subject, text: text}]
|
198
|
+
end
|
199
|
+
|
200
|
+
|
201
|
+
# e.g. Enable Wifi
|
202
|
+
get /^(Enable|Disable) Wifi$/i do |raw_state|
|
203
|
+
|
204
|
+
state = raw_state.downcase.to_sym == :enable ? 0 : 1
|
205
|
+
[SetWifiAction, {state: state}]
|
206
|
+
|
207
|
+
end
|
208
|
+
|
209
|
+
# e.g. Play: Altair
|
210
|
+
get /^Play: (.*)$/i do |name|
|
211
|
+
|
212
|
+
[PlaySoundAction, {file_path: name}]
|
213
|
+
|
214
|
+
end
|
215
|
+
|
216
|
+
# e.g. Launch Settings
|
217
|
+
get /^Launch (.*)$/i do |application|
|
218
|
+
|
219
|
+
h = {
|
220
|
+
application_name: application,
|
221
|
+
package_to_launch: 'com.android.' + application.downcase
|
222
|
+
}
|
223
|
+
[LaunchActivityAction, h]
|
224
|
+
|
225
|
+
end
|
226
|
+
|
227
|
+
# e.g. HTTP GET http://someurl.com/something
|
228
|
+
get /^HTTP GET ([^$]+)$/i do |url|
|
229
|
+
|
230
|
+
[OpenWebPageAction, url_to_open: url]
|
231
|
+
|
232
|
+
end
|
233
|
+
|
234
|
+
get /^HTTP GET$/i do
|
235
|
+
|
236
|
+
[OpenWebPageAction, {}]
|
237
|
+
|
238
|
+
end
|
239
|
+
|
240
|
+
# e.g. webhook entered_kitchen
|
241
|
+
#
|
242
|
+
get /(?:webhook|HTTP GET) ([^$]+)$/i do |s|
|
243
|
+
key = s =~ /^http/ ? :url_to_open : :identifier
|
244
|
+
[OpenWebPageAction, {key => s}]
|
245
|
+
end
|
246
|
+
|
247
|
+
#
|
248
|
+
get /^WebHook \(Url\)/i do
|
249
|
+
[OpenWebPageAction, params]
|
250
|
+
end
|
251
|
+
|
252
|
+
# e.g. webhook entered_kitchen
|
253
|
+
#
|
254
|
+
get /^webhook$/i do
|
255
|
+
[OpenWebPageAction, params]
|
256
|
+
end
|
257
|
+
|
258
|
+
# -- Location ---------------------------------------------------------
|
259
|
+
|
260
|
+
get /^Force Location Update$/i do
|
261
|
+
[ForceLocationUpdateAction, params]
|
262
|
+
end
|
263
|
+
|
264
|
+
get /^Share Location$/i do
|
265
|
+
[ShareLocationAction, params]
|
266
|
+
end
|
267
|
+
|
268
|
+
#a: Keep Device Awake Screen On Until Disabled
|
269
|
+
#
|
270
|
+
get /Keep Device Awake Screen On Until Disabled/i do
|
271
|
+
[KeepAwakeAction, {enabled: true, permanent: true, screen_option: 0}]
|
272
|
+
end
|
273
|
+
|
274
|
+
|
275
|
+
#a: Keep Device Awake Screen On 1h 1m 1s
|
276
|
+
#
|
277
|
+
get /Keep Device Awake Screen On ([^$]+)/i do |duration|
|
278
|
+
|
279
|
+
a = duration.split.map(&:to_i)
|
280
|
+
secs = Subunit.new(units={minutes:60, hours:60, seconds: 60}, a).to_i
|
281
|
+
|
282
|
+
h = {
|
283
|
+
permanent: true, screen_option: 0, seconds_to_stay_awake_for: secs
|
284
|
+
}
|
285
|
+
[KeepAwakeAction, h]
|
286
|
+
end
|
287
|
+
|
288
|
+
#a: Disable Keep Awake
|
289
|
+
#
|
290
|
+
get /Disable Keep Awake/i do
|
291
|
+
[KeepAwakeAction, {enabled: false, screen_option: 0}]
|
292
|
+
end
|
293
|
+
|
294
|
+
#e.g a: if Airplane mode enabled
|
295
|
+
#
|
296
|
+
get /if (.*)/i do
|
297
|
+
[IfConditionAction, {}]
|
298
|
+
end
|
299
|
+
|
300
|
+
get /End If/i do
|
301
|
+
[EndIfAction, {}]
|
302
|
+
end
|
303
|
+
|
304
|
+
# -- MacroDroid Specific ------------------------------------------------
|
305
|
+
#
|
306
|
+
get /^Set Variable$/i do
|
307
|
+
[SetVariableAction, {}]
|
308
|
+
end
|
309
|
+
|
310
|
+
end
|
311
|
+
|
312
|
+
alias find_action run_route
|
313
|
+
|
314
|
+
|
315
|
+
end
|
316
|
+
|
317
|
+
class ConstraintsNlp
|
318
|
+
include AppRoutes
|
319
|
+
|
320
|
+
def initialize()
|
321
|
+
|
322
|
+
super()
|
323
|
+
params = {}
|
324
|
+
constraints(params)
|
325
|
+
|
326
|
+
end
|
327
|
+
|
328
|
+
def constraints(params)
|
329
|
+
|
330
|
+
get /^airplane mode (.*)/i do |state|
|
331
|
+
[AirplaneModeConstraint, {enabled: (state =~ /^enabled|on$/i) == 0}]
|
332
|
+
end
|
333
|
+
|
334
|
+
end
|
335
|
+
|
336
|
+
alias find_constraint run_route
|
337
|
+
|
338
|
+
end
|
339
|
+
|
340
|
+
|
341
|
+
class MacroError < Exception
|
342
|
+
end
|
20
343
|
|
21
344
|
class Macro
|
22
345
|
using ColouredText
|
@@ -34,7 +357,7 @@ class Macro
|
|
34
357
|
|
35
358
|
puts 'inside Macro#initialize' if @debug
|
36
359
|
|
37
|
-
@local_variables, @triggers, @actions, @constraints =
|
360
|
+
@local_variables, @triggers, @actions, @constraints = {}, [], [], []
|
38
361
|
@h = {}
|
39
362
|
|
40
363
|
end
|
@@ -61,9 +384,13 @@ class Macro
|
|
61
384
|
end
|
62
385
|
|
63
386
|
def to_h()
|
387
|
+
|
388
|
+
a = @local_variables.map do |k,v|
|
389
|
+
varify(k,v).to_camelcase.map{|key,value| ['m_' + key, value]}.to_h
|
390
|
+
end
|
64
391
|
|
65
392
|
h = {
|
66
|
-
local_variables:
|
393
|
+
local_variables: a,
|
67
394
|
m_trigger_list: @triggers.map(&:to_h),
|
68
395
|
m_action_list: @actions.map(&:to_h),
|
69
396
|
m_category: @category,
|
@@ -73,7 +400,7 @@ class Macro
|
|
73
400
|
m_excludeLog: false,
|
74
401
|
m_GUID: guid(),
|
75
402
|
m_isOrCondition: false,
|
76
|
-
m_enabled:
|
403
|
+
m_enabled: true,
|
77
404
|
m_descriptionOpen: false,
|
78
405
|
m_headingColor: 0
|
79
406
|
}
|
@@ -98,7 +425,7 @@ class Macro
|
|
98
425
|
if h[:local_variables].any? and h[:local_variables].first.any? then
|
99
426
|
|
100
427
|
@local_variables = h[:local_variables].map do |var|
|
101
|
-
|
428
|
+
|
102
429
|
val = case var[:type]
|
103
430
|
when 0 # boolean
|
104
431
|
var[:boolean_value]
|
@@ -117,7 +444,7 @@ class Macro
|
|
117
444
|
|
118
445
|
# fetch the triggers
|
119
446
|
@triggers = h[:trigger_list].map do |trigger|
|
120
|
-
puts 'trigger: ' + trigger.inspect
|
447
|
+
puts 'trigger: ' + trigger.inspect if @debug
|
121
448
|
#exit
|
122
449
|
object(trigger.to_snake_case)
|
123
450
|
|
@@ -196,24 +523,7 @@ class Macro
|
|
196
523
|
|
197
524
|
@title = node.text('macro') || node.attributes[:name]
|
198
525
|
|
199
|
-
|
200
|
-
|
201
|
-
label, v = e.text.to_s.split(/: */,2)
|
202
|
-
|
203
|
-
value = if v.to_f.to_s == v
|
204
|
-
v.to_f
|
205
|
-
elsif v.downcase == 'true'
|
206
|
-
true
|
207
|
-
elsif v.downcase == 'false'
|
208
|
-
false
|
209
|
-
elsif v.to_i.to_s == v
|
210
|
-
v.to_i
|
211
|
-
else
|
212
|
-
v
|
213
|
-
end
|
214
|
-
|
215
|
-
[label, value]
|
216
|
-
end
|
526
|
+
node.xpath('variable').each {|e| set_var(*e.text.to_s.split(/: */,2)) }
|
217
527
|
|
218
528
|
#@description = node.attributes[:description]
|
219
529
|
|
@@ -245,7 +555,8 @@ class Macro
|
|
245
555
|
|
246
556
|
r = tp.find_trigger trigger
|
247
557
|
puts 'r: ' + r.inspect if @debug
|
248
|
-
o = r[0].new([description, self]) if r
|
558
|
+
#o = r[0].new([description, self]) if r
|
559
|
+
o = object_create(r[0], [description, self]) if r
|
249
560
|
puts 'after o' if @debug
|
250
561
|
o
|
251
562
|
|
@@ -265,7 +576,12 @@ class Macro
|
|
265
576
|
end
|
266
577
|
|
267
578
|
r = tp.find_trigger trigger
|
268
|
-
r[0].new(h) if r
|
579
|
+
#r[0].new(h) if r
|
580
|
+
if r then
|
581
|
+
object_create(r[0], h)
|
582
|
+
else
|
583
|
+
raise MacroError, 'App-routes: Trigger "' + trigger + '" not found'
|
584
|
+
end
|
269
585
|
|
270
586
|
end
|
271
587
|
|
@@ -273,11 +589,20 @@ class Macro
|
|
273
589
|
|
274
590
|
trigger = e.text.strip
|
275
591
|
r = tp.find_trigger trigger
|
276
|
-
r[0].new(r[1]) if r
|
592
|
+
#r[0].new(r[1]) if r
|
593
|
+
|
594
|
+
if r then
|
595
|
+
object_create(r[0],r[1])
|
596
|
+
else
|
597
|
+
raise MacroError, 'App-routes: Trigger "' + trigger + '" not found'
|
598
|
+
end
|
277
599
|
|
278
600
|
end
|
279
601
|
|
602
|
+
|
280
603
|
end
|
604
|
+
|
605
|
+
|
281
606
|
|
282
607
|
ap = ActionsNlp.new self
|
283
608
|
|
@@ -306,7 +631,9 @@ class Macro
|
|
306
631
|
|
307
632
|
r = ap.find_action action
|
308
633
|
puts 'r: ' + r.inspect if @debug
|
309
|
-
|
634
|
+
puts 'description: ' + description.xml.inspect if @debug
|
635
|
+
#o = r[0].new([description, self]) if r
|
636
|
+
o = object_create(r[0],[description, self]) if r
|
310
637
|
puts 'after o' if @debug
|
311
638
|
o
|
312
639
|
|
@@ -315,6 +642,7 @@ class Macro
|
|
315
642
|
else
|
316
643
|
|
317
644
|
action = e.text.strip
|
645
|
+
puts 'action: ' + action.inspect if @debug
|
318
646
|
r = ap.find_action action
|
319
647
|
|
320
648
|
a = e.xpath('item/*')
|
@@ -324,9 +652,11 @@ class Macro
|
|
324
652
|
else
|
325
653
|
{}
|
326
654
|
end
|
655
|
+
puts 'h: ' + h.inspect if @debug
|
327
656
|
|
328
|
-
r = ap.find_action action
|
329
|
-
r[0].new(h) if r
|
657
|
+
#r = ap.find_action action
|
658
|
+
#r[0].new(h.merge(macro: self)) if r
|
659
|
+
object_create(r[0], h.merge(macro: self)) if r
|
330
660
|
|
331
661
|
end
|
332
662
|
|
@@ -334,7 +664,8 @@ class Macro
|
|
334
664
|
|
335
665
|
action = e.text.strip
|
336
666
|
r = ap.find_action action
|
337
|
-
r[0].new(r[1]) if r
|
667
|
+
#r[0].new(r[1]) if r
|
668
|
+
object_create(r[0],r[1]) if r
|
338
669
|
|
339
670
|
end
|
340
671
|
|
@@ -347,9 +678,7 @@ class Macro
|
|
347
678
|
r = cp.find_constraint e.text
|
348
679
|
puts 'found constraint ' + r.inspect if @debug
|
349
680
|
|
350
|
-
if r
|
351
|
-
r[0].new(r[1])
|
352
|
-
end
|
681
|
+
object_create(r[0], r[1]) if r
|
353
682
|
|
354
683
|
end
|
355
684
|
|
@@ -394,6 +723,27 @@ class Macro
|
|
394
723
|
def set_env()
|
395
724
|
@triggers.each(&:set_env)
|
396
725
|
end
|
726
|
+
|
727
|
+
def set_var(label, v='')
|
728
|
+
|
729
|
+
value = if v.to_f.to_s == v
|
730
|
+
v.to_f
|
731
|
+
elsif v.downcase == 'true'
|
732
|
+
true
|
733
|
+
elsif v.downcase == 'false'
|
734
|
+
false
|
735
|
+
elsif v.to_i.to_s == v
|
736
|
+
v.to_i
|
737
|
+
else
|
738
|
+
v
|
739
|
+
end
|
740
|
+
|
741
|
+
if not @local_variables.has_key? label.to_sym then
|
742
|
+
@local_variables.merge!({label.to_sym => value})
|
743
|
+
end
|
744
|
+
|
745
|
+
varify(label, value)
|
746
|
+
end
|
397
747
|
|
398
748
|
def to_pc()
|
399
749
|
|
@@ -441,6 +791,7 @@ EOF
|
|
441
791
|
a << @triggers.map do |x|
|
442
792
|
|
443
793
|
puts 'x: ' + x.inspect if @debug
|
794
|
+
raise 'Macro#to_s trigger cannot be nil' if x.nil?
|
444
795
|
|
445
796
|
s =-x.to_s(colour: colour)
|
446
797
|
puts 's: ' + s.inspect if @debug
|
@@ -587,43 +938,47 @@ EOF
|
|
587
938
|
|
588
939
|
puts ('inside object h:' + h.inspect).debug if @debug
|
589
940
|
klass = Object.const_get h[:class_type]
|
590
|
-
puts klass.inspect.highlight if
|
941
|
+
puts klass.inspect.highlight if @debug
|
591
942
|
|
592
943
|
if klass == GeofenceTrigger then
|
593
|
-
puts 'GeofenceTrigger found'.highlight if
|
944
|
+
puts 'GeofenceTrigger found'.highlight if @debug
|
594
945
|
GeofenceTrigger.new(h, geofences: @geofences)
|
595
946
|
else
|
596
|
-
puts 'before klass'
|
947
|
+
puts 'before klass' if @debug
|
597
948
|
h2 = h.merge( macro: self)
|
598
|
-
puts 'h2: ' + h2.inspect
|
949
|
+
puts 'h2: ' + h2.inspect if @debug
|
599
950
|
r = klass.new h2
|
600
|
-
puts 'r:' + r.inspect
|
951
|
+
puts 'r:' + r.inspect if @debug
|
601
952
|
r
|
602
953
|
|
603
954
|
end
|
604
955
|
|
605
956
|
end
|
606
957
|
|
607
|
-
def
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
puts 'VAR_TYPES: ' + VAR_TYPES.inspect
|
614
|
-
type = VAR_TYPES[value.class.to_s.to_sym]
|
615
|
-
puts 'type: ' + type.inspect
|
616
|
-
h = {
|
617
|
-
boolean_value: false,
|
618
|
-
decimal_value: 0.0,
|
619
|
-
int_value: 0,
|
620
|
-
name: key,
|
621
|
-
string_value: '',
|
622
|
-
type: type[0]
|
623
|
-
}
|
624
|
-
h[type[1]] = value
|
625
|
-
h
|
958
|
+
def object_create(klass, *args)
|
959
|
+
|
960
|
+
begin
|
961
|
+
klass.new(*args)
|
962
|
+
rescue
|
963
|
+
raise MacroError, klass.to_s + ': ' + ($!).to_s
|
626
964
|
end
|
965
|
+
end
|
966
|
+
|
967
|
+
def varify(label, value='')
|
968
|
+
|
969
|
+
|
970
|
+
type = VAR_TYPES[value.class.to_s.to_sym]
|
971
|
+
|
972
|
+
h = {
|
973
|
+
boolean_value: false,
|
974
|
+
decimal_value: 0.0,
|
975
|
+
int_value: 0,
|
976
|
+
name: label,
|
977
|
+
string_value: '',
|
978
|
+
type: type[0]
|
979
|
+
}
|
980
|
+
h[type[1]] = value
|
981
|
+
h
|
627
982
|
|
628
983
|
end
|
629
984
|
|
@@ -421,27 +421,33 @@ class WebHookTrigger < Trigger
|
|
421
421
|
h = if obj.is_a? Hash then
|
422
422
|
obj
|
423
423
|
elsif obj.is_a? Array
|
424
|
+
|
424
425
|
e, macro = obj
|
425
426
|
txt = e.text('item/description')
|
426
|
-
|
427
|
+
|
428
|
+
h2 = if txt then
|
429
|
+
{url: (txt || e.text)}
|
430
|
+
else
|
431
|
+
a = e.xpath('item/*')
|
432
|
+
a.map {|node| [node.name.to_sym, node.text.to_s]}.to_h
|
433
|
+
end
|
434
|
+
|
435
|
+
h2.merge(macro: macro)
|
427
436
|
end
|
428
437
|
|
429
438
|
if h[:url] then
|
430
|
-
h[:identifier] = h[:url]
|
439
|
+
h[:identifier] = h[:url]\
|
440
|
+
[/https:\/\/trigger.macrodroid.com\/(?:\w+\-){4}\w+\/([^$]+)/,1]
|
441
|
+
elsif h[:identifier].nil? or h[:identifier].empty? then
|
442
|
+
h[:identifier] = h[:macro].title.downcase.gsub(/ +/,'-')
|
431
443
|
end
|
432
444
|
|
433
|
-
|
434
445
|
options = {
|
435
446
|
identifier: ''
|
436
447
|
}
|
437
448
|
|
438
449
|
@deviceid = h[:macro].deviceid
|
439
|
-
|
440
|
-
|
441
|
-
if h[:identifier].nil? or h[:identifier].empty? then
|
442
|
-
h[:identifier] = h[:macro].title.downcase.gsub(/ +/,'-')
|
443
|
-
end
|
444
|
-
|
450
|
+
|
445
451
|
super(options.merge filter(options,h))
|
446
452
|
@list << 'identifier'
|
447
453
|
|
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.9.
|
4
|
+
version: 0.9.2
|
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-10-
|
38
|
+
date: 2020-10-05 00:00:00.000000000 Z
|
39
39
|
dependencies:
|
40
40
|
- !ruby/object:Gem::Dependency
|
41
41
|
name: glw
|
metadata.gz.sig
CHANGED
Binary file
|