Create .ZIPs from multiple folders
There we go with yet another exercise in Python :-)
The idea here is to archive several folders, having each folder in a ZIP file. So if you have two folders, A and B, you end up with A.zip and B.zip.
No doubt this can be done with shell programming (and it will be much better since this solution doesn't provide support for recursion) but this is intended as a way of improving my python skills, so no moaning about the choice of language here! ;-)
And here is the little script:
import sys
import zipfile
if len(sys.argv) > 1:
folder = sys.argv[1]
else:
folder = '.'
for item in os.listdir(folder):
full_path = os.path.join(folder, item)
if not os.path.isdir(full_path):
continue
dst_filename = item + '.zip'
dst_item = os.path.join(folder, dst_filename)
if os.path.exists(dst_item) and os.path.getsize(dst_item) > 0:
continue
output_file = zipfile.ZipFile(dst_item, "w", zipfile.ZIP_DEFLATED)
for item_file in os.listdir(full_path):
output_file.write(os.path.join(full_path, item_file), item_file)
output_file.close()
You can download it from my supersnippets repository, and then execute it with
Maybe changing the way I do the imports would help, so instead of doing import os and then using os.listdir, I would write from os import listdir and then simply use listdir from then on, but for some reason I kind of prefer the more verbose way for now, so that I don't have to guess where does each function come from.
I suppose once I get more fluent with Python, I won't need to use those long statements.


Sergi Mansilla
20080827
Good work and good blog!
Your script seems likely to throw an error in the following lines:
output_file.write(os.path.join(full_path, item_file), item_file)
given that you are handling files and folders at the same time, and as far as I can remember (not sure though), it will attempt to read the folder information as if it were a file to write its contents inside the .zip file. I think you should filter the folders out as you did already some lines before.
Here is my attempt at writing a recursive solution for the problem:
from os.path import join, isdir, exists
import sys
import zipfile
if len(sys.argv) > 1:
folder = sys.argv[1]
else:
folder = '.'
def dirwalk(dir):
for root, dirs, files in walk(dir):
for name in dirs:
yield [root, name]
for ff, item in dirwalk(folder):
folder_path = join(ff, item)
dst_item = folder_path + '.zip'
if not exists(dst_item):
output_file = zipfile.ZipFile(dst_item, "w", zipfile.ZIP_DEFLATED)
file_path = join(folder_path,file)
for item_file in [file for file in listdir(folder_path) if not isdir(file_path)]:
output_file.write(file_path, item_file)
output_file.close()
Sergi Mansilla
20080827
Ugh it didn't indent my code :(
sole
20080827
Hey! Thanks for the improved script. You're right, it didn't look for anything recursive, because for this specific case I hadn't folders inside folders, only plain files.
By the way, I applied some formatting to your code :)
I didn't know about yield in Python, and I'm glad to see how my supposition about imports was right. I think I'm in the right way :D
Thanks again for all!