0

I'm using this function (based on this awnser) to compress a folder to an encrypted .zip file using 7zip in a subprocess:

def zipbkp(directoryToZip):

    zipFileName = directoryToZip+".zip"
    password = "minmin3"

    appPath = "C:\Program Files\\7-Zip"
    zApp    = "7z.exe"
    zAction = 'a'
    zPass   = '-p{0} -mhe'.format(password)
    zAnswer = '-y'
    zDir    = directoryToZip
    progDir = os.path.join(appPath,zApp)

    print("[*] Trying to create .zip File, please wait...")
    cmd = [zApp, zAction, zipFileName, zPass, zAnswer, zDir]
    zipper = subprocess.Popen(cmd, executable=progDir, stderr=subprocess.STDOUT, stdout=subprocess.PIPE)

    #Lacking Progressbar here

    zipper.wait()
    print("[*] Successfully created .zip File")
    return zipFileName

This works fine as is. My only problem is since the directory to zip is pretty huge i want to give information about the compression progress.

I've installed and used tqdm succesfully before to display a progressbar but can't get it to work with this 7zip subprocess.

For reference, this is how i used tqdm on a ftp upload script:

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

tqdm even provides an example on how to use pipes but i don't really understand it. The example also is using grep which isn't available on Windows.

example

I also found this example which is even worse to understand.

Any idea how to get and parse the information provided by 7zip using tqdm?

Lyux
  • 453
  • 1
  • 10
  • 22

1 Answers1

1

To use the tqdm progress bar you can simply instantiate the progress bar with the parameter total, as done here, then call update (as done here) passing the increment on the bar. You can also specify that the total is in bytes and you want to show it with unit='B' and unit_scale=True

This with 7zip can be done in three steps:

  1. By invoking 7z l {zip file name} you can get the size of the files and their names, so the script can invoke the command and parse the output. The recommended way with recent Python versions is through the subprocess module.

  2. Instantiate the tqdm object with the total final size of the uncompressed files

  3. Using subprocess.Popen you can invoke ['7z', 'x', '-bd', filename] (-bd avoid builtin progress reporting) , and pass stdout=subprocess.PIPE to be able to read the standard output of the process using process.stdout.readline() where process is the value returned by Popen, and parse the output to get the current status. When a file is decompressed it reports its name and so you can call tqdm.update with the relative size retrieved at step 1.

Jacopofar
  • 3,407
  • 2
  • 19
  • 29