How to download a file from the internet using gdscript?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By earlroxas
:warning: Old Version Published before Godot 3 was released.

I want to download a file from internet using gdscript,
if possible it can track the progress of the download (percentage of the size of downloaded file), and also when it done downloading it will write the file to sdcard. And it all done in the background, so possibly using thread or something.

:bust_in_silhouette: Reply From: vinod

Check this
http://codetuto.com/2015/05/using-httpclient-in-godot/

extends Node
var t = Thread.new()
func _init():
 var arg_bytes_loaded = {"name":"bytes_loaded","type":TYPE_INT}
 var arg_bytes_total = {"name":"bytes_total","type":TYPE_INT}
 add_user_signal("loading",[arg_bytes_loaded,arg_bytes_total])
 var arg_result = {"name":"result","type":TYPE_RAW_ARRAY}
 add_user_signal("loaded",[arg_result])
 pass
func get(domain,url,port,ssl):
 if(t.is_active()):
  return
 t.start(self,"_load",{"domain":domain,"url":url,"port":port,"ssl":ssl})
 
func _load(params):
 var err = 0
 var http = HTTPClient.new()
 err = http.connect(params.domain,params.port,params.ssl)
 
 while(http.get_status() == HTTPClient.STATUS_CONNECTING or http.get_status() == HTTPClient.STATUS_RESOLVING):
  http.poll()
  OS.delay_msec(100)
  
 var headers = [
  "User-Agent: Pirulo/1.0 (Godot)",
  "Accept: */*"
 ]
 
 err = http.request(HTTPClient.METHOD_GET,params.url,headers)
 
 while (http.get_status() == HTTPClient.STATUS_REQUESTING):
  http.poll()
  OS.delay_msec(500)
# 
 var rb = RawArray()
 if(http.has_response()):
  var headers = http.get_response_headers_as_dictionary()
  while(http.get_status()==HTTPClient.STATUS_BODY):
   http.poll()
   var chunk = http.read_response_body_chunk()
   if(chunk.size()==0):
    OS.delay_usec(100)
   else:
    rb = rb+chunk
    call_deferred("_send_loading_signal",rb.size(),http.get_response_body_length())
  
 call_deferred("_send_loaded_signal")
 http.close()
 return rb
func _send_loading_signal(l,t):
 emit_signal("loading",l,t)
 pass
 
func _send_loaded_signal():
 var r = t.wait_to_finish()
 emit_signal("loaded",r)
 pass

Sample Usage

var http = preload('http.xml').instance()
http.connect("loading",self,"_on_loading")
http.connect("loaded",self,"_on_loaded")
http.get("http://example.com","/page?id=1",80,false) #domain,url,port,useSSL
func _on_loading(loaded,total):
    var percent = loaded*100/total
func _on_loaded(result):
    var result_string = result.get_string_from_ascii()
    print(result_string)

I did this on my openclipart plugin. You can check it to know how I implemented it here.

Wow, nice tutorial. It helps a lot. Thanks! :slight_smile:

earlroxas | 2016-11-14 02:21