0

I have currently this:

def download_dropbox(url, pre_file_name):
    file = url[42:]
    file = file[:-5]
    file_name = pre_file_name + file
    print('Downloading from ' + url + ' to ' + file_name)
    print(file)
    u = urllib.request.urlopen(url)
    data = u.read()
    u.close()

    with open(file_name, "wb") as f:
        f.write(data)
    print('Download Completed from ' + url + ' and saved to ' + file_name)

This basically downloads files from dropbox and saves it to a directory. However I want to be able to have some sort of text progress bar like:


[==== ]50%


OR


50%

The hard part i would think is doing it with any external modules like the loading bar module, etc. Also, as the title states, I need it in python 3. Thank-you.

Edit:

Thanks to Martin Evans for the data read while loop and progress bar here is the end result of the code:

#Get the total number of bytes of the file to download before downloading
print ("opening url:", url)
u = urllib.request.urlopen(url)
meta = u.info()
print(str(meta).split())
metaInfo = str(meta).split()
print(len(metaInfo))
print ("Content-Length:" + metaInfo[46] + " bytes")
fileTotalbytes=int(metaInfo[46])

data_blocks = []
# total = int(metaInfo[46])
total=0

while True:
    block = u.read(1024)
    data_blocks.append(block)
    total += len(block)
    hash = ((60*total)//fileTotalbytes)
    print("[{}{}] {}%".format('#' * hash, ' ' * (60-hash), int(total/fileTotalbytes*100)), end="\r")

    if not len(block):
        break

data=b''.join(data_blocks) #had to add b because I was joining bytes not strings
u.close()

with open('test.zip', "wb") as f:
        f.write(data)
RoomofR
  • 5
  • 3

2 Answers2

0

You can use print with \r at the start to go to the start of the line and write over the previous text (so you need to write spaces if you want to clear a character). Here's a simple example:

from time import sleep
x = 0
while x < 20:
    print('\r' + '.' * x, end="")
    x += 1
    sleep(0.1)
multivac
  • 146
  • 5
  • Thank you for a loading bar, but how do you use that to work with the actual progress of the downloading. Because so far I a screen that doesn't move telling the user that the file is downloading. I want it to show the progress of the download it self. – RoomofR Aug 30 '15 at 14:58
0

To answer your main question, how to make a text progress bar, you could use something like the following to give you an idea:

import time

for n in range(1,101):
    hash = ((60*n)//100)
    print("[{}{}] {}%".format('#' * hash, ' ' * (60-hash), n), end="\r")
    time.sleep(0.05)

This would give you the following:

[###########################                                 ] 45%

Your main problem though is that there is no obvious way to determine how many bytes will eventually be downloaded unless you already know the exact size of the item being downloaded beforehand. If you control the server end then you could arrange for the length to be obtained before starting.

You can though start by at least converting your read() line to something like the following:

u = urllib.request.urlopen(url)

data_blocks = []
total = 0

while True:
    block = fd.read(1024)
    data_blocks.append(block)
    total += len(block)
    print("Downloaded {} bytes".format(total), end="\r")

    if not len(block):
        break

data = "".join(data_blocks)
u.close()

By doing it this way, you read it a bit at a time and can then provide feedback.

Martin Evans
  • 45,791
  • 17
  • 81
  • 97
  • Thank-you this was what I was looking for. I had to make some adjustments such as fd.read(1024) changed to u.read(1024). And also the join(data_blocks) is used for joining of string. For bytes I had to use b''.join(data_blocks). Also I figured out a way to get the bytes of the file before downloading the file using info() from the urllib module. I made the final version of my code with the addition from your and it works flawlessly. Once again, thank you for your help. – RoomofR Aug 31 '15 at 17:31