roku_builder 3.13.0 → 4.0.0
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
- 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
data/lib/roku_builder/keyer.rb
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
# ********** Copyright Viacom, Inc. Apache 2.0 **********
|
|
2
|
-
|
|
3
|
-
module RokuBuilder
|
|
4
|
-
|
|
5
|
-
# Change or get dev key
|
|
6
|
-
class Keyer < Util
|
|
7
|
-
|
|
8
|
-
def genkey(out_file: nil)
|
|
9
|
-
password, dev_id = generate_new_key()
|
|
10
|
-
@logger.unknown("Password: "+password)
|
|
11
|
-
@logger.info("DevID: "+dev_id)
|
|
12
|
-
|
|
13
|
-
unless out_file
|
|
14
|
-
out_file = File.join(Dir.tmpdir, "key_"+dev_id+".pkg")
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
Dir.mktmpdir { |dir|
|
|
18
|
-
ManifestManager.update_manifest({root_dir: dir, attributes: {}})
|
|
19
|
-
Dir.mkdir(File.join(dir, "source"))
|
|
20
|
-
File.open(File.join(dir, "source", "main.brs"), "w") do |io|
|
|
21
|
-
io.puts "sub main()"
|
|
22
|
-
io.puts " print \"Load\""
|
|
23
|
-
io.puts "end sub"
|
|
24
|
-
end
|
|
25
|
-
@device_config[:init_params] = {root_dir: dir}
|
|
26
|
-
loader = Loader.new(**@device_config)
|
|
27
|
-
loader.sideload()
|
|
28
|
-
@device_config.delete(:init_params)
|
|
29
|
-
packager = Packager.new(**@device_config)
|
|
30
|
-
packager.package(app_name_version: "key_"+dev_id, out_file: out_file, password: password)
|
|
31
|
-
@logger.unknown("Keyed PKG: "+out_file)
|
|
32
|
-
}
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
# Sets the key on the roku device
|
|
36
|
-
# @param keyed_pkg [String] Path for a package signed with the desired key
|
|
37
|
-
# @param password [String] Password for the package
|
|
38
|
-
# @return [Boolean] True if key changed, false otherwise
|
|
39
|
-
def rekey(keyed_pkg:, password:)
|
|
40
|
-
oldId = dev_id
|
|
41
|
-
|
|
42
|
-
# upload new key with password
|
|
43
|
-
path = "/plugin_inspect"
|
|
44
|
-
conn = multipart_connection
|
|
45
|
-
payload = {
|
|
46
|
-
mysubmit: "Rekey",
|
|
47
|
-
passwd: password,
|
|
48
|
-
archive: Faraday::UploadIO.new(keyed_pkg, 'application/octet-stream')
|
|
49
|
-
}
|
|
50
|
-
conn.post path, payload
|
|
51
|
-
|
|
52
|
-
# check key
|
|
53
|
-
newId = dev_id
|
|
54
|
-
@logger.info("Key did not change") unless newId != oldId
|
|
55
|
-
@logger.debug(oldId + " -> " + newId)
|
|
56
|
-
newId != oldId
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
# Get the current dev id
|
|
60
|
-
# @return [String] The current dev id
|
|
61
|
-
def dev_id
|
|
62
|
-
path = "/plugin_package"
|
|
63
|
-
conn = simple_connection
|
|
64
|
-
response = conn.get path
|
|
65
|
-
|
|
66
|
-
dev_id = /Your Dev ID:\s*<font[^>]*>([^<]*)<\/font>/.match(response.body)
|
|
67
|
-
dev_id ||= /Your Dev ID:[^>]*<\/label> ([^<]*)/.match(response.body)
|
|
68
|
-
dev_id = dev_id[1] if dev_id
|
|
69
|
-
dev_id ||= "none"
|
|
70
|
-
dev_id
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
private
|
|
74
|
-
|
|
75
|
-
# Uses the device to generate a new signing key
|
|
76
|
-
# @return [Array<String>] Password and dev_id for the new key
|
|
77
|
-
def generate_new_key()
|
|
78
|
-
telnet_config = {
|
|
79
|
-
'Host' => @roku_ip_address,
|
|
80
|
-
'Port' => 8080
|
|
81
|
-
}
|
|
82
|
-
connection = Net::Telnet.new(telnet_config)
|
|
83
|
-
connection.puts("genkey")
|
|
84
|
-
waitfor_config = {
|
|
85
|
-
'Match' => /./,
|
|
86
|
-
'Timeout' => false
|
|
87
|
-
}
|
|
88
|
-
password = nil
|
|
89
|
-
dev_id = nil
|
|
90
|
-
while password.nil? or dev_id.nil?
|
|
91
|
-
connection.waitfor(waitfor_config) do |txt|
|
|
92
|
-
while line = txt.slice!(/^.*\n/) do
|
|
93
|
-
words = line.split
|
|
94
|
-
if words[0] == "Password:"
|
|
95
|
-
password = words[1]
|
|
96
|
-
elsif words[0] == "DevID:"
|
|
97
|
-
dev_id = words[1]
|
|
98
|
-
end
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
end
|
|
102
|
-
connection.close
|
|
103
|
-
return password, dev_id
|
|
104
|
-
end
|
|
105
|
-
end
|
|
106
|
-
end
|
data/lib/roku_builder/loader.rb
DELETED
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
# ********** Copyright Viacom, Inc. Apache 2.0 **********
|
|
2
|
-
|
|
3
|
-
module RokuBuilder
|
|
4
|
-
|
|
5
|
-
# Load/Unload/Build roku applications
|
|
6
|
-
class Loader < Util
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
# Set the root directory
|
|
10
|
-
def init(root_dir: nil)
|
|
11
|
-
@root_dir = root_dir
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
# Sideload an app onto a roku device
|
|
15
|
-
# @param root_dir [String] Path to the root directory of the roku app
|
|
16
|
-
# @param content [Hash] Hash containing arrays for folder, files, and excludes. Default: nil
|
|
17
|
-
# @return [String] Build version on success, nil otherwise
|
|
18
|
-
def sideload(update_manifest: false, content: nil, infile: nil, out_file: nil)
|
|
19
|
-
Navigator.new(**@device_config).nav(commands: [:home])
|
|
20
|
-
result = FAILED_SIDELOAD
|
|
21
|
-
build_version = nil
|
|
22
|
-
if infile
|
|
23
|
-
build_version = ManifestManager.build_version(root_dir: infile)
|
|
24
|
-
out_file = infile
|
|
25
|
-
else
|
|
26
|
-
# Update manifest
|
|
27
|
-
if update_manifest
|
|
28
|
-
build_version = ManifestManager.update_build(root_dir: @root_dir)
|
|
29
|
-
else
|
|
30
|
-
build_version = ManifestManager.build_version(root_dir: @root_dir)
|
|
31
|
-
end
|
|
32
|
-
@logger.info "Build: #{out_file}" if out_file
|
|
33
|
-
out_file = build(build_version: build_version, out_file: out_file, content: content)
|
|
34
|
-
end
|
|
35
|
-
return [MISSING_MANIFEST, nil] if out_file == MISSING_MANIFEST
|
|
36
|
-
path = "/plugin_install"
|
|
37
|
-
# Connect to roku and upload file
|
|
38
|
-
conn = multipart_connection
|
|
39
|
-
payload = {
|
|
40
|
-
mysubmit: "Replace",
|
|
41
|
-
archive: Faraday::UploadIO.new(out_file, 'application/zip')
|
|
42
|
-
}
|
|
43
|
-
response = conn.post path, payload
|
|
44
|
-
# Cleanup
|
|
45
|
-
File.delete(out_file) if infile.nil? and out_file.nil?
|
|
46
|
-
result = SUCCESS if response.status==200 and response.body=~/Install Success/
|
|
47
|
-
result = IDENTICAL_SIDELOAD if response.status==200 and response.body=~/Identical to previous version/
|
|
48
|
-
[result, build_version]
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
# Build an app to sideload later
|
|
53
|
-
# @param root_dir [String] Path to the root directory of the roku app
|
|
54
|
-
# @param build_version [String] Version to assigne to the build. If nil will pull the build version form the manifest. Default: nil
|
|
55
|
-
# @param out_file [String] Path for the output file. If nil will create a file in /tmp. Default: nil
|
|
56
|
-
# @param content [Hash] Hash containing arrays for folder, files, and excludes. Default: nil
|
|
57
|
-
# @return [String] Path of the build
|
|
58
|
-
def build(build_version: nil, out_file: nil, content: nil)
|
|
59
|
-
build_version = ManifestManager.build_version(root_dir: @root_dir) unless build_version
|
|
60
|
-
return MISSING_MANIFEST if build_version == MISSING_MANIFEST
|
|
61
|
-
content ||= {}
|
|
62
|
-
content[:folders] ||= Dir.entries(@root_dir).select {|entry| File.directory? File.join(@root_dir, entry) and !(entry =='.' || entry == '..') }
|
|
63
|
-
content[:files] ||= Dir.entries(@root_dir).select {|entry| File.file? File.join(@root_dir, entry)}
|
|
64
|
-
content[:excludes] ||= []
|
|
65
|
-
out_file = "#{Dir.tmpdir}/#{build_version}" unless out_file
|
|
66
|
-
out_file = out_file+".zip" unless out_file.end_with?(".zip")
|
|
67
|
-
File.delete(out_file) if File.exist?(out_file)
|
|
68
|
-
io = Zip::File.open(out_file, Zip::File::CREATE)
|
|
69
|
-
# Add folders to zip
|
|
70
|
-
content[:folders].each do |folder|
|
|
71
|
-
base_folder = File.join(@root_dir, folder)
|
|
72
|
-
if File.exist?(base_folder)
|
|
73
|
-
entries = Dir.entries(base_folder)
|
|
74
|
-
entries.delete(".")
|
|
75
|
-
entries.delete("..")
|
|
76
|
-
writeEntries(@root_dir, entries, folder, content[:excludes], io)
|
|
77
|
-
else
|
|
78
|
-
@logger.warn "Missing Folder: #{base_folder}"
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
# Add file to zip
|
|
82
|
-
writeEntries(@root_dir, content[:files], "", content[:excludes], io)
|
|
83
|
-
io.close()
|
|
84
|
-
out_file
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
# Remove the currently sideloaded app
|
|
88
|
-
def unload()
|
|
89
|
-
path = "/plugin_install"
|
|
90
|
-
|
|
91
|
-
# Connect to roku and upload file
|
|
92
|
-
conn = multipart_connection
|
|
93
|
-
payload = {
|
|
94
|
-
mysubmit: "Delete",
|
|
95
|
-
archive: ""
|
|
96
|
-
}
|
|
97
|
-
response = conn.post path, payload
|
|
98
|
-
if response.status == 200 and response.body =~ /Install Success/
|
|
99
|
-
return true
|
|
100
|
-
end
|
|
101
|
-
return false
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
private
|
|
105
|
-
|
|
106
|
-
# Recursively write directory contents to a zip archive
|
|
107
|
-
# @param root_dir [String] Path of the root directory
|
|
108
|
-
# @param entries [Array<String>] Array of file paths of files/directories to store in the zip archive
|
|
109
|
-
# @param path [String] The path of the current directory starting at the root directory
|
|
110
|
-
# @param io [IO] zip IO object
|
|
111
|
-
def writeEntries(root_dir, entries, path, excludes, io)
|
|
112
|
-
entries.each { |e|
|
|
113
|
-
zipFilePath = path == "" ? e : File.join(path, e)
|
|
114
|
-
diskFilePath = File.join(root_dir, zipFilePath)
|
|
115
|
-
if File.directory?(diskFilePath)
|
|
116
|
-
io.mkdir(zipFilePath)
|
|
117
|
-
subdir =Dir.entries(diskFilePath); subdir.delete("."); subdir.delete("..")
|
|
118
|
-
writeEntries(root_dir, subdir, zipFilePath, excludes, io)
|
|
119
|
-
else
|
|
120
|
-
unless excludes.include?(zipFilePath)
|
|
121
|
-
if File.exist?(diskFilePath)
|
|
122
|
-
io.get_output_stream(zipFilePath) { |f| f.puts(File.open(diskFilePath, "rb").read()) }
|
|
123
|
-
else
|
|
124
|
-
@logger.warn "Missing File: #{diskFilePath}"
|
|
125
|
-
end
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
}
|
|
129
|
-
end
|
|
130
|
-
end
|
|
131
|
-
end
|
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
# ********** Copyright Viacom, Inc. Apache 2.0 **********
|
|
2
|
-
|
|
3
|
-
module RokuBuilder
|
|
4
|
-
|
|
5
|
-
# Updates or retrives build version
|
|
6
|
-
class ManifestManager
|
|
7
|
-
|
|
8
|
-
# Updates the build version in the manifest file
|
|
9
|
-
# @param root_dir [String] Path to the root directory for the app
|
|
10
|
-
# @return [String] Build version on success, empty string otherwise
|
|
11
|
-
def self.update_build(root_dir:)
|
|
12
|
-
return MISSING_MANIFEST unless self.check_manifest(root_dir: root_dir)
|
|
13
|
-
build_version = self.build_version(root_dir: root_dir).split(".")
|
|
14
|
-
if 2 == build_version.length
|
|
15
|
-
iteration = build_version[1].to_i + 1
|
|
16
|
-
build_version[0] = Time.now.strftime("%m%d%y")
|
|
17
|
-
build_version[1] = iteration
|
|
18
|
-
build_version = build_version.join(".")
|
|
19
|
-
else
|
|
20
|
-
iteration = build_version[0].to_i + 1
|
|
21
|
-
build_version = iteration.to_s
|
|
22
|
-
end
|
|
23
|
-
self.update_manifest(root_dir: root_dir, attributes: {build_version: build_version})
|
|
24
|
-
self.build_version(root_dir: root_dir)
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
# Retrive the build version from the manifest file
|
|
29
|
-
# @param root_dir [String] Path to the root directory for the app
|
|
30
|
-
# @return [String] Build version on success, empty string otherwise
|
|
31
|
-
def self.build_version(root_dir:)
|
|
32
|
-
return MISSING_MANIFEST unless self.check_manifest(root_dir: root_dir)
|
|
33
|
-
read_manifest(root_dir: root_dir)[:build_version]
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def self.read_manifest(root_dir:)
|
|
37
|
-
return MISSING_MANIFEST unless self.check_manifest(root_dir: root_dir)
|
|
38
|
-
attrs = {}
|
|
39
|
-
get_attrs = lambda { |file|
|
|
40
|
-
file.each_line do |line|
|
|
41
|
-
key, value = line.split("=")
|
|
42
|
-
if value
|
|
43
|
-
attrs[key.chomp.to_sym]= value.chomp
|
|
44
|
-
elsif key and !key.chomp.empty?
|
|
45
|
-
attrs[key.chomp.to_sym]= nil
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
}
|
|
49
|
-
if File.directory?(root_dir)
|
|
50
|
-
path = File.join(root_dir, 'manifest')
|
|
51
|
-
File.open(path, 'r', &get_attrs)
|
|
52
|
-
elsif File.extname(root_dir) == ".zip"
|
|
53
|
-
Zip::File.open(root_dir) do |zip_file|
|
|
54
|
-
entry = zip_file.glob("manifest").first
|
|
55
|
-
entry.get_input_stream(&get_attrs)
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
attrs
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
# Update attributes in the app manifest
|
|
62
|
-
# It will add missing attributes but not remove them
|
|
63
|
-
# @param root_dir [String] The app root directory
|
|
64
|
-
# @param attributes [Hash] The new attributes for the app manifest
|
|
65
|
-
def self.update_manifest(root_dir:, attributes:, set_default: true)
|
|
66
|
-
temp_file = Tempfile.new('manifest')
|
|
67
|
-
path = File.join(root_dir, 'manifest')
|
|
68
|
-
new_params = attributes.dup
|
|
69
|
-
begin
|
|
70
|
-
if File.exist?(path)
|
|
71
|
-
File.open(path, 'r') do |file|
|
|
72
|
-
file.each_line do |line|
|
|
73
|
-
key = line.split("=")[0]
|
|
74
|
-
if new_params.include?(key.to_sym)
|
|
75
|
-
temp_file.puts("#{key}=#{new_params[key.to_sym]}")
|
|
76
|
-
new_params.delete(key.to_sym)
|
|
77
|
-
else
|
|
78
|
-
temp_file.puts(line)
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
elsif set_default
|
|
83
|
-
new_params = self.default_params().merge(new_params)
|
|
84
|
-
end
|
|
85
|
-
new_params.each_pair do |key, value|
|
|
86
|
-
temp_file.puts("#{key}=#{value}")
|
|
87
|
-
end
|
|
88
|
-
temp_file.rewind
|
|
89
|
-
FileUtils.cp(temp_file.path, path)
|
|
90
|
-
ensure
|
|
91
|
-
temp_file.close
|
|
92
|
-
temp_file.unlink
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
# Check to make sure that the manifest file exists
|
|
97
|
-
# @param root_dir [String] Path to the root directory for the app
|
|
98
|
-
# @return [Boolean] True if manifest exists, false otherwise
|
|
99
|
-
def self.check_manifest(root_dir:)
|
|
100
|
-
return false unless File.exist?(root_dir)
|
|
101
|
-
if File.directory?(root_dir)
|
|
102
|
-
path = File.join(root_dir, 'manifest')
|
|
103
|
-
return false unless File.exist?(path)
|
|
104
|
-
elsif File.extname(root_dir) == ".zip"
|
|
105
|
-
Zip::File.open(root_dir) do |zip_file|
|
|
106
|
-
entry = zip_file.glob("manifest").first
|
|
107
|
-
return false unless entry
|
|
108
|
-
end
|
|
109
|
-
end
|
|
110
|
-
true
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
# Returns the default manafest values
|
|
114
|
-
# @return [Hash] default manifest values
|
|
115
|
-
def self.default_params
|
|
116
|
-
{
|
|
117
|
-
title: "Default Title",
|
|
118
|
-
major_version: 1,
|
|
119
|
-
minor_version: 0,
|
|
120
|
-
build_version: "010101.0001",
|
|
121
|
-
mm_icon_focus_hd: "<insert hd focus icon url>",
|
|
122
|
-
mm_icon_focus_sd: "<insert sd focus icon url>"
|
|
123
|
-
}
|
|
124
|
-
end
|
|
125
|
-
end
|
|
126
|
-
end
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
# ********** Copyright Viacom, Inc. Apache 2.0 **********
|
|
2
|
-
|
|
3
|
-
module RokuBuilder
|
|
4
|
-
|
|
5
|
-
# Method of packaging app for submission
|
|
6
|
-
class Packager < Util
|
|
7
|
-
|
|
8
|
-
# Sign and download the currently sideloaded app
|
|
9
|
-
# @param app_name_version [String] The name and version of the package
|
|
10
|
-
# @param out_file [String] Location to download signed package to
|
|
11
|
-
# @param password [String] Password for the devices current key
|
|
12
|
-
# @return [Boolean] True on package success and download, false otherwise
|
|
13
|
-
def package(app_name_version:, out_file:, password:)
|
|
14
|
-
# Sign package
|
|
15
|
-
path = "/plugin_package"
|
|
16
|
-
conn = multipart_connection
|
|
17
|
-
payload = {
|
|
18
|
-
mysubmit: "Package",
|
|
19
|
-
app_name: app_name_version,
|
|
20
|
-
passwd: password,
|
|
21
|
-
pkg_time: Time.now.to_i
|
|
22
|
-
}
|
|
23
|
-
response = conn.post path, payload
|
|
24
|
-
|
|
25
|
-
# Check for error
|
|
26
|
-
failed = /(Failed: [^\.]*\.)/.match(response.body)
|
|
27
|
-
return failed[1] if failed
|
|
28
|
-
|
|
29
|
-
# Download signed package
|
|
30
|
-
pkg = /<a href="pkgs[^>]*>([^<]*)</.match(response.body)[1]
|
|
31
|
-
path = "/pkgs/#{pkg}"
|
|
32
|
-
conn = Faraday.new(url: @url) do |f|
|
|
33
|
-
f.request :digest, @dev_username, @dev_password
|
|
34
|
-
f.adapter Faraday.default_adapter
|
|
35
|
-
end
|
|
36
|
-
response = conn.get path
|
|
37
|
-
return false if response.status != 200
|
|
38
|
-
out_file = out_file+".pkg" unless out_file.end_with?(".pkg")
|
|
39
|
-
File.open(out_file, 'w+') {|fp| fp.write(response.body)}
|
|
40
|
-
true
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
# ********** Copyright Viacom, Inc. Apache 2.0 **********
|
|
2
|
-
|
|
3
|
-
module RokuBuilder
|
|
4
|
-
|
|
5
|
-
# Scene Graph Profiler
|
|
6
|
-
class Profiler < Util
|
|
7
|
-
|
|
8
|
-
# Run the profiler commands
|
|
9
|
-
# @param command [Symbol] The profiler command to run
|
|
10
|
-
def run(command:)
|
|
11
|
-
case command
|
|
12
|
-
when :stats
|
|
13
|
-
print_stats
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
private
|
|
18
|
-
|
|
19
|
-
# Print the node stats
|
|
20
|
-
def print_stats
|
|
21
|
-
lines = get_all_nodes
|
|
22
|
-
xml_string = lines.join("\n")
|
|
23
|
-
stats = {"Total" => 0}
|
|
24
|
-
doc = Nokogiri::XML(xml_string)
|
|
25
|
-
handle_node(stats: stats, node: doc.root)
|
|
26
|
-
stats = stats.to_a
|
|
27
|
-
stats = stats.sort {|a, b| b[1] <=> a[1]}
|
|
28
|
-
printf "%30s | %5s\n", "Name", "Count"
|
|
29
|
-
stats.each do |key_pair|
|
|
30
|
-
printf "%30s | %5d\n", key_pair[0], key_pair[1]
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def handle_node(stats:, node:)
|
|
35
|
-
node.element_children.each do |element|
|
|
36
|
-
stats[element.name] ||= 0
|
|
37
|
-
stats[element.name] += 1
|
|
38
|
-
stats["Total"] += 1
|
|
39
|
-
handle_node(stats: stats, node: element)
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
# Retrive list of all nodes
|
|
44
|
-
# @return [Array<String>] Array of lines
|
|
45
|
-
def get_all_nodes
|
|
46
|
-
waitfor_config = {
|
|
47
|
-
'Match' => /.+/,
|
|
48
|
-
'Timeout' => 5
|
|
49
|
-
}
|
|
50
|
-
telnet_config ={
|
|
51
|
-
'Host' => @roku_ip_address,
|
|
52
|
-
'Port' => 8080
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
connection = Net::Telnet.new(telnet_config)
|
|
56
|
-
|
|
57
|
-
lines = []
|
|
58
|
-
all_txt = ""
|
|
59
|
-
in_nodes = false
|
|
60
|
-
done = false
|
|
61
|
-
connection.puts("sgnodes all\n")
|
|
62
|
-
while not done
|
|
63
|
-
begin
|
|
64
|
-
connection.waitfor(waitfor_config) do |txt|
|
|
65
|
-
in_nodes, done, all_txt = handle_text(all_txt: all_txt, txt: txt, in_nodes: in_nodes, lines: lines)
|
|
66
|
-
end
|
|
67
|
-
rescue Net::ReadTimeout
|
|
68
|
-
@logger.warn "Timed out reading profiler information"
|
|
69
|
-
done = true
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
lines
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
# Handle profiling text
|
|
76
|
-
# @param all_txt [String] remainder text from last run
|
|
77
|
-
# @param txt [String] current text from telnet
|
|
78
|
-
# @param in_nodes [Boolean] currently parsing test text
|
|
79
|
-
# @return [Boolean] currently parsing test text
|
|
80
|
-
def handle_text(all_txt:, txt:, in_nodes:, lines:)
|
|
81
|
-
all_txt += txt
|
|
82
|
-
end_reg = /<\/All_Nodes>/
|
|
83
|
-
start_reg = /<All_Nodes>/
|
|
84
|
-
done = false
|
|
85
|
-
while line = all_txt.slice!(/^.*\n/) do
|
|
86
|
-
in_nodes = true if line =~ start_reg
|
|
87
|
-
lines.push(line) if in_nodes
|
|
88
|
-
if line =~ end_reg
|
|
89
|
-
in_nodes = false
|
|
90
|
-
done = true
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
[in_nodes, done, all_txt]
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
end
|