From f2e9bb3e4991fafccdf54035fb74ce7b2623c607 Mon Sep 17 00:00:00 2001 From: Oleg Broytman Date: Wed, 5 Jun 2024 20:41:08 +0300 Subject: [PATCH] Feat(zip): Save and restore symlinks zip.py: Save symlinks. unzip.py: Restore symlinks. --- bin/unzip.py | 15 ++++++++++----- bin/zip.py | 14 +++++++++++--- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/bin/unzip.py b/bin/unzip.py index 57af7b1..ab62d24 100755 --- a/bin/unzip.py +++ b/bin/unzip.py @@ -42,10 +42,15 @@ for zinfo in zf.infolist(): if not tgt.endswith('/'): infile = zf.open(zinfo.filename) - fp = open(tgt, 'wb') - copyfileobj(infile, fp) - fp.close() + if zinfo.external_attr == 0xA1ED0000: + os.symlink(infile.read(), tgt) + else: # regular file + fp = open(tgt, 'wb') + copyfileobj(infile, fp) + fp.close() infile.close() - dt = time.mktime(zinfo.date_time + (0, 0, -1)) - os.utime(tgt, (dt, dt)) + if zinfo.external_attr != 0xA1ED0000: + # set timestamp for directories and files but not symlinks + dt = time.mktime(zinfo.date_time + (0, 0, -1)) + os.utime(tgt, (dt, dt)) zf.close() diff --git a/bin/zip.py b/bin/zip.py index 35bf0e6..bf55a08 100755 --- a/bin/zip.py +++ b/bin/zip.py @@ -6,7 +6,7 @@ import sys, os from getopt import getopt, GetoptError -from zipfile import ZipFile, ZIP_DEFLATED +from zipfile import ZipFile, ZipInfo, ZIP_DEFLATED from m_lib.defenc import default_encoding def usage(): @@ -21,13 +21,21 @@ if len(arguments) < 2: usage() def addToZip(zf, path): - if os.path.isfile(path): + if os.path.isfile(path) or os.path.islink(path): print(path) if isinstance(path, bytes): recoded_path = path.decode(default_encoding).encode('cp866') else: recoded_path = path - zf.write(path, recoded_path, ZIP_DEFLATED) + if os.path.islink(path): + # http://www.mail-archive.com/python-list@python.org/msg34223.html + zipInfo = ZipInfo(recoded_path) + zipInfo.create_system = 3 + # say, symlink attr magic... + zipInfo.external_attr = 0xA1ED0000 + zf.writestr(zipInfo, os.readlink(path)) + else: + zf.write(path, recoded_path, ZIP_DEFLATED) elif os.path.isdir(path): for nm in os.listdir(path): addToZip(zf, os.path.join(path, nm)) -- 2.39.2