2

I'm trying to use progressbar to display the FTP file download progress (ftplib) but the progress does not update correctly. The speed starts out high then gradually decreases (down to bytes). The download ends up completing after a few seconds while the progress bar is still at 0%. It appears I am not updating the progress correctly and am not sure how to correct this.

I tried the solution I found here Show FTP download progress in Python (ProgressBar) using pbar += len(data) but this gave me the following error:

Traceback (most recent call last):                                                             ] ETA:  --:--:--   0.00  B/s
  File "ftp.py", line 38, in <module>
    ftp.retrbinary('RETR ' + file, file_write)
  File "/usr/lib/python3.5/ftplib.py", line 446, in retrbinary
    callback(data)
  File "ftp.py", line 29, in file_write
    pbar += len(data)
TypeError: unsupported operand type(s) for +=: 'ProgressBar' and 'int'

So I tweaked it by adding pbar.update(len(data)) to my file_write() function and got it working without the error, but as I said the speed is totally incorrect, keeps dropping (till it hits 0 probably) and then just suddenly completes.

Here is my entire script:

from ftplib import FTP_TLS
import time

from progressbar import AnimatedMarker, Bar, BouncingBar, Counter, ETA, \
    AdaptiveETA, FileTransferSpeed, FormatLabel, Percentage, \
    ProgressBar, ReverseBar, RotatingMarker, \
    SimpleProgress, Timer, UnknownLength

ftp_host = 'domain.com'
ftp_port = 21
ftp_user = 'user'
ftp_pass = 'pass'

ftp = FTP_TLS()

ftp.connect(ftp_host, ftp_port)
ftp.login(ftp_user, ftp_pass)
ftp.cwd('/videos')

files = ftp.nlst()

widgets = ['Downloading: ', Percentage(), ' ', Bar(marker='#', \
            left='[',right=']'), ' ', ETA(), ' ', FileTransferSpeed()]

def file_write(data):
    localfile.write(data)
    global pbar
    pbar.update(len(data))
    #pbar += len(data)

for file in files:
    size = ftp.size(file)
    pbar = ProgressBar(widgets = widgets, maxval = size)
    pbar.start()

    localfile = open('/local/videos/' + file, 'wb')

    ftp.retrbinary('RETR ' + file, file_write)

    pbar.finish() 
    localfile.close()

ftp.quit()

Any help would be much appreciated to get this code working like it should.

UPDATE:

I made the following additions/changes and got the right speed/progress bar movement:

i = 0
def file_write(data):
    localfile.write(data)
    global pbar, i
    pbar.update(i * 1024 * 10)
    i+=1
    #pbar += len(data)

but just as it is about to finish I get this error:

Traceback (most recent call last):################################################## ] ETA:  0:00:00  45.62 MB/s
  File "ftp.py", line 42, in <module>
    ftp.retrbinary('RETR ' + file, file_write)
  File "/usr/lib/python3.5/ftplib.py", line 446, in retrbinary
    callback(data)
  File "ftp.py", line 30, in file_write
    pbar.update(o * 1024 * 10)
  File "/usr/local/lib/python3.5/dist-packages/progressbar/progressbar.py", line 250, in update
    raise ValueError('Value out of range')
ValueError: Value out of range

I'm using progressbar 2.5 (latest) and Python 3.5.

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
enzobruno
  • 115
  • 1
  • 8
  • Works just fine for me with `pbar += len(data)` -- The error with unsupported operand is for `x = pbar + len(data)` -- probably some test of yours, which has nothing to do with the actual code you have posted. --- I do not see what's the point of your `pbar.update(i * 1024 * 10)` --- It's obvious why you get `ValueError` for that code. But the code (the numbers) is totally arbitrary. It can randomly work for your particular download speed, but in general it cannot show correct values. – Martin Prikryl Apr 11 '19 at 05:36
  • I copied the wrong error, but when I use `pbar += len(data)` I get `TypeError: unsupported operand type(s) for +=: 'ProgressBar' and 'int'` I'm using progressbar 2.5 (latest) and Python 3.5 – enzobruno Apr 11 '19 at 19:55

1 Answers1

0

The code is actually for progressbar2 library.

Its ProgressBar class implements __iadd__.

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
  • Thank you!! Once progressbar replaced with progressbar2 everything worked as intended. The old progressbar ought to be removed from python as it seems unmaintained and lacks documentation. – enzobruno Apr 14 '19 at 02:29