ruby-macrodroid 0.8.10 → 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 +4 -1
- data/lib/ruby-macrodroid.rb +29 -261
- data/lib/ruby-macrodroid/actions.rb +196 -47
- data/lib/ruby-macrodroid/base.rb +21 -15
- data/lib/ruby-macrodroid/constraints.rb +1338 -0
- data/lib/ruby-macrodroid/macro.rb +498 -27
- data/lib/ruby-macrodroid/triggers.rb +49 -10
- metadata +11 -10
- 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
data/lib/ruby-macrodroid.rb
CHANGED
@@ -38,254 +38,13 @@ require 'rxfhelper'
|
|
38
38
|
require 'chronic_cron'
|
39
39
|
|
40
40
|
|
41
|
+
|
41
42
|
MODEL =<<EOF
|
42
43
|
device
|
43
44
|
connectivity
|
44
45
|
airplane_mode is disabled
|
45
46
|
EOF
|
46
47
|
|
47
|
-
class TriggersNlp
|
48
|
-
include AppRoutes
|
49
|
-
|
50
|
-
def initialize()
|
51
|
-
|
52
|
-
super()
|
53
|
-
params = {}
|
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
|
-
|
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()
|
134
|
-
|
135
|
-
super()
|
136
|
-
params = {}
|
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 = onoffstate.downcase == 'on' ? 0 : 1
|
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
|
-
# e.g. Display Notification: Hi there: This is the body of the message
|
182
|
-
get /^Display Notification: ([^:]+): [^$]+$/i do |subject, text|
|
183
|
-
[NotificationAction, {subject: subject, text: text}]
|
184
|
-
end
|
185
|
-
|
186
|
-
|
187
|
-
# e.g. Enable Wifi
|
188
|
-
get /^(Enable|Disable) Wifi$/i do |raw_state|
|
189
|
-
|
190
|
-
state = raw_state.downcase.to_sym == :enable ? 0 : 1
|
191
|
-
[SetWifiAction, {state: state}]
|
192
|
-
|
193
|
-
end
|
194
|
-
|
195
|
-
# e.g. Play: Altair
|
196
|
-
get /^Play: (.*)$/i do |name|
|
197
|
-
|
198
|
-
[PlaySoundAction, {file_path: name}]
|
199
|
-
|
200
|
-
end
|
201
|
-
|
202
|
-
# e.g. Launch Settings
|
203
|
-
get /^Launch (.*)$/i do |application|
|
204
|
-
|
205
|
-
h = {
|
206
|
-
application_name: application,
|
207
|
-
package_to_launch: 'com.android.' + application.downcase
|
208
|
-
}
|
209
|
-
[LaunchActivityAction, h]
|
210
|
-
|
211
|
-
end
|
212
|
-
|
213
|
-
# e.g. HTTP GET http://someurl.com/something
|
214
|
-
get /^HTTP GET ([^$]+)$/i do |url|
|
215
|
-
|
216
|
-
[OpenWebPageAction, url_to_open: url]
|
217
|
-
|
218
|
-
end
|
219
|
-
|
220
|
-
# e.g. webhook entered_kitchen
|
221
|
-
#
|
222
|
-
get /webhook|HTTP GET/i do
|
223
|
-
[OpenWebPageAction, {}]
|
224
|
-
end
|
225
|
-
|
226
|
-
#a: Keep Device Awake Screen On Until Disabled
|
227
|
-
#
|
228
|
-
get /Keep Device Awake Screen On Until Disabled/i do
|
229
|
-
[KeepAwakeAction, {enabled: true, permanent: true, screen_option: 0}]
|
230
|
-
end
|
231
|
-
|
232
|
-
|
233
|
-
#a: Keep Device Awake Screen On 1h 1m 1s
|
234
|
-
#
|
235
|
-
get /Keep Device Awake Screen On ([^$]+)/i do |duration|
|
236
|
-
|
237
|
-
a = duration.split.map(&:to_i)
|
238
|
-
secs = Subunit.new(units={minutes:60, hours:60, seconds: 60}, a).to_i
|
239
|
-
|
240
|
-
h = {
|
241
|
-
permanent: true, screen_option: 0, seconds_to_stay_awake_for: secs
|
242
|
-
}
|
243
|
-
[KeepAwakeAction, h]
|
244
|
-
end
|
245
|
-
|
246
|
-
#a: Disable Keep Awake
|
247
|
-
#
|
248
|
-
get /Disable Keep Awake/i do
|
249
|
-
[KeepAwakeAction, {enabled: false, screen_option: 0}]
|
250
|
-
end
|
251
|
-
|
252
|
-
#a: Disable Keep Awake
|
253
|
-
#
|
254
|
-
get /if (.*)/i do
|
255
|
-
[IfConditionAction, {}]
|
256
|
-
end
|
257
|
-
|
258
|
-
end
|
259
|
-
|
260
|
-
alias find_action run_route
|
261
|
-
|
262
|
-
|
263
|
-
end
|
264
|
-
|
265
|
-
class ConstraintsNlp
|
266
|
-
include AppRoutes
|
267
|
-
|
268
|
-
def initialize()
|
269
|
-
|
270
|
-
super()
|
271
|
-
params = {}
|
272
|
-
constraints(params)
|
273
|
-
|
274
|
-
end
|
275
|
-
|
276
|
-
def constraints(params)
|
277
|
-
|
278
|
-
get /^airplane mode (.*)/i do |state|
|
279
|
-
[AirplaneModeConstraint, {enabled: (state =~ /^enabled|on$/) == 0}]
|
280
|
-
end
|
281
|
-
|
282
|
-
end
|
283
|
-
|
284
|
-
alias find_constraint run_route
|
285
|
-
|
286
|
-
end
|
287
|
-
|
288
|
-
|
289
48
|
module Params
|
290
49
|
|
291
50
|
refine Hash do
|
@@ -315,16 +74,16 @@ module Params
|
|
315
74
|
end
|
316
75
|
|
317
76
|
# turns keys from snake_case to CamelCase
|
318
|
-
def
|
77
|
+
def to_camelcase(h=self)
|
319
78
|
|
320
79
|
h.inject({}) do |r,x|
|
321
80
|
|
322
81
|
key, value = x
|
323
82
|
|
324
83
|
val = if value.is_a?(Hash) then
|
325
|
-
|
84
|
+
to_camelcase(value)
|
326
85
|
elsif value.is_a?(Array) and value.first.is_a? Hash
|
327
|
-
value.map {|row|
|
86
|
+
value.map {|row| to_camelcase(row)}
|
328
87
|
else
|
329
88
|
value
|
330
89
|
end
|
@@ -341,24 +100,23 @@ end
|
|
341
100
|
|
342
101
|
|
343
102
|
|
344
|
-
|
345
|
-
|
346
103
|
class MacroDroidError < Exception
|
347
104
|
end
|
348
105
|
|
349
106
|
class MacroDroid
|
107
|
+
include RXFHelperModule
|
350
108
|
using ColouredText
|
351
109
|
using Params
|
352
110
|
|
353
111
|
attr_reader :macros, :geofences, :yaml
|
354
|
-
attr_accessor :deviceid
|
112
|
+
attr_accessor :deviceid, :remote_url
|
355
113
|
|
356
114
|
# note: The deviceid can only be found from an existing Webhook trigger,
|
357
115
|
# generated from MacroDroid itself.
|
358
116
|
|
359
|
-
def initialize(obj=nil, deviceid: nil, debug: false)
|
117
|
+
def initialize(obj=nil, deviceid: nil, remote_url: nil, debug: false)
|
360
118
|
|
361
|
-
@deviceid, @debug = deviceid, debug
|
119
|
+
@deviceid, @remote_url, @debug = deviceid, remote_url, debug
|
362
120
|
|
363
121
|
@geofences = {}
|
364
122
|
|
@@ -387,10 +145,16 @@ class MacroDroid
|
|
387
145
|
puts 'before RowX.new' if @debug
|
388
146
|
|
389
147
|
s2 = s.gsub(/^g:/,'geofence:').gsub(/^m:/,'macro:')\
|
390
|
-
.gsub(/^
|
391
|
-
.gsub(/^c:/,'constraint:').gsub(/^#.*/,'')
|
148
|
+
.gsub(/^v:/,'variable:').gsub(/^t:/,'trigger:')\
|
149
|
+
.gsub(/^a:/,'action:').gsub(/^c:/,'constraint:').gsub(/^#.*/,'')
|
150
|
+
|
151
|
+
a = s2.split(/(?=^macro:)/)
|
392
152
|
|
393
|
-
|
153
|
+
raw_geofences = a.shift if a.first =~ /^geofence/
|
154
|
+
raw_macros = a.join
|
155
|
+
#raw_macros, raw_geofences .reverse
|
156
|
+
|
157
|
+
puts 'raw_macros: ' + raw_macros.inspect if @debug
|
394
158
|
|
395
159
|
if raw_geofences then
|
396
160
|
|
@@ -402,7 +166,7 @@ class MacroDroid
|
|
402
166
|
|
403
167
|
end
|
404
168
|
|
405
|
-
xml = RowX.new(raw_macros).to_xml
|
169
|
+
xml = RowX.new(raw_macros, allow_lonely_keyfield: true).to_xml
|
406
170
|
puts 'xml: ' + xml if @debug
|
407
171
|
import_rowxml(xml)
|
408
172
|
|
@@ -457,14 +221,16 @@ class MacroDroid
|
|
457
221
|
|
458
222
|
}
|
459
223
|
end
|
224
|
+
|
225
|
+
def export(filepath)
|
226
|
+
FileX.write filepath, to_json
|
227
|
+
end
|
460
228
|
|
461
|
-
def
|
229
|
+
def to_json()
|
462
230
|
|
463
231
|
to_h.to_json
|
464
232
|
|
465
233
|
end
|
466
|
-
|
467
|
-
alias to_json export_json
|
468
234
|
|
469
235
|
|
470
236
|
def to_h()
|
@@ -475,7 +241,7 @@ class MacroDroid
|
|
475
241
|
},
|
476
242
|
macro_list: @macros.map(&:to_h)
|
477
243
|
}
|
478
|
-
@h.merge(h).
|
244
|
+
@h.merge(h).to_camelcase
|
479
245
|
|
480
246
|
end
|
481
247
|
|
@@ -566,7 +332,7 @@ class MacroDroid
|
|
566
332
|
# puts '@geofences: ' + @geofences.inspect if @debug
|
567
333
|
|
568
334
|
m = Macro.new(geofences: @geofences.map(&:last), deviceid: @deviceid,
|
569
|
-
debug: @debug )
|
335
|
+
remote_url: @remote_url, debug: @debug )
|
570
336
|
m.import_h(macro)
|
571
337
|
m
|
572
338
|
|
@@ -588,7 +354,7 @@ class MacroDroid
|
|
588
354
|
@macros = doc.root.xpath('item').map do |node|
|
589
355
|
puts ('geofences: ' + geofences.inspect).highlight if @debug
|
590
356
|
Macro.new(geofences: geofences.map(&:last), deviceid: @deviceid,
|
591
|
-
debug: @debug).import_xml(node)
|
357
|
+
remote_url: @remote_url, debug: @debug).import_xml(node)
|
592
358
|
|
593
359
|
end
|
594
360
|
|
@@ -610,7 +376,7 @@ class MacroDroid
|
|
610
376
|
end
|
611
377
|
|
612
378
|
@macros = doc.root.xpath('macro').map do |node|
|
613
|
-
|
379
|
+
puts 'node: ' + node.inspect if @debug
|
614
380
|
Macro.new(geofences: @geofences.map(&:last), deviceid: @deviceid,
|
615
381
|
debug: @debug).import_xml(node)
|
616
382
|
|
@@ -811,7 +577,9 @@ class DroidSim
|
|
811
577
|
|
812
578
|
end
|
813
579
|
|
580
|
+
|
814
581
|
require 'ruby-macrodroid/base'
|
815
582
|
require 'ruby-macrodroid/triggers'
|
816
583
|
require 'ruby-macrodroid/actions'
|
817
584
|
require 'ruby-macrodroid/constraints'
|
585
|
+
require 'ruby-macrodroid/macro'
|
@@ -42,15 +42,15 @@ class Action < MacroObject
|
|
42
42
|
macro = h[:macro]
|
43
43
|
h.delete :macro
|
44
44
|
super(h)
|
45
|
-
|
46
|
-
# fetch the constraints
|
45
|
+
|
47
46
|
@constraints = @h[:constraint_list].map do |constraint|
|
48
47
|
object(constraint.to_snake_case.merge(macro: macro))
|
49
|
-
end
|
48
|
+
end
|
49
|
+
|
50
50
|
end
|
51
51
|
|
52
|
-
def invoke(
|
53
|
-
"%s/%s: %s" % [@group, @type,
|
52
|
+
def invoke(h={})
|
53
|
+
"%s/%s: %s" % [@group, @type, h.to_json]
|
54
54
|
end
|
55
55
|
|
56
56
|
|
@@ -136,26 +136,95 @@ class LaunchShortcutAction < ApplicationAction
|
|
136
136
|
|
137
137
|
end
|
138
138
|
|
139
|
+
class OpenWebPageActionError < Exception
|
140
|
+
end
|
141
|
+
|
139
142
|
# Category: Applications
|
140
143
|
#
|
141
144
|
class OpenWebPageAction < ApplicationAction
|
142
145
|
|
143
|
-
def initialize(
|
146
|
+
def initialize(obj={}, macro=nil)
|
147
|
+
|
148
|
+
# puts 'obj: ' + obj[0].xml.inspect
|
149
|
+
|
150
|
+
h = if obj.is_a? Hash then
|
151
|
+
|
152
|
+
obj
|
153
|
+
|
154
|
+
elsif obj.is_a? Array
|
155
|
+
|
156
|
+
puts 'obj: ' + obj.inspect if $debug
|
157
|
+
e, macro = obj
|
158
|
+
|
159
|
+
a = e.xpath('item/*')
|
160
|
+
|
161
|
+
h2 = if a.any? then
|
162
|
+
a.map {|node| [node.name.to_sym, node.text.to_s]}.to_h
|
163
|
+
else
|
164
|
+
txt = e.text('item/description')
|
165
|
+
{url: (txt || e.text)}
|
166
|
+
end
|
167
|
+
|
168
|
+
h2.merge(macro: macro)
|
169
|
+
|
170
|
+
end
|
171
|
+
|
172
|
+
puts 'h:' + h.inspect if $debug
|
144
173
|
|
145
|
-
h[:url_to_open] = h[:url] if h[:url]
|
174
|
+
#h[:url_to_open] = h[:url] if h[:url] and h[:url].length > 1
|
146
175
|
|
147
176
|
options = {
|
148
|
-
variable_to_save_response: {:
|
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},
|
149
180
|
url_to_open: '',
|
150
181
|
http_get: true,
|
151
182
|
disable_url_encode: false,
|
152
183
|
block_next_action: false
|
153
184
|
}
|
185
|
+
|
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
|
189
|
+
raise OpenWebPageActionError, 'remote_url not found'
|
190
|
+
end
|
191
|
+
|
192
|
+
url = if h[:url] and h[:url].length > 1 then
|
193
|
+
|
194
|
+
h[:url]
|
154
195
|
|
155
|
-
|
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?)
|
201
|
+
|
202
|
+
h[:url_to_open] = h[:macro].remote_url.sub(/\/$/,'') + '/' +
|
203
|
+
h[:macro].title.downcase.gsub(/ +/,'-')
|
204
|
+
|
205
|
+
end
|
206
|
+
|
207
|
+
if h2 then
|
208
|
+
|
209
|
+
h2.delete :identifier
|
210
|
+
h2.delete :url
|
211
|
+
|
212
|
+
if h2.any? then
|
213
|
+
url += '?' + \
|
214
|
+
URI.escape(h2.map {|key,value| "%s=%s" % [key, value]}.join('&'))
|
215
|
+
end
|
216
|
+
|
217
|
+
end
|
218
|
+
|
219
|
+
h[:url_to_open] = url
|
220
|
+
super(options.merge h)
|
156
221
|
|
157
222
|
end
|
158
223
|
|
224
|
+
def invoke()
|
225
|
+
super(url: @h[:url_to_open])
|
226
|
+
end
|
227
|
+
|
159
228
|
def to_s(colour: false, indent: 0)
|
160
229
|
@s = "HTTP GET\nurl: " + @h[:url_to_open]
|
161
230
|
super()
|
@@ -317,25 +386,50 @@ end
|
|
317
386
|
# Conditions/Loops
|
318
387
|
#
|
319
388
|
class IfConditionAction < Action
|
320
|
-
|
389
|
+
|
321
390
|
def initialize(obj=nil)
|
391
|
+
|
392
|
+
options = {
|
393
|
+
a: true,
|
394
|
+
constraint_list: []
|
395
|
+
}
|
322
396
|
|
323
|
-
|
324
|
-
|
397
|
+
if obj.is_a? Hash then
|
398
|
+
|
399
|
+
h = obj
|
400
|
+
macro = h[:macro]
|
401
|
+
h2 = options.merge(filter(options,h).merge(macro: macro))
|
402
|
+
super(h2)
|
403
|
+
|
404
|
+
elsif obj.is_a? Array
|
405
|
+
e, macro = obj
|
406
|
+
super()
|
407
|
+
raw_txt = e.text('item/description') || e.text.to_s
|
408
|
+
puts 'raw_txt: ' + raw_txt.inspect if $debug
|
409
|
+
|
410
|
+
clause = raw_txt[/^if (.*)/i,1]
|
411
|
+
conditions = clause.split(/\s+\b(?:AND|OR)\b\s+/i)
|
412
|
+
|
413
|
+
cp = ConstraintsNlp.new
|
414
|
+
|
415
|
+
@constraints = conditions.map do |c|
|
416
|
+
puts 'c: ' + c.inspect
|
417
|
+
r = cp.find_constraint c
|
418
|
+
puts 'found constraint ' + r.inspect if $debug
|
419
|
+
|
420
|
+
r[0].new(r[1]) if r
|
421
|
+
|
422
|
+
end
|
423
|
+
puts '@constraints: ' + @constraints.inspect if $debug
|
424
|
+
{}
|
325
425
|
else
|
326
426
|
# get the constraints
|
327
427
|
|
328
428
|
end
|
329
429
|
|
330
|
-
|
331
|
-
a: true,
|
332
|
-
constraint_list: ''
|
333
|
-
}
|
430
|
+
|
334
431
|
|
335
|
-
macro = h[:macro]
|
336
|
-
h2 = options.merge(filter(options,h).merge(macro: macro))
|
337
432
|
|
338
|
-
super(h2)
|
339
433
|
|
340
434
|
@label = 'If '
|
341
435
|
|
@@ -344,7 +438,7 @@ class IfConditionAction < Action
|
|
344
438
|
def to_s(colour: false, indent: 0)
|
345
439
|
|
346
440
|
h = @h.clone
|
347
|
-
h.delete :macro
|
441
|
+
#h.delete :macro
|
348
442
|
@s = 'If '
|
349
443
|
operator = @h[:is_or_condition] ? 'OR' : 'AND'
|
350
444
|
constraints = @constraints.map \
|
@@ -418,13 +512,22 @@ end
|
|
418
512
|
|
419
513
|
class EndIfAction < Action
|
420
514
|
|
421
|
-
def initialize(
|
422
|
-
|
515
|
+
def initialize(obj={})
|
516
|
+
|
517
|
+
h = if obj.is_a? Hash then
|
518
|
+
obj
|
519
|
+
elsif obj.is_a? Rexle::Element
|
520
|
+
{}
|
521
|
+
else
|
522
|
+
{}
|
523
|
+
end
|
524
|
+
|
525
|
+
|
423
526
|
options = {
|
424
|
-
constraint_list:
|
527
|
+
constraint_list: []
|
425
528
|
}
|
426
529
|
|
427
|
-
super(
|
530
|
+
super()
|
428
531
|
|
429
532
|
end
|
430
533
|
|
@@ -432,6 +535,8 @@ class EndIfAction < Action
|
|
432
535
|
'End If'
|
433
536
|
end
|
434
537
|
|
538
|
+
alias to_summary to_s
|
539
|
+
|
435
540
|
end
|
436
541
|
|
437
542
|
class ConnectivityAction < Action
|
@@ -667,9 +772,10 @@ class SayTimeAction < DateTimeAction
|
|
667
772
|
end
|
668
773
|
|
669
774
|
def invoke()
|
670
|
-
time = ($env and $env[:time]) ? $env[:time] : Time.now
|
775
|
+
#time = ($env and $env[:time]) ? $env[:time] : Time.now
|
776
|
+
time = Time.now
|
671
777
|
tformat = @h['12_hour'] ? "%-I:%M%P" : "%H:%M"
|
672
|
-
super(time.strftime(tformat))
|
778
|
+
super(txt: time.strftime(tformat))
|
673
779
|
end
|
674
780
|
|
675
781
|
def to_pc()
|
@@ -758,10 +864,18 @@ end
|
|
758
864
|
#
|
759
865
|
class SpeakTextAction < DeviceAction
|
760
866
|
|
761
|
-
def initialize(
|
762
|
-
|
867
|
+
def initialize(obj=nil)
|
868
|
+
|
869
|
+
h = if obj.is_a? Hash then
|
870
|
+
obj
|
871
|
+
elsif obj.is_a? Array
|
872
|
+
e, macro = obj
|
873
|
+
txt = e.text('item/description')
|
874
|
+
{text: (txt || e.text)}
|
875
|
+
end
|
876
|
+
|
763
877
|
options = {
|
764
|
-
text_to_say: '',
|
878
|
+
text_to_say: h[:text] || '',
|
765
879
|
queue: false,
|
766
880
|
read_numbers_individually: false,
|
767
881
|
specify_audio_stream: false,
|
@@ -775,8 +889,13 @@ class SpeakTextAction < DeviceAction
|
|
775
889
|
|
776
890
|
end
|
777
891
|
|
892
|
+
def invoke()
|
893
|
+
super(text: @h[:text_to_say])
|
894
|
+
end
|
895
|
+
|
778
896
|
def to_s(colour: false, indent: 0)
|
779
|
-
"Speak Text (%s)" % @h[:text_to_say]
|
897
|
+
@s = "Speak Text (%s)" % @h[:text_to_say]
|
898
|
+
super()
|
780
899
|
end
|
781
900
|
|
782
901
|
end
|
@@ -928,6 +1047,9 @@ class CameraFlashLightAction < DeviceSettingsAction
|
|
928
1047
|
super(options.merge h)
|
929
1048
|
|
930
1049
|
end
|
1050
|
+
def invoke()
|
1051
|
+
super(state: @h[:state])
|
1052
|
+
end
|
931
1053
|
|
932
1054
|
def to_pc()
|
933
1055
|
['torch :on', 'torch :off', 'torch :toggle'][@h[:state]]
|
@@ -1232,7 +1354,7 @@ class ForceLocationUpdateAction < LocationAction
|
|
1232
1354
|
end
|
1233
1355
|
|
1234
1356
|
def to_s(colour: false, indent: 0)
|
1235
|
-
'
|
1357
|
+
'Force Location Update' #+ @h.inspect
|
1236
1358
|
end
|
1237
1359
|
|
1238
1360
|
alias to_summary to_s
|
@@ -1253,26 +1375,34 @@ end
|
|
1253
1375
|
#
|
1254
1376
|
class ShareLocationAction < LocationAction
|
1255
1377
|
|
1256
|
-
def initialize(
|
1378
|
+
def initialize(obj=nil)
|
1257
1379
|
|
1258
|
-
|
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()
|
1259
1389
|
|
1260
1390
|
options = {
|
1261
1391
|
email: '',
|
1262
|
-
variable: {:
|
1263
|
-
:
|
1264
|
-
:
|
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},
|
1265
1395
|
sim_id: 0,
|
1266
1396
|
output_channel: 5,
|
1267
1397
|
old_variable_format: true
|
1268
1398
|
}
|
1269
|
-
|
1399
|
+
#options[:variable].merge! h
|
1270
1400
|
super(options.merge h)
|
1271
1401
|
|
1272
1402
|
end
|
1273
1403
|
|
1274
1404
|
def to_s(colour: false, indent: 0)
|
1275
|
-
@s = 'Share Location' + "\
|
1405
|
+
@s = 'Share Location' + "\n" + @h[:variable][:name] # + @h.inspect
|
1276
1406
|
super()
|
1277
1407
|
end
|
1278
1408
|
|
@@ -1467,7 +1597,15 @@ end
|
|
1467
1597
|
#
|
1468
1598
|
class SetVariableAction < Action
|
1469
1599
|
|
1470
|
-
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
|
1471
1609
|
|
1472
1610
|
options = {
|
1473
1611
|
:user_prompt=>true,
|
@@ -1475,9 +1613,21 @@ class SetVariableAction < Action
|
|
1475
1613
|
:user_prompt_show_cancel=>true,
|
1476
1614
|
:user_prompt_stop_after_cancel=>true,
|
1477
1615
|
:user_prompt_title=>"Word reverse",
|
1478
|
-
: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
|
+
}
|
1479
1629
|
}
|
1480
|
-
super(h)
|
1630
|
+
super(options.merge h)
|
1481
1631
|
|
1482
1632
|
end
|
1483
1633
|
|
@@ -1938,11 +2088,10 @@ class ToastAction < NotificationsAction
|
|
1938
2088
|
|
1939
2089
|
h = if obj.is_a? Hash then
|
1940
2090
|
obj
|
1941
|
-
elsif obj.is_a?
|
1942
|
-
|
1943
|
-
|
1944
|
-
|
1945
|
-
{msg: obj}
|
2091
|
+
elsif obj.is_a? Array
|
2092
|
+
e, macro = obj
|
2093
|
+
txt = e.text('item/description')
|
2094
|
+
{msg: (txt || e.text)}
|
1946
2095
|
end
|
1947
2096
|
|
1948
2097
|
if h[:msg] then
|
@@ -1966,7 +2115,7 @@ class ToastAction < NotificationsAction
|
|
1966
2115
|
end
|
1967
2116
|
|
1968
2117
|
def invoke()
|
1969
|
-
super(@h[:message_text])
|
2118
|
+
super(msg: @h[:message_text])
|
1970
2119
|
end
|
1971
2120
|
|
1972
2121
|
def to_pc()
|