Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Zip directory with subdirectories in Robot Framework

Working with Robot Framework, I'm trying to zip a directory with one files and three subdirectories containing files. I'm using the ArchiveLibrary and the keyword Create Zip From Files In Directory. The result is a zipped directory containing the one file in the top directory and three empty subfolders.

How can I adjust the library so that also the subfolder's content is included?

This is how the keyword is originally defined:

def create_zip_from_files_in_directory(self, directory, filename):

    ''' Take all files in a directory and create a zip package from them
    `directory` Path to the directory that holds our files
    `filename` Path to our destination ZIP package.
    '''

    if not directory.endswith("/"):
        directory = directory + "/"
    zip = zipfile.ZipFile(filename, "w")
    files = os.listdir(directory)
    for name in files:
        zip.write(directory + name, arcname=name)
    zip.close()

Link to the complete library.

I've been experimenting with os.walk, without success.

How the keyword is used in the .robot file:

Zip xml file
    ${zipfilename}=    set variable    komplett.zip
    Create zip from Files in directory    ../xml/komplett/  ${zipfilename}

If it makes a difference, I really only need to solve this specific case, not a general one, meaning that I don't mind typing in paths to each directory and then join that somehow, I just don't understand how to do it... Also, I use PyCharm as editor, not RIDE.

like image 865
Sabotchick Avatar asked Mar 24 '17 09:03

Sabotchick


1 Answers

EDIT: when using the library version 0.4 and up, you can choose whether subdirectories should be included. E.g.:

Create Zip From Files In Directory    ../xml/komplett/  no_sub_folders.zip
Create Zip From Files In Directory    ../xml/komplett/  dir_and_sub_folders.zip   sub_directories=${true}

The keyword for creating tar is a bit different - by default it includes the files in subdirectories, and now you have an option not to:

Create Tar From Files In Directory    ../xml/komplett/  dir_and_sub_folders.tar 
Create Tar From Files In Directory    ../xml/komplett/  no_sub_folders.tar   sub_directories=${false}

The default values of sub_directories are based on the preexisting behavior, not to break exisiting usages in test cases.


Original answer, for versions < 0.4:

If you're willing to patch the library, this code should do:

zip = zipfile.ZipFile(filename, "w")
for path, _, files in os.walk(directory):
    for name in files:
        file_to_archive = os.path.join(path, name)

        # get rid of the starting directory - so the zip structure is top-level starting from it
        file_name = path.replace(directory, '')
        file_name = os.path.join(file_name, name)

        zip.write(file_to_archive, arcname=file_name) # set the desired name in the archive by the arcname argument
zip.close()

Edit: preserves the sub-directory structure for files in - subdirectories. The generated file is with top-level the target directory, and all its subdirectories - beneath it (as opposed to the archive preserving the full path to the target directory)

The arcname argument controls what is the name of a file stored in the archive - and through line 7, we are preserving the relative directory plus the file name.

Always use os.path.join cause it automatically takes care of differences in the different file systems (ntfs/linux/etc).

If the final solution works for you, don't forget to propose a patch to the library owner - give back to the community :)

like image 96
Todor Minakov Avatar answered Oct 19 '22 21:10

Todor Minakov