#!/usr/bin/python
import os, sys, zipfile, optparse, zlib, fnmatch, time
optp=optparse.OptionParser(usage="%prog [options] <target-zip> <source-dir> [<source-dir...>]")
optp.add_option("-x", help="exclude mask", action="append", dest="exclude", default=[])
optp.add_option("-q", help="be quiet", action="store_true", dest="quiet", default=False)
optp.add_option("-e", help="omit empty directories", action="store_true", dest="omit_empty", default=False)
err=optp.error
options, args = optp.parse_args()
if len(args)<2:
optp.print_usage()
sys.exit(1)
zf=zipfile.ZipFile(args[0], "w")
def zfAddNullFile(zf, arcname, date_time, extattr=0):
""" Adapted from the method in zipfile """
arcname = os.path.normpath(os.path.splitdrive(arcname)[1])
arcname = arcname.lstrip(os.sep + (os.altsep or ""))
zinfo = zipfile.ZipInfo(arcname, date_time)
zinfo.external_attr = extattr
zinfo.compress_type = zf.compression
zinfo.file_size = 0
zinfo.flag_bits = 0x00
zinfo.header_offset = zf.fp.tell() # Start of header bytes
zf._writecheck(zinfo)
zf._didModify = True
zinfo.CRC = CRC = zlib.crc32("")
zinfo.compress_size = 0
zinfo.file_size = 0
zf.fp.write(zinfo.FileHeader())
zf.filelist.append(zinfo)
zf.NameToInfo[zinfo.filename] = zinfo
def printFilename(f, msg=None):
if not options.quiet:
if msg:
print msg,
try:
print f
except:
print f.encode("charmap", "replace")
for sourceDir in args[1:]:
try:
sourceDir=sourceDir.decode("latin-1")
except:
print sourceDir
print "Exception while trying to process directory"
for dp, dn, fn in os.walk(sourceDir):
if fn:
for f in fn:
f=os.path.join(dp, f)
ok=True
for xmask in options.exclude:
if fnmatch.fnmatch(f, xmask):
ok=False
break
if ok:
try:
mtime=time.localtime(os.stat(f).st_mtime)
except ValueError:
print "Error: Modified time out of range."
printFilename(f)
print os.stat(f).st_mtime
mtime=time.localtime(0) #set time to unix epoch 0 = 'Thu Jan 01 07:00:00 1970'
except WindowsError:
print "Error: Can't find file due to windows limitations."
printFilename(f)
mtime=time.localtime(0) #set time to unix epoch 0 = 'Thu Jan 01 07:00:00 1970'
zfAddNullFile(zf, f, (mtime.tm_year, mtime.tm_mon, mtime.tm_mday, mtime.tm_hour, mtime.tm_min, mtime.tm_sec))
elif not options.omit_empty:
mtime=time.localtime(os.stat(dp).st_mtime)
#printFilename(dp, "(empty directory)")
zfAddNullFile(zf, dp, (mtime.tm_year, mtime.tm_mon, mtime.tm_mday, mtime.tm_hour, mtime.tm_min, mtime.tm_sec), 16)
zf.close()
print "All Done."