ruby-macrodroid 0.9.1 → 0.9.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/ruby-macrodroid.rb +11 -7
- data/lib/ruby-macrodroid/actions.rb +231 -43
- data/lib/ruby-macrodroid/base.rb +118 -15
- data/lib/ruby-macrodroid/constraints.rb +28 -5
- data/lib/ruby-macrodroid/macro.rb +510 -95
- data/lib/ruby-macrodroid/triggers.rb +16 -10
- 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: 652f6174d50060ca2b7e3197c2bc79062ed6af498b1982ef8c73e27b0422ad85
|
4
|
+
data.tar.gz: 86096eb1c1fef612666065e0e3d48c619b4768d801723b6beaa273687d643fec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f9705342b8176dc48a5bfca362a17e340bfd56f67d2eafa3b20602fa493d02cbf5a9cbfe13b2dfb02565a74bb02bf01477de6884151a659fab4500c4b2cbfea4
|
7
|
+
data.tar.gz: 6e7bae11b8cf64ff3b0efd4f852f6bb8c2e419aa8d25693aeb894dde64c063c2dbcf9abe9bddf5dbe87cb630d8fa6e6c183d105b6b71fedee804918a79467489
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/lib/ruby-macrodroid.rb
CHANGED
@@ -38,6 +38,8 @@ 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
|
@@ -73,16 +75,16 @@ module Params
|
|
73
75
|
end
|
74
76
|
|
75
77
|
# turns keys from snake_case to CamelCase
|
76
|
-
def
|
78
|
+
def to_camelcase(h=self)
|
77
79
|
|
78
80
|
h.inject({}) do |r,x|
|
79
81
|
|
80
82
|
key, value = x
|
81
83
|
|
82
84
|
val = if value.is_a?(Hash) then
|
83
|
-
|
85
|
+
to_camelcase(value)
|
84
86
|
elsif value.is_a?(Array) and value.first.is_a? Hash
|
85
|
-
value.map {|row|
|
87
|
+
value.map {|row| to_camelcase(row)}
|
86
88
|
else
|
87
89
|
value
|
88
90
|
end
|
@@ -144,8 +146,9 @@ class MacroDroid
|
|
144
146
|
puts 'before RowX.new' if @debug
|
145
147
|
|
146
148
|
s2 = s.gsub(/^g:/,'geofence:').gsub(/^m:/,'macro:')\
|
147
|
-
.gsub(/^
|
148
|
-
.gsub(/^
|
149
|
+
.gsub(/^d:/,'description:').gsub(/^v:/,'variable:')\
|
150
|
+
.gsub(/^t:/,'trigger:').gsub(/^a:/,'action:')\
|
151
|
+
.gsub(/^c:/,'constraint:').gsub(/^#.*/,'')
|
149
152
|
|
150
153
|
a = s2.split(/(?=^macro:)/)
|
151
154
|
|
@@ -165,7 +168,7 @@ class MacroDroid
|
|
165
168
|
|
166
169
|
end
|
167
170
|
|
168
|
-
xml = RowX.new(raw_macros).to_xml
|
171
|
+
xml = RowX.new(raw_macros, allow_lonely_keyfield: true).to_xml
|
169
172
|
puts 'xml: ' + xml if @debug
|
170
173
|
import_rowxml(xml)
|
171
174
|
|
@@ -240,7 +243,7 @@ class MacroDroid
|
|
240
243
|
},
|
241
244
|
macro_list: @macros.map(&:to_h)
|
242
245
|
}
|
243
|
-
@h.merge(h).
|
246
|
+
@h.merge(h).to_camelcase
|
244
247
|
|
245
248
|
end
|
246
249
|
|
@@ -576,6 +579,7 @@ class DroidSim
|
|
576
579
|
|
577
580
|
end
|
578
581
|
|
582
|
+
# PASTE_END
|
579
583
|
|
580
584
|
require 'ruby-macrodroid/base'
|
581
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
|
|
@@ -141,22 +143,39 @@ end
|
|
141
143
|
|
142
144
|
# Category: Applications
|
143
145
|
#
|
146
|
+
|
147
|
+
|
144
148
|
class OpenWebPageAction < ApplicationAction
|
149
|
+
using ColouredText
|
145
150
|
|
146
151
|
def initialize(obj={}, macro=nil)
|
152
|
+
|
153
|
+
$debug = true
|
154
|
+
puts ('obj: ' + obj.inspect).debug if $debug
|
147
155
|
|
148
156
|
h = if obj.is_a? Hash then
|
149
157
|
|
150
|
-
obj
|
158
|
+
obj.merge({macro: macro})
|
151
159
|
|
152
160
|
elsif obj.is_a? Array
|
153
|
-
|
161
|
+
|
162
|
+
puts ('obj: ' + obj.inspect).debug if $debug
|
154
163
|
e, macro = obj
|
155
164
|
|
156
165
|
a = e.xpath('item/*')
|
157
166
|
|
158
167
|
h2 = if a.any? then
|
159
|
-
|
168
|
+
|
169
|
+
a.map do |node|
|
170
|
+
|
171
|
+
if node.name == 'description' and node.text.to_s =~ /: / then
|
172
|
+
node.text.to_s.split(/: +/,2).map(&:strip)
|
173
|
+
else
|
174
|
+
[node.name.to_sym, node.text.to_s.strip]
|
175
|
+
end
|
176
|
+
|
177
|
+
end.to_h
|
178
|
+
|
160
179
|
else
|
161
180
|
txt = e.text('item/description')
|
162
181
|
{url: (txt || e.text)}
|
@@ -166,41 +185,54 @@ class OpenWebPageAction < ApplicationAction
|
|
166
185
|
|
167
186
|
end
|
168
187
|
|
169
|
-
puts 'h:' + h.inspect if
|
188
|
+
puts ('h:' + h.inspect).debug if $debug
|
170
189
|
|
171
|
-
h[:url_to_open] = h[:url] if h[:url] and h[:url].length > 1
|
190
|
+
#h[:url_to_open] = h[:url] if h[:url] and h[:url].length > 1
|
172
191
|
|
173
192
|
options = {
|
174
|
-
variable_to_save_response: {:
|
175
|
-
|
176
|
-
excludeFromLog: false,
|
193
|
+
variable_to_save_response: {:string_value=>"", :name=>"coords",
|
194
|
+
decimal_value: 0.0, isLocal: true, m_boolean_value: false,
|
195
|
+
excludeFromLog: false, int_value: 0, type: 2},
|
177
196
|
url_to_open: '',
|
178
197
|
http_get: true,
|
179
198
|
disable_url_encode: false,
|
180
199
|
block_next_action: false
|
181
200
|
}
|
182
201
|
|
183
|
-
|
184
|
-
|
202
|
+
return super(options.merge h) if h[:url_to_open]
|
203
|
+
|
204
|
+
if h[:macro].remote_url.nil? and (h[:url].nil? or h[:url].empty?) then
|
185
205
|
raise OpenWebPageActionError, 'remote_url not found'
|
186
206
|
end
|
187
207
|
|
188
|
-
if
|
189
|
-
|
208
|
+
url = if h[:url] and h[:url].length > 1 then
|
209
|
+
|
210
|
+
h[:url]
|
211
|
+
|
212
|
+
elsif h2 and h[:macro].remote_url and h[:identifier]
|
213
|
+
|
214
|
+
"%s/%s" % [h[:macro].remote_url.sub(/\/$/,''), h[:identifier]]
|
215
|
+
|
216
|
+
elsif (h[:identifier].nil? or h[:identifier].empty?)
|
190
217
|
|
191
218
|
h[:url_to_open] = h[:macro].remote_url.sub(/\/$/,'') + '/' +
|
192
|
-
h[:macro].title.downcase.gsub(/ +/,'-')
|
219
|
+
h[:macro].title.downcase.gsub(/ +/,'-')
|
193
220
|
|
194
|
-
|
221
|
+
end
|
222
|
+
|
223
|
+
if h2 then
|
195
224
|
|
196
|
-
url = "%s/%s" % [h[:macro].remote_url.sub(/\/$/,''), h[:identifier]]
|
197
225
|
h2.delete :identifier
|
198
|
-
url
|
199
|
-
URI.escape(h2.map {|key,value| "%s=%s" % [key, value]}.join('&'))
|
200
|
-
h[:url_to_open] = url
|
226
|
+
h2.delete :url
|
201
227
|
|
202
|
-
|
228
|
+
if h2.any? then
|
229
|
+
url += '?' + \
|
230
|
+
URI.escape(h2.map {|key,value| "%s=%s" % [key, value]}.join('&'))
|
231
|
+
end
|
232
|
+
|
233
|
+
end
|
203
234
|
|
235
|
+
h[:url_to_open] = url
|
204
236
|
super(options.merge h)
|
205
237
|
|
206
238
|
end
|
@@ -377,6 +409,7 @@ class IfConditionAction < Action
|
|
377
409
|
a: true,
|
378
410
|
constraint_list: []
|
379
411
|
}
|
412
|
+
puts 'obj: ' + obj.inspect if $debug
|
380
413
|
|
381
414
|
if obj.is_a? Hash then
|
382
415
|
|
@@ -386,18 +419,23 @@ class IfConditionAction < Action
|
|
386
419
|
super(h2)
|
387
420
|
|
388
421
|
elsif obj.is_a? Array
|
422
|
+
|
389
423
|
e, macro = obj
|
390
|
-
super()
|
391
|
-
|
424
|
+
super()
|
425
|
+
puts 'e.xml: ' + e.xml if $debug
|
426
|
+
puts 'e.text: ' + e.text.to_s.strip if $debug
|
427
|
+
raw_txt = e.text.to_s.strip[/^if [^$]+/i] || e.text('item/description')
|
392
428
|
puts 'raw_txt: ' + raw_txt.inspect if $debug
|
393
429
|
|
394
|
-
clause = raw_txt[/^
|
430
|
+
clause = raw_txt[/^If (.*)/i,1]
|
431
|
+
puts 'clause: ' + clause.inspect if $debug
|
395
432
|
conditions = clause.split(/\s+\b(?:AND|OR)\b\s+/i)
|
433
|
+
puts 'conditions: ' + conditions.inspect if $debug
|
396
434
|
|
397
435
|
cp = ConstraintsNlp.new
|
398
436
|
|
399
437
|
@constraints = conditions.map do |c|
|
400
|
-
puts 'c: ' + c.inspect
|
438
|
+
puts 'c: ' + c.inspect if $debug
|
401
439
|
r = cp.find_constraint c
|
402
440
|
puts 'found constraint ' + r.inspect if $debug
|
403
441
|
|
@@ -405,7 +443,24 @@ class IfConditionAction < Action
|
|
405
443
|
|
406
444
|
end
|
407
445
|
puts '@constraints: ' + @constraints.inspect if $debug
|
408
|
-
|
446
|
+
|
447
|
+
# find any nested actions
|
448
|
+
item = e.element('item')
|
449
|
+
|
450
|
+
if item then
|
451
|
+
|
452
|
+
ap = ActionsNlp.new
|
453
|
+
obj2 = action_to_object(ap, item, item, macro)
|
454
|
+
puts 'obj2: ' + obj2.inspect if $debug
|
455
|
+
#macro.add obj2
|
456
|
+
|
457
|
+
end
|
458
|
+
|
459
|
+
h = {
|
460
|
+
constraint_list: @constraints.map(&:to_h)
|
461
|
+
}
|
462
|
+
super(h) {}
|
463
|
+
|
409
464
|
else
|
410
465
|
# get the constraints
|
411
466
|
|
@@ -434,21 +489,47 @@ class IfConditionAction < Action
|
|
434
489
|
out << s + constraints
|
435
490
|
out.join("\n")
|
436
491
|
|
437
|
-
end
|
492
|
+
end
|
493
|
+
|
438
494
|
end
|
439
495
|
|
440
496
|
class ElseAction < Action
|
441
497
|
|
442
|
-
def initialize(
|
498
|
+
def initialize(obj=[])
|
443
499
|
|
444
500
|
options = {
|
445
|
-
constraint_list:
|
501
|
+
constraint_list: []
|
446
502
|
}
|
503
|
+
|
504
|
+
if obj.is_a? Hash then
|
505
|
+
|
506
|
+
h = obj
|
447
507
|
|
448
|
-
|
508
|
+
super(options.merge h)
|
509
|
+
|
510
|
+
elsif obj.is_a? Array
|
511
|
+
|
512
|
+
e, macro = obj
|
513
|
+
|
514
|
+
# find any nested actions
|
515
|
+
item = e.element('item')
|
516
|
+
|
517
|
+
if item then
|
518
|
+
|
519
|
+
ap = ActionsNlp.new
|
520
|
+
obj2 = action_to_object(ap, item, item, macro)
|
521
|
+
puts 'obj2: ' + obj2.inspect if $debug
|
522
|
+
#macro.add obj2
|
523
|
+
|
524
|
+
end
|
525
|
+
|
526
|
+
super(options)
|
527
|
+
end
|
528
|
+
|
449
529
|
|
450
530
|
|
451
|
-
|
531
|
+
|
532
|
+
end
|
452
533
|
|
453
534
|
def to_s(colour: false, indent: 0)
|
454
535
|
'Else'
|
@@ -1050,7 +1131,17 @@ end
|
|
1050
1131
|
class VibrateAction < DeviceSettingsAction
|
1051
1132
|
|
1052
1133
|
def initialize(h={})
|
1053
|
-
|
1134
|
+
|
1135
|
+
pattern = [
|
1136
|
+
'Blip', 'Short Buzz', 'Long Buzz', 'Rapid', 'Slow', 'Increasing',
|
1137
|
+
'Constant', 'Decreasing', 'Final Fantasy', 'Game Over', 'Star Wars',
|
1138
|
+
'Mini Blip', 'Micro Blip'
|
1139
|
+
]
|
1140
|
+
|
1141
|
+
if h[:pattern] then
|
1142
|
+
h[:vibrate_pattern] = pattern.map(&:downcase).index h[:pattern]
|
1143
|
+
end
|
1144
|
+
|
1054
1145
|
options = {
|
1055
1146
|
vibrate_pattern: 1
|
1056
1147
|
}
|
@@ -1338,7 +1429,7 @@ class ForceLocationUpdateAction < LocationAction
|
|
1338
1429
|
end
|
1339
1430
|
|
1340
1431
|
def to_s(colour: false, indent: 0)
|
1341
|
-
'
|
1432
|
+
'Force Location Update' #+ @h.inspect
|
1342
1433
|
end
|
1343
1434
|
|
1344
1435
|
alias to_summary to_s
|
@@ -1359,26 +1450,34 @@ end
|
|
1359
1450
|
#
|
1360
1451
|
class ShareLocationAction < LocationAction
|
1361
1452
|
|
1362
|
-
def initialize(
|
1453
|
+
def initialize(obj=nil)
|
1363
1454
|
|
1364
|
-
|
1455
|
+
h = if obj.is_a? Hash then
|
1456
|
+
obj
|
1457
|
+
elsif obj.is_a? Array
|
1458
|
+
e, macro = obj
|
1459
|
+
{variable: macro.set_var(e.text('item/description').to_s)}
|
1460
|
+
|
1461
|
+
end
|
1462
|
+
|
1463
|
+
#super()
|
1365
1464
|
|
1366
1465
|
options = {
|
1367
1466
|
email: '',
|
1368
|
-
variable: {:
|
1369
|
-
:
|
1370
|
-
:
|
1467
|
+
variable: {:string_value=>"", :name=>"",
|
1468
|
+
:decimal_value=>0.0, :is_local=>true, :boolean_value=>false,
|
1469
|
+
:exclude_from_log=>false, :int_value=>0, :type=>2},
|
1371
1470
|
sim_id: 0,
|
1372
1471
|
output_channel: 5,
|
1373
1472
|
old_variable_format: true
|
1374
1473
|
}
|
1375
|
-
|
1474
|
+
#options[:variable].merge! h
|
1376
1475
|
super(options.merge h)
|
1377
1476
|
|
1378
1477
|
end
|
1379
1478
|
|
1380
1479
|
def to_s(colour: false, indent: 0)
|
1381
|
-
@s = 'Share Location' + "\
|
1480
|
+
@s = 'Share Location' + "\n" + @h[:variable][:name] # + @h.inspect
|
1382
1481
|
super()
|
1383
1482
|
end
|
1384
1483
|
|
@@ -1572,8 +1671,24 @@ end
|
|
1572
1671
|
# MacroDroid Specific
|
1573
1672
|
#
|
1574
1673
|
class SetVariableAction < Action
|
1674
|
+
using ColouredText
|
1575
1675
|
|
1576
|
-
def initialize(
|
1676
|
+
def initialize(obj=nil)
|
1677
|
+
|
1678
|
+
h = if obj.is_a? Hash then
|
1679
|
+
obj
|
1680
|
+
elsif obj.is_a? Array
|
1681
|
+
e, macro = obj
|
1682
|
+
node = e.element('item/*')
|
1683
|
+
#puts ("node.name: %s node.value: %s" % [node.name, node.value]).debug
|
1684
|
+
r = macro.set_var node.name, node.value.to_s
|
1685
|
+
puts ('r: ' + r.inspect).debug if $debug
|
1686
|
+
r
|
1687
|
+
if r[:type] == 2 then
|
1688
|
+
{ variable: {name: r[:name], type: r[:type]}, new_string_value: r[:string_value]
|
1689
|
+
}
|
1690
|
+
end
|
1691
|
+
end
|
1577
1692
|
|
1578
1693
|
options = {
|
1579
1694
|
:user_prompt=>true,
|
@@ -1581,9 +1696,21 @@ class SetVariableAction < Action
|
|
1581
1696
|
:user_prompt_show_cancel=>true,
|
1582
1697
|
:user_prompt_stop_after_cancel=>true,
|
1583
1698
|
:user_prompt_title=>"Word reverse",
|
1584
|
-
:name => 'word'
|
1699
|
+
:name => 'word',
|
1700
|
+
:false_label=>"False", :int_expression=>false, :int_random=>false,
|
1701
|
+
:int_random_max=>0, :int_random_min=>0, :int_value_decrement=>false,
|
1702
|
+
:int_value_increment=>false, :new_boolean_value=>false,
|
1703
|
+
:new_double_value=>0.0, :new_int_value=>0,
|
1704
|
+
:new_string_value=>"[battery]", :true_label=>"True",
|
1705
|
+
:user_prompt=>false, :user_prompt_show_cancel=>true,
|
1706
|
+
:user_prompt_stop_after_cancel=>true,
|
1707
|
+
:variable=>{
|
1708
|
+
:exclude_from_log=>false, :is_local=>true,
|
1709
|
+
:boolean_value=>false, :decimal_value=>0.0,
|
1710
|
+
:int_value=>0, :name=>"foo", :string_value=>"52", :type=>2
|
1711
|
+
}
|
1585
1712
|
}
|
1586
|
-
super(h)
|
1713
|
+
super(options.merge h)
|
1587
1714
|
|
1588
1715
|
end
|
1589
1716
|
|
@@ -2280,8 +2407,31 @@ end
|
|
2280
2407
|
# Category: Screen
|
2281
2408
|
#
|
2282
2409
|
class ScreenOnAction < ScreenAction
|
2410
|
+
using ColouredText
|
2283
2411
|
|
2284
|
-
def initialize(
|
2412
|
+
def initialize(obj=nil)
|
2413
|
+
|
2414
|
+
debug = false
|
2415
|
+
|
2416
|
+
h = if obj.is_a? Hash then
|
2417
|
+
|
2418
|
+
obj
|
2419
|
+
|
2420
|
+
elsif obj.is_a? Array
|
2421
|
+
=begin
|
2422
|
+
puts 'obj: ' + obj.inspect if debug
|
2423
|
+
e, macro = obj
|
2424
|
+
puts ('e: ' + e.xml.inspect).debug if debug
|
2425
|
+
a = e.xpath('item/*')
|
2426
|
+
|
2427
|
+
txt = e.text.to_s
|
2428
|
+
puts ('txt: ' + txt.inspect).debug if debug
|
2429
|
+
state = txt[/Screen (On|Off)/i,1]
|
2430
|
+
|
2431
|
+
{screen_off: state.downcase == 'off'}
|
2432
|
+
=end
|
2433
|
+
{}
|
2434
|
+
end
|
2285
2435
|
|
2286
2436
|
options = {
|
2287
2437
|
pie_lock_screen: false,
|
@@ -2337,8 +2487,46 @@ end
|
|
2337
2487
|
# disable keep awake => enabled: false
|
2338
2488
|
#
|
2339
2489
|
class KeepAwakeAction < ScreenAction
|
2490
|
+
using ColouredText
|
2340
2491
|
|
2341
|
-
def initialize(
|
2492
|
+
def initialize(obj=nil)
|
2493
|
+
|
2494
|
+
|
2495
|
+
h = if obj.is_a? Hash then
|
2496
|
+
|
2497
|
+
obj
|
2498
|
+
|
2499
|
+
elsif obj.is_a? Array
|
2500
|
+
|
2501
|
+
puts 'obj: ' + obj.inspect if $debug
|
2502
|
+
e, macro = obj
|
2503
|
+
|
2504
|
+
a = e.xpath('item/*')
|
2505
|
+
|
2506
|
+
txt = e.text('item/description')
|
2507
|
+
|
2508
|
+
h2 = if txt then
|
2509
|
+
|
2510
|
+
raw_duration = (txt || e.text).to_s
|
2511
|
+
puts 'raw_duration: ' + raw_duration.inspect if $debug
|
2512
|
+
duration = raw_duration[/Screen On - ([^$]+)/i]
|
2513
|
+
{duration: duration}
|
2514
|
+
|
2515
|
+
elsif a.any? then
|
2516
|
+
a.map {|node| [node.name.to_sym, node.text.to_s]}.to_h
|
2517
|
+
end
|
2518
|
+
|
2519
|
+
h2.merge(macro: macro)
|
2520
|
+
|
2521
|
+
end
|
2522
|
+
|
2523
|
+
puts ('h: ' + h.inspect).debug if $debug
|
2524
|
+
|
2525
|
+
if h[:duration] then
|
2526
|
+
|
2527
|
+
h[:seconds_to_stay_awake_for] = Subunit.hms_to_seconds(h[:duration])
|
2528
|
+
|
2529
|
+
end
|
2342
2530
|
|
2343
2531
|
options = {
|
2344
2532
|
enabled: true,
|