Search code examples
python-3.xprogress-barstatusbarpysmb

progress bar in pysmb


To transfer a file via the SMB protocol I use the following code:

file_obj = open('file.txt', 'rb')
connection = SMBConnection(username = 'Admin',
                        password = 'Pa$$w0rd',
                        my_name = '',
                        remote_name = 'PC',
                        domain = 'WORKGROUP',
                        use_ntlm_v2=True)

connection.connect(ip='192.168.10.10')

connection.storeFile(service_name='Share',
                    path='file.txt',
                    file_obj=file_obj)

connection.close()

Everything works well, but there is one problem, I would like to monitor the file transfer process, if a large file is used, then the command line freezes for some time until the file is eaten.

I have a certain design with a progress bar tqdm for downloading files from the Internet.

chunk_size = 1024
        
total_size = int(r.headers['content-length'])
                
for chunk in tqdm(iterable=r.iter_content(chunk_size=chunk_size), 
total=total_size / chunk_size, unit=' KB', dynamic_ncols=True):
                            f.write(chunk)

But I can’t figure out how to connect this construction with my code.

I understand that the total_size variable for a file is not calculated this way and I use total_size = os.path.getsize('file.txt')

but still I can’t solve the problem to use this progressbar, the error concerns the iterable=r.iter_content(chunk_size=chunk_size) parameter in for chunk in tqdm I don’t know how to make a working option with r.

Could you tell me please, how can I make a working status bar. You can offer me any option for tracking the status of sending a file, you can use any status bar, for example alive_bar


Solution

  • You can create a class that wraps a given file object with a read method that updates a tqdm object through its update method:

    import os
    from tqdm import tqdm
    
    class TQDMFileReader:
        def __init__(self, file):
            self.file = file
            self.tqdm = tqdm(total=os.stat(file.fileno()).st_size, unit='bytes')
    
        def read(self, size):
            value = self.file.read(size)
            self.tqdm.update(len(value))
            return value
    

    so that you can call connection.storeFile with file_obj wrapped in a TQDMFileReader instance:

    connection.storeFile(service_name='Share',
                        path='file.txt',
                        file_obj=TQDMFileReader(file_obj))
    

    Demo: https://replit.com/@blhsing1/OverdueJoyousBooleanalgebra