From b99938ae3ca17601a6d690b7b175ab0508679334 Mon Sep 17 00:00:00 2001 From: Cyberarm Date: Tue, 16 Nov 2021 14:29:11 -0600 Subject: [PATCH] Downloading packages now works most of the time, primary download indictator is now driven by the Task --- lib/api.rb | 4 +- lib/application_manager/task.rb | 52 ++++++++++++++++++++-- lib/application_manager/tasks/installer.rb | 15 +++++++ lib/cache.rb | 3 +- lib/pages/download_manager.rb | 38 +++------------- lib/pages/games.rb | 2 +- lib/states/interface.rb | 28 ++++++++++-- lib/window.rb | 10 +++++ 8 files changed, 109 insertions(+), 43 deletions(-) diff --git a/lib/api.rb b/lib/api.rb index 08b14ab..182cfbd 100644 --- a/lib/api.rb +++ b/lib/api.rb @@ -144,8 +144,8 @@ class W3DHub # /apis/launcher/1/get-package-details # client requests package details: data={"packages":[{"category":"games","name":"apb.ico","subcategory":"apb","version":""}]} def self.package_details(packages) - response = W3DHUB_API_CONNECTION.post( - path: "apis/launcher/1/get-package-details", + response = Excon.post( + "#{ENDPOINT}/apis/launcher/1/get-package-details", headers: DEFAULT_HEADERS.merge({"Content-Type": "application/x-www-form-urlencoded"}), body: "data=#{JSON.dump({ packages: packages })}" ) diff --git a/lib/application_manager/task.rb b/lib/application_manager/task.rb index c6ad80e..7b652ad 100644 --- a/lib/application_manager/task.rb +++ b/lib/application_manager/task.rb @@ -77,6 +77,27 @@ class W3DHub window.main_thread_queue << block end + def update_application_taskbar(message, status, progress) + run_on_main_thread( + proc do + window.current_state.show_application_taskbar + window.current_state.update_application_taskbar(message, status, progress) + end + ) + end + + def hide_application_taskbar + run_on_main_thread( + proc do + window.current_state.hide_application_taskbar + end + ) + end + + ############### + # Tasks/Steps # + ############### + def fetch_manifests manifests = [] @@ -135,9 +156,26 @@ class W3DHub package_details = Api.package_details(hashes) if package_details + download_queue = [] + package_details.each do |pkg| unless verify_package(pkg, pkg.category, pkg.subcategory, pkg.name, pkg.version) - package_fetch(pkg.category, pkg.subcategory, pkg.name, pkg.version) + download_queue << pkg + end + end + + total_bytes_to_download = download_queue.sum { |pkg| pkg.size } + bytes_downloaded = 0 + + download_queue.each do |pkg| + package_fetch(pkg.category, pkg.subcategory, pkg.name, pkg.version) do |chunk, remaining_bytes, total_bytes| + bytes_downloaded += chunk.to_s.length + + update_application_taskbar( + "Downloading #{@application.name}...", + "#{W3DHub.format_size(bytes_downloaded)} / #{W3DHub.format_size(total_bytes_to_download)}", + bytes_downloaded.to_f / total_bytes_to_download + ) end end else @@ -163,7 +201,11 @@ class W3DHub puts "#{@app_id} has been installed." end - def fetch_manifest(category, subcategory, name, version) + ############# + # Functions # + ############# + + def fetch_manifest(category, subcategory, name, version, &block) # Check for and integrity of local manifest if File.exist?(Cache.package_path(category, subcategory, name, version)) package = Api.package_details([{ category: category, subcategory: subcategory, name: name, version: version }]) @@ -178,16 +220,18 @@ class W3DHub end end - def package_fetch(category, subcategory, name, version) + def package_fetch(category, subcategory, name, version, &block) puts "Downloading: #{category}:#{subcategory}:#{name}-#{version}" Api.package(category, subcategory, name, version) do |chunk, remaining_bytes, total_bytes| # Store progress somewhere # Kernel.puts "#{name}-#{version}: #{(remaining_bytes.to_f / total_bytes).round}%" + + block&.call(chunk, remaining_bytes, total_bytes) end end - def verify_package(package, category, subcategory, name, version) + def verify_package(package, category, subcategory, name, version, &block) puts "Verifying: #{category}:#{subcategory}:#{name}-#{version}" digest = Digest::SHA256.new diff --git a/lib/application_manager/tasks/installer.rb b/lib/application_manager/tasks/installer.rb index 11774f1..1a013aa 100644 --- a/lib/application_manager/tasks/installer.rb +++ b/lib/application_manager/tasks/installer.rb @@ -2,30 +2,45 @@ class W3DHub class ApplicationManager class Installer < Task def execute_task + update_application_taskbar("Downloading #{@application.name}...", "Fetching manifests...", 0.0) manifests = fetch_manifests return false if failed? + # update_application_taskbar("Downloading #{@application.name}...", "Building package list...", 0.0) packages = build_package_list(manifests) return false if failed? + # update_application_taskbar("Downloading #{@application.name}...", "Downloading packages...", 0.0) fetch_packages(packages) return false if failed? + update_application_taskbar("Downloading #{@application.name}...", "Verifying packages...", 0.0) verify_packages(packages) return false if failed? + update_application_taskbar("Installing #{@application.name}...", "Unpacking...", 0.0) unpack_packages(packages) return false if failed? + sleep 1 + update_application_taskbar("Installing #{@application.name}...", "Creating wine prefix...", 0.0) create_wine_prefix return false if failed? + sleep 1 + + update_application_taskbar("Installing #{@application.name}...", "Installing dependencies...", 0.0) install_dependencies(packages) return false if failed? + sleep 1 mark_application_installed return false if failed? + update_application_taskbar("Installed #{@application.name}", "", 1.0) + sleep 5 + hide_application_taskbar + true end end diff --git a/lib/cache.rb b/lib/cache.rb index d67d1f4..cb7c9b7 100644 --- a/lib/cache.rb +++ b/lib/cache.rb @@ -57,8 +57,9 @@ class W3DHub # Create a new connection due to some weirdness somewhere in Excon response = Excon.post( "#{Api::ENDPOINT}/apis/launcher/1/get-package", - headers: Api::DEFAULT_HEADERS.merge({"Content-Type": "application/x-www-form-urlencoded"}), + headers: Api::DEFAULT_HEADERS.merge({ "Content-Type": "application/x-www-form-urlencoded" }), body: "data=#{JSON.dump({ category: category, subcategory: subcategory, name: name, version: version })}", + chunk_size: 4_000_000, response_block: streamer ) diff --git a/lib/pages/download_manager.rb b/lib/pages/download_manager.rb index 61cd875..cc29c6e 100644 --- a/lib/pages/download_manager.rb +++ b/lib/pages/download_manager.rb @@ -27,42 +27,18 @@ class W3DHub end end - # UPDATES - stack(width: 1.0, height: 0.1) do - background 0x44_000000 - inscription "Something something updates...", width: 1.0, text_align: :center, margin_top: 18 - end - - # Available to download - stack(width: 1.0, height: 0.8, padding: 8, scroll: true) do + # Operations + stack(width: 1.0, height: 0.9, padding: 8, scroll: true) do window.applications.games.reject { |g| g.id == "ren" }.each_with_index do |game, i| - flow(width: 1.0, height: 64, padding: 8) do + stack(width: 1.0, height: 24, padding: 8) do background 0xff_333333 if i.odd? - flow(width: 0.7, height: 1.0) do - image "#{GAME_ROOT_PATH}/media/icons/#{game.id}.png", width: 0.1, margin_right: 8 - - stack(width: 0.9, height: 1.0) do - title game.name - inscription "This is a brief description of the game", width: 1.0 - end + flow(width: 1.0, height: 22) do + inscription game.name, width: 0.7, text_wrap: :none + inscription "Pending...", width: 0.3, text_align: :right, text_wrap: :none end - flow(width: 0.3, height: 1.0) do - version_selector = list_box items: game.channels.map { |c| c.name }, width: 0.499, enabled: game.channels.count > 1 - version_selector.subscribe(:changed) do |item| - p item.value - end - - button "Install", width: 0.5 do - # Download/verify game-channel manifest - # Download broken/missing files - # Unpack - # Configure - # Disable install - # Enable Uninstall - end - end + progress fraction: rand(0.25..0.8), height: 2, width: 1.0 end end end diff --git a/lib/pages/games.rb b/lib/pages/games.rb index c02c16c..ac10c99 100644 --- a/lib/pages/games.rb +++ b/lib/pages/games.rb @@ -141,7 +141,7 @@ class W3DHub end end - button "Import", margin_left: 24 do + button "Import", margin_left: 24, enabled: false do window.application_manager.import(game.id, channel.name, "?") end end diff --git a/lib/states/interface.rb b/lib/states/interface.rb index 84165ee..555693a 100644 --- a/lib/states/interface.rb +++ b/lib/states/interface.rb @@ -65,6 +65,10 @@ class W3DHub width: 18, image_width: 18, checkmark_image: "#{GAME_ROOT_PATH}/media/ui_icons/checkmark.png" + }, + Progress: { + fraction_background: 0xff_00acff, + border_thickness: 0 } }) @@ -111,13 +115,13 @@ class W3DHub end end - stack(width: 0.77, height: 1.0, margin_left: 16) do + @application_taskbar_container = stack(width: 0.77, height: 1.0, margin_left: 16) do flow(width: 1.0, height: 0.65) do - inscription "Downloading Expansive Civilian Warfare...", width: 0.7, text_wrap: :none - inscription "460.2 MB / 254.5 GB", width: 0.3, text_align: :right, text_wrap: :none + @application_taskbar_label = inscription "Downloading Expansive Civilian Warfare...", width: 0.65, text_wrap: :none + @application_taskbar_status_label = inscription "460.2 MB / 254.5 GB", width: 0.35, text_align: :right, text_wrap: :none end - progress fraction: 0.4, height: 2, width: 1.0, fraction_background: 0xff_00acff, border_thickness: 0 + @application_taskbar_progressbar = progress fraction: 0.4, height: 2, width: 1.0 end end end @@ -172,6 +176,8 @@ class W3DHub else page(W3DHub::Pages::Games) end + + hide_application_taskbar end def draw @@ -220,6 +226,20 @@ class W3DHub @page.setup @page.focus end + + def show_application_taskbar + @application_taskbar_container.show + end + + def hide_application_taskbar + @application_taskbar_container.hide + end + + def update_application_taskbar(message, status, progress) + @application_taskbar_label.value = message + @application_taskbar_status_label.value = status + @application_taskbar_progressbar.value = progress.clamp(0.0, 1.0) + end end end end diff --git a/lib/window.rb b/lib/window.rb index b45f707..0fa8df6 100644 --- a/lib/window.rb +++ b/lib/window.rb @@ -19,5 +19,15 @@ class W3DHub super if @application_manager.idle? end + + def main_thread_queue + if current_state.is_a?(W3DHub::States::Interface) + current_state.main_thread_queue + else + warn "Task will not be run for:" + warn caller + [] + end + end end end \ No newline at end of file