Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Show progressbar for ftp upload in python

Tags:

python

ftp

So I'm writing a script that will search a folder recursively for a .mkv file and upload it to my NAS. I have the script working but I can't see the progress. I imported this progressbar I found on github and was able to use the demo to see it work. It is what I want however the FTP example they included is to retrieve a file from the server. I need to upload.

How do I get the uploaded amount on an interval so I can run an update to the progress bar?

Bellow is the code I have that works for the upload

import os
import ftplib
import ntpath

ntpath.basename("a/b/c")

def path_leaf(path):
head, tail = ntpath.split(path)
return tail or ntpath.basename(head)

from glob import glob
FileTransferList = [y for x in os.walk('/tmp/rippedMovies') for y in glob(os.path.join(x[0], '*.mkv'))]

global ftp

def FTP_GLOB_transfer(URL, UserName, Password):
    ftp = ftplib.FTP(URL, UserName, Password)   # connect to host, default port
    print URL, UserName, Password
    for file in FileTransferList:
        FileName = path_leaf(file)
        print file
        TheFile = open(file, 'r')
        ftp.storbinary('STOR ' + FileName, TheFile, 1024)
        TheFile.close()
    ftp.quit()
    ftp = None

FTP_GLOB_transfer('<IP>', '<USER>', '<PASSWORD>')
like image 748
MatthewEnderle Avatar asked Apr 06 '26 15:04

MatthewEnderle


1 Answers

I figured it out. I decided to use TQDM as I found some easier to read documentation for it. I was assuming that storbinary() had to have a return or something to tell it's progress, just didn't know I was looking for a callback.

Anyways I added a new import from tqdm import tqdm

I added this filesize = os.path.getsize(file) to get the file size of the file

Then I replaced ftp.storbinary('STOR ' + FileName, TheFile, 1024) with this code

with tqdm(unit = 'blocks', unit_scale = True, leave = False, miniters = 1, desc = 'Uploading......', total = filesize) as tqdm_instance:
        ftp.storbinary('STOR ' + FileName, TheFile, 2048, callback = lambda sent: tqdm_instance.update(len(sent)))

And overall the new working code looks like

import os
import ftplib
import ntpath
from tqdm import tqdm

ntpath.basename("a/b/c")

def path_leaf(path):
    head, tail = ntpath.split(path)
    return tail or ntpath.basename(head)

from glob import glob
FileTransferList = [y for x in os.walk('/tmp/rippedMovies') for y in glob(os.path.join(x[0], '*.mkv'))]

global ftp

def FTP_GLOB_transfer(URL, UserName, Password):
    ftp = ftplib.FTP(URL, UserName, Password)   # connect to host, default port
    print URL, UserName, Password
    for file in FileTransferList:
        FileName = path_leaf(file)
        filesize = os.path.getsize(file)
        print file
        TheFile = open(file, 'r')
        with tqdm(unit = 'blocks', unit_scale = True, leave = False, miniters = 1, desc = 'Uploading......', total = filesize) as tqdm_instance:
            ftp.storbinary('STOR ' + FileName, TheFile, 2048, callback = lambda sent: tqdm_instance.update(len(sent)))
        TheFile.close()
    ftp.quit()
    ftp = None

It now outputs as

/tmp/rippedMovies/TestMovie.mkv
Uploading......:  51%|████████████████████▉                    | 547M/1.07G 
[00:05<00:14, 36.8Mblocks/s]
like image 161
MatthewEnderle Avatar answered Apr 09 '26 03:04

MatthewEnderle



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!