]> git.phdru.name Git - dotfiles.git/commitdiff
Feat(zip): Save and restore symlinks master
authorOleg Broytman <phd@phdru.name>
Wed, 5 Jun 2024 17:41:08 +0000 (20:41 +0300)
committerOleg Broytman <phd@phdru.name>
Wed, 5 Jun 2024 17:41:08 +0000 (20:41 +0300)
zip.py: Save symlinks.
unzip.py: Restore symlinks.

.mc/menu
bin/cp_recode_fname
bin/unzip.py
bin/zip.py

index c2198c8978457c3e3ae2b81f25ad519b2ef36151..f5e1b68131e20b62b608b0795c2937a66f8e55d6 100644 (file)
--- a/.mc/menu
+++ b/.mc/menu
@@ -311,7 +311,7 @@ z  Compress the current subdirectory to zip
    echo -n "Name of the distribution file (without extension) [$Pwd]: "
    read zip
    if [ "$zip"x = x ]; then zip="$Pwd"; fi
-   cd .. && zip -r9 "$zip".zip "$Pwd" &&
+   cd .. && zip -ry9 "$zip".zip "$Pwd" &&
    echo ../"$zip".zip created.
 
 + t d & f ^\.\.$
@@ -358,7 +358,7 @@ z  xz the file
 
 + ! f \.(z|Z|bz2|gz|lz|lzma)|(tbz2|tgz|tz|zip|ZIP|rar|RAR|xz|7z)$ & t lr
 z  zip the file/directory
-   exec zip -r9 %f.zip %f
+   exec zip -ry9 %f.zip %f
 
 + ! f \.(z|Z|bz2|gz|lz|lzma)|(tbz2|tgz|tz|zip|ZIP|rar|RAR|xz|7z)$ & t lr
 y  zip the file/directory recoding filename(s)
@@ -367,7 +367,7 @@ y  zip the file/directory recoding filename(s)
 + t t
 Z  zip selected files/directories
    ZIP=%{Enter zip name}
-   exec zip -r9 "$ZIP" %s
+   exec zip -ry9 "$ZIP" %s
 
 + t t
 Y  zip selected files/directories recoding filenames
index 8cae733e8642c03a8b6f90dcdd2eec230762cfa7..d6dd74b8f0398574784dc8a25b987f554be81720 100755 (executable)
@@ -31,7 +31,7 @@ case "$cmd" in
     cp_*) cmd="cp -p" ;;
     mv_*) cmd=mv ;;
     *)
-        echo "Uncnown command $0, aborting" >&2
+        echo "Unknown command $0, aborting" >&2
         exit 2
     ;;
 esac
index 57af7b1d5a277eec95eb5b9e1e6265c57c98750d..ab62d240cf83482892dbcd08a0437cf1aa997fb0 100755 (executable)
@@ -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()
index 35bf0e69f00da71c92c80ef55c09767c904e0120..bf55a08f7f01c004111a5e84a37525f10851141c 100755 (executable)
@@ -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))