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.
The code is actually for progressbar2
library.
Its ProgressBar
class implements __iadd__
.