Solved Create a download progress bar in python

Hi,
I found the following functions on a stackoverflow topic, and I want to apply it on c4d.gui.GeDialog.
I put more details in the code:

import urllib2

def chunk_report(bytes_so_far, chunk_size, total_size):
    percent = float(bytes_so_far) / total_size
    percent = round(percent*100, 2)

    sys.stdout.write("Downloaded %d of %d bytes (%0.2f%%)\r" % 
        (bytes_so_far, total_size, percent))

    if bytes_so_far >= total_size:
        sys.stdout.write('\n')

def chunk_read(response, chunk_size=8192, report_hook=None):
   total_size = response.info().getheader('Content-Length').strip()
   total_size = int(total_size)
   bytes_so_far = 0

   while 1:
      chunk = response.read(chunk_size)
      bytes_so_far += len(chunk)

      if not chunk:
         break

      if report_hook:
        report_hook(bytes_so_far, chunk_size, total_size)

   return bytes_so_far

class Update(c4d.gui.GeDialog):
    UPDATE_BTN = 1000
    PROGRESS = 1001
    PROGRESSBAR = 1002
    state = ""

    def CreateLayout(self) :
        self.AddButton(self.UPDATE_BTN, flags = c4d.BFH_LEFT, inith = 13, name = "Update")
        self.AddStaticText(self.PROGRESS, flags=c4d.BFH_SCALEFIT, initw=0, inith=0, name=self.state, borderstyle=0)

        # I want take the percentage value from the function chunk_report() and apply it to the following CUSTOMGUI_PROGRESSBARCUSTOMGUI_PROGRESSBAR
        self.GroupBegin(id=0, flags=c4d.BFH_LEFT, cols=1, rows=0)
        self.GroupBorderNoTitle(c4d.BORDER_THIN_IN)
        self.AddCustomGui(self.PROGRESSBAR, c4d.CUSTOMGUI_PROGRESSBAR, "", c4d.BFH_SCALEFIT|c4d.BFV_SCALEFIT,200, 8)        
        self.GroupEnd()

    def Command(self, id, msg):

        if id == self.UPDATE_BTN :
            filedata = urllib2.urlopen('https://www.domainname.com/file.zip')
            chunk_read(filedata, report_hook= chunk_report)

            self.SetString(self.PROGRESS, "Or showing the write result of chunk_report() function here?") # <---

Thanks

Hi,
I found the solution.

import urllib2

class Update(c4d.gui.GeDialog):
    UPDATE_BTN = 1000
    PROGRESS = 1001
    PROGRESSBAR = 1002
    state = ""

    def CreateLayout(self) :
        self.AddButton(self.UPDATE_BTN, flags = c4d.BFH_LEFT, inith = 13, name = "Update")
        self.AddStaticText(self.PROGRESS, flags=c4d.BFH_SCALEFIT, initw=0, inith=0, name=self.state, borderstyle=0)

        # How to taking the percentage value from the function chunk_report() and apply it to the following CUSTOMGUI_PROGRESSBAR
        self.GroupBegin(id=0, flags=c4d.BFH_LEFT, cols=1, rows=0)
        self.GroupBorderNoTitle(c4d.BORDER_THIN_IN)
        self.AddCustomGui(self.PROGRESSBAR, c4d.CUSTOMGUI_PROGRESSBAR, "", c4d.BFH_SCALEFIT|c4d.BFV_SCALEFIT,200, 8)        
        self.GroupEnd()

    def chunk_read(self, response, chunk_size=8192):
        total_size = response.info().getheader('Content-Length').strip()
        total_size = int(total_size)
        bytes_so_far = 0
        
        progressMsg = c4d.BaseContainer(c4d.BFM_SETSTATUSBAR)
        progressMsg[c4d.BFM_STATUSBAR_PROGRESSON] = True

        while 1:
            chunk = response.read(chunk_size)
            bytes_so_far += len(chunk)

            if not chunk:
                break

            percent = float(bytes_so_far) / total_size
            percent = round(percent*100, 2)

            progressMsg[c4d.BFM_STATUSBAR_PROGRESS] = percent/100
            self.SendMessage(self.PROGRESSBAR, progressMsg)
            self.SetString(self.PROGRESS, percent)

    def Command(self, id, msg):

        if id == self.UPDATE_BTN :
            filedata = urllib2.urlopen('https://www.domainname.com/file.zip')
            self.chunk_read(filedata)

Hi,
I found the solution.

import urllib2

class Update(c4d.gui.GeDialog):
    UPDATE_BTN = 1000
    PROGRESS = 1001
    PROGRESSBAR = 1002
    state = ""

    def CreateLayout(self) :
        self.AddButton(self.UPDATE_BTN, flags = c4d.BFH_LEFT, inith = 13, name = "Update")
        self.AddStaticText(self.PROGRESS, flags=c4d.BFH_SCALEFIT, initw=0, inith=0, name=self.state, borderstyle=0)

        # How to taking the percentage value from the function chunk_report() and apply it to the following CUSTOMGUI_PROGRESSBAR
        self.GroupBegin(id=0, flags=c4d.BFH_LEFT, cols=1, rows=0)
        self.GroupBorderNoTitle(c4d.BORDER_THIN_IN)
        self.AddCustomGui(self.PROGRESSBAR, c4d.CUSTOMGUI_PROGRESSBAR, "", c4d.BFH_SCALEFIT|c4d.BFV_SCALEFIT,200, 8)        
        self.GroupEnd()

    def chunk_read(self, response, chunk_size=8192):
        total_size = response.info().getheader('Content-Length').strip()
        total_size = int(total_size)
        bytes_so_far = 0
        
        progressMsg = c4d.BaseContainer(c4d.BFM_SETSTATUSBAR)
        progressMsg[c4d.BFM_STATUSBAR_PROGRESSON] = True

        while 1:
            chunk = response.read(chunk_size)
            bytes_so_far += len(chunk)

            if not chunk:
                break

            percent = float(bytes_so_far) / total_size
            percent = round(percent*100, 2)

            progressMsg[c4d.BFM_STATUSBAR_PROGRESS] = percent/100
            self.SendMessage(self.PROGRESSBAR, progressMsg)
            self.SetString(self.PROGRESS, percent)

    def Command(self, id, msg):

        if id == self.UPDATE_BTN :
            filedata = urllib2.urlopen('https://www.domainname.com/file.zip')
            self.chunk_read(filedata)

tx, but how can i use this in a simple scenario?
it doesnt do anything when pasted into the script manager

@indexofrefraction

Hi,
Here is a full example that you can test it on script manager:

# The following code allow to download a file and then save it on the desktop 
import c4d, os, math, urllib2
from c4d import gui

PLUGIN_ID = 99999999
            
class MyDialog(gui.GeDialog): 
    DOWNLOAD = 2000
    CLOSE = 2001
    STATE_GROUP = 2002
    PROGRESSBAR_GROUP = 2003
    PROGRESSBAR = 2004
    PROGRESS_TEXT = 2005

    def InitValues(self):
        self.HideElement(self.PROGRESSBAR_GROUP, True)
        self.LayoutChanged(self.STATE_GROUP)

        return True

    def StopProgress(self):
        progressMsg = c4d.BaseContainer(c4d.BFM_SETSTATUSBAR)
        progressMsg.SetBool(c4d.BFM_STATUSBAR_PROGRESSON, False)
        self.SendMessage(self.PROGRESSBAR, progressMsg)

    def CreateLayout(self):
                  
        self.GroupBegin(0, flags=c4d.BFH_SCALEFIT, rows=1, cols=1)
        self.SetTitle("File Downloader")    
 
        self.GroupBegin(0, c4d.BFH_SCALEFIT, cols=3)
        self.GroupBorderSpace(0, 5, 2, 5)
        
        self.AddButton(self.DOWNLOAD, flags = c4d.BFH_LEFT, inith = 13, name = "Download")  
        self.AddButton(self.CLOSE, flags = c4d.BFH_RIGHT, inith = 13, name = "Close")
        
        self.GroupEnd()

        if self.GroupBegin(id=self.STATE_GROUP, flags=c4d.BFH_SCALEFIT, rows=0, title="", cols=2, groupflags=0):

            self.GroupBegin(self.PROGRESSBAR_GROUP, c4d.BFH_LEFT, cols=2)
            self.GroupBegin(id=0, flags=c4d.BFH_LEFT, cols=1, rows=0)
            self.GroupBorderNoTitle(c4d.BORDER_THIN_IN)
            self.AddCustomGui(self.PROGRESSBAR, c4d.CUSTOMGUI_PROGRESSBAR, "", c4d.BFH_SCALEFIT|c4d.BFV_SCALEFIT,200, 8)        
            self.GroupEnd()
            self.GroupEnd()

            self.GroupBegin(id=0, flags=c4d.BFH_SCALEFIT, cols=1, rows=0)
            self.GroupBorderSpace(8,2,0,0) 
            self.AddStaticText(self.PROGRESS_TEXT, flags=c4d.BFH_SCALEFIT, initw=0, inith=16, name="", borderstyle=0)
            self.GroupEnd()
            self.GroupEnd()

            self.GroupEnd()

        self.GroupEnd()
        return True

    def convert_size(self, size_bytes):
        if size_bytes == 0:
           return "0B"
        size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")
        i = int(math.floor(math.log(size_bytes, 1024)))
        p = math.pow(1024, i)
        s = round(size_bytes / p, 2)
        return "%s %s" % (s, size_name[i])

    def chunk_read(self, response, chunk_size=8192):
        total_size = response.info().getheader('Content-Length').strip()
        total_size = int(total_size)
        bytes_so_far = 0
        
        progressMsg = c4d.BaseContainer(c4d.BFM_SETSTATUSBAR)
        progressMsg[c4d.BFM_STATUSBAR_PROGRESSON] = True

        data = b""

        while 1:
            chunk = response.read(chunk_size)
            bytes_so_far += len(chunk)

            if not chunk:
                break

            percent = float(bytes_so_far) / total_size
            percent = round(percent*100, 2)

            
            progressMsg[c4d.BFM_STATUSBAR_PROGRESS] = percent/100
            self.SendMessage(self.PROGRESSBAR, progressMsg)

            self.SetString(self.PROGRESS_TEXT, "Downloaded %s of %s bytes (%0.2f%%)\r" % (self.convert_size(bytes_so_far), self.convert_size(total_size), percent))
            data += chunk

        return data
    
    def Command(self, id, msg):

        if id == self.DOWNLOAD:
            self.HideElement(self.PROGRESSBAR_GROUP, False)
            self.LayoutChanged(self.STATE_GROUP)
            
            # path to save downloaded file on desktop
            write_path = os.path.join(c4d.storage.GeGetC4DPath(c4d.C4D_PATH_DESKTOP), 'zip_9MB.zip')
            response = urllib2.urlopen('https://file-examples.com/wp-content/uploads/2017/02/zip_9MB.zip')

            datatowrite = self.chunk_read(response)

            with open(write_path, 'wb') as f:
                f.write(datatowrite)
            
            self.HideElement(self.PROGRESSBAR_GROUP, True)
            self.LayoutChanged(self.STATE_GROUP)

            self.SetString(self.PROGRESS_TEXT, "")

            self.StopProgress()

        if id == self.CLOSE:
            self.Close() 

        return True

def main():
    
    Dlg = MyDialog()
    Dlg.Open(dlgtype=c4d.DLG_TYPE_MODAL, pluginid=PLUGIN_ID, defaultw=500, defaulth=120)

if __name__=='__main__':
    main()

@indexofrefraction and just in case you have this example from CUSTOMGUI_PROGRESSBAR if you want a more minimal script.

Cheers,
Maxime.