0 votes

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.

in Engine by (81 points)

1 Answer

+2 votes
Best answer

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.
https://github.com/vinod8990/godot_plugins/tree/master/OpenClipArt_Store

by (750 points)
selected by

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

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.