94 lines
4.6 KiB
GDScript
94 lines
4.6 KiB
GDScript
# CORE FRAMEWORK SOURCE FILE
|
|
# Copyright (c) 2024 The StarOpenSource Project & Contributors
|
|
# Licensed under the GNU Affero General Public License v3
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Affero General Public License
|
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
## A easy download/request maker.
|
|
##
|
|
## Allows for awaited and/or batched requests.
|
|
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.diagf("Edl", "Generated new download id " + str(id))
|
|
return id
|
|
|
|
func awaited_request(url: String, method: HTTPClient.Method = HTTPClient.Method.METHOD_GET, headers: PackedStringArray = PackedStringArray([]), data: String = "") -> Dictionary:
|
|
logger.verbf("Edl", "Creating awaited request")
|
|
var id: int = create_download(url, method, headers, data)
|
|
start_download(id)
|
|
logger.diagf("Edl", "Waiting for request " + 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 oneline_awaited_request(url: String, return_utf8: bool = true, ignore_http_code: bool = false, method: HTTPClient.Method = HTTPClient.Method.METHOD_GET, headers: PackedStringArray = PackedStringArray([]), data: String = "") -> Variant:
|
|
var dldata: Dictionary = await awaited_request(url, method, headers, data)
|
|
if dldata["result"] != Error.OK: return null
|
|
elif !ignore_http_code and dldata["http_code"] != 200: return null
|
|
else:
|
|
if return_utf8: return dldata["body_utf8"]
|
|
else: return dldata["body"]
|
|
|
|
func batch_awaited_request(urls: PackedStringArray, method: HTTPClient.Method = HTTPClient.Method.METHOD_GET, headers: PackedStringArray = PackedStringArray([]), data: String = "") -> Array[Dictionary]:
|
|
logger.verbf("Edl", "Creating " + str(urls.size()) + " awaited request(s)")
|
|
var dldata: Array[Dictionary]= []
|
|
for url in urls:
|
|
var id: int = create_download(url, method, headers, data)
|
|
start_download(id)
|
|
logger.diagf("Edl", "Waiting for request " + str(id) + " to finish")
|
|
while !is_download_complete(id): await get_tree().create_timer(0.1, true).timeout
|
|
dldata.append(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.verbf("Edl", "Creating new request\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.verbf("Edl", "Starting request " + str(id))
|
|
list_active.merge({ id: list_queue[id] })
|
|
list_queue.erase(id)
|
|
logger.diagf("Edl", "Creating new HTTPRequest \"Request #" + str(id) + "\"")
|
|
var download: HTTPRequest = HTTPRequest.new()
|
|
download.name = "Request #" + 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.verbf("Edl", "Request " + 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.verbf("Edl", "Cleaning request queue")
|
|
list_queue.clear()
|
|
|
|
func clean_completed() -> void:
|
|
logger.verbf("Edl", "Cleaning completed requests")
|
|
list_complete.clear()
|