0

So as it says in the title I am attempting to write a branching if/elif to check a zip file for a subdirectory to determine if I can just extract the subdirectory and files or if I need to create a new directory for it. The purpose of this is that I have a lot of comics and image archives, some of them only contain images and some of them contain one or multiple subdirectories. So I want to automate the unarchiving process, leaving all images in the exact same directory structure. The code I have so far looked like this:

if name.endswith('.zip'):
    
    zip_ref = zipfile.ZipFile(archive, 'r')

    # OS path splits the name away from the file extension and path variable
    new_folder = os.path.splitext(archive)[0][0:]

    zip_con = [zip_ref.namelist()]

    for f in zip_con[0]:
       if f.endswith('/'):
           try:
               zip_ref.extractall()
           except(OSError, IOError) as err:
               if err.errno != errno.EEXIST:
                   raise
           continue
    os.remove(archive)

This works for files with subdirectories, it extracts the subdirs and images, then deletes the original archive, but if it fails the if it automatically deletes an archive without extracting anything.

I attempted to add something like this:

else:
    os.mkdir(new_folder)
    zip_ref.extractall(new_folder)
    os.remove(archive)

and also:

elif not f.endswith('/'):
    os.mkdir(new_folder)
    zip_ref.extractall(new_folder)
    os.remove(archive)

But due to the for loop, it would always trigger it at least once, so if a zip file had a subdirectory it would end up giving me both. One copy of just the subdir and one copy of a directory with another copy of the subdir and images nested inside of it. Or it would simply fail as soon as it got to the elif and crash.

Edit: Directory and file information as well as clear example of current code results

So for testing purposes I have all of the zips in one folder, with the python script. This is currently the structure, note that "All-rounder_Meguru" zips do not contain a subdirectory but the "One Piece" zips do.

Zip structure enter image description here

Current Results from my code: Unarchived files enter image description here

This results in a duplication of the extraction and the full named One Piece folders (eg One Piece v06 (2005) (Digital) (AnHeroGold-Empire)) would also contain the "One Piece V06" subdirectory, with images nested inside that.

Current, added the makedirs just like from the example linked in the comments.

 #Path to the archive
        archive = os.path.abspath(path)

        if name.endswith('.zip') or name.endswith('.cbz') or name.endswith('.ZIP') or name.endswith('.CBZ'):

            zip_ref = zipfile.ZipFile(archive, 'r')

            # OS path splits the name away from the file extension and path variable
            new_folder = os.path.splitext(archive)[0][0:]

            zip_con = [zip_ref.namelist()]

            for f in zip_con[0]:
                if f.endswith('/'):
                    try:
                        zip_ref.extractall()
                    except(OSError, IOError) as err:
                        if err.errno != errno.EEXIST:
                            raise
                    continue
                else:
                    try:
                        os.makedirs(new_folder)
                        zip_ref.extractall(new_folder)
                    except OSError as exc:
                        if exc.errno == errno.EEXIST and os.path.isdir(new_folder):
                            pass
            os.remove(archive)
ErebusC
  • 1
  • 4
  • 1
    Your indentation looks wrong, it's hard to understand the structure of your code. I'd recommend you clean it up, so we can try to help you. – Fábio Batista Jul 03 '20 at 01:09
  • If you're just looking for a way to create a directory if it does not exist, check the following answer: https://stackoverflow.com/a/600612/292586 – Fábio Batista Jul 03 '20 at 01:09
  • @FábioBatista I will have a look at the link now. Apologies for the indentation, I approved an edit of it from another user, I didn't realise it made it more difficult to follow. – ErebusC Jul 03 '20 at 03:28
  • Please provide an mcve. Provide stack traces of any crashes. Provide sample directory structure and zip listing. I don't really know what the problem is based on your prose. – Mad Physicist Jul 03 '20 at 03:44
  • @FábioBatista so that link doesn't really solve my issues. As shown in the last code snippets, I know how to use os.mkdir/makedir to create a directory. I am having an issue with the logic however. Seemingly I can either make a new directory for a zip file, meaning for a large part of my files I will have randomly lots of nested files or I can have only the subdirectory but any zip that did not have one will be completely removed with no extraction taking place. I am trying to achieve an result where it checks the zip for a dir, if it exists, it just extracts the contents, else creates dir. – ErebusC Jul 03 '20 at 03:47
  • @MadPhysicist I added some images, I hope that clears it up. Currently my code doesn't error but it is duplicating the extraction for any zip file with a subdirectory. Previous versions of the code when I changed the elif/else structure would simply delete the zip archive for any Zip that did not have a subdirectory. Leaving me without half of my files. – ErebusC Jul 03 '20 at 04:01

1 Answers1

0

After some long rest and coming back to the problem I found it was just me not quite understanding how to use things in python like continue, break and StopIteration. Probably asked the wrong question too looking back.

adding 'break' here fixed all my issues:

try:
   zip_ref.extractall()
   break
ErebusC
  • 1
  • 4