extends HTTPRequest var kinds = { "topo": "http://imbrium.mit.edu/DATA/SLDEM2015/TILES/FLOAT_IMG/%s", "color": "https://nextcloud.alfi.li/nextcloud/index.php/s/dMELm8P8sPxbC5f/download?path=%2F&files=%s" } var downloads = {} var downloading = false onready var UI = get_node("/root/Main/UI/Downloader") signal file_downloaded signal downloads_finished # signal stats_updated -> now via Messenger:statusUpdate signal downloads_started export(bool) var blind_mode : bool = false var _headers : Array = [] var _last_method : int var _ssl : bool = false var _file := File.new() var _timer : float = 0.0 var currentDownload : Download class Download: var _file_name : String var _file_size : float var _current_url : String var _kind : String var _downloaded_percent : float = 0 var _downloaded_size : float = 0 func _init() -> void: set_process(false) connect("request_completed", self, "_on_request_completed") func get_stats() -> Download: return currentDownload func _reset() -> void: currentDownload = Download.new() func _downloads_done() -> void: set_process(false) _update_stats() _file.close() emit_signal("downloads_finished", currentDownload) _reset() downloading = false UI.hide() func _update_stats() -> void: if blind_mode == false: _calculate_percentage() Messenger.emit_signal("statusUpdate",currentDownload) func _process(delta): if not downloading: if len(downloads) == 0: set_process(false) return for kind in downloads: for file in downloads[kind]: var dl = downloads[kind][file] currentDownload = dl _download() _timer += delta if _timer > 1: _update_stats() _timer = 0.0 func _download(): ensureFolder(currentDownload._kind) download_file = currentDownload._file_name _send_head_request() print("downloading %s" %currentDownload._current_url) downloading = true UI.show() func ensureFolder(kind): var dir = Directory.new() dir.open("user://") if not dir.dir_exists(kind): dir.make_dir(kind) func download(file, kind): set_process(true) if not kinds.has(kind): print("don't know kind %s"%kind) return if not downloads.has(kind): downloads[kind] = {} if downloads[kind].has(file): return var download = Download.new() download._file_name = "user://%s/%s"%[kind, file] download._current_url = make_filename(kind, file) download._kind = kind downloads[kind][download._file_name] = download func make_filename(kind, file): return kinds[kind]%file func _send_head_request() -> void: # The HEAD method only gets the head and not the body. Therefore, doesn't # download the file. request(currentDownload._current_url, _headers, _ssl, HTTPClient.METHOD_HEAD) _last_method = HTTPClient.METHOD_HEAD func _send_get_request() -> void: var error = request(currentDownload._current_url, _headers, _ssl, HTTPClient.METHOD_GET) if error == OK: emit_signal("downloads_started") _last_method = HTTPClient.METHOD_GET set_process(true) elif error == ERR_INVALID_PARAMETER: print("Given string isn't a valid url ") elif error == ERR_CANT_CONNECT: print("Can't connect to host") func _on_request_completed(p_result, _p_response_code, p_headers, _p_body) -> void: if p_result == RESULT_SUCCESS: if _p_response_code != 200: push_error("Download HTTP Error %s:%s" %[_p_response_code,_p_body]) return if _last_method == HTTPClient.METHOD_HEAD and blind_mode == false: var regex = "(?i)content-length: [0-9]*" var size = _extract_regex_from_header(regex, p_headers.join(' ')) size = size.replace("Content-Length: ", "") currentDownload._file_size = size.to_float() _send_get_request() elif _last_method == HTTPClient.METHOD_HEAD and blind_mode == true: _send_get_request() elif _last_method == HTTPClient.METHOD_GET: print("file download complete %s"%currentDownload._current_url) _file.close() emit_signal("file_downloaded", currentDownload) Messenger.emit_signal("fileDownloaded", currentDownload) downloading = false remove_download() elif p_result == RESULT_DOWNLOAD_FILE_CANT_OPEN: push_error("Download cannot open file %s" %currentDownload._file_name) else: print("HTTP Request error: ", p_result) func remove_download(): downloads[currentDownload._kind].erase(currentDownload._file_name) if len(downloads[currentDownload._kind]) == 0: downloads.erase(currentDownload._kind) if len(downloads) == 0: _downloads_done() func _calculate_percentage() -> void: var error : int error = _file.open(download_file, File.READ) if error == OK and currentDownload._file_size > 0: currentDownload._downloaded_size = _file.get_len() currentDownload._downloaded_percent = (currentDownload._downloaded_size / currentDownload._file_size) *100 func _extract_regex_from_header(p_regex : String, p_header : String) -> String: var regex = RegEx.new() regex.compile(p_regex) var result = regex.search(p_header) return result.get_string()