ruby-macrodroid 0.6.0 → 0.7.4
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 +613 -85
- metadata +49 -9
- 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: e28ec7303f297d90ed5edbbec3806c577d1fe3036851620c230b4620d4a8a98f
|
4
|
+
data.tar.gz: fd27b2da1d660144aae8bc85b3f392b10b385934d1a38f65817d53ff774e382c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f727092bb6f96799f1cd288e5ebf822b189d70ef2b5bcdb5bab452b93b412b737229fa6fed2d982f1233aa5f21d35fb1791e834d8ea023474c1eac6a3d330fd5
|
7
|
+
data.tar.gz: 706f9423e28c7fda560bf059f4686834e4404dca9576d5682f3e43c82440a79c84e5ddeb65619a5410098993da1ee9574cc681912a94285147b40aba1468f8a8
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/lib/ruby-macrodroid.rb
CHANGED
@@ -2,11 +2,121 @@
|
|
2
2
|
|
3
3
|
# file: ruby-macrodroid.rb
|
4
4
|
|
5
|
-
|
5
|
+
# This file contains the following classes:
|
6
|
+
#
|
7
|
+
# ## Nlp classes
|
8
|
+
#
|
9
|
+
# TriggersNlp ActionsNlp ConstraintsNlp
|
10
|
+
#
|
11
|
+
#
|
12
|
+
# ## Macro class
|
13
|
+
#
|
14
|
+
# Macro
|
15
|
+
#
|
16
|
+
#
|
17
|
+
# ## Error class
|
18
|
+
#
|
19
|
+
# MacroDroidError
|
20
|
+
#
|
21
|
+
#
|
22
|
+
# ## Droid class
|
23
|
+
#
|
24
|
+
# MacroDroid
|
25
|
+
#
|
26
|
+
#
|
27
|
+
# ## Map class
|
28
|
+
#
|
29
|
+
# GeofenceMap
|
30
|
+
#
|
31
|
+
#
|
32
|
+
# ## Object class
|
33
|
+
#
|
34
|
+
# MacroObject
|
35
|
+
#
|
36
|
+
#
|
37
|
+
# ## Trigger classes
|
38
|
+
#
|
39
|
+
# Trigger WebHookTrigger WifiConnectionTrigger
|
40
|
+
# ApplicationInstalledRemovedTrigger ApplicationLaunchedTrigger
|
41
|
+
# BatteryLevelTrigger BatteryTemperatureTrigger PowerButtonToggleTrigger
|
42
|
+
# ExternalPowerTrigger CallActiveTrigger IncomingCallTrigger
|
43
|
+
# OutgoingCallTrigger CallEndedTrigger CallMissedTrigger IncomingSMSTrigger
|
44
|
+
# WebHookTrigger WifiConnectionTrigger BluetoothTrigger HeadphonesTrigger
|
45
|
+
# SignalOnOffTrigger UsbDeviceConnectionTrigger WifiSSIDTrigger
|
46
|
+
# CalendarTrigger TimerTrigger StopwatchTrigger DayTrigger
|
47
|
+
# RegularIntervalTrigger DeviceEventsTrigger AirplaneModeTrigger
|
48
|
+
# AutoSyncChangeTrigger DayDreamTrigger DockTrigger FailedLoginTrigger
|
49
|
+
# GPSEnabledTrigger MusicPlayingTrigger DeviceUnlockedTrigger
|
50
|
+
# AutoRotateChangeTrigger ClipboardChangeTrigger BootTrigger
|
51
|
+
# IntentReceivedTrigger NotificationTrigger ScreenOnOffTrigger
|
52
|
+
# SilentModeTrigger WeatherTrigger GeofenceTrigger SunriseSunsetTrigger
|
53
|
+
# SensorsTrigger ActivityRecognitionTrigger ProximityTrigger
|
54
|
+
# ShakeDeviceTrigger FlipDeviceTrigger OrientationTrigger
|
55
|
+
# FloatingButtonTrigger ShortcutTrigger VolumeButtonTrigger
|
56
|
+
# MediaButtonPressedTrigger SwipeTrigger
|
57
|
+
#
|
58
|
+
#
|
59
|
+
# ## Action classes
|
60
|
+
#
|
61
|
+
# Action LocationAction ShareLocationAction ApplicationAction
|
62
|
+
# LaunchActivityAction KillBackgroundAppAction OpenWebPageAction CameraAction
|
63
|
+
# UploadPhotoAction TakePictureAction ConnectivityAction SetWifiAction
|
64
|
+
# SetBluetoothAction SetBluetoothAction SendIntentAction DateTimeAction
|
65
|
+
# SetAlarmClockAction StopWatchAction SayTimeAction DeviceAction
|
66
|
+
# AndroidShortcutsAction ClipboardAction PressBackAction SpeakTextAction
|
67
|
+
# UIInteractionAction VoiceSearchAction DeviceSettingsAction
|
68
|
+
# ExpandCollapseStatusBarAction LaunchHomeScreenAction CameraFlashLightAction
|
69
|
+
# VibrateAction SetAutoRotateAction DayDreamAction SetKeyboardAction
|
70
|
+
# SetKeyguardAction CarModeAction ChangeKeyboardAction SetWallpaperAction
|
71
|
+
# FileAction OpenFileAction LocationAction ForceLocationUpdateAction
|
72
|
+
# ShareLocationAction SetLocationUpdateRateAction LoggingAction
|
73
|
+
# AddCalendarEntryAction LogAction ClearLogAction MediaAction
|
74
|
+
# RecordMicrophoneAction PlaySoundAction MessagingAction SendEmailAction
|
75
|
+
# SendSMSAction UDPCommandAction NotificationsAction ClearNotificationsAction
|
76
|
+
# MessageDialogAction AllowLEDNotificationLightAction
|
77
|
+
# SetNotificationSoundAction SetNotificationSoundAction
|
78
|
+
# SetNotificationSoundAction NotificationAction ToastAction PhoneAction
|
79
|
+
# AnswerCallAction ClearCallLogAction OpenCallLogAction RejectCallAction
|
80
|
+
# MakeCallAction SetRingtoneAction ScreenAction SetBrightnessAction
|
81
|
+
# ForceScreenRotationAction ScreenOnAction DimScreenAction KeepAwakeAction
|
82
|
+
# SetScreenTimeoutAction VolumeAction SilentModeVibrateOffAction
|
83
|
+
# SetVibrateAction VolumeIncrementDecrementAction SpeakerPhoneAction
|
84
|
+
# SetVolumeAction
|
85
|
+
#
|
86
|
+
#
|
87
|
+
# ## Constraint classes
|
88
|
+
#
|
89
|
+
# Constraint TimeOfDayConstraint BatteryLevelConstraint
|
90
|
+
# BatterySaverStateConstraint BatteryTemperatureConstraint
|
91
|
+
# ExternalPowerConstraint BluetoothConstraint GPSEnabledConstraint
|
92
|
+
# LocationModeConstraint SignalOnOffConstraint WifiConstraint
|
93
|
+
# CellTowerConstraint IsRoamingConstraint DataOnOffConstraint
|
94
|
+
# WifiHotSpotConstraint CalendarConstraint DayOfWeekConstraint
|
95
|
+
# TimeOfDayConstraint DayOfMonthConstraint MonthOfYearConstraint
|
96
|
+
# SunsetSunriseConstraint AirplaneModeConstraint AutoRotateConstraint
|
97
|
+
# DeviceLockedConstraint RoamingOnOffConstraint TimeSinceBootConstraint
|
98
|
+
# AutoSyncConstraint NFCStateConstraint IsRootedConstraint VpnConstraint
|
99
|
+
# MacroEnabledConstraint ModeConstraint TriggerThatInvokedConstraint
|
100
|
+
# LastRunTimeConstraint HeadphonesConnectionConstraint MusicActiveConstraint
|
101
|
+
# NotificationPresentConstraint PriorityModeConstraint
|
102
|
+
# NotificationVolumeConstraint InCallConstraint PhoneRingingConstraint
|
103
|
+
# BrightnessConstraint VolumeConstraint SpeakerPhoneConstraint
|
104
|
+
# DarkThemeConstraint ScreenOnOffConstraint VolumeLevelConstraint
|
105
|
+
# FaceUpDownConstraint LightLevelConstraint DeviceOrientationConstraint
|
106
|
+
# ProximitySensorConstraint
|
107
|
+
|
108
|
+
|
109
|
+
|
6
110
|
require 'yaml'
|
7
|
-
require '
|
8
|
-
require '
|
9
|
-
require '
|
111
|
+
require 'rowx'
|
112
|
+
require 'uuid'
|
113
|
+
#require 'glw'
|
114
|
+
#require 'geozone'
|
115
|
+
require 'subunit'
|
116
|
+
#require 'rxfhelper'
|
117
|
+
require 'requestor'
|
118
|
+
eval Requestor.read('http://a0.jamesrobertson.eu/rorb/r/ruby'){|x| x.require 'rxfhelper' }
|
119
|
+
|
10
120
|
require 'chronic_cron'
|
11
121
|
|
12
122
|
|
@@ -68,6 +178,20 @@ class TriggersNlp
|
|
68
178
|
[GeofenceTrigger, {name: name, enter_area: enter_area}]
|
69
179
|
end
|
70
180
|
|
181
|
+
get /^location (entered|exited) \(([^\)]+)/i do |direction, name|
|
182
|
+
enter_area = direction.downcase.to_sym == :entered
|
183
|
+
[GeofenceTrigger, {name: name, enter_area: enter_area}]
|
184
|
+
end
|
185
|
+
|
186
|
+
# eg. Proximity Sensor (Near)
|
187
|
+
#
|
188
|
+
get /^Proximity Sensor \(([^\)]+)\)/i do |distance|
|
189
|
+
|
190
|
+
[ProximityTrigger, {distance: distance}]
|
191
|
+
end
|
192
|
+
|
193
|
+
|
194
|
+
|
71
195
|
end
|
72
196
|
|
73
197
|
alias find_trigger run_route
|
@@ -153,6 +277,38 @@ class ActionsNlp
|
|
153
277
|
[OpenWebPageAction, url_to_open: url]
|
154
278
|
|
155
279
|
end
|
280
|
+
|
281
|
+
# e.g. webhook entered_kitchen
|
282
|
+
#
|
283
|
+
get /webhook|HTTP GET/i do
|
284
|
+
[OpenWebPageAction, {}]
|
285
|
+
end
|
286
|
+
|
287
|
+
#a: Keep Device Awake Screen On Until Disabled
|
288
|
+
#
|
289
|
+
get /Keep Device Awake Screen On Until Disabled/i do
|
290
|
+
[KeepAwakeAction, {enabled: true, permanent: true, screen_option: 0}]
|
291
|
+
end
|
292
|
+
|
293
|
+
|
294
|
+
#a: Keep Device Awake Screen On 1h 1m 1s
|
295
|
+
#
|
296
|
+
get /Keep Device Awake Screen On ([^$]+)/i do |duration|
|
297
|
+
|
298
|
+
a = duration.split.map(&:to_i)
|
299
|
+
secs = Subunit.new(units={minutes:60, hours:60, seconds: 60}, a).to_i
|
300
|
+
|
301
|
+
h = {
|
302
|
+
permanent: true, screen_option: 0, seconds_to_stay_awake_for: secs
|
303
|
+
}
|
304
|
+
[KeepAwakeAction, h]
|
305
|
+
end
|
306
|
+
|
307
|
+
#a: Disable Keep Awake
|
308
|
+
#
|
309
|
+
get /Disable Keep Awake/i do
|
310
|
+
[KeepAwakeAction, {enabled: false, screen_option: 0}]
|
311
|
+
end
|
156
312
|
|
157
313
|
|
158
314
|
end
|
@@ -244,9 +400,9 @@ class Macro
|
|
244
400
|
attr_reader :local_variables, :triggers, :actions, :constraints, :guid
|
245
401
|
attr_accessor :title, :description
|
246
402
|
|
247
|
-
def initialize(name=nil,
|
403
|
+
def initialize(name=nil, geofences: geofences, debug: false)
|
248
404
|
|
249
|
-
@title, @
|
405
|
+
@title, @geofences, @debug = name, geofences, debug
|
250
406
|
|
251
407
|
puts 'inside Macro#initialize' if @debug
|
252
408
|
|
@@ -337,19 +493,20 @@ class Macro
|
|
337
493
|
end
|
338
494
|
|
339
495
|
def import_xml(node)
|
340
|
-
|
496
|
+
|
341
497
|
if @debug then
|
342
498
|
puts 'inside Macro#import_xml'
|
343
499
|
puts 'node: ' + node.xml.inspect
|
344
500
|
end
|
345
501
|
|
346
|
-
@title = node.attributes[:name]
|
347
|
-
@description = node.attributes[:description]
|
348
|
-
|
349
502
|
if node.element('triggers') then
|
350
|
-
|
503
|
+
|
351
504
|
# level 2
|
352
505
|
|
506
|
+
@title = node.attributes[:name]
|
507
|
+
@description = node.attributes[:description]
|
508
|
+
|
509
|
+
|
353
510
|
# get all the triggers
|
354
511
|
@triggers = node.xpath('triggers/*').map do |e|
|
355
512
|
|
@@ -385,6 +542,12 @@ class Macro
|
|
385
542
|
|
386
543
|
# Level 1
|
387
544
|
|
545
|
+
puts 'import_xml: inside level 1' if @debug
|
546
|
+
|
547
|
+
@title = node.text('macro') || node.attributes[:name]
|
548
|
+
|
549
|
+
#@description = node.attributes[:description]
|
550
|
+
|
388
551
|
tp = TriggersNlp.new
|
389
552
|
|
390
553
|
@triggers = node.xpath('trigger').map do |e|
|
@@ -394,7 +557,11 @@ class Macro
|
|
394
557
|
puts 'found trigger ' + r.inspect if @debug
|
395
558
|
|
396
559
|
if r then
|
397
|
-
r[0]
|
560
|
+
if r[0] == GeofenceTrigger then
|
561
|
+
GeofenceTrigger.new(r[1], geofences: @geofences)
|
562
|
+
else
|
563
|
+
r[0].new(r[1])
|
564
|
+
end
|
398
565
|
end
|
399
566
|
|
400
567
|
end
|
@@ -403,11 +570,21 @@ class Macro
|
|
403
570
|
|
404
571
|
@actions = node.xpath('action').map do |e|
|
405
572
|
|
573
|
+
puts 'action e: ' + e.xml.inspect if @debug
|
406
574
|
r = ap.find_action e.text
|
407
575
|
puts 'found action ' + r.inspect if @debug
|
408
576
|
|
409
577
|
if r then
|
410
|
-
|
578
|
+
|
579
|
+
a = e.xpath('item/*')
|
580
|
+
|
581
|
+
h = if a.any? then
|
582
|
+
a.map {|node| [node.name.to_sym, node.text.to_s]}.to_h
|
583
|
+
else
|
584
|
+
{}
|
585
|
+
end
|
586
|
+
|
587
|
+
r[0].new(r[1].merge(h))
|
411
588
|
end
|
412
589
|
|
413
590
|
end
|
@@ -485,18 +662,56 @@ EOF
|
|
485
662
|
|
486
663
|
def to_s()
|
487
664
|
|
665
|
+
indent = 0
|
666
|
+
actions = @actions.map do |x|
|
667
|
+
|
668
|
+
s = x.to_s
|
669
|
+
|
670
|
+
r = if indent <= 0 then
|
671
|
+
|
672
|
+
"a: %s" % s
|
673
|
+
|
674
|
+
elsif indent > 0
|
675
|
+
|
676
|
+
if s =~ /^Else/ then
|
677
|
+
(' ' * (indent-1)) + "%s" % s
|
678
|
+
elsif s =~ /^End/
|
679
|
+
indent -= 1
|
680
|
+
(' ' * indent) + "%s" % s
|
681
|
+
else
|
682
|
+
(' ' * indent) + "%s" % s
|
683
|
+
end
|
684
|
+
|
685
|
+
end
|
686
|
+
|
687
|
+
if s =~ /^If/i then
|
688
|
+
if indent < 1 then
|
689
|
+
r = "a:\n %s" % s
|
690
|
+
indent += 1
|
691
|
+
else
|
692
|
+
r = (' ' * indent) + "%s" % s
|
693
|
+
end
|
694
|
+
|
695
|
+
indent += 1
|
696
|
+
end
|
697
|
+
|
698
|
+
r
|
699
|
+
|
700
|
+
end.join("\n")
|
701
|
+
|
488
702
|
a = [
|
489
703
|
'm: ' + @title,
|
490
704
|
@triggers.map {|x| "t: %s" % x}.join("\n"),
|
491
|
-
|
492
|
-
@constraints.map {|x| "a: %s" % x}.join("\n")
|
705
|
+
actions
|
493
706
|
]
|
494
707
|
|
708
|
+
a << @constraints.map {|x| "c: %s" % x}.join("\n") if @constraints.any?
|
709
|
+
|
495
710
|
if @description and @description.length >= 1 then
|
496
|
-
a.insert(1, 'd: ' + @description)
|
711
|
+
a.insert(1, 'd: ' + @description.gsub(/\n/,"\n "))
|
497
712
|
end
|
498
713
|
|
499
|
-
a.join("\n")
|
714
|
+
a.join("\n") + "\n"
|
500
715
|
|
501
716
|
end
|
502
717
|
|
@@ -504,11 +719,11 @@ EOF
|
|
504
719
|
|
505
720
|
a = [
|
506
721
|
'm: ' + @title,
|
507
|
-
't: ' + @triggers.map(&:
|
508
|
-
'a: ' + @actions.map(&:
|
722
|
+
't: ' + @triggers.map(&:to_summary).join(", "),
|
723
|
+
'a: ' + @actions.map(&:to_summary).join(", "),
|
509
724
|
]
|
510
725
|
|
511
|
-
a << 'c: ' + @constraints.map(&:
|
726
|
+
a << 'c: ' + @constraints.map(&:to_summary).join(", ") if @constraints.any?
|
512
727
|
|
513
728
|
a.join("\n") + "\n"
|
514
729
|
|
@@ -528,7 +743,7 @@ EOF
|
|
528
743
|
|
529
744
|
if klass == GeofenceTrigger then
|
530
745
|
puts 'GeofenceTrigger found'.highlight if $debug
|
531
|
-
|
746
|
+
GeofenceTrigger.new(h, geofences: @geofences)
|
532
747
|
else
|
533
748
|
klass.new h
|
534
749
|
end
|
@@ -545,12 +760,14 @@ class MacroDroid
|
|
545
760
|
using ColouredText
|
546
761
|
using Params
|
547
762
|
|
548
|
-
attr_reader :macros, :
|
763
|
+
attr_reader :macros, :geofences, :yaml
|
549
764
|
|
550
765
|
def initialize(obj=nil, debug: false)
|
551
766
|
|
552
767
|
@debug = debug
|
553
768
|
|
769
|
+
@geofences = {}
|
770
|
+
|
554
771
|
if obj then
|
555
772
|
|
556
773
|
raw_s, _ = RXFHelper.read(obj)
|
@@ -570,18 +787,37 @@ class MacroDroid
|
|
570
787
|
|
571
788
|
puts 's: ' + s.inspect if @debug
|
572
789
|
|
573
|
-
|
574
|
-
|
575
|
-
|
790
|
+
if s =~ /m(?:acro)?:\s/ then
|
791
|
+
|
792
|
+
puts 'before RowX.new' if @debug
|
793
|
+
|
794
|
+
s2 = s.gsub(/^g:/,'geofence:').gsub(/^m:/,'macro:')\
|
795
|
+
.gsub(/^t:/,'trigger:').gsub(/^a:/,'action:')\
|
796
|
+
.gsub(/^c:/,'constraint:').gsub(/^#.*/,'')
|
797
|
+
|
798
|
+
raw_macros, raw_geofences = s2.split(/(?=^macro:)/,2).reverse
|
799
|
+
|
800
|
+
if raw_geofences then
|
801
|
+
|
802
|
+
geoxml = RowX.new(raw_geofences).to_xml
|
803
|
+
|
804
|
+
geodoc = Rexle.new(geoxml)
|
805
|
+
geofences = geodoc.root.xpath('item/geofence')
|
806
|
+
@geofences = fetch_geofences(geofences) if geofences.any?
|
807
|
+
|
808
|
+
end
|
809
|
+
|
810
|
+
xml = RowX.new(raw_macros).to_xml
|
811
|
+
import_rowxml(xml)
|
812
|
+
|
576
813
|
elsif s =~ /^# /
|
577
|
-
pc_to_xml(s)
|
814
|
+
xml = pc_to_xml(s)
|
815
|
+
import_xml(xml)
|
578
816
|
else
|
579
817
|
raise MacroDroidError, 'invalid input'
|
580
818
|
end
|
581
|
-
import_xml(xml)
|
582
|
-
@h = build_h
|
583
819
|
|
584
|
-
|
820
|
+
@h = build_h
|
585
821
|
|
586
822
|
end
|
587
823
|
|
@@ -637,7 +873,13 @@ class MacroDroid
|
|
637
873
|
|
638
874
|
def to_h()
|
639
875
|
|
640
|
-
|
876
|
+
h = {
|
877
|
+
geofence_data: {
|
878
|
+
geofence_map: @geofences.map {|key, value| [key, value.to_h] }.to_h
|
879
|
+
},
|
880
|
+
macro_list: @macros.map(&:to_h)
|
881
|
+
}
|
882
|
+
@h.merge(h).to_camel_case
|
641
883
|
|
642
884
|
end
|
643
885
|
|
@@ -648,7 +890,16 @@ class MacroDroid
|
|
648
890
|
end
|
649
891
|
|
650
892
|
def to_s()
|
651
|
-
|
893
|
+
|
894
|
+
lines = []
|
895
|
+
|
896
|
+
if @geofences.any? then
|
897
|
+
lines << @geofences.map {|_, value| 'g: ' + value.to_s}.join("\n\n") + "\n"
|
898
|
+
end
|
899
|
+
|
900
|
+
lines << @macros.map(&:to_s).join("\n")
|
901
|
+
lines.join("\n")
|
902
|
+
|
652
903
|
end
|
653
904
|
|
654
905
|
def to_summary()
|
@@ -657,10 +908,37 @@ class MacroDroid
|
|
657
908
|
|
658
909
|
private
|
659
910
|
|
911
|
+
def fetch_geofences(nodes)
|
912
|
+
|
913
|
+
nodes.map do |e|
|
914
|
+
|
915
|
+
name = e.text.to_s.strip
|
916
|
+
item = e.element('item')
|
917
|
+
coordinates = item.text('coordinates')
|
918
|
+
latitude, longitude = coordinates.split(/, */,2)
|
919
|
+
radius = item.text('radius')
|
920
|
+
|
921
|
+
id = UUID.new.generate
|
922
|
+
|
923
|
+
h = {
|
924
|
+
name: name,
|
925
|
+
longitude: longitude,
|
926
|
+
latitude: latitude,
|
927
|
+
radius: radius,
|
928
|
+
id: id
|
929
|
+
}
|
930
|
+
|
931
|
+
[id.to_sym, GeofenceMap.new(h)]
|
932
|
+
|
933
|
+
end.to_h
|
934
|
+
|
935
|
+
end
|
936
|
+
|
660
937
|
def import_json(s)
|
661
938
|
|
662
939
|
h = JSON.parse(s, symbolize_names: true)
|
663
940
|
puts 'json_to_yaml: ' + h.to_yaml if @debug
|
941
|
+
@yaml = h.to_yaml # helpful for debugging and testing
|
664
942
|
|
665
943
|
@h = h.to_snake_case
|
666
944
|
puts ('@h: ' + @h.inspect).debug if @debug
|
@@ -669,7 +947,7 @@ class MacroDroid
|
|
669
947
|
# fetch the geofence data
|
670
948
|
if @h[:geofence_data] then
|
671
949
|
|
672
|
-
@
|
950
|
+
@geofences = @h[:geofence_data][:geofence_map].map do |id, properties|
|
673
951
|
[id, GeofenceMap.new(properties)]
|
674
952
|
end.to_h
|
675
953
|
|
@@ -678,9 +956,9 @@ class MacroDroid
|
|
678
956
|
@macros = @h[:macro_list].map do |macro|
|
679
957
|
|
680
958
|
puts ('macro: ' + macro.inspect).debug if @debug
|
681
|
-
|
959
|
+
# puts '@geofences: ' + @geofences.inspect if @debug
|
682
960
|
|
683
|
-
m = Macro.new(
|
961
|
+
m = Macro.new(geofences: @geofences.map(&:last), debug: @debug )
|
684
962
|
m.import_h(macro)
|
685
963
|
m
|
686
964
|
|
@@ -690,9 +968,30 @@ class MacroDroid
|
|
690
968
|
|
691
969
|
end
|
692
970
|
|
971
|
+
def import_rowxml(raws)
|
972
|
+
|
973
|
+
s = RXFHelper.read(raws).first
|
974
|
+
puts 's: ' + s.inspect if @debug
|
975
|
+
doc = Rexle.new(s)
|
976
|
+
puts 'after doc' if @debug
|
977
|
+
puts 'import_rowxml: @geofences: ' + @geofences.inspect if @debug
|
978
|
+
geofences = @geofences
|
979
|
+
|
980
|
+
@macros = doc.root.xpath('item').map do |node|
|
981
|
+
puts ('geofences: ' + geofences.inspect).highlight if @debug
|
982
|
+
Macro.new(geofences: geofences.map(&:last), debug: @debug).import_xml(node)
|
983
|
+
|
984
|
+
end
|
985
|
+
|
986
|
+
end
|
987
|
+
|
693
988
|
def import_xml(raws)
|
694
989
|
|
695
|
-
|
990
|
+
if @debug then
|
991
|
+
puts 'inside import_xml'
|
992
|
+
|
993
|
+
puts 'raws: ' + raws.inspect
|
994
|
+
end
|
696
995
|
s = RXFHelper.read(raws).first
|
697
996
|
puts 's: ' + s.inspect if @debug
|
698
997
|
doc = Rexle.new(s)
|
@@ -700,14 +999,10 @@ class MacroDroid
|
|
700
999
|
if @debug then
|
701
1000
|
puts 'doc: ' + doc.root.xml
|
702
1001
|
end
|
703
|
-
|
704
|
-
debug = @debug
|
705
|
-
|
1002
|
+
|
706
1003
|
@macros = doc.root.xpath('macro').map do |node|
|
707
1004
|
|
708
|
-
|
709
|
-
macro.import_xml(node)
|
710
|
-
macro
|
1005
|
+
Macro.new(geofences: @geofences.map(&:last), debug: @debug).import_xml(node)
|
711
1006
|
|
712
1007
|
end
|
713
1008
|
end
|
@@ -732,36 +1027,7 @@ class MacroDroid
|
|
732
1027
|
doc = Rexle.new([:macros, {}, '', *macros])
|
733
1028
|
doc.root.xml pretty: true
|
734
1029
|
|
735
|
-
end
|
736
|
-
|
737
|
-
def text_to_xml(s)
|
738
|
-
|
739
|
-
a = s.split(/.*(?=^m:)/)
|
740
|
-
puts 'a : ' + a.inspect if @debug
|
741
|
-
a.map!(&:chomp)
|
742
|
-
|
743
|
-
macros = a.map do |x|
|
744
|
-
|
745
|
-
lines = x.lines
|
746
|
-
puts 'lines: ' + lines.inspect if @debug
|
747
|
-
|
748
|
-
name = lines.shift[/^m: +(.*)/,1]
|
749
|
-
h = {t: [], a: [], c: []}
|
750
|
-
|
751
|
-
lines.each {|line| h[line[0].to_sym] << line[/^\w: +(.*)/,1] }
|
752
|
-
triggers = h[:t].map {|text| [:trigger, {}, text]}
|
753
|
-
actions = h[:a].map {|text| [:action, {}, text]}
|
754
|
-
constraints = h[:c].map {|text| [:constraint, {}, text]}
|
755
|
-
|
756
|
-
[:macro, {name: name},'', *triggers, *actions, *constraints]
|
757
|
-
|
758
|
-
end
|
759
|
-
|
760
|
-
doc = Rexle.new([:macros, {}, '', *macros])
|
761
|
-
doc.root.xml pretty: true
|
762
|
-
|
763
|
-
end
|
764
|
-
|
1030
|
+
end
|
765
1031
|
|
766
1032
|
end
|
767
1033
|
|
@@ -769,8 +1035,30 @@ class GeofenceMap
|
|
769
1035
|
|
770
1036
|
attr_accessor :name, :longitude, :latitude, :radius, :id
|
771
1037
|
|
772
|
-
def initialize(
|
773
|
-
|
1038
|
+
def initialize(id: '', longitude: '', latitude: '', name: '', radius: '')
|
1039
|
+
|
1040
|
+
@id, @latitude, @longitude, @name, @radius = id, latitude, \
|
1041
|
+
longitude, name, radius
|
1042
|
+
|
1043
|
+
end
|
1044
|
+
|
1045
|
+
def to_h()
|
1046
|
+
|
1047
|
+
{
|
1048
|
+
id: @id,
|
1049
|
+
longitude: @longitude,
|
1050
|
+
latitude: @latitude,
|
1051
|
+
name: @name,
|
1052
|
+
radius: @radius
|
1053
|
+
}
|
1054
|
+
|
1055
|
+
end
|
1056
|
+
|
1057
|
+
def to_s()
|
1058
|
+
|
1059
|
+
coordinates = "%s, %s" % [@longitude, @latitude]
|
1060
|
+
"%s\n coordinates: %s\n radius: %s" % [@name, coordinates, @radius]
|
1061
|
+
|
774
1062
|
end
|
775
1063
|
|
776
1064
|
end
|
@@ -817,6 +1105,8 @@ class MacroObject
|
|
817
1105
|
def to_s()
|
818
1106
|
"#<%s %s>" % [self.class, @h.inspect]
|
819
1107
|
end
|
1108
|
+
|
1109
|
+
alias to_summary to_s
|
820
1110
|
|
821
1111
|
protected
|
822
1112
|
|
@@ -831,13 +1121,32 @@ class MacroObject
|
|
831
1121
|
UUID.new.generate
|
832
1122
|
end
|
833
1123
|
|
1124
|
+
def object(h={})
|
1125
|
+
|
1126
|
+
puts ('inside object h:' + h.inspect).debug if @debug
|
1127
|
+
klass = Object.const_get h[:class_type]
|
1128
|
+
puts klass.inspect.highlight if $debug
|
1129
|
+
|
1130
|
+
klass.new h
|
1131
|
+
|
1132
|
+
end
|
1133
|
+
|
834
1134
|
end
|
835
1135
|
|
836
1136
|
class Trigger < MacroObject
|
837
|
-
|
1137
|
+
using Params
|
1138
|
+
|
1139
|
+
attr_reader :constraints
|
1140
|
+
|
838
1141
|
def initialize(h={})
|
839
1142
|
super({fakeIcon: 0}.merge(h))
|
840
1143
|
@list << 'fakeIcon'
|
1144
|
+
|
1145
|
+
# fetch the constraints
|
1146
|
+
@constraints = @h[:constraint_list].map do |constraint|
|
1147
|
+
object(constraint.to_snake_case)
|
1148
|
+
end
|
1149
|
+
|
841
1150
|
end
|
842
1151
|
|
843
1152
|
def match?(detail={}, model=nil)
|
@@ -950,6 +1259,11 @@ class BatteryLevelTrigger < Trigger
|
|
950
1259
|
super(options.merge h)
|
951
1260
|
|
952
1261
|
end
|
1262
|
+
|
1263
|
+
def to_s()
|
1264
|
+
operator = @h[:decreases_to] ? '<=' : '>='
|
1265
|
+
"Battery %s %s%%" % [operator, @h[:battery_level]]
|
1266
|
+
end
|
953
1267
|
|
954
1268
|
end
|
955
1269
|
|
@@ -1597,6 +1911,10 @@ class DeviceUnlockedTrigger < DeviceEventsTrigger
|
|
1597
1911
|
super(options.merge h)
|
1598
1912
|
|
1599
1913
|
end
|
1914
|
+
|
1915
|
+
def to_s()
|
1916
|
+
'Screen Unlocked'
|
1917
|
+
end
|
1600
1918
|
|
1601
1919
|
end
|
1602
1920
|
|
@@ -1755,12 +2073,12 @@ end
|
|
1755
2073
|
#
|
1756
2074
|
class GeofenceTrigger < Trigger
|
1757
2075
|
|
1758
|
-
def initialize(
|
2076
|
+
def initialize( h={}, geofences: {})
|
1759
2077
|
|
1760
2078
|
if h[:name] then
|
1761
|
-
|
1762
|
-
found =
|
1763
|
-
h[:geofence_id] = found.id
|
2079
|
+
puts ('geofences2: ' + geofences.inspect)
|
2080
|
+
found = geofences.find {|x| x.name.downcase == h[:name].downcase}
|
2081
|
+
h[:geofence_id] = found.id if found
|
1764
2082
|
|
1765
2083
|
end
|
1766
2084
|
|
@@ -1773,15 +2091,25 @@ class GeofenceTrigger < Trigger
|
|
1773
2091
|
}
|
1774
2092
|
|
1775
2093
|
super(options.merge filter(options, h))
|
1776
|
-
@
|
2094
|
+
@geofences = geofences
|
1777
2095
|
|
1778
2096
|
end
|
1779
2097
|
|
1780
2098
|
def to_s()
|
1781
2099
|
|
1782
|
-
|
2100
|
+
if $debug then
|
2101
|
+
puts ' @geofences: ' + @geofences.inspect
|
2102
|
+
puts '@h: ' + @h.inspect
|
2103
|
+
puts '@h[:geofence_id]: ' + @h[:geofence_id].inspect
|
2104
|
+
end
|
2105
|
+
|
1783
2106
|
direction = @h[:enter_area] ? 'Entry' : 'Exit'
|
1784
|
-
|
2107
|
+
|
2108
|
+
found = @geofences.find {|x| x.id == @h[:geofence_id]}
|
2109
|
+
puts 'found: ' + found.inspect if @debug
|
2110
|
+
label = found ? found.name : 'error: name not found'
|
2111
|
+
|
2112
|
+
"Geofence %s (%s)" % [direction, label]
|
1785
2113
|
|
1786
2114
|
end
|
1787
2115
|
|
@@ -1826,8 +2154,28 @@ class ActivityRecognitionTrigger < SensorsTrigger
|
|
1826
2154
|
}
|
1827
2155
|
|
1828
2156
|
super(options.merge h)
|
2157
|
+
|
2158
|
+
@activity = ['In Vehicle', 'On Bicycle', 'Running', 'Walking', 'Still']
|
1829
2159
|
|
1830
2160
|
end
|
2161
|
+
|
2162
|
+
def to_s()
|
2163
|
+
activity = @activity[@h[:selected_index]]
|
2164
|
+
'Activity - ' + activity
|
2165
|
+
end
|
2166
|
+
|
2167
|
+
def to_summary
|
2168
|
+
|
2169
|
+
activity = @activity[@h[:selected_index]]
|
2170
|
+
s = if activity.length > 10 then
|
2171
|
+
activity[0..7] + '..'
|
2172
|
+
else
|
2173
|
+
activity
|
2174
|
+
end
|
2175
|
+
|
2176
|
+
'Activity - ' + s
|
2177
|
+
|
2178
|
+
end
|
1831
2179
|
|
1832
2180
|
end
|
1833
2181
|
|
@@ -1837,14 +2185,33 @@ class ProximityTrigger < SensorsTrigger
|
|
1837
2185
|
|
1838
2186
|
def initialize(h={})
|
1839
2187
|
|
2188
|
+
if h[:distance] then
|
2189
|
+
|
2190
|
+
case h[:distance].to_sym
|
2191
|
+
when :near
|
2192
|
+
options[:near] = true
|
2193
|
+
end
|
2194
|
+
end
|
2195
|
+
|
1840
2196
|
options = {
|
1841
2197
|
near: true,
|
1842
2198
|
selected_option: 0
|
1843
2199
|
}
|
1844
2200
|
|
1845
|
-
super(options.merge h)
|
2201
|
+
super(options.merge filter(options,h))
|
1846
2202
|
|
1847
2203
|
end
|
2204
|
+
|
2205
|
+
def to_s()
|
2206
|
+
|
2207
|
+
distance = if @h[:near] then
|
2208
|
+
'Near'
|
2209
|
+
else
|
2210
|
+
'Far'
|
2211
|
+
end
|
2212
|
+
|
2213
|
+
"Proximity Sensor (%s)" % distance
|
2214
|
+
end
|
1848
2215
|
|
1849
2216
|
end
|
1850
2217
|
|
@@ -2017,9 +2384,17 @@ end
|
|
2017
2384
|
|
2018
2385
|
|
2019
2386
|
class Action < MacroObject
|
2387
|
+
using Params
|
2388
|
+
|
2389
|
+
attr_reader :constraints
|
2020
2390
|
|
2021
2391
|
def initialize(h={})
|
2022
2392
|
super(h)
|
2393
|
+
|
2394
|
+
# fetch the constraints
|
2395
|
+
@constraints = @h[:constraint_list].map do |constraint|
|
2396
|
+
object(constraint.to_snake_case)
|
2397
|
+
end
|
2023
2398
|
end
|
2024
2399
|
|
2025
2400
|
def invoke(s='')
|
@@ -2117,6 +2492,8 @@ end
|
|
2117
2492
|
class OpenWebPageAction < ApplicationAction
|
2118
2493
|
|
2119
2494
|
def initialize(h={})
|
2495
|
+
|
2496
|
+
h[:url_to_open] = h[:url] if h[:url]
|
2120
2497
|
|
2121
2498
|
options = {
|
2122
2499
|
variable_to_save_response: {:m_stringValue=>"", :m_name=>"", :m_decimalValue=>0.0, :isLocal=>true, :m_booleanValue=>false, :excludeFromLog=>false, :m_intValue=>0, :m_type=>2},
|
@@ -2126,12 +2503,12 @@ class OpenWebPageAction < ApplicationAction
|
|
2126
2503
|
block_next_action: false
|
2127
2504
|
}
|
2128
2505
|
|
2129
|
-
super(options.merge h)
|
2506
|
+
super(options.merge filter(options,h))
|
2130
2507
|
|
2131
2508
|
end
|
2132
2509
|
|
2133
2510
|
def to_s()
|
2134
|
-
|
2511
|
+
"HTTP GET\n url: " + @h[:url_to_open]
|
2135
2512
|
end
|
2136
2513
|
|
2137
2514
|
end
|
@@ -2192,6 +2569,64 @@ class TakePictureAction < CameraAction
|
|
2192
2569
|
|
2193
2570
|
end
|
2194
2571
|
|
2572
|
+
class IfConditionAction < Action
|
2573
|
+
|
2574
|
+
def initialize(h={})
|
2575
|
+
|
2576
|
+
options = {
|
2577
|
+
a: true,
|
2578
|
+
constraint_list: ''
|
2579
|
+
}
|
2580
|
+
|
2581
|
+
super(options.merge h)
|
2582
|
+
|
2583
|
+
end
|
2584
|
+
|
2585
|
+
def to_s()
|
2586
|
+
|
2587
|
+
operator = @h[:is_or_condition] ? 'OR' : 'AND'
|
2588
|
+
r = 'If ' + @constraints.map(&:to_s).join(" %s " % operator)
|
2589
|
+
puts 'if ... @h ' + @h.inspect
|
2590
|
+
r
|
2591
|
+
|
2592
|
+
end
|
2593
|
+
end
|
2594
|
+
|
2595
|
+
class ElseAction < Action
|
2596
|
+
|
2597
|
+
def initialize(h={})
|
2598
|
+
|
2599
|
+
options = {
|
2600
|
+
constraint_list: ''
|
2601
|
+
}
|
2602
|
+
|
2603
|
+
super(options.merge h)
|
2604
|
+
|
2605
|
+
end
|
2606
|
+
|
2607
|
+
def to_s()
|
2608
|
+
'Else'
|
2609
|
+
end
|
2610
|
+
|
2611
|
+
end
|
2612
|
+
|
2613
|
+
class EndIfAction < Action
|
2614
|
+
|
2615
|
+
def initialize(h={})
|
2616
|
+
|
2617
|
+
options = {
|
2618
|
+
constraint_list: ''
|
2619
|
+
}
|
2620
|
+
|
2621
|
+
super(options.merge h)
|
2622
|
+
|
2623
|
+
end
|
2624
|
+
|
2625
|
+
def to_s()
|
2626
|
+
'End If'
|
2627
|
+
end
|
2628
|
+
|
2629
|
+
end
|
2195
2630
|
|
2196
2631
|
class ConnectivityAction < Action
|
2197
2632
|
|
@@ -2446,6 +2881,10 @@ class SpeakTextAction < DeviceAction
|
|
2446
2881
|
super(options.merge h)
|
2447
2882
|
|
2448
2883
|
end
|
2884
|
+
|
2885
|
+
def to_s()
|
2886
|
+
"Speak Text (%s)" % @h[:text_to_say]
|
2887
|
+
end
|
2449
2888
|
|
2450
2889
|
end
|
2451
2890
|
|
@@ -2560,6 +2999,17 @@ class VibrateAction < DeviceSettingsAction
|
|
2560
2999
|
super(options.merge h)
|
2561
3000
|
|
2562
3001
|
end
|
3002
|
+
|
3003
|
+
def to_s()
|
3004
|
+
|
3005
|
+
pattern = [
|
3006
|
+
'Blip', 'Short Buzz', 'Long Buzz', 'Rapid', 'Slow', 'Increasing',
|
3007
|
+
'Constant', 'Decreasing', 'Final Fantasy', 'Game Over', 'Star Wars',
|
3008
|
+
'Mini Blip', 'Micro Blip'
|
3009
|
+
]
|
3010
|
+
|
3011
|
+
'Vibrate ' + "(%s)" % pattern[@h[:vibrate_pattern].to_i]
|
3012
|
+
end
|
2563
3013
|
|
2564
3014
|
end
|
2565
3015
|
|
@@ -3347,6 +3797,10 @@ end
|
|
3347
3797
|
|
3348
3798
|
# Category: Screen
|
3349
3799
|
#
|
3800
|
+
# options:
|
3801
|
+
# keep awake, screen on => enabled: true
|
3802
|
+
# disable keep awake => enabled: false
|
3803
|
+
#
|
3350
3804
|
class KeepAwakeAction < ScreenAction
|
3351
3805
|
|
3352
3806
|
def initialize(h={})
|
@@ -3361,7 +3815,30 @@ class KeepAwakeAction < ScreenAction
|
|
3361
3815
|
super(options.merge h)
|
3362
3816
|
|
3363
3817
|
end
|
3364
|
-
|
3818
|
+
|
3819
|
+
def to_s()
|
3820
|
+
|
3821
|
+
screen = @h[:screen_option] == 0 ? 'Screen On' : 'Screen Off'
|
3822
|
+
|
3823
|
+
if @h[:enabled] then
|
3824
|
+
|
3825
|
+
whenx = if @h[:seconds_to_stay_awake_for] == 0 then
|
3826
|
+
|
3827
|
+
'Until Disabled'
|
3828
|
+
|
3829
|
+
else
|
3830
|
+
scnds = @h[:seconds_to_stay_awake_for]
|
3831
|
+
Subunit.new(units={minutes:60, hours:60}, seconds: scnds).strfunit("%x")
|
3832
|
+
end
|
3833
|
+
|
3834
|
+
'Keep Device Awake ' + screen + ' ' + whenx
|
3835
|
+
|
3836
|
+
else
|
3837
|
+
'Disable Keep Awake'
|
3838
|
+
end
|
3839
|
+
|
3840
|
+
|
3841
|
+
end
|
3365
3842
|
end
|
3366
3843
|
|
3367
3844
|
# Category: Screen
|
@@ -3542,6 +4019,21 @@ class BatteryLevelConstraint < Constraint
|
|
3542
4019
|
super(options.merge h)
|
3543
4020
|
|
3544
4021
|
end
|
4022
|
+
|
4023
|
+
def to_s()
|
4024
|
+
|
4025
|
+
operator = if @h[:greater_than] then
|
4026
|
+
'>'
|
4027
|
+
elsif @h[:equals]
|
4028
|
+
'='
|
4029
|
+
else
|
4030
|
+
'<'
|
4031
|
+
end
|
4032
|
+
|
4033
|
+
level = @h[:battery_level]
|
4034
|
+
|
4035
|
+
"Battery %s %s%%" % [operator, level]
|
4036
|
+
end
|
3545
4037
|
|
3546
4038
|
end
|
3547
4039
|
|
@@ -3593,6 +4085,11 @@ class ExternalPowerConstraint < Constraint
|
|
3593
4085
|
super(options.merge h)
|
3594
4086
|
|
3595
4087
|
end
|
4088
|
+
|
4089
|
+
def to_s()
|
4090
|
+
connection = @h[:external_power] ? 'Connected' : 'Disconnected'
|
4091
|
+
'Power ' + connection
|
4092
|
+
end
|
3596
4093
|
|
3597
4094
|
end
|
3598
4095
|
|
@@ -3611,6 +4108,12 @@ class BluetoothConstraint < Constraint
|
|
3611
4108
|
super(options.merge h)
|
3612
4109
|
|
3613
4110
|
end
|
4111
|
+
|
4112
|
+
def to_s()
|
4113
|
+
device = @h[:device_name] #== 'Any Device' ? 'Any' : @h[:device_name]
|
4114
|
+
"Device Connected (%s)" % device
|
4115
|
+
end
|
4116
|
+
|
3614
4117
|
|
3615
4118
|
end
|
3616
4119
|
|
@@ -3935,6 +4438,10 @@ class DeviceLockedConstraint < Constraint
|
|
3935
4438
|
super(options.merge h)
|
3936
4439
|
|
3937
4440
|
end
|
4441
|
+
|
4442
|
+
def to_s()
|
4443
|
+
'Device ' + (@h[:locked] ? 'Locked' : 'Unlocked')
|
4444
|
+
end
|
3938
4445
|
|
3939
4446
|
end
|
3940
4447
|
|
@@ -4121,6 +4628,11 @@ class HeadphonesConnectionConstraint < Constraint
|
|
4121
4628
|
super(options.merge h)
|
4122
4629
|
|
4123
4630
|
end
|
4631
|
+
|
4632
|
+
def to_s()
|
4633
|
+
connection = @h[:connected] ? 'Connected' : 'Disconnected'
|
4634
|
+
'Headphones ' + connection
|
4635
|
+
end
|
4124
4636
|
|
4125
4637
|
end
|
4126
4638
|
|
@@ -4310,6 +4822,10 @@ class ScreenOnOffConstraint < Constraint
|
|
4310
4822
|
super(options.merge h)
|
4311
4823
|
|
4312
4824
|
end
|
4825
|
+
|
4826
|
+
def to_s()
|
4827
|
+
'Screen ' + (@h[:screen_on] ? 'On' : 'Off')
|
4828
|
+
end
|
4313
4829
|
|
4314
4830
|
end
|
4315
4831
|
|
@@ -4363,6 +4879,14 @@ class LightLevelConstraint < Constraint
|
|
4363
4879
|
super(options.merge h)
|
4364
4880
|
|
4365
4881
|
end
|
4882
|
+
|
4883
|
+
def to_s()
|
4884
|
+
|
4885
|
+
operator = @h[:light_level] == -1 ? 'Less than' : 'Greater than'
|
4886
|
+
condition = operator + ' ' + @h[:light_level_float].to_s + 'lx'
|
4887
|
+
'Light Sensor ' + condition
|
4888
|
+
|
4889
|
+
end
|
4366
4890
|
|
4367
4891
|
end
|
4368
4892
|
|
@@ -4395,5 +4919,9 @@ class ProximitySensorConstraint < Constraint
|
|
4395
4919
|
super(options.merge h)
|
4396
4920
|
|
4397
4921
|
end
|
4922
|
+
|
4923
|
+
def to_s()
|
4924
|
+
'Proximity Sensor: ' + (@h[:near] ? 'Near' : 'Far')
|
4925
|
+
end
|
4398
4926
|
|
4399
4927
|
end
|
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.
|
4
|
+
version: 0.7.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Robertson
|
@@ -35,8 +35,28 @@ cert_chain:
|
|
35
35
|
NZ2kdBIUDnAM24e0/wXdVxg4HnsZbdymxyzMQ4P5pKYcpI6oisBxI37p/Xy+wAg3
|
36
36
|
SBHno3GEuuD8ZWj24IMJpfbp
|
37
37
|
-----END CERTIFICATE-----
|
38
|
-
date: 2020-09-
|
38
|
+
date: 2020-09-08 00:00:00.000000000 Z
|
39
39
|
dependencies:
|
40
|
+
- !ruby/object:Gem::Dependency
|
41
|
+
name: glw
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0.2'
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: 0.2.2
|
50
|
+
type: :runtime
|
51
|
+
prerelease: false
|
52
|
+
version_requirements: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - "~>"
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0.2'
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: 0.2.2
|
40
60
|
- !ruby/object:Gem::Dependency
|
41
61
|
name: uuid
|
42
62
|
requirement: !ruby/object:Gem::Requirement
|
@@ -58,25 +78,45 @@ dependencies:
|
|
58
78
|
- !ruby/object:Gem::Version
|
59
79
|
version: 2.3.9
|
60
80
|
- !ruby/object:Gem::Dependency
|
61
|
-
name:
|
81
|
+
name: rowx
|
62
82
|
requirement: !ruby/object:Gem::Requirement
|
63
83
|
requirements:
|
64
|
-
- - "~>"
|
65
|
-
- !ruby/object:Gem::Version
|
66
|
-
version: '0.2'
|
67
84
|
- - ">="
|
68
85
|
- !ruby/object:Gem::Version
|
69
|
-
version: 0.
|
86
|
+
version: 0.7.0
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.7'
|
70
90
|
type: :runtime
|
71
91
|
prerelease: false
|
72
92
|
version_requirements: !ruby/object:Gem::Requirement
|
73
93
|
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.7.0
|
74
97
|
- - "~>"
|
75
98
|
- !ruby/object:Gem::Version
|
76
|
-
version: '0.
|
99
|
+
version: '0.7'
|
100
|
+
- !ruby/object:Gem::Dependency
|
101
|
+
name: subunit
|
102
|
+
requirement: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
77
104
|
- - ">="
|
78
105
|
- !ruby/object:Gem::Version
|
79
|
-
version: 0.
|
106
|
+
version: 0.6.0
|
107
|
+
- - "~>"
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0.6'
|
110
|
+
type: :runtime
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: 0.6.0
|
117
|
+
- - "~>"
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '0.6'
|
80
120
|
- !ruby/object:Gem::Dependency
|
81
121
|
name: geozone
|
82
122
|
requirement: !ruby/object:Gem::Requirement
|
metadata.gz.sig
CHANGED
Binary file
|