From 4c92ed5d0a674776a72541016e9dac5e4c9b4b12 Mon Sep 17 00:00:00 2001 From: JeremyStarTM Date: Fri, 9 Feb 2024 22:27:21 +0100 Subject: [PATCH] Implement simple downloading module --- src/core.gd | 8 ++++++ src/edl.gd | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 src/edl.gd diff --git a/src/core.gd b/src/core.gd index 045a4c4..e99a679 100644 --- a/src/core.gd +++ b/src/core.gd @@ -34,6 +34,7 @@ var logger: CoreBaseModule var misc: CoreBaseModule var sms: CoreBaseModule var logui: CoreBaseModule +var edl: CoreBaseModule # Variables var basepath: String @@ -65,26 +66,31 @@ func initialize_modules() -> void: misc = CoreBaseModule.new() sms = CoreBaseModule.new() logui = CoreBaseModule.new() + edl = CoreBaseModule.new() # Set names logger.name = "Logger" misc.name = "Misc" sms.name = "SceneManagementSystem" logui.name = "LogUI" + edl.name = "EasyDownLoader" # Set scripts logger.set_script(ResourceLoader.load(basepath + "src/logger.gd")) misc.set_script(ResourceLoader.load(basepath + "src/misc.gd")) sms.set_script(ResourceLoader.load(basepath + "src/sms.gd")) logui.set_script(ResourceLoader.load(basepath + "src/logui.gd")) + edl.set_script(ResourceLoader.load(basepath + "src/edl.gd")) # Set reference to self logger.core = self misc.core = self sms.core = self logui.core = self + edl.core = self # Call _initialize() (workaround as modules cannot access "core" during _init()) logger._initialize() misc._initialize() sms._initialize() logui._initialize() + edl._initialize() # Inject modules into the SceneTree func inject_modules() -> void: @@ -92,6 +98,7 @@ func inject_modules() -> void: add_child(misc) add_child(sms) add_child(logui) + add_child(edl) # Registers a custom module func register_custom_module(module_name: String, module_class: CoreBaseModule) -> void: @@ -143,6 +150,7 @@ func apply_configuration() -> void: misc._pull_config() sms._pull_config() logui._pull_config() + edl._pull_config() for module in custom_modules: logger.diag("Updating configuration for custom module \"" + module.name + "\"") module._pull_config() diff --git a/src/edl.gd b/src/edl.gd new file mode 100644 index 0000000..831afbe --- /dev/null +++ b/src/edl.gd @@ -0,0 +1,78 @@ +############################################################################## +### CORE FRAMEWORK SOURCE FILE ### +### Copyright (c) 2024 The StarOpenSource Project & Contributors ### +### Licensed under the GNU General Public License v3 ### +### ### +### This program is free software: you can redistribute it and/or modify ### +### it under the terms of the GNU General Public License as published by ### +### the Free Software Foundation, either version 3 of the License, or ### +### (at your option) any later version. ### +### ### +### This program is distributed in the hope that it will be useful, ### +### but WITHOUT ANY WARRANTY; without even the implied warranty of ### +### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### +### GNU General Public License for more details. ### +### ### +### You should have received a copy of the GNU General Public License ### +### along with this program. If not, see . ### +############################################################################## +### src/edl.gd (Easy DownLoader) ### +### ### +### This source file allows for awaited and/or batched downloads. ### +############################################################################## +extends CoreBaseModule + +var list_queue: Dictionary = {} +var list_active: Dictionary = {} +var list_complete: Dictionary = {} + +func generate_id() -> int: + var id = randi() + if list_queue.has(id) or list_active.has(id): return generate_id() + logger.diag("Generated new download id " + str(id)) + return id + +func await_download(url: String, method: HTTPClient.Method = HTTPClient.Method.METHOD_GET, headers: PackedStringArray = PackedStringArray([]), data: String = "") -> Dictionary: + logger.verb("Creating awaited download") + logger.diag("Creating new download") + var id: int = create_download(url, method, headers, data) + logger.diag("Starting new download " + str(id)) + start_download(id) + logger.diag("Waiting for download " + str(id) + " to finish") + while !is_download_complete(id): await get_tree().create_timer(0.1, true).timeout + var dldata: Dictionary = list_complete[id] + list_complete.erase(id) + return dldata + +func create_download(url: String, method: HTTPClient.Method = HTTPClient.Method.METHOD_GET, headers: PackedStringArray = PackedStringArray([]), body: String = "") -> int: + logger.verb("Creating new download\n-> URL: " + url + "\n-> Method: " + str(method) + "\nHeaders:\n" + str(headers) + "\nBody:\n" + body) + var id = generate_id() + list_queue.merge({ id: { "url": url, "method": method, "headers": headers, "body": body } }) + return id + +func start_download(id) -> void: + logger.verb("Starting download " + str(id)) + list_active.merge({ id: list_queue[id] }) + list_queue.erase(id) + logger.diag("Creating new HTTPRequest \"Download #" + str(id) + "\"") + var download: HTTPRequest = HTTPRequest.new() + download.name = "Download #" + str(id) + download.accept_gzip = true + download.use_threads = true + var lambda: Callable = func(result: int, http_code: int, headers: PackedStringArray, body: PackedByteArray) -> void: + logger.verb("Download " + str(id) + " completed\nResult: " + str(result) + "\nHTTP response code: " + str(http_code) + "\nHeaders:\n" + str(headers) + "\nBody size: " + str(body.size()) + " Bytes // " + str(core.misc.byte2mib(body.size(), true)) + " MiB") + list_complete.merge({ id: { "result": result, "http_code": http_code, "headers": headers, "body": body, "body_utf8": body.get_string_from_utf8() } }) + list_active.erase(id) + download.connect("request_completed", lambda) + add_child(download) + download.request(list_active[id]["url"], list_active[id]["headers"], list_active[id]["method"], list_active[id]["body"]) + +func is_download_complete(id: int) -> bool: return list_complete.has(id) + +func clean_queue() -> void: + logger.verb("Cleaning download queue") + list_queue.clear() + +func clean_completed() -> void: + logger.verb("Cleaning completed downloads") + list_complete.clear()