ruby-macrodroid 0.9.0 → 0.9.5
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 +11 -278
- data/lib/ruby-macrodroid/actions.rb +221 -39
- data/lib/ruby-macrodroid/base.rb +109 -15
- data/lib/ruby-macrodroid/constraints.rb +25 -5
- data/lib/ruby-macrodroid/macro.rb +466 -95
- data/lib/ruby-macrodroid/triggers.rb +33 -15
- 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: b7aa07338b6ffd2e4edcad4e7a2b63dee60f71632cb5a29a7f54de51570136f9
|
4
|
+
data.tar.gz: 55009e156bce03bdfb487a46cb0085f3c7f0b5375949b602e3e76ce216148e15
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 710ed235030b9553dcd3ca9f7c79efc6a7608f46ad59e4c14b38a5a2725b81f2145e5bc13cbc7d1385718754115a1de1976896030185b497833b916897d1e57f
|
7
|
+
data.tar.gz: de58a516f728dc63dc0660eac45b137a03a1f447554e8e34a8ed61e06e0a578abc1dd1567ff83592677d416534efa5923649dce8af20c19ad991f21006447e77
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/lib/ruby-macrodroid.rb
CHANGED
@@ -38,281 +38,14 @@ require 'rxfhelper'
|
|
38
38
|
require 'chronic_cron'
|
39
39
|
|
40
40
|
|
41
|
+
# PASTE_START
|
42
|
+
|
41
43
|
MODEL =<<EOF
|
42
44
|
device
|
43
45
|
connectivity
|
44
46
|
airplane_mode is disabled
|
45
47
|
EOF
|
46
48
|
|
47
|
-
class TriggersNlp
|
48
|
-
include AppRoutes
|
49
|
-
|
50
|
-
def initialize(macro=nil)
|
51
|
-
|
52
|
-
super()
|
53
|
-
params = {macro: macro}
|
54
|
-
triggers(params)
|
55
|
-
|
56
|
-
end
|
57
|
-
|
58
|
-
def triggers(params)
|
59
|
-
|
60
|
-
# e.g. at 7:30pm daily
|
61
|
-
get /^(?:at )?(\d+:\d+(?:[ap]m)?) daily/i do |time, days|
|
62
|
-
[TimerTrigger, {time: time,
|
63
|
-
days: %w(Mon Tue Wed Thu Fri Sat Sun).join(', ')}]
|
64
|
-
end
|
65
|
-
|
66
|
-
get /^(?:at )?(\d+:\d+(?:[ap]m)?) (?:on )?(.*)/i do |time, days|
|
67
|
-
[TimerTrigger, {time: time, days: days}]
|
68
|
-
end
|
69
|
-
|
70
|
-
# time.is? 'at 18:30pm on Mon or Tue'
|
71
|
-
get /^time.is\? ['"](?:at )?(\d+:\d+(?:[ap]m)?) (?:on )?(.*)['"]/i do |time, days|
|
72
|
-
[TimerTrigger, {time: time, days: days.gsub(' or ',', ')}]
|
73
|
-
end
|
74
|
-
|
75
|
-
get /^shake[ _]device\??$/i do
|
76
|
-
[ShakeDeviceTrigger, {}]
|
77
|
-
end
|
78
|
-
|
79
|
-
get /^Flip Device (.*)$/i do |motion|
|
80
|
-
facedown = motion =~ /Face Up (?:->|to) Face Down/i
|
81
|
-
[FlipDeviceTrigger, {face_down: facedown }]
|
82
|
-
end
|
83
|
-
|
84
|
-
get /^flip_device_down\?$/i do
|
85
|
-
[FlipDeviceTrigger, {face_down: true }]
|
86
|
-
end
|
87
|
-
|
88
|
-
get /^flip_device_up\?$/i do
|
89
|
-
[FlipDeviceTrigger, {face_down: false }]
|
90
|
-
end
|
91
|
-
|
92
|
-
get /^Failed Login Attempt$/i do
|
93
|
-
[FailedLoginTrigger, {}]
|
94
|
-
end
|
95
|
-
|
96
|
-
get /^failed_login?$/i do
|
97
|
-
[FailedLoginTrigger, {}]
|
98
|
-
end
|
99
|
-
|
100
|
-
get /^Geofence (Entry|Exit) \(([^\)]+)/i do |direction, name|
|
101
|
-
enter_area = direction.downcase.to_sym == :entry
|
102
|
-
[GeofenceTrigger, {name: name, enter_area: enter_area}]
|
103
|
-
end
|
104
|
-
|
105
|
-
get /^location (entered|exited) \(([^\)]+)/i do |direction, name|
|
106
|
-
enter_area = direction.downcase.to_sym == :entered
|
107
|
-
[GeofenceTrigger, {name: name, enter_area: enter_area}]
|
108
|
-
end
|
109
|
-
|
110
|
-
# eg. Proximity Sensor (Near)
|
111
|
-
#
|
112
|
-
get /^Proximity Sensor \(([^\)]+)\)/i do |distance|
|
113
|
-
|
114
|
-
[ProximityTrigger, {distance: distance}]
|
115
|
-
end
|
116
|
-
|
117
|
-
get /^WebHook \(Url\)/i do
|
118
|
-
[WebHookTrigger, params]
|
119
|
-
end
|
120
|
-
|
121
|
-
get /^WebHook/i do
|
122
|
-
[WebHookTrigger, params]
|
123
|
-
end
|
124
|
-
|
125
|
-
get /^wh/i do
|
126
|
-
[WebHookTrigger, params]
|
127
|
-
end
|
128
|
-
|
129
|
-
|
130
|
-
end
|
131
|
-
|
132
|
-
alias find_trigger run_route
|
133
|
-
|
134
|
-
def to_s(colour: false)
|
135
|
-
'TriggersNlp ' + @h.inspect
|
136
|
-
end
|
137
|
-
|
138
|
-
alias to_summary to_s
|
139
|
-
end
|
140
|
-
|
141
|
-
class ActionsNlp
|
142
|
-
include AppRoutes
|
143
|
-
|
144
|
-
def initialize(macro=nil)
|
145
|
-
|
146
|
-
super()
|
147
|
-
params = {macro: macro}
|
148
|
-
actions(params)
|
149
|
-
|
150
|
-
end
|
151
|
-
|
152
|
-
def actions(params)
|
153
|
-
|
154
|
-
# e.g. message popup: hello world!
|
155
|
-
get /^message popup: (.*)/i do |msg|
|
156
|
-
[ToastAction, {msg: msg}]
|
157
|
-
end
|
158
|
-
|
159
|
-
# e.g. Popup Message 'hello world!'
|
160
|
-
get /^Popup[ _]Message ['"]([^'"]+)/i do |msg|
|
161
|
-
[ToastAction, {msg: msg}]
|
162
|
-
end
|
163
|
-
|
164
|
-
# e.g. Popup Message\n hello world!
|
165
|
-
get /^Popup Message\n\s+(.*)/im do |msg|
|
166
|
-
[ToastAction, {msg: msg}]
|
167
|
-
end
|
168
|
-
|
169
|
-
# e.g. Popup Message
|
170
|
-
get /^Popup Message$/i do
|
171
|
-
[ToastAction, {}]
|
172
|
-
end
|
173
|
-
|
174
|
-
# e.g. say current time
|
175
|
-
get /^say current[ _]time/i do
|
176
|
-
[SayTimeAction, {}]
|
177
|
-
end
|
178
|
-
|
179
|
-
get /^Torch :?(.*)/i do |onoffstate|
|
180
|
-
state = %w(on off toggle).index onoffstate.downcase
|
181
|
-
[CameraFlashLightAction, {state: state}]
|
182
|
-
end
|
183
|
-
|
184
|
-
get /^Take Picture/i do
|
185
|
-
[TakePictureAction, {}]
|
186
|
-
end
|
187
|
-
|
188
|
-
get /^take_picture/i do
|
189
|
-
[TakePictureAction, {}]
|
190
|
-
end
|
191
|
-
|
192
|
-
# e.g. Display Notification: Hi there: This is the body of the message
|
193
|
-
get /^Display Notification: ([^:]+): [^$]+$/i do |subject, text|
|
194
|
-
[NotificationAction, {subject: subject, text: text}]
|
195
|
-
end
|
196
|
-
|
197
|
-
|
198
|
-
# e.g. Enable Wifi
|
199
|
-
get /^(Enable|Disable) Wifi$/i do |raw_state|
|
200
|
-
|
201
|
-
state = raw_state.downcase.to_sym == :enable ? 0 : 1
|
202
|
-
[SetWifiAction, {state: state}]
|
203
|
-
|
204
|
-
end
|
205
|
-
|
206
|
-
# e.g. Play: Altair
|
207
|
-
get /^Play: (.*)$/i do |name|
|
208
|
-
|
209
|
-
[PlaySoundAction, {file_path: name}]
|
210
|
-
|
211
|
-
end
|
212
|
-
|
213
|
-
# e.g. Launch Settings
|
214
|
-
get /^Launch (.*)$/i do |application|
|
215
|
-
|
216
|
-
h = {
|
217
|
-
application_name: application,
|
218
|
-
package_to_launch: 'com.android.' + application.downcase
|
219
|
-
}
|
220
|
-
[LaunchActivityAction, h]
|
221
|
-
|
222
|
-
end
|
223
|
-
|
224
|
-
# e.g. HTTP GET http://someurl.com/something
|
225
|
-
get /^HTTP GET ([^$]+)$/i do |url|
|
226
|
-
|
227
|
-
[OpenWebPageAction, url_to_open: url]
|
228
|
-
|
229
|
-
end
|
230
|
-
|
231
|
-
# e.g. webhook entered_kitchen
|
232
|
-
#
|
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]
|
247
|
-
end
|
248
|
-
|
249
|
-
#a: Keep Device Awake Screen On Until Disabled
|
250
|
-
#
|
251
|
-
get /Keep Device Awake Screen On Until Disabled/i do
|
252
|
-
[KeepAwakeAction, {enabled: true, permanent: true, screen_option: 0}]
|
253
|
-
end
|
254
|
-
|
255
|
-
|
256
|
-
#a: Keep Device Awake Screen On 1h 1m 1s
|
257
|
-
#
|
258
|
-
get /Keep Device Awake Screen On ([^$]+)/i do |duration|
|
259
|
-
|
260
|
-
a = duration.split.map(&:to_i)
|
261
|
-
secs = Subunit.new(units={minutes:60, hours:60, seconds: 60}, a).to_i
|
262
|
-
|
263
|
-
h = {
|
264
|
-
permanent: true, screen_option: 0, seconds_to_stay_awake_for: secs
|
265
|
-
}
|
266
|
-
[KeepAwakeAction, h]
|
267
|
-
end
|
268
|
-
|
269
|
-
#a: Disable Keep Awake
|
270
|
-
#
|
271
|
-
get /Disable Keep Awake/i do
|
272
|
-
[KeepAwakeAction, {enabled: false, screen_option: 0}]
|
273
|
-
end
|
274
|
-
|
275
|
-
#e.g a: if Airplane mode enabled
|
276
|
-
#
|
277
|
-
get /if (.*)/i do
|
278
|
-
[IfConditionAction, {}]
|
279
|
-
end
|
280
|
-
|
281
|
-
get /End If/i do
|
282
|
-
[EndIfAction, {}]
|
283
|
-
end
|
284
|
-
|
285
|
-
end
|
286
|
-
|
287
|
-
alias find_action run_route
|
288
|
-
|
289
|
-
|
290
|
-
end
|
291
|
-
|
292
|
-
class ConstraintsNlp
|
293
|
-
include AppRoutes
|
294
|
-
|
295
|
-
def initialize()
|
296
|
-
|
297
|
-
super()
|
298
|
-
params = {}
|
299
|
-
constraints(params)
|
300
|
-
|
301
|
-
end
|
302
|
-
|
303
|
-
def constraints(params)
|
304
|
-
|
305
|
-
get /^airplane mode (.*)/i do |state|
|
306
|
-
[AirplaneModeConstraint, {enabled: (state =~ /^enabled|on$/i) == 0}]
|
307
|
-
end
|
308
|
-
|
309
|
-
end
|
310
|
-
|
311
|
-
alias find_constraint run_route
|
312
|
-
|
313
|
-
end
|
314
|
-
|
315
|
-
|
316
49
|
module Params
|
317
50
|
|
318
51
|
refine Hash do
|
@@ -342,16 +75,16 @@ module Params
|
|
342
75
|
end
|
343
76
|
|
344
77
|
# turns keys from snake_case to CamelCase
|
345
|
-
def
|
78
|
+
def to_camelcase(h=self)
|
346
79
|
|
347
80
|
h.inject({}) do |r,x|
|
348
81
|
|
349
82
|
key, value = x
|
350
83
|
|
351
84
|
val = if value.is_a?(Hash) then
|
352
|
-
|
85
|
+
to_camelcase(value)
|
353
86
|
elsif value.is_a?(Array) and value.first.is_a? Hash
|
354
|
-
value.map {|row|
|
87
|
+
value.map {|row| to_camelcase(row)}
|
355
88
|
else
|
356
89
|
value
|
357
90
|
end
|
@@ -368,8 +101,6 @@ end
|
|
368
101
|
|
369
102
|
|
370
103
|
|
371
|
-
|
372
|
-
|
373
104
|
class MacroDroidError < Exception
|
374
105
|
end
|
375
106
|
|
@@ -415,8 +146,9 @@ class MacroDroid
|
|
415
146
|
puts 'before RowX.new' if @debug
|
416
147
|
|
417
148
|
s2 = s.gsub(/^g:/,'geofence:').gsub(/^m:/,'macro:')\
|
418
|
-
.gsub(/^
|
419
|
-
.gsub(/^
|
149
|
+
.gsub(/^d:/,'description:').gsub(/^v:/,'variable:')\
|
150
|
+
.gsub(/^t:/,'trigger:').gsub(/^a:/,'action:')\
|
151
|
+
.gsub(/^c:/,'constraint:').gsub(/^#.*/,'')
|
420
152
|
|
421
153
|
a = s2.split(/(?=^macro:)/)
|
422
154
|
|
@@ -436,7 +168,7 @@ class MacroDroid
|
|
436
168
|
|
437
169
|
end
|
438
170
|
|
439
|
-
xml = RowX.new(raw_macros).to_xml
|
171
|
+
xml = RowX.new(raw_macros, allow_lonely_keyfield: true).to_xml
|
440
172
|
puts 'xml: ' + xml if @debug
|
441
173
|
import_rowxml(xml)
|
442
174
|
|
@@ -511,7 +243,7 @@ class MacroDroid
|
|
511
243
|
},
|
512
244
|
macro_list: @macros.map(&:to_h)
|
513
245
|
}
|
514
|
-
@h.merge(h).
|
246
|
+
@h.merge(h).to_camelcase
|
515
247
|
|
516
248
|
end
|
517
249
|
|
@@ -847,6 +579,7 @@ class DroidSim
|
|
847
579
|
|
848
580
|
end
|
849
581
|
|
582
|
+
# PASTE_END
|
850
583
|
|
851
584
|
require 'ruby-macrodroid/base'
|
852
585
|
require 'ruby-macrodroid/triggers'
|
@@ -33,7 +33,9 @@
|
|
33
33
|
|
34
34
|
|
35
35
|
class Action < MacroObject
|
36
|
+
using ColouredText
|
36
37
|
using Params
|
38
|
+
include ObjectX
|
37
39
|
|
38
40
|
attr_reader :constraints
|
39
41
|
|
@@ -143,42 +145,98 @@ end
|
|
143
145
|
#
|
144
146
|
class OpenWebPageAction < ApplicationAction
|
145
147
|
|
146
|
-
def initialize(obj={})
|
148
|
+
def initialize(obj={}, macro=nil)
|
149
|
+
|
150
|
+
# puts 'obj: ' + obj[0].xml.inspect
|
147
151
|
|
148
152
|
h = if obj.is_a? Hash then
|
153
|
+
|
149
154
|
obj
|
155
|
+
|
150
156
|
elsif obj.is_a? Array
|
157
|
+
|
158
|
+
puts 'obj: ' + obj.inspect if $debug
|
151
159
|
e, macro = obj
|
152
|
-
|
153
|
-
|
154
|
-
|
160
|
+
|
161
|
+
a = e.xpath('item/*')
|
162
|
+
|
163
|
+
h2 = if a.any? then
|
164
|
+
|
165
|
+
a.map do |node|
|
166
|
+
|
167
|
+
if node.name == 'description' and node.text.to_s =~ /: / then
|
168
|
+
node.text.to_s.split(/: +/,2).map(&:strip)
|
169
|
+
else
|
170
|
+
[node.name.to_sym, node.text.to_s.strip]
|
171
|
+
end
|
172
|
+
|
173
|
+
end.to_h
|
174
|
+
|
175
|
+
else
|
176
|
+
txt = e.text('item/description')
|
177
|
+
{url: (txt || e.text)}
|
178
|
+
end
|
179
|
+
|
180
|
+
h2.merge(macro: macro)
|
181
|
+
|
182
|
+
end
|
183
|
+
|
184
|
+
puts 'h:' + h.inspect if $debug
|
155
185
|
|
156
|
-
h[:url_to_open] = h[:url] if h[:url]
|
186
|
+
#h[:url_to_open] = h[:url] if h[:url] and h[:url].length > 1
|
157
187
|
|
158
188
|
options = {
|
159
|
-
variable_to_save_response: {:
|
160
|
-
|
161
|
-
excludeFromLog: false,
|
189
|
+
variable_to_save_response: {:string_value=>"", :name=>"coords",
|
190
|
+
decimal_value: 0.0, isLocal: true, m_boolean_value: false,
|
191
|
+
excludeFromLog: false, int_value: 0, type: 2},
|
162
192
|
url_to_open: '',
|
163
193
|
http_get: true,
|
164
194
|
disable_url_encode: false,
|
165
195
|
block_next_action: false
|
166
196
|
}
|
167
197
|
|
168
|
-
if h[:
|
198
|
+
return super(options.merge h) if h[:url_to_open]
|
199
|
+
|
200
|
+
if h[:macro].remote_url.nil? and (h[:url].nil? or h[:url].empty?) then
|
169
201
|
raise OpenWebPageActionError, 'remote_url not found'
|
170
202
|
end
|
171
203
|
|
172
|
-
if
|
173
|
-
|
204
|
+
url = if h[:url] and h[:url].length > 1 then
|
205
|
+
|
206
|
+
h[:url]
|
207
|
+
|
208
|
+
elsif h2 and h[:macro].remote_url and h[:identifier]
|
209
|
+
|
210
|
+
"%s/%s" % [h[:macro].remote_url.sub(/\/$/,''), h[:identifier]]
|
211
|
+
|
212
|
+
elsif (h[:identifier].nil? or h[:identifier].empty?)
|
213
|
+
|
174
214
|
h[:url_to_open] = h[:macro].remote_url.sub(/\/$/,'') + '/' +
|
175
|
-
h[:macro].title.downcase.gsub(/ +/,'-')
|
215
|
+
h[:macro].title.downcase.gsub(/ +/,'-')
|
216
|
+
|
217
|
+
end
|
218
|
+
|
219
|
+
if h2 then
|
220
|
+
|
221
|
+
h2.delete :identifier
|
222
|
+
h2.delete :url
|
223
|
+
|
224
|
+
if h2.any? then
|
225
|
+
url += '?' + \
|
226
|
+
URI.escape(h2.map {|key,value| "%s=%s" % [key, value]}.join('&'))
|
227
|
+
end
|
228
|
+
|
176
229
|
end
|
177
230
|
|
231
|
+
h[:url_to_open] = url
|
178
232
|
super(options.merge h)
|
179
233
|
|
180
234
|
end
|
181
235
|
|
236
|
+
def invoke()
|
237
|
+
super(url: @h[:url_to_open])
|
238
|
+
end
|
239
|
+
|
182
240
|
def to_s(colour: false, indent: 0)
|
183
241
|
@s = "HTTP GET\nurl: " + @h[:url_to_open]
|
184
242
|
super()
|
@@ -347,6 +405,7 @@ class IfConditionAction < Action
|
|
347
405
|
a: true,
|
348
406
|
constraint_list: []
|
349
407
|
}
|
408
|
+
puts 'obj: ' + obj.inspect if $debug
|
350
409
|
|
351
410
|
if obj.is_a? Hash then
|
352
411
|
|
@@ -355,18 +414,24 @@ class IfConditionAction < Action
|
|
355
414
|
h2 = options.merge(filter(options,h).merge(macro: macro))
|
356
415
|
super(h2)
|
357
416
|
|
358
|
-
elsif obj.is_a?
|
359
|
-
|
360
|
-
|
417
|
+
elsif obj.is_a? Array
|
418
|
+
|
419
|
+
e, macro = obj
|
420
|
+
super()
|
421
|
+
puts 'e.xml: ' + e.xml if $debug
|
422
|
+
puts 'e.text: ' + e.text.to_s.strip if $debug
|
423
|
+
raw_txt = e.text.to_s.strip[/^if [^$]+/i] || e.text('item/description')
|
361
424
|
puts 'raw_txt: ' + raw_txt.inspect if $debug
|
362
425
|
|
363
|
-
clause = raw_txt[/^
|
426
|
+
clause = raw_txt[/^If (.*)/i,1]
|
427
|
+
puts 'clause: ' + clause.inspect if $debug
|
364
428
|
conditions = clause.split(/\s+\b(?:AND|OR)\b\s+/i)
|
429
|
+
puts 'conditions: ' + conditions.inspect if $debug
|
365
430
|
|
366
431
|
cp = ConstraintsNlp.new
|
367
432
|
|
368
433
|
@constraints = conditions.map do |c|
|
369
|
-
puts 'c: ' + c.inspect
|
434
|
+
puts 'c: ' + c.inspect if $debug
|
370
435
|
r = cp.find_constraint c
|
371
436
|
puts 'found constraint ' + r.inspect if $debug
|
372
437
|
|
@@ -374,6 +439,19 @@ class IfConditionAction < Action
|
|
374
439
|
|
375
440
|
end
|
376
441
|
puts '@constraints: ' + @constraints.inspect if $debug
|
442
|
+
|
443
|
+
# find any nested actions
|
444
|
+
item = e.element('item')
|
445
|
+
|
446
|
+
if item then
|
447
|
+
|
448
|
+
ap = ActionsNlp.new
|
449
|
+
obj2 = action_to_object(ap, item, item, macro)
|
450
|
+
puts 'obj2: ' + obj2.inspect if $debug
|
451
|
+
#macro.add obj2
|
452
|
+
|
453
|
+
end
|
454
|
+
|
377
455
|
{}
|
378
456
|
else
|
379
457
|
# get the constraints
|
@@ -391,7 +469,7 @@ class IfConditionAction < Action
|
|
391
469
|
def to_s(colour: false, indent: 0)
|
392
470
|
|
393
471
|
h = @h.clone
|
394
|
-
h.delete :macro
|
472
|
+
#h.delete :macro
|
395
473
|
@s = 'If '
|
396
474
|
operator = @h[:is_or_condition] ? 'OR' : 'AND'
|
397
475
|
constraints = @constraints.map \
|
@@ -403,7 +481,8 @@ class IfConditionAction < Action
|
|
403
481
|
out << s + constraints
|
404
482
|
out.join("\n")
|
405
483
|
|
406
|
-
end
|
484
|
+
end
|
485
|
+
|
407
486
|
end
|
408
487
|
|
409
488
|
class ElseAction < Action
|
@@ -471,6 +550,8 @@ class EndIfAction < Action
|
|
471
550
|
obj
|
472
551
|
elsif obj.is_a? Rexle::Element
|
473
552
|
{}
|
553
|
+
else
|
554
|
+
{}
|
474
555
|
end
|
475
556
|
|
476
557
|
|
@@ -478,7 +559,7 @@ class EndIfAction < Action
|
|
478
559
|
constraint_list: []
|
479
560
|
}
|
480
561
|
|
481
|
-
super(
|
562
|
+
super()
|
482
563
|
|
483
564
|
end
|
484
565
|
|
@@ -723,9 +804,10 @@ class SayTimeAction < DateTimeAction
|
|
723
804
|
end
|
724
805
|
|
725
806
|
def invoke()
|
726
|
-
time = ($env and $env[:time]) ? $env[:time] : Time.now
|
807
|
+
#time = ($env and $env[:time]) ? $env[:time] : Time.now
|
808
|
+
time = Time.now
|
727
809
|
tformat = @h['12_hour'] ? "%-I:%M%P" : "%H:%M"
|
728
|
-
super(time.strftime(tformat))
|
810
|
+
super(txt: time.strftime(tformat))
|
729
811
|
end
|
730
812
|
|
731
813
|
def to_pc()
|
@@ -814,10 +896,18 @@ end
|
|
814
896
|
#
|
815
897
|
class SpeakTextAction < DeviceAction
|
816
898
|
|
817
|
-
def initialize(
|
818
|
-
|
899
|
+
def initialize(obj=nil)
|
900
|
+
|
901
|
+
h = if obj.is_a? Hash then
|
902
|
+
obj
|
903
|
+
elsif obj.is_a? Array
|
904
|
+
e, macro = obj
|
905
|
+
txt = e.text('item/description')
|
906
|
+
{text: (txt || e.text)}
|
907
|
+
end
|
908
|
+
|
819
909
|
options = {
|
820
|
-
text_to_say: '',
|
910
|
+
text_to_say: h[:text] || '',
|
821
911
|
queue: false,
|
822
912
|
read_numbers_individually: false,
|
823
913
|
specify_audio_stream: false,
|
@@ -831,8 +921,13 @@ class SpeakTextAction < DeviceAction
|
|
831
921
|
|
832
922
|
end
|
833
923
|
|
924
|
+
def invoke()
|
925
|
+
super(text: @h[:text_to_say])
|
926
|
+
end
|
927
|
+
|
834
928
|
def to_s(colour: false, indent: 0)
|
835
|
-
"Speak Text (%s)" % @h[:text_to_say]
|
929
|
+
@s = "Speak Text (%s)" % @h[:text_to_say]
|
930
|
+
super()
|
836
931
|
end
|
837
932
|
|
838
933
|
end
|
@@ -984,6 +1079,9 @@ class CameraFlashLightAction < DeviceSettingsAction
|
|
984
1079
|
super(options.merge h)
|
985
1080
|
|
986
1081
|
end
|
1082
|
+
def invoke()
|
1083
|
+
super(state: @h[:state])
|
1084
|
+
end
|
987
1085
|
|
988
1086
|
def to_pc()
|
989
1087
|
['torch :on', 'torch :off', 'torch :toggle'][@h[:state]]
|
@@ -1000,7 +1098,17 @@ end
|
|
1000
1098
|
class VibrateAction < DeviceSettingsAction
|
1001
1099
|
|
1002
1100
|
def initialize(h={})
|
1003
|
-
|
1101
|
+
|
1102
|
+
pattern = [
|
1103
|
+
'Blip', 'Short Buzz', 'Long Buzz', 'Rapid', 'Slow', 'Increasing',
|
1104
|
+
'Constant', 'Decreasing', 'Final Fantasy', 'Game Over', 'Star Wars',
|
1105
|
+
'Mini Blip', 'Micro Blip'
|
1106
|
+
]
|
1107
|
+
|
1108
|
+
if h[:pattern] then
|
1109
|
+
h[:vibrate_pattern] = pattern.map(&:downcase).index h[:pattern]
|
1110
|
+
end
|
1111
|
+
|
1004
1112
|
options = {
|
1005
1113
|
vibrate_pattern: 1
|
1006
1114
|
}
|
@@ -1288,7 +1396,7 @@ class ForceLocationUpdateAction < LocationAction
|
|
1288
1396
|
end
|
1289
1397
|
|
1290
1398
|
def to_s(colour: false, indent: 0)
|
1291
|
-
'
|
1399
|
+
'Force Location Update' #+ @h.inspect
|
1292
1400
|
end
|
1293
1401
|
|
1294
1402
|
alias to_summary to_s
|
@@ -1309,26 +1417,34 @@ end
|
|
1309
1417
|
#
|
1310
1418
|
class ShareLocationAction < LocationAction
|
1311
1419
|
|
1312
|
-
def initialize(
|
1420
|
+
def initialize(obj=nil)
|
1313
1421
|
|
1314
|
-
|
1422
|
+
h = if obj.is_a? Hash then
|
1423
|
+
obj
|
1424
|
+
elsif obj.is_a? Array
|
1425
|
+
e, macro = obj
|
1426
|
+
{variable: macro.set_var(e.text('item/description').to_s)}
|
1427
|
+
|
1428
|
+
end
|
1429
|
+
|
1430
|
+
#super()
|
1315
1431
|
|
1316
1432
|
options = {
|
1317
1433
|
email: '',
|
1318
|
-
variable: {:
|
1319
|
-
:
|
1320
|
-
:
|
1434
|
+
variable: {:string_value=>"", :name=>"",
|
1435
|
+
:decimal_value=>0.0, :is_local=>true, :boolean_value=>false,
|
1436
|
+
:exclude_from_log=>false, :int_value=>0, :type=>2},
|
1321
1437
|
sim_id: 0,
|
1322
1438
|
output_channel: 5,
|
1323
1439
|
old_variable_format: true
|
1324
1440
|
}
|
1325
|
-
|
1441
|
+
#options[:variable].merge! h
|
1326
1442
|
super(options.merge h)
|
1327
1443
|
|
1328
1444
|
end
|
1329
1445
|
|
1330
1446
|
def to_s(colour: false, indent: 0)
|
1331
|
-
@s = 'Share Location' + "\
|
1447
|
+
@s = 'Share Location' + "\n" + @h[:variable][:name] # + @h.inspect
|
1332
1448
|
super()
|
1333
1449
|
end
|
1334
1450
|
|
@@ -1522,8 +1638,24 @@ end
|
|
1522
1638
|
# MacroDroid Specific
|
1523
1639
|
#
|
1524
1640
|
class SetVariableAction < Action
|
1641
|
+
using ColouredText
|
1525
1642
|
|
1526
|
-
def initialize(
|
1643
|
+
def initialize(obj=nil)
|
1644
|
+
|
1645
|
+
h = if obj.is_a? Hash then
|
1646
|
+
obj
|
1647
|
+
elsif obj.is_a? Array
|
1648
|
+
e, macro = obj
|
1649
|
+
node = e.element('item/*')
|
1650
|
+
#puts ("node.name: %s node.value: %s" % [node.name, node.value]).debug
|
1651
|
+
r = macro.set_var node.name, node.value.to_s
|
1652
|
+
puts ('r: ' + r.inspect).debug if $debug
|
1653
|
+
r
|
1654
|
+
if r[:type] == 2 then
|
1655
|
+
{ variable: {name: r[:name], type: r[:type]}, new_string_value: r[:string_value]
|
1656
|
+
}
|
1657
|
+
end
|
1658
|
+
end
|
1527
1659
|
|
1528
1660
|
options = {
|
1529
1661
|
:user_prompt=>true,
|
@@ -1531,9 +1663,21 @@ class SetVariableAction < Action
|
|
1531
1663
|
:user_prompt_show_cancel=>true,
|
1532
1664
|
:user_prompt_stop_after_cancel=>true,
|
1533
1665
|
:user_prompt_title=>"Word reverse",
|
1534
|
-
:name => 'word'
|
1666
|
+
:name => 'word',
|
1667
|
+
:false_label=>"False", :int_expression=>false, :int_random=>false,
|
1668
|
+
:int_random_max=>0, :int_random_min=>0, :int_value_decrement=>false,
|
1669
|
+
:int_value_increment=>false, :new_boolean_value=>false,
|
1670
|
+
:new_double_value=>0.0, :new_int_value=>0,
|
1671
|
+
:new_string_value=>"[battery]", :true_label=>"True",
|
1672
|
+
:user_prompt=>false, :user_prompt_show_cancel=>true,
|
1673
|
+
:user_prompt_stop_after_cancel=>true,
|
1674
|
+
:variable=>{
|
1675
|
+
:exclude_from_log=>false, :is_local=>true,
|
1676
|
+
:boolean_value=>false, :decimal_value=>0.0,
|
1677
|
+
:int_value=>0, :name=>"foo", :string_value=>"52", :type=>2
|
1678
|
+
}
|
1535
1679
|
}
|
1536
|
-
super(h)
|
1680
|
+
super(options.merge h)
|
1537
1681
|
|
1538
1682
|
end
|
1539
1683
|
|
@@ -2287,8 +2431,46 @@ end
|
|
2287
2431
|
# disable keep awake => enabled: false
|
2288
2432
|
#
|
2289
2433
|
class KeepAwakeAction < ScreenAction
|
2434
|
+
using ColouredText
|
2290
2435
|
|
2291
|
-
def initialize(
|
2436
|
+
def initialize(obj=nil)
|
2437
|
+
|
2438
|
+
|
2439
|
+
h = if obj.is_a? Hash then
|
2440
|
+
|
2441
|
+
obj
|
2442
|
+
|
2443
|
+
elsif obj.is_a? Array
|
2444
|
+
|
2445
|
+
puts 'obj: ' + obj.inspect if $debug
|
2446
|
+
e, macro = obj
|
2447
|
+
|
2448
|
+
a = e.xpath('item/*')
|
2449
|
+
|
2450
|
+
txt = e.text('item/description')
|
2451
|
+
|
2452
|
+
h2 = if txt then
|
2453
|
+
|
2454
|
+
raw_duration = (txt || e.text).to_s
|
2455
|
+
puts 'raw_duration: ' + raw_duration.inspect if $debug
|
2456
|
+
duration = raw_duration[/Screen On - ([^$]+)/i]
|
2457
|
+
{duration: duration}
|
2458
|
+
|
2459
|
+
elsif a.any? then
|
2460
|
+
a.map {|node| [node.name.to_sym, node.text.to_s]}.to_h
|
2461
|
+
end
|
2462
|
+
|
2463
|
+
h2.merge(macro: macro)
|
2464
|
+
|
2465
|
+
end
|
2466
|
+
|
2467
|
+
puts ('h: ' + h.inspect).debug if $debug
|
2468
|
+
|
2469
|
+
if h[:duration] then
|
2470
|
+
|
2471
|
+
h[:seconds_to_stay_awake_for] = Subunit.hms_to_seconds(h[:duration])
|
2472
|
+
|
2473
|
+
end
|
2292
2474
|
|
2293
2475
|
options = {
|
2294
2476
|
enabled: true,
|