Skip to content

Instantly share code, notes, and snippets.

@kgn
Created October 5, 2010 03:04
Show Gist options
  • Save kgn/610907 to your computer and use it in GitHub Desktop.
Save kgn/610907 to your computer and use it in GitHub Desktop.
Python function to zip up a directory and preserve any symlinks and empty directories.
import os
import zipfile
def ZipDir(inputDir, outputZip):
'''Zip up a directory and preserve symlinks and empty directories'''
zipOut = zipfile.ZipFile(outputZip, 'w', compression=zipfile.ZIP_DEFLATED)
rootLen = len(os.path.dirname(inputDir))
def _ArchiveDirectory(parentDirectory):
contents = os.listdir(parentDirectory)
#store empty directories
if not contents:
#http://www.velocityreviews.com/forums/t318840-add-empty-directory-using-zipfile.html
archiveRoot = parentDirectory[rootLen:].replace('\\', '/').lstrip('/')
zipInfo = zipfile.ZipInfo(archiveRoot+'/')
zipOut.writestr(zipInfo, '')
for item in contents:
fullPath = os.path.join(parentDirectory, item)
if os.path.isdir(fullPath) and not os.path.islink(fullPath):
_ArchiveDirectory(fullPath)
else:
archiveRoot = fullPath[rootLen:].replace('\\', '/').lstrip('/')
if os.path.islink(fullPath):
# http://www.mail-archive.com/[email protected]/msg34223.html
zipInfo = zipfile.ZipInfo(archiveRoot)
zipInfo.create_system = 3
# long type of hex val of '0xA1ED0000L',
# say, symlink attr magic...
zipInfo.external_attr = 2716663808L
zipOut.writestr(zipInfo, os.readlink(fullPath))
else:
zipOut.write(fullPath, archiveRoot, zipfile.ZIP_DEFLATED)
_ArchiveDirectory(inputDir)
zipOut.close()
@simonwagner
Copy link

For an explanation of what zipInfo.external_attr actually means, look here: http://unix.stackexchange.com/a/14727

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment