roku_builder 3.13.0 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/CHANGELOG +12 -0
- data/Gemfile.lock +22 -7
- data/Guardfile +3 -3
- data/README.md +22 -398
- data/bin/roku +1 -194
- data/config.json.example +1 -1
- data/intergration/roku_builder/test_core.rb +52 -0
- data/intergration/roku_builder/test_files/core_intergration_test/manifest_template +7 -0
- data/intergration/roku_builder/test_files/core_intergration_test/test.pkg +0 -0
- data/intergration/roku_builder/test_files/inspector_intergration_test/components/rectanglescene.xml +28 -0
- data/intergration/roku_builder/test_files/inspector_intergration_test/images/rde_mm_focus_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/inspector_intergration_test/images/rde_mm_focus_sd.jpg +0 -0
- data/intergration/roku_builder/test_files/inspector_intergration_test/images/rde_splash_fhd.jpg +0 -0
- data/intergration/roku_builder/test_files/inspector_intergration_test/images/rde_splash_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/inspector_intergration_test/images/rde_splash_sd.jpg +0 -0
- data/intergration/roku_builder/test_files/inspector_intergration_test/images/rsgde_bg_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/inspector_intergration_test/images/rsgde_mm_focus_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/inspector_intergration_test/images/rsgde_splash_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/inspector_intergration_test/manifest +21 -0
- data/intergration/roku_builder/test_files/inspector_intergration_test/source/main.brs +23 -0
- data/intergration/roku_builder/test_files/inspector_intergration_test/test.pkg +0 -0
- data/intergration/roku_builder/test_files/linker_intergration_test/components/rectanglescene.xml +29 -0
- data/intergration/roku_builder/test_files/linker_intergration_test/images/rde_mm_focus_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/linker_intergration_test/images/rde_mm_focus_sd.jpg +0 -0
- data/intergration/roku_builder/test_files/linker_intergration_test/images/rde_splash_fhd.jpg +0 -0
- data/intergration/roku_builder/test_files/linker_intergration_test/images/rde_splash_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/linker_intergration_test/images/rde_splash_sd.jpg +0 -0
- data/intergration/roku_builder/test_files/linker_intergration_test/images/rsgde_bg_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/linker_intergration_test/images/rsgde_mm_focus_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/linker_intergration_test/images/rsgde_splash_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/linker_intergration_test/manifest +21 -0
- data/intergration/roku_builder/test_files/linker_intergration_test/source/main.brs +21 -0
- data/intergration/roku_builder/test_files/linker_intergration_test/test.pkg +0 -0
- data/intergration/roku_builder/test_files/loader_intergration_test/components/rectanglescene.xml +29 -0
- data/intergration/roku_builder/test_files/loader_intergration_test/images/rde_mm_focus_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/loader_intergration_test/images/rde_mm_focus_sd.jpg +0 -0
- data/intergration/roku_builder/test_files/loader_intergration_test/images/rde_splash_fhd.jpg +0 -0
- data/intergration/roku_builder/test_files/loader_intergration_test/images/rde_splash_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/loader_intergration_test/images/rde_splash_sd.jpg +0 -0
- data/intergration/roku_builder/test_files/loader_intergration_test/images/rsgde_bg_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/loader_intergration_test/images/rsgde_mm_focus_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/loader_intergration_test/images/rsgde_splash_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/loader_intergration_test/manifest +21 -0
- data/intergration/roku_builder/test_files/loader_intergration_test/source/main.brs +21 -0
- data/intergration/roku_builder/test_files/loader_intergration_test/test.pkg +0 -0
- data/intergration/roku_builder/test_files/monitor_intergration_test/components/rectanglescene.xml +29 -0
- data/intergration/roku_builder/test_files/monitor_intergration_test/images/rde_mm_focus_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/monitor_intergration_test/images/rde_mm_focus_sd.jpg +0 -0
- data/intergration/roku_builder/test_files/monitor_intergration_test/images/rde_splash_fhd.jpg +0 -0
- data/intergration/roku_builder/test_files/monitor_intergration_test/images/rde_splash_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/monitor_intergration_test/images/rde_splash_sd.jpg +0 -0
- data/intergration/roku_builder/test_files/monitor_intergration_test/images/rsgde_bg_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/monitor_intergration_test/images/rsgde_mm_focus_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/monitor_intergration_test/images/rsgde_splash_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/monitor_intergration_test/manifest +21 -0
- data/intergration/roku_builder/test_files/monitor_intergration_test/source/main.brs +21 -0
- data/intergration/roku_builder/test_files/monitor_intergration_test/test.pkg +0 -0
- data/intergration/roku_builder/test_files/navigator_intergration_test/components/rectanglescene.xml +29 -0
- data/intergration/roku_builder/test_files/navigator_intergration_test/images/rde_mm_focus_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/navigator_intergration_test/images/rde_mm_focus_sd.jpg +0 -0
- data/intergration/roku_builder/test_files/navigator_intergration_test/images/rde_splash_fhd.jpg +0 -0
- data/intergration/roku_builder/test_files/navigator_intergration_test/images/rde_splash_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/navigator_intergration_test/images/rde_splash_sd.jpg +0 -0
- data/intergration/roku_builder/test_files/navigator_intergration_test/images/rsgde_bg_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/navigator_intergration_test/images/rsgde_mm_focus_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/navigator_intergration_test/images/rsgde_splash_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/navigator_intergration_test/manifest +21 -0
- data/intergration/roku_builder/test_files/navigator_intergration_test/source/main.brs +21 -0
- data/intergration/roku_builder/test_files/navigator_intergration_test/test.pkg +0 -0
- data/intergration/roku_builder/test_files/packager_intergration_test/components/rectanglescene.xml +29 -0
- data/intergration/roku_builder/test_files/packager_intergration_test/images/rde_mm_focus_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/packager_intergration_test/images/rde_mm_focus_sd.jpg +0 -0
- data/intergration/roku_builder/test_files/packager_intergration_test/images/rde_splash_fhd.jpg +0 -0
- data/intergration/roku_builder/test_files/packager_intergration_test/images/rde_splash_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/packager_intergration_test/images/rde_splash_sd.jpg +0 -0
- data/intergration/roku_builder/test_files/packager_intergration_test/images/rsgde_bg_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/packager_intergration_test/images/rsgde_mm_focus_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/packager_intergration_test/images/rsgde_splash_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/packager_intergration_test/manifest +21 -0
- data/intergration/roku_builder/test_files/packager_intergration_test/source/main.brs +21 -0
- data/intergration/roku_builder/test_files/packager_intergration_test/test.pkg +0 -0
- data/intergration/roku_builder/test_files/profiler_intergration_test/components/rectanglescene.xml +29 -0
- data/intergration/roku_builder/test_files/profiler_intergration_test/images/rde_mm_focus_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/profiler_intergration_test/images/rde_mm_focus_sd.jpg +0 -0
- data/intergration/roku_builder/test_files/profiler_intergration_test/images/rde_splash_fhd.jpg +0 -0
- data/intergration/roku_builder/test_files/profiler_intergration_test/images/rde_splash_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/profiler_intergration_test/images/rde_splash_sd.jpg +0 -0
- data/intergration/roku_builder/test_files/profiler_intergration_test/images/rsgde_bg_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/profiler_intergration_test/images/rsgde_mm_focus_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/profiler_intergration_test/images/rsgde_splash_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/profiler_intergration_test/manifest +21 -0
- data/intergration/roku_builder/test_files/profiler_intergration_test/source/main.brs +21 -0
- data/intergration/roku_builder/test_files/profiler_intergration_test/test.pkg +0 -0
- data/intergration/roku_builder/test_files/scripter_intergration_test/components/rectanglescene.xml +29 -0
- data/intergration/roku_builder/test_files/scripter_intergration_test/images/rde_mm_focus_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/scripter_intergration_test/images/rde_mm_focus_sd.jpg +0 -0
- data/intergration/roku_builder/test_files/scripter_intergration_test/images/rde_splash_fhd.jpg +0 -0
- data/intergration/roku_builder/test_files/scripter_intergration_test/images/rde_splash_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/scripter_intergration_test/images/rde_splash_sd.jpg +0 -0
- data/intergration/roku_builder/test_files/scripter_intergration_test/images/rsgde_bg_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/scripter_intergration_test/images/rsgde_mm_focus_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/scripter_intergration_test/images/rsgde_splash_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/scripter_intergration_test/manifest +21 -0
- data/intergration/roku_builder/test_files/scripter_intergration_test/source/main.brs +21 -0
- data/intergration/roku_builder/test_files/scripter_intergration_test/test.pkg +0 -0
- data/intergration/roku_builder/test_files/tester_intergration_test/components/rectanglescene.xml +29 -0
- data/intergration/roku_builder/test_files/tester_intergration_test/images/rde_mm_focus_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/tester_intergration_test/images/rde_mm_focus_sd.jpg +0 -0
- data/intergration/roku_builder/test_files/tester_intergration_test/images/rde_splash_fhd.jpg +0 -0
- data/intergration/roku_builder/test_files/tester_intergration_test/images/rde_splash_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/tester_intergration_test/images/rde_splash_sd.jpg +0 -0
- data/intergration/roku_builder/test_files/tester_intergration_test/images/rsgde_bg_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/tester_intergration_test/images/rsgde_mm_focus_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/tester_intergration_test/images/rsgde_splash_hd.jpg +0 -0
- data/intergration/roku_builder/test_files/tester_intergration_test/manifest +21 -0
- data/intergration/roku_builder/test_files/tester_intergration_test/source/main.brs +21 -0
- data/intergration/roku_builder/test_files/tester_intergration_test/test.pkg +0 -0
- data/intergration/roku_builder/test_helper.rb +138 -0
- data/intergration/roku_builder/test_inspector.rb +35 -0
- data/intergration/roku_builder/test_linker.rb +32 -0
- data/intergration/roku_builder/test_loader.rb +38 -0
- data/intergration/roku_builder/test_monitor.rb +21 -0
- data/intergration/roku_builder/test_navigator.rb +34 -0
- data/intergration/roku_builder/test_packager.rb +41 -0
- data/intergration/roku_builder/test_profiler.rb +48 -0
- data/intergration/roku_builder/test_scripter.rb +38 -0
- data/intergration/roku_builder/test_tester.rb +21 -0
- data/lib/roku_builder.rb +143 -154
- data/lib/roku_builder/config.rb +17 -40
- data/lib/roku_builder/config_parser.rb +49 -200
- data/lib/roku_builder/config_validator.rb +1 -1
- data/lib/roku_builder/errors.rb +12 -0
- data/lib/roku_builder/git.rb +28 -0
- data/lib/roku_builder/hash.rb +8 -0
- data/lib/roku_builder/manifest.rb +121 -0
- data/lib/roku_builder/options.rb +68 -29
- data/lib/roku_builder/plugin.rb +30 -0
- data/lib/roku_builder/plugins/core.rb +117 -0
- data/lib/roku_builder/plugins/inspector.rb +104 -0
- data/lib/roku_builder/{linker.rb → plugins/linker.rb} +38 -12
- data/lib/roku_builder/plugins/loader.rb +152 -0
- data/lib/roku_builder/{monitor.rb → plugins/monitor.rb} +20 -9
- data/lib/roku_builder/{navigator.rb → plugins/navigator.rb} +136 -88
- data/lib/roku_builder/plugins/packager.rb +194 -0
- data/lib/roku_builder/plugins/profiler.rb +135 -0
- data/lib/roku_builder/plugins/scripter.rb +53 -0
- data/lib/roku_builder/{tester.rb → plugins/tester.rb} +28 -19
- data/lib/roku_builder/stager.rb +48 -12
- data/lib/roku_builder/string.rb +20 -0
- data/lib/roku_builder/util.rb +10 -34
- data/lib/roku_builder/version.rb +1 -1
- data/rakefile +5 -1
- data/roku_builder.gemspec +2 -0
- data/test/roku_builder/plugins/test_core.rb +112 -0
- data/test/roku_builder/plugins/test_inspector.rb +165 -0
- data/test/roku_builder/plugins/test_linker.rb +123 -0
- data/test/roku_builder/plugins/test_loader.rb +115 -0
- data/test/roku_builder/plugins/test_monitor.rb +141 -0
- data/test/roku_builder/plugins/test_navigator.rb +274 -0
- data/test/roku_builder/plugins/test_packager.rb +202 -0
- data/test/roku_builder/plugins/test_profiler.rb +127 -0
- data/test/roku_builder/plugins/test_scripter.rb +110 -0
- data/test/roku_builder/plugins/test_tester.rb +109 -0
- data/test/roku_builder/test_config.rb +51 -35
- data/test/roku_builder/test_config_parser.rb +76 -154
- data/test/roku_builder/test_config_validator.rb +18 -1
- data/test/roku_builder/test_files/{loader_test/manifest → config_parser_test/test.pkg} +0 -0
- data/test/roku_builder/test_files/config_test/config.json +3 -0
- data/test/roku_builder/test_files/controller_commands_test/manifest_template +7 -0
- data/test/roku_builder/test_files/core_test/manifest_template +7 -0
- data/test/roku_builder/test_files/core_test/test.pkg +0 -0
- data/test/roku_builder/test_files/inspector_test/manifest +6 -0
- data/test/roku_builder/test_files/inspector_test/test.pkg +0 -0
- data/test/roku_builder/test_files/linker_test/manifest +6 -0
- data/test/roku_builder/test_files/linker_test/test.pkg +0 -0
- data/test/roku_builder/test_files/loader_test/manifest_template +6 -0
- data/test/roku_builder/test_files/loader_test/test.pkg +0 -0
- data/test/roku_builder/test_files/loader_test/test.zip +0 -0
- data/test/roku_builder/test_files/manifest_test/manifest_comments +6 -0
- data/test/roku_builder/test_files/manifest_test/manifest_template +7 -0
- data/test/roku_builder/test_files/manifest_test/test.zip +0 -0
- data/test/roku_builder/test_files/packager_test/manifest +6 -0
- data/test/roku_builder/test_files/packager_test/scripter_test/manifest +6 -0
- data/test/roku_builder/test_files/packager_test/test.pkg +0 -0
- data/test/roku_builder/test_files/roku_builder_test/config.json +32 -0
- data/test/roku_builder/test_files/scripter_test/manifest +6 -0
- data/test/roku_builder/test_files/scripter_test/test.pkg +0 -0
- data/test/roku_builder/test_files/stager_test/test.pkg +0 -0
- data/test/roku_builder/test_files/tester_test/manifest +6 -0
- data/test/roku_builder/test_files/tester_test/test.pkg +0 -0
- data/test/roku_builder/test_helper.rb +44 -11
- data/test/roku_builder/test_logger.rb +1 -0
- data/test/roku_builder/test_manifest.rb +99 -0
- data/test/roku_builder/test_options.rb +106 -77
- data/test/roku_builder/test_options_plugins.rb +111 -0
- data/test/roku_builder/test_plugin.rb +48 -0
- data/test/roku_builder/test_roku_builder.rb +239 -0
- data/test/roku_builder/test_stager.rb +49 -101
- data/test/roku_builder/test_util.rb +19 -4
- metadata +241 -47
- data/lib/roku_builder/controller.rb +0 -98
- data/lib/roku_builder/controller_commands.rb +0 -224
- data/lib/roku_builder/error_handler.rb +0 -142
- data/lib/roku_builder/inspector.rb +0 -82
- data/lib/roku_builder/keyer.rb +0 -106
- data/lib/roku_builder/loader.rb +0 -131
- data/lib/roku_builder/manifest_manager.rb +0 -126
- data/lib/roku_builder/packager.rb +0 -43
- data/lib/roku_builder/profiler.rb +0 -96
- data/lib/roku_builder/scripter.rb +0 -39
- data/test/roku_builder/test_controller.rb +0 -70
- data/test/roku_builder/test_controller_commands.rb +0 -465
- data/test/roku_builder/test_error_handler.rb +0 -90
- data/test/roku_builder/test_inspector.rb +0 -298
- data/test/roku_builder/test_keyer.rb +0 -176
- data/test/roku_builder/test_linker.rb +0 -110
- data/test/roku_builder/test_loader.rb +0 -337
- data/test/roku_builder/test_manifest_manager.rb +0 -103
- data/test/roku_builder/test_monitor.rb +0 -137
- data/test/roku_builder/test_navigator.rb +0 -280
- data/test/roku_builder/test_packager.rb +0 -127
- data/test/roku_builder/test_profiler.rb +0 -35
- data/test/roku_builder/test_scripter.rb +0 -102
- data/test/roku_builder/test_tester.rb +0 -130
@@ -4,15 +4,42 @@ module RokuBuilder
|
|
4
4
|
|
5
5
|
# Launch application, sending parameters
|
6
6
|
class Linker < Util
|
7
|
+
extend Plugin
|
8
|
+
|
9
|
+
def self.commands
|
10
|
+
{
|
11
|
+
deeplink: {device: true, stage: true},
|
12
|
+
applist: {device: true}
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.parse_options(parser:, options:)
|
17
|
+
parser.separator "Commands:"
|
18
|
+
parser.on("-o", "--deeplink OPTIONS", "Deeplink into app. Define options as keypairs. (eg. a:b, c:d,e:f)") do |o|
|
19
|
+
options[:deeplink] = o
|
20
|
+
end
|
21
|
+
parser.on("-A", "--app-list", "List currently installed apps") do
|
22
|
+
options[:applist] = true
|
23
|
+
end
|
24
|
+
parser.separator "Options:"
|
25
|
+
parser.on("-a", "--app ID", "Send App id for deeplinking") do |a|
|
26
|
+
options[:app_id] = a
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.dependencies
|
31
|
+
[Loader]
|
32
|
+
end
|
33
|
+
|
7
34
|
# Deeplink to an app
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
35
|
+
def deeplink(options:)
|
36
|
+
if options.has_source?
|
37
|
+
Loader.new(config: @config).sideload(options: options)
|
38
|
+
end
|
39
|
+
app_id = options[:app_id]
|
40
|
+
app_id ||= "dev"
|
14
41
|
path = "/launch/#{app_id}"
|
15
|
-
payload =
|
42
|
+
payload = RokuBuilder.options_parse(options: options[:deeplink])
|
16
43
|
|
17
44
|
unless payload.keys.count > 0
|
18
45
|
@logger.warn "No options sent to launched app"
|
@@ -25,15 +52,13 @@ module RokuBuilder
|
|
25
52
|
@logger.info "curl -d '' '#{@url}:8060#{path}'"
|
26
53
|
end
|
27
54
|
|
28
|
-
|
29
|
-
|
30
|
-
response = conn.post path
|
31
|
-
return response.success?
|
55
|
+
response = multipart_connection(port: 8060).post path
|
56
|
+
@logger.fatal("Failed Deeplinking") unless response.success?
|
32
57
|
end
|
33
58
|
|
34
59
|
# List currently installed apps
|
35
60
|
# @param logger [Logger] System Logger
|
36
|
-
def
|
61
|
+
def applist(options:)
|
37
62
|
path = "/query/apps"
|
38
63
|
conn = multipart_connection(port: 8060)
|
39
64
|
response = conn.get path
|
@@ -58,4 +83,5 @@ module RokuBuilder
|
|
58
83
|
params.collect{|k,v| "#{k}=#{CGI.escape(v)}"}.join('&')
|
59
84
|
end
|
60
85
|
end
|
86
|
+
RokuBuilder.register_plugin(Linker)
|
61
87
|
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
# ********** Copyright Viacom, Inc. Apache 2.0 **********
|
2
|
+
|
3
|
+
module RokuBuilder
|
4
|
+
|
5
|
+
# Load/Unload/Build roku applications
|
6
|
+
class Loader < Util
|
7
|
+
extend Plugin
|
8
|
+
|
9
|
+
def self.commands
|
10
|
+
{
|
11
|
+
sideload: {source: true, device: true, stage: true},
|
12
|
+
build: {source: true, stage: true, exclude: true},
|
13
|
+
delete: {device: true}
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.parse_options(parser:, options:)
|
18
|
+
parser.separator "Commands:"
|
19
|
+
parser.on("-l", "--sideload", "Sideload an app") do
|
20
|
+
options[:sideload] = true
|
21
|
+
end
|
22
|
+
parser.on("-d", "--delete", "Delete the currently sideloaded app") do
|
23
|
+
options[:delete] = true
|
24
|
+
end
|
25
|
+
parser.on("-b", "--build", "Build a zip to be sideloaded") do
|
26
|
+
options[:build] = true
|
27
|
+
end
|
28
|
+
parser.separator "Options:"
|
29
|
+
parser.on("-x", "--exclude", "Apply exclude config to sideload") do
|
30
|
+
options[:exclude] = true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.dependencies
|
35
|
+
[Navigator]
|
36
|
+
end
|
37
|
+
|
38
|
+
# Sideload an app onto a roku device
|
39
|
+
def sideload(options:)
|
40
|
+
Navigator.new(config: @config).nav(options:{nav: "home"})
|
41
|
+
did_build = false
|
42
|
+
unless options[:in]
|
43
|
+
did_build = true
|
44
|
+
build(options: options)
|
45
|
+
end
|
46
|
+
upload
|
47
|
+
# Cleanup
|
48
|
+
File.delete(file_path(:in)) if did_build and not options[:out]
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
# Build an app to sideload later
|
53
|
+
def build(options:)
|
54
|
+
@options = options
|
55
|
+
build_zip(setup_build_content)
|
56
|
+
@config.in = @config.out #setting in path for possible sideload
|
57
|
+
end
|
58
|
+
|
59
|
+
# Remove the currently sideloaded app
|
60
|
+
def delete(options:)
|
61
|
+
payload = {mysubmit: "Delete", archive: ""}
|
62
|
+
response = multipart_connection.post "/plugin_install", payload
|
63
|
+
unless response.status == 200 and response.body =~ /Delete Succeeded/
|
64
|
+
raise ExecutionError, "Failed Unloading"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def upload
|
71
|
+
payload = {
|
72
|
+
mysubmit: "Replace",
|
73
|
+
archive: Faraday::UploadIO.new(file_path(:in), 'application/zip')
|
74
|
+
}
|
75
|
+
response = multipart_connection.post "/plugin_install", payload
|
76
|
+
if response.status==200 and response.body=~/Identical to previous version/
|
77
|
+
@logger.warn("Sideload identival to previous version")
|
78
|
+
elsif not (response.status==200 and response.body=~/Install Success/)
|
79
|
+
@logger.debug("Status: #{response.status}, Body: #{response.body}")
|
80
|
+
raise ExecutionError, "Failed Sideloading"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def file_path(type)
|
85
|
+
file = @config.send(type)[:file]
|
86
|
+
file ||= Manifest.new(config: @config).build_version
|
87
|
+
file = file+".zip" unless file.end_with?(".zip")
|
88
|
+
File.join(@config.send(type)[:folder], file)
|
89
|
+
end
|
90
|
+
|
91
|
+
def setup_build_content()
|
92
|
+
content = {}
|
93
|
+
content[:excludes] = []
|
94
|
+
if @options[:current]
|
95
|
+
content[:folders] = Dir.entries(@config.root_dir).select {|entry| File.directory? File.join(@config.root_dir, entry) and !(entry =='.' || entry == '..') }
|
96
|
+
content[:files] = Dir.entries(@config.root_dir).select {|entry| File.file? File.join(@config.root_dir, entry)}
|
97
|
+
else
|
98
|
+
content[:folders] = @config.project[:folders]
|
99
|
+
content[:files] = @config.project[:files]
|
100
|
+
content[:exclude] if @options[:exclude] or @options.exclude_command?
|
101
|
+
end
|
102
|
+
content
|
103
|
+
end
|
104
|
+
|
105
|
+
def build_zip(content)
|
106
|
+
path = file_path(:out)
|
107
|
+
File.delete(path) if File.exist?(path)
|
108
|
+
io = Zip::File.open(path, Zip::File::CREATE)
|
109
|
+
# Add folders to zip
|
110
|
+
content[:folders].each do |folder|
|
111
|
+
base_folder = File.join(@config.root_dir, folder)
|
112
|
+
if File.exist?(base_folder)
|
113
|
+
entries = Dir.entries(base_folder)
|
114
|
+
entries.delete(".")
|
115
|
+
entries.delete("..")
|
116
|
+
writeEntries(@config.root_dir, entries, folder, content[:excludes], io)
|
117
|
+
else
|
118
|
+
@logger.warn "Missing Folder: #{base_folder}"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
# Add file to zip
|
122
|
+
writeEntries(@config.parsed[:root_dir], content[:files], "", content[:excludes], io)
|
123
|
+
io.close()
|
124
|
+
end
|
125
|
+
|
126
|
+
# Recursively write directory contents to a zip archive
|
127
|
+
# @param root_dir [String] Path of the root directory
|
128
|
+
# @param entries [Array<String>] Array of file paths of files/directories to store in the zip archive
|
129
|
+
# @param path [String] The path of the current directory starting at the root directory
|
130
|
+
# @param io [IO] zip IO object
|
131
|
+
def writeEntries(root_dir, entries, path, excludes, io)
|
132
|
+
entries.each { |e|
|
133
|
+
zipFilePath = path == "" ? e : File.join(path, e)
|
134
|
+
diskFilePath = File.join(root_dir, zipFilePath)
|
135
|
+
if File.directory?(diskFilePath)
|
136
|
+
io.mkdir(zipFilePath)
|
137
|
+
subdir =Dir.entries(diskFilePath); subdir.delete("."); subdir.delete("..")
|
138
|
+
writeEntries(root_dir, subdir, zipFilePath, excludes, io)
|
139
|
+
else
|
140
|
+
unless excludes.include?(zipFilePath)
|
141
|
+
if File.exist?(diskFilePath)
|
142
|
+
io.get_output_stream(zipFilePath) { |f| f.puts(File.open(diskFilePath, "rb").read()) }
|
143
|
+
else
|
144
|
+
@logger.warn "Missing File: #{diskFilePath}"
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
}
|
149
|
+
end
|
150
|
+
end
|
151
|
+
RokuBuilder.register_plugin(Loader)
|
152
|
+
end
|
@@ -4,25 +4,35 @@ module RokuBuilder
|
|
4
4
|
|
5
5
|
# Monitor development Logs
|
6
6
|
class Monitor < Util
|
7
|
+
extend Plugin
|
8
|
+
|
9
|
+
def self.commands
|
10
|
+
{ monitor: {device: true}}
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.parse_options(parser:, options:)
|
14
|
+
parser.separator "Commands:"
|
15
|
+
parser.on("-m", "--monitor [TYPE]", "Run telnet to monitor roku log") do |m|
|
16
|
+
options[:monitor] = m || "main"
|
17
|
+
end
|
18
|
+
parser.separator "Options:"
|
19
|
+
parser.on("-R", "--regexp REGEXP", "A regular expression used to filter monitor logs") do |r|
|
20
|
+
options[:regexp] = r
|
21
|
+
end
|
22
|
+
end
|
7
23
|
|
8
24
|
# Initialize port config
|
9
25
|
def init()
|
10
26
|
@ports = {
|
11
27
|
main: 8085,
|
12
|
-
sg: 8089,
|
13
|
-
task1: 8090,
|
14
|
-
task2: 8091,
|
15
|
-
task3: 8092,
|
16
|
-
taskX: 8093,
|
17
28
|
profiler: 8080,
|
18
29
|
}
|
19
30
|
@show_prompt = false
|
20
31
|
end
|
21
32
|
|
22
33
|
# Monitor a development log on the Roku device
|
23
|
-
|
24
|
-
|
25
|
-
def monitor(type:, regexp: nil)
|
34
|
+
def monitor(options:)
|
35
|
+
type = options[:monitor].to_sym
|
26
36
|
telnet_config = { 'Host' => @roku_ip_address, 'Port' => @ports[type] }
|
27
37
|
waitfor_config = { 'Match' => /./, 'Timeout' => false }
|
28
38
|
|
@@ -33,7 +43,7 @@ module RokuBuilder
|
|
33
43
|
all_text = ""
|
34
44
|
while true
|
35
45
|
connection.waitfor(waitfor) do |txt|
|
36
|
-
all_text = manage_text(all_text: all_text, txt: txt, regexp: regexp)
|
46
|
+
all_text = manage_text(all_text: all_text, txt: txt, regexp: options[:regexp])
|
37
47
|
end
|
38
48
|
end
|
39
49
|
}
|
@@ -118,4 +128,5 @@ module RokuBuilder
|
|
118
128
|
all_text
|
119
129
|
end
|
120
130
|
end
|
131
|
+
RokuBuilder.register_plugin(Monitor)
|
121
132
|
end
|
@@ -4,9 +4,39 @@ module RokuBuilder
|
|
4
4
|
|
5
5
|
# Navigation methods
|
6
6
|
class Navigator < Util
|
7
|
+
extend Plugin
|
8
|
+
|
9
|
+
def self.commands
|
10
|
+
{
|
11
|
+
nav: {device: true},
|
12
|
+
navigate: {device: true},
|
13
|
+
type: {device: true},
|
14
|
+
screen: {device: true},
|
15
|
+
screens: {}
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.parse_options(parser:, options:)
|
20
|
+
parser.separator("Commands:")
|
21
|
+
parser.on("-N", "--nav CMD", "Send the given command to the roku") do |n|
|
22
|
+
options[:nav] = n
|
23
|
+
end
|
24
|
+
parser.on("--navigate", "Run interactive navigator") do
|
25
|
+
options[:navigate] = true
|
26
|
+
end
|
27
|
+
parser.on("-y", "--type TEXT", "Type the given text on the roku device") do |t|
|
28
|
+
options[:type] = t
|
29
|
+
end
|
30
|
+
parser.on("--screen SCREEN", "Show a screen") do |s|
|
31
|
+
options[:screen] = s
|
32
|
+
end
|
33
|
+
parser.on("--screens", "Show possible screens") do
|
34
|
+
options[:screens] = true
|
35
|
+
end
|
36
|
+
end
|
7
37
|
|
8
38
|
# Setup navigation commands
|
9
|
-
def init(
|
39
|
+
def init()
|
10
40
|
@commands = {
|
11
41
|
home: "Home", rew: "Rev", ff: "Fwd",
|
12
42
|
play: "Play", select: "Select", left: "Left",
|
@@ -33,67 +63,33 @@ module RokuBuilder
|
|
33
63
|
@runable = [
|
34
64
|
:secret, :channels
|
35
65
|
]
|
36
|
-
mappings_init
|
66
|
+
mappings_init
|
37
67
|
end
|
38
68
|
|
39
|
-
# Init Mappings
|
40
|
-
def mappings_init(mappings: nil)
|
41
|
-
@mappings = {
|
42
|
-
"\e[1~": [ "home", "Home" ],
|
43
|
-
"<": [ "rew", "<" ],
|
44
|
-
">": [ "ff", ">" ],
|
45
|
-
"=": [ "play", "=" ],
|
46
|
-
"\r": [ "select", "Enter" ],
|
47
|
-
"\e[D": [ "left", "Left Arrow" ],
|
48
|
-
"\e[C": [ "right", "Right Arrow" ],
|
49
|
-
"\e[B": [ "down", "Down Arrow" ],
|
50
|
-
"\e[A": [ "up", "Up Arrow" ],
|
51
|
-
"\t": [ "back", "Tab" ],
|
52
|
-
#"": [ "replay", "" ],
|
53
|
-
"*": [ "info", "*" ],
|
54
|
-
"\u007f": [ "backspace", "Backspace" ],
|
55
|
-
"?": [ "search", "?" ],
|
56
|
-
"\e\r": [ "enter", "Alt + Enter" ],
|
57
|
-
"\e[5~": [ "volumeup", "Page Up" ],
|
58
|
-
"\e[6~": [ "volumedown", "Page Down" ],
|
59
|
-
"\e[4~": [ "mute", "End" ],
|
60
|
-
#"": [ "channeldown", "" ],
|
61
|
-
#"": [ "channelup", "" ],
|
62
|
-
#"": [ "tuner", "" ],
|
63
|
-
#"": [ "hdmi1", "" ],
|
64
|
-
#"": [ "hdmi2", "" ],
|
65
|
-
#"": [ "hdmi3", "" ],
|
66
|
-
#"": [ "hdmi4", "" ],
|
67
|
-
#"": [ "avi", "" ]
|
68
|
-
}
|
69
|
-
@mappings.merge!(mappings) if mappings
|
70
|
-
end
|
71
69
|
|
72
70
|
# Send a navigation command to the roku device
|
73
71
|
# @param command [Symbol] The smbol of the command to send
|
74
72
|
# @return [Boolean] Success
|
75
|
-
def nav(
|
73
|
+
def nav(options:)
|
74
|
+
commands = options[:nav].split(/, */).map{|c| c.to_sym}
|
76
75
|
commands.each do |command|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
path = "/keypress/#{@commands[command]}"
|
81
|
-
@logger.debug("Send Command: "+path)
|
82
|
-
response = conn.post path
|
83
|
-
return false unless response.success?
|
84
|
-
else
|
85
|
-
return false
|
76
|
+
unless @commands.has_key?(command)
|
77
|
+
raise ExecutionError, "Unknown Navigation Command"
|
86
78
|
end
|
79
|
+
conn = multipart_connection(port: 8060)
|
80
|
+
path = "/keypress/#{@commands[command]}"
|
81
|
+
@logger.debug("Send Command: "+path)
|
82
|
+
response = conn.post path
|
83
|
+
raise ExecutionError, "Navigation Failed" unless response.success?
|
87
84
|
end
|
88
|
-
return true
|
89
85
|
end
|
90
86
|
|
91
87
|
# Type text on the roku device
|
92
88
|
# @param text [String] The text to type on the device
|
93
89
|
# @return [Boolean] Success
|
94
|
-
def type(
|
90
|
+
def type(options:)
|
95
91
|
conn = multipart_connection(port: 8060)
|
96
|
-
|
92
|
+
options[:type].split(//).each do |c|
|
97
93
|
path = "/keypress/LIT_#{CGI::escape(c)}"
|
98
94
|
@logger.debug("Send Letter: "+path)
|
99
95
|
response = conn.post path
|
@@ -102,7 +98,7 @@ module RokuBuilder
|
|
102
98
|
return true
|
103
99
|
end
|
104
100
|
|
105
|
-
def
|
101
|
+
def navigate(options:)
|
106
102
|
running = true
|
107
103
|
@logger.info("Key Mappings:")
|
108
104
|
@mappings.each_value {|key|
|
@@ -115,64 +111,83 @@ module RokuBuilder
|
|
115
111
|
if char == "\u0003"
|
116
112
|
running = false
|
117
113
|
else
|
118
|
-
Thread.new(char) {|character|
|
119
|
-
if @mappings[character.to_sym] != nil
|
120
|
-
nav(commands:[@mappings[character.to_sym][0].to_sym])
|
121
|
-
elsif character.inspect.force_encoding("UTF-8").ascii_only?
|
122
|
-
type(text: character)
|
123
|
-
end
|
124
|
-
}
|
114
|
+
Thread.new(char) {|character| handle_navigate_input(character)}
|
125
115
|
end
|
126
116
|
end
|
127
117
|
end
|
128
118
|
|
119
|
+
|
129
120
|
# Show the commands for one of the roku secret screens
|
130
121
|
# @param type [Symbol] The type of screen to show
|
131
122
|
# @return [Boolean] Screen found
|
132
|
-
def screen(
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
display, count, string = [], [], ""
|
140
|
-
@screens[type].each do |command|
|
141
|
-
if display.count > 0 and display[-1] == command
|
142
|
-
count[-1] = count[-1] + 1
|
143
|
-
else
|
144
|
-
display.push(command)
|
145
|
-
count.push(1)
|
146
|
-
end
|
147
|
-
end
|
148
|
-
display.each_index do |i|
|
149
|
-
if count[i] > 1
|
150
|
-
string = string + @commands[display[i]]+" x "+count[i].to_s+", "
|
151
|
-
else
|
152
|
-
string = string + @commands[display[i]]+", "
|
153
|
-
end
|
154
|
-
end
|
155
|
-
if @runable.include?(type)
|
156
|
-
@logger.info(string.strip)
|
157
|
-
else
|
158
|
-
@logger.unknown(string.strip)
|
159
|
-
end
|
123
|
+
def screen(options:)
|
124
|
+
type = options[:screen].to_sym
|
125
|
+
unless @screens.has_key?(type)
|
126
|
+
raise ExecutionError, "Unknown Screen"
|
127
|
+
end
|
128
|
+
if @runable.include?(type)
|
129
|
+
nav(options: {nav: @screens[type].join(", ")})
|
160
130
|
else
|
161
|
-
|
131
|
+
@logger.unknown("Cannot run command automatically")
|
162
132
|
end
|
163
|
-
|
133
|
+
display_screen_command(type)
|
164
134
|
end
|
165
135
|
|
166
136
|
# Show avaiable roku secret screens
|
167
|
-
def screens
|
137
|
+
def screens(options:)
|
168
138
|
@screens.keys.each {|screen| @logger.unknown(screen)}
|
169
139
|
end
|
170
140
|
|
141
|
+
private
|
142
|
+
|
143
|
+
def mappings_init()
|
144
|
+
@mappings = {
|
145
|
+
"\e[1~": [ "home", "Home" ],
|
146
|
+
"<": [ "rew", "<" ],
|
147
|
+
">": [ "ff", ">" ],
|
148
|
+
"=": [ "play", "=" ],
|
149
|
+
"\r": [ "select", "Enter" ],
|
150
|
+
"\e[D": [ "left", "Left Arrow" ],
|
151
|
+
"\e[C": [ "right", "Right Arrow" ],
|
152
|
+
"\e[B": [ "down", "Down Arrow" ],
|
153
|
+
"\e[A": [ "up", "Up Arrow" ],
|
154
|
+
"\t": [ "back", "Tab" ],
|
155
|
+
#"": [ "replay", "" ],
|
156
|
+
"*": [ "info", "*" ],
|
157
|
+
"\u007f": [ "backspace", "Backspace" ],
|
158
|
+
"?": [ "search", "?" ],
|
159
|
+
"\e\r": [ "enter", "Alt + Enter" ],
|
160
|
+
"\e[5~": [ "volumeup", "Page Up" ],
|
161
|
+
"\e[6~": [ "volumedown", "Page Down" ],
|
162
|
+
"\e[4~": [ "mute", "End" ],
|
163
|
+
#"": [ "channeldown", "" ],
|
164
|
+
#"": [ "channelup", "" ],
|
165
|
+
#"": [ "tuner", "" ],
|
166
|
+
#"": [ "hdmi1", "" ],
|
167
|
+
#"": [ "hdmi2", "" ],
|
168
|
+
#"": [ "hdmi3", "" ],
|
169
|
+
#"": [ "hdmi4", "" ],
|
170
|
+
#"": [ "avi", "" ]
|
171
|
+
}
|
172
|
+
@mappings.merge!(generate_maggings) if @config.input_mappings
|
173
|
+
end
|
174
|
+
|
175
|
+
def generate_maggings
|
176
|
+
mappings = {}
|
177
|
+
if @config.input_mappings
|
178
|
+
@config.input_mappings.each_pair {|key, value|
|
179
|
+
unless "".to_sym == key
|
180
|
+
key = key.to_s.sub(/\\e/, "\e").to_sym
|
181
|
+
mappings[key] = value
|
182
|
+
end
|
183
|
+
}
|
184
|
+
end
|
185
|
+
mappings
|
186
|
+
end
|
187
|
+
|
171
188
|
def read_char
|
172
189
|
STDIN.echo = false
|
173
190
|
STDIN.raw!
|
174
|
-
|
175
|
-
|
176
191
|
input = STDIN.getc.chr
|
177
192
|
if input == "\e" then
|
178
193
|
input << STDIN.read_nonblock(3) rescue nil
|
@@ -183,5 +198,38 @@ module RokuBuilder
|
|
183
198
|
STDIN.echo = true
|
184
199
|
STDIN.cooked!
|
185
200
|
end
|
201
|
+
|
202
|
+
def handle_navigate_input(char)
|
203
|
+
if @mappings[char.to_sym] != nil
|
204
|
+
nav(options: {nav: @mappings[char.to_sym][0]})
|
205
|
+
elsif char.inspect.force_encoding("UTF-8").ascii_only?
|
206
|
+
type(options: {type: char})
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
def display_screen_command(type)
|
211
|
+
display, count, string = [], [], ""
|
212
|
+
@screens[type].each do |command|
|
213
|
+
if display.count > 0 and display[-1] == command
|
214
|
+
count[-1] = count[-1] + 1
|
215
|
+
else
|
216
|
+
display.push(command)
|
217
|
+
count.push(1)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
display.each_index do |i|
|
221
|
+
if count[i] > 1
|
222
|
+
string = string + @commands[display[i]]+" x "+count[i].to_s+", "
|
223
|
+
else
|
224
|
+
string = string + @commands[display[i]]+", "
|
225
|
+
end
|
226
|
+
end
|
227
|
+
if @runable.include?(type)
|
228
|
+
@logger.info(string.strip)
|
229
|
+
else
|
230
|
+
@logger.unknown(string.strip)
|
231
|
+
end
|
232
|
+
end
|
186
233
|
end
|
234
|
+
RokuBuilder.register_plugin(Navigator)
|
187
235
|
end
|