0
votes

I'm trying (and failing) to create a Python function that essentially zips up some text, then zips the archive up again and again (the number based on a parameter).

So we'd end up with file1.zip containing file2.zip which in turn contains file3.zip. i.e (file1.zip(file2.zip(file3.zip))). Hope that's articulated well enough.

import io
import zipfile
import gzip

hexdata = "5a69702054657374"


def zip_it(filename, depth):
    zip_buffer = io.BytesIO()

    for i in range(0, depth):
        with zipfile.ZipFile(zip_buffer, "a", zipfile.ZIP_DEFLATED, False) as zip_file:
            zip_file.writestr(filename + str(i), bytes.fromhex(hexdata).decode("utf-8"))

    with open(filename + ".zip", "wb") as f:
        f.write(zip_buffer.getvalue())


if __name__ == '__main__':
    zip_it("testfile", 3)

The above code is what I have so far, it's not quite right, it creates 1 compressed file with the 3files all at the same level and not within each other. I figure this is a recursive problem.

Also i'd probably want to do the same with gzip, rar etc - just saying in case if effects any help i get.

Thanks

1

1 Answers

0
votes

I think you're right that this is a recursive task.

For this I'd separate the code for creating a zip file with data from the code which only writes a zipfile of a (-nother zip-) file.
Furthermore, the code for actually writing a real file to disk, not only BytesIO-objects, should be even outside of the function, because as a recursive function it is completely part of the loop.

import io
import zipfile

hexdata = "5a69702054657374"


def zip_it(filename, depth):

    zip_buffer = io.BytesIO()

    with zipfile.ZipFile(zip_buffer, "a", zipfile.ZIP_DEFLATED, False) as zip_file:
        if depth > 0:
            content = zip_it(filename, depth - 1)
            fname = 'testZipFile'
            depth = str(depth)
            ext = '.zip'
        else:
            content = bytes.fromhex(hexdata).decode("utf-8")
            fname = 'myTextfile'
            depth = ''
            ext = '.txt'
        zip_file.writestr(fname + depth + ext, content)

    return zip_buffer.getvalue()


if __name__ == '__main__':
    with open("testfile" + ".zip", "wb") as f:
        f.write(zip_it("testfile", 3))

Of course you could put this in another function, e.g. write_zip(filename) which calls zip_it, but this is a matter of taste or structure of your project.