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.


Log in to reply