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.
Files changed (226) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/CHANGELOG +12 -0
  4. data/Gemfile.lock +22 -7
  5. data/Guardfile +3 -3
  6. data/README.md +22 -398
  7. data/bin/roku +1 -194
  8. data/config.json.example +1 -1
  9. data/intergration/roku_builder/test_core.rb +52 -0
  10. data/intergration/roku_builder/test_files/core_intergration_test/manifest_template +7 -0
  11. data/intergration/roku_builder/test_files/core_intergration_test/test.pkg +0 -0
  12. data/intergration/roku_builder/test_files/inspector_intergration_test/components/rectanglescene.xml +28 -0
  13. data/intergration/roku_builder/test_files/inspector_intergration_test/images/rde_mm_focus_hd.jpg +0 -0
  14. data/intergration/roku_builder/test_files/inspector_intergration_test/images/rde_mm_focus_sd.jpg +0 -0
  15. data/intergration/roku_builder/test_files/inspector_intergration_test/images/rde_splash_fhd.jpg +0 -0
  16. data/intergration/roku_builder/test_files/inspector_intergration_test/images/rde_splash_hd.jpg +0 -0
  17. data/intergration/roku_builder/test_files/inspector_intergration_test/images/rde_splash_sd.jpg +0 -0
  18. data/intergration/roku_builder/test_files/inspector_intergration_test/images/rsgde_bg_hd.jpg +0 -0
  19. data/intergration/roku_builder/test_files/inspector_intergration_test/images/rsgde_mm_focus_hd.jpg +0 -0
  20. data/intergration/roku_builder/test_files/inspector_intergration_test/images/rsgde_splash_hd.jpg +0 -0
  21. data/intergration/roku_builder/test_files/inspector_intergration_test/manifest +21 -0
  22. data/intergration/roku_builder/test_files/inspector_intergration_test/source/main.brs +23 -0
  23. data/intergration/roku_builder/test_files/inspector_intergration_test/test.pkg +0 -0
  24. data/intergration/roku_builder/test_files/linker_intergration_test/components/rectanglescene.xml +29 -0
  25. data/intergration/roku_builder/test_files/linker_intergration_test/images/rde_mm_focus_hd.jpg +0 -0
  26. data/intergration/roku_builder/test_files/linker_intergration_test/images/rde_mm_focus_sd.jpg +0 -0
  27. data/intergration/roku_builder/test_files/linker_intergration_test/images/rde_splash_fhd.jpg +0 -0
  28. data/intergration/roku_builder/test_files/linker_intergration_test/images/rde_splash_hd.jpg +0 -0
  29. data/intergration/roku_builder/test_files/linker_intergration_test/images/rde_splash_sd.jpg +0 -0
  30. data/intergration/roku_builder/test_files/linker_intergration_test/images/rsgde_bg_hd.jpg +0 -0
  31. data/intergration/roku_builder/test_files/linker_intergration_test/images/rsgde_mm_focus_hd.jpg +0 -0
  32. data/intergration/roku_builder/test_files/linker_intergration_test/images/rsgde_splash_hd.jpg +0 -0
  33. data/intergration/roku_builder/test_files/linker_intergration_test/manifest +21 -0
  34. data/intergration/roku_builder/test_files/linker_intergration_test/source/main.brs +21 -0
  35. data/intergration/roku_builder/test_files/linker_intergration_test/test.pkg +0 -0
  36. data/intergration/roku_builder/test_files/loader_intergration_test/components/rectanglescene.xml +29 -0
  37. data/intergration/roku_builder/test_files/loader_intergration_test/images/rde_mm_focus_hd.jpg +0 -0
  38. data/intergration/roku_builder/test_files/loader_intergration_test/images/rde_mm_focus_sd.jpg +0 -0
  39. data/intergration/roku_builder/test_files/loader_intergration_test/images/rde_splash_fhd.jpg +0 -0
  40. data/intergration/roku_builder/test_files/loader_intergration_test/images/rde_splash_hd.jpg +0 -0
  41. data/intergration/roku_builder/test_files/loader_intergration_test/images/rde_splash_sd.jpg +0 -0
  42. data/intergration/roku_builder/test_files/loader_intergration_test/images/rsgde_bg_hd.jpg +0 -0
  43. data/intergration/roku_builder/test_files/loader_intergration_test/images/rsgde_mm_focus_hd.jpg +0 -0
  44. data/intergration/roku_builder/test_files/loader_intergration_test/images/rsgde_splash_hd.jpg +0 -0
  45. data/intergration/roku_builder/test_files/loader_intergration_test/manifest +21 -0
  46. data/intergration/roku_builder/test_files/loader_intergration_test/source/main.brs +21 -0
  47. data/intergration/roku_builder/test_files/loader_intergration_test/test.pkg +0 -0
  48. data/intergration/roku_builder/test_files/monitor_intergration_test/components/rectanglescene.xml +29 -0
  49. data/intergration/roku_builder/test_files/monitor_intergration_test/images/rde_mm_focus_hd.jpg +0 -0
  50. data/intergration/roku_builder/test_files/monitor_intergration_test/images/rde_mm_focus_sd.jpg +0 -0
  51. data/intergration/roku_builder/test_files/monitor_intergration_test/images/rde_splash_fhd.jpg +0 -0
  52. data/intergration/roku_builder/test_files/monitor_intergration_test/images/rde_splash_hd.jpg +0 -0
  53. data/intergration/roku_builder/test_files/monitor_intergration_test/images/rde_splash_sd.jpg +0 -0
  54. data/intergration/roku_builder/test_files/monitor_intergration_test/images/rsgde_bg_hd.jpg +0 -0
  55. data/intergration/roku_builder/test_files/monitor_intergration_test/images/rsgde_mm_focus_hd.jpg +0 -0
  56. data/intergration/roku_builder/test_files/monitor_intergration_test/images/rsgde_splash_hd.jpg +0 -0
  57. data/intergration/roku_builder/test_files/monitor_intergration_test/manifest +21 -0
  58. data/intergration/roku_builder/test_files/monitor_intergration_test/source/main.brs +21 -0
  59. data/intergration/roku_builder/test_files/monitor_intergration_test/test.pkg +0 -0
  60. data/intergration/roku_builder/test_files/navigator_intergration_test/components/rectanglescene.xml +29 -0
  61. data/intergration/roku_builder/test_files/navigator_intergration_test/images/rde_mm_focus_hd.jpg +0 -0
  62. data/intergration/roku_builder/test_files/navigator_intergration_test/images/rde_mm_focus_sd.jpg +0 -0
  63. data/intergration/roku_builder/test_files/navigator_intergration_test/images/rde_splash_fhd.jpg +0 -0
  64. data/intergration/roku_builder/test_files/navigator_intergration_test/images/rde_splash_hd.jpg +0 -0
  65. data/intergration/roku_builder/test_files/navigator_intergration_test/images/rde_splash_sd.jpg +0 -0
  66. data/intergration/roku_builder/test_files/navigator_intergration_test/images/rsgde_bg_hd.jpg +0 -0
  67. data/intergration/roku_builder/test_files/navigator_intergration_test/images/rsgde_mm_focus_hd.jpg +0 -0
  68. data/intergration/roku_builder/test_files/navigator_intergration_test/images/rsgde_splash_hd.jpg +0 -0
  69. data/intergration/roku_builder/test_files/navigator_intergration_test/manifest +21 -0
  70. data/intergration/roku_builder/test_files/navigator_intergration_test/source/main.brs +21 -0
  71. data/intergration/roku_builder/test_files/navigator_intergration_test/test.pkg +0 -0
  72. data/intergration/roku_builder/test_files/packager_intergration_test/components/rectanglescene.xml +29 -0
  73. data/intergration/roku_builder/test_files/packager_intergration_test/images/rde_mm_focus_hd.jpg +0 -0
  74. data/intergration/roku_builder/test_files/packager_intergration_test/images/rde_mm_focus_sd.jpg +0 -0
  75. data/intergration/roku_builder/test_files/packager_intergration_test/images/rde_splash_fhd.jpg +0 -0
  76. data/intergration/roku_builder/test_files/packager_intergration_test/images/rde_splash_hd.jpg +0 -0
  77. data/intergration/roku_builder/test_files/packager_intergration_test/images/rde_splash_sd.jpg +0 -0
  78. data/intergration/roku_builder/test_files/packager_intergration_test/images/rsgde_bg_hd.jpg +0 -0
  79. data/intergration/roku_builder/test_files/packager_intergration_test/images/rsgde_mm_focus_hd.jpg +0 -0
  80. data/intergration/roku_builder/test_files/packager_intergration_test/images/rsgde_splash_hd.jpg +0 -0
  81. data/intergration/roku_builder/test_files/packager_intergration_test/manifest +21 -0
  82. data/intergration/roku_builder/test_files/packager_intergration_test/source/main.brs +21 -0
  83. data/intergration/roku_builder/test_files/packager_intergration_test/test.pkg +0 -0
  84. data/intergration/roku_builder/test_files/profiler_intergration_test/components/rectanglescene.xml +29 -0
  85. data/intergration/roku_builder/test_files/profiler_intergration_test/images/rde_mm_focus_hd.jpg +0 -0
  86. data/intergration/roku_builder/test_files/profiler_intergration_test/images/rde_mm_focus_sd.jpg +0 -0
  87. data/intergration/roku_builder/test_files/profiler_intergration_test/images/rde_splash_fhd.jpg +0 -0
  88. data/intergration/roku_builder/test_files/profiler_intergration_test/images/rde_splash_hd.jpg +0 -0
  89. data/intergration/roku_builder/test_files/profiler_intergration_test/images/rde_splash_sd.jpg +0 -0
  90. data/intergration/roku_builder/test_files/profiler_intergration_test/images/rsgde_bg_hd.jpg +0 -0
  91. data/intergration/roku_builder/test_files/profiler_intergration_test/images/rsgde_mm_focus_hd.jpg +0 -0
  92. data/intergration/roku_builder/test_files/profiler_intergration_test/images/rsgde_splash_hd.jpg +0 -0
  93. data/intergration/roku_builder/test_files/profiler_intergration_test/manifest +21 -0
  94. data/intergration/roku_builder/test_files/profiler_intergration_test/source/main.brs +21 -0
  95. data/intergration/roku_builder/test_files/profiler_intergration_test/test.pkg +0 -0
  96. data/intergration/roku_builder/test_files/scripter_intergration_test/components/rectanglescene.xml +29 -0
  97. data/intergration/roku_builder/test_files/scripter_intergration_test/images/rde_mm_focus_hd.jpg +0 -0
  98. data/intergration/roku_builder/test_files/scripter_intergration_test/images/rde_mm_focus_sd.jpg +0 -0
  99. data/intergration/roku_builder/test_files/scripter_intergration_test/images/rde_splash_fhd.jpg +0 -0
  100. data/intergration/roku_builder/test_files/scripter_intergration_test/images/rde_splash_hd.jpg +0 -0
  101. data/intergration/roku_builder/test_files/scripter_intergration_test/images/rde_splash_sd.jpg +0 -0
  102. data/intergration/roku_builder/test_files/scripter_intergration_test/images/rsgde_bg_hd.jpg +0 -0
  103. data/intergration/roku_builder/test_files/scripter_intergration_test/images/rsgde_mm_focus_hd.jpg +0 -0
  104. data/intergration/roku_builder/test_files/scripter_intergration_test/images/rsgde_splash_hd.jpg +0 -0
  105. data/intergration/roku_builder/test_files/scripter_intergration_test/manifest +21 -0
  106. data/intergration/roku_builder/test_files/scripter_intergration_test/source/main.brs +21 -0
  107. data/intergration/roku_builder/test_files/scripter_intergration_test/test.pkg +0 -0
  108. data/intergration/roku_builder/test_files/tester_intergration_test/components/rectanglescene.xml +29 -0
  109. data/intergration/roku_builder/test_files/tester_intergration_test/images/rde_mm_focus_hd.jpg +0 -0
  110. data/intergration/roku_builder/test_files/tester_intergration_test/images/rde_mm_focus_sd.jpg +0 -0
  111. data/intergration/roku_builder/test_files/tester_intergration_test/images/rde_splash_fhd.jpg +0 -0
  112. data/intergration/roku_builder/test_files/tester_intergration_test/images/rde_splash_hd.jpg +0 -0
  113. data/intergration/roku_builder/test_files/tester_intergration_test/images/rde_splash_sd.jpg +0 -0
  114. data/intergration/roku_builder/test_files/tester_intergration_test/images/rsgde_bg_hd.jpg +0 -0
  115. data/intergration/roku_builder/test_files/tester_intergration_test/images/rsgde_mm_focus_hd.jpg +0 -0
  116. data/intergration/roku_builder/test_files/tester_intergration_test/images/rsgde_splash_hd.jpg +0 -0
  117. data/intergration/roku_builder/test_files/tester_intergration_test/manifest +21 -0
  118. data/intergration/roku_builder/test_files/tester_intergration_test/source/main.brs +21 -0
  119. data/intergration/roku_builder/test_files/tester_intergration_test/test.pkg +0 -0
  120. data/intergration/roku_builder/test_helper.rb +138 -0
  121. data/intergration/roku_builder/test_inspector.rb +35 -0
  122. data/intergration/roku_builder/test_linker.rb +32 -0
  123. data/intergration/roku_builder/test_loader.rb +38 -0
  124. data/intergration/roku_builder/test_monitor.rb +21 -0
  125. data/intergration/roku_builder/test_navigator.rb +34 -0
  126. data/intergration/roku_builder/test_packager.rb +41 -0
  127. data/intergration/roku_builder/test_profiler.rb +48 -0
  128. data/intergration/roku_builder/test_scripter.rb +38 -0
  129. data/intergration/roku_builder/test_tester.rb +21 -0
  130. data/lib/roku_builder.rb +143 -154
  131. data/lib/roku_builder/config.rb +17 -40
  132. data/lib/roku_builder/config_parser.rb +49 -200
  133. data/lib/roku_builder/config_validator.rb +1 -1
  134. data/lib/roku_builder/errors.rb +12 -0
  135. data/lib/roku_builder/git.rb +28 -0
  136. data/lib/roku_builder/hash.rb +8 -0
  137. data/lib/roku_builder/manifest.rb +121 -0
  138. data/lib/roku_builder/options.rb +68 -29
  139. data/lib/roku_builder/plugin.rb +30 -0
  140. data/lib/roku_builder/plugins/core.rb +117 -0
  141. data/lib/roku_builder/plugins/inspector.rb +104 -0
  142. data/lib/roku_builder/{linker.rb → plugins/linker.rb} +38 -12
  143. data/lib/roku_builder/plugins/loader.rb +152 -0
  144. data/lib/roku_builder/{monitor.rb → plugins/monitor.rb} +20 -9
  145. data/lib/roku_builder/{navigator.rb → plugins/navigator.rb} +136 -88
  146. data/lib/roku_builder/plugins/packager.rb +194 -0
  147. data/lib/roku_builder/plugins/profiler.rb +135 -0
  148. data/lib/roku_builder/plugins/scripter.rb +53 -0
  149. data/lib/roku_builder/{tester.rb → plugins/tester.rb} +28 -19
  150. data/lib/roku_builder/stager.rb +48 -12
  151. data/lib/roku_builder/string.rb +20 -0
  152. data/lib/roku_builder/util.rb +10 -34
  153. data/lib/roku_builder/version.rb +1 -1
  154. data/rakefile +5 -1
  155. data/roku_builder.gemspec +2 -0
  156. data/test/roku_builder/plugins/test_core.rb +112 -0
  157. data/test/roku_builder/plugins/test_inspector.rb +165 -0
  158. data/test/roku_builder/plugins/test_linker.rb +123 -0
  159. data/test/roku_builder/plugins/test_loader.rb +115 -0
  160. data/test/roku_builder/plugins/test_monitor.rb +141 -0
  161. data/test/roku_builder/plugins/test_navigator.rb +274 -0
  162. data/test/roku_builder/plugins/test_packager.rb +202 -0
  163. data/test/roku_builder/plugins/test_profiler.rb +127 -0
  164. data/test/roku_builder/plugins/test_scripter.rb +110 -0
  165. data/test/roku_builder/plugins/test_tester.rb +109 -0
  166. data/test/roku_builder/test_config.rb +51 -35
  167. data/test/roku_builder/test_config_parser.rb +76 -154
  168. data/test/roku_builder/test_config_validator.rb +18 -1
  169. data/test/roku_builder/test_files/{loader_test/manifest → config_parser_test/test.pkg} +0 -0
  170. data/test/roku_builder/test_files/config_test/config.json +3 -0
  171. data/test/roku_builder/test_files/controller_commands_test/manifest_template +7 -0
  172. data/test/roku_builder/test_files/core_test/manifest_template +7 -0
  173. data/test/roku_builder/test_files/core_test/test.pkg +0 -0
  174. data/test/roku_builder/test_files/inspector_test/manifest +6 -0
  175. data/test/roku_builder/test_files/inspector_test/test.pkg +0 -0
  176. data/test/roku_builder/test_files/linker_test/manifest +6 -0
  177. data/test/roku_builder/test_files/linker_test/test.pkg +0 -0
  178. data/test/roku_builder/test_files/loader_test/manifest_template +6 -0
  179. data/test/roku_builder/test_files/loader_test/test.pkg +0 -0
  180. data/test/roku_builder/test_files/loader_test/test.zip +0 -0
  181. data/test/roku_builder/test_files/manifest_test/manifest_comments +6 -0
  182. data/test/roku_builder/test_files/manifest_test/manifest_template +7 -0
  183. data/test/roku_builder/test_files/manifest_test/test.zip +0 -0
  184. data/test/roku_builder/test_files/packager_test/manifest +6 -0
  185. data/test/roku_builder/test_files/packager_test/scripter_test/manifest +6 -0
  186. data/test/roku_builder/test_files/packager_test/test.pkg +0 -0
  187. data/test/roku_builder/test_files/roku_builder_test/config.json +32 -0
  188. data/test/roku_builder/test_files/scripter_test/manifest +6 -0
  189. data/test/roku_builder/test_files/scripter_test/test.pkg +0 -0
  190. data/test/roku_builder/test_files/stager_test/test.pkg +0 -0
  191. data/test/roku_builder/test_files/tester_test/manifest +6 -0
  192. data/test/roku_builder/test_files/tester_test/test.pkg +0 -0
  193. data/test/roku_builder/test_helper.rb +44 -11
  194. data/test/roku_builder/test_logger.rb +1 -0
  195. data/test/roku_builder/test_manifest.rb +99 -0
  196. data/test/roku_builder/test_options.rb +106 -77
  197. data/test/roku_builder/test_options_plugins.rb +111 -0
  198. data/test/roku_builder/test_plugin.rb +48 -0
  199. data/test/roku_builder/test_roku_builder.rb +239 -0
  200. data/test/roku_builder/test_stager.rb +49 -101
  201. data/test/roku_builder/test_util.rb +19 -4
  202. metadata +241 -47
  203. data/lib/roku_builder/controller.rb +0 -98
  204. data/lib/roku_builder/controller_commands.rb +0 -224
  205. data/lib/roku_builder/error_handler.rb +0 -142
  206. data/lib/roku_builder/inspector.rb +0 -82
  207. data/lib/roku_builder/keyer.rb +0 -106
  208. data/lib/roku_builder/loader.rb +0 -131
  209. data/lib/roku_builder/manifest_manager.rb +0 -126
  210. data/lib/roku_builder/packager.rb +0 -43
  211. data/lib/roku_builder/profiler.rb +0 -96
  212. data/lib/roku_builder/scripter.rb +0 -39
  213. data/test/roku_builder/test_controller.rb +0 -70
  214. data/test/roku_builder/test_controller_commands.rb +0 -465
  215. data/test/roku_builder/test_error_handler.rb +0 -90
  216. data/test/roku_builder/test_inspector.rb +0 -298
  217. data/test/roku_builder/test_keyer.rb +0 -176
  218. data/test/roku_builder/test_linker.rb +0 -110
  219. data/test/roku_builder/test_loader.rb +0 -337
  220. data/test/roku_builder/test_manifest_manager.rb +0 -103
  221. data/test/roku_builder/test_monitor.rb +0 -137
  222. data/test/roku_builder/test_navigator.rb +0 -280
  223. data/test/roku_builder/test_packager.rb +0 -127
  224. data/test/roku_builder/test_profiler.rb +0 -35
  225. data/test/roku_builder/test_scripter.rb +0 -102
  226. data/test/roku_builder/test_tester.rb +0 -130
@@ -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
@@ -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