]> git.phdru.name Git - dotfiles.git/blobdiff - bin/unzip.py
Refactor(bin/decode-URLs.py): Python3-only
[dotfiles.git] / bin / unzip.py
index 6eb4832dc91efa9ef35dcc1786d663ce958602f4..ab62d240cf83482892dbcd08a0437cf1aa997fb0 100755 (executable)
@@ -1,11 +1,12 @@
-#! /usr/bin/env python
+#! /usr/bin/env python3
 """Unzip with encoded filenames
 
-   Written by Oleg Broytman. Copyright (C) 2009, 2010 PhiloSoft Design.
+   Written by Oleg Broytman. Copyright (C) 2009-2024 PhiloSoft Design.
 """
 
 import sys, os, time
 from getopt import getopt, GetoptError
+from shutil import copyfileobj
 from zipfile import ZipFile
 from m_lib.defenc import default_encoding
 
@@ -13,11 +14,11 @@ def usage():
     sys.exit('Usage: %s file.zip' % sys.argv[0])
 
 try:
-  options, arguments = getopt(sys.argv[1:], '')
+    options, arguments = getopt(sys.argv[1:], '')
 except GetoptError:
     usage()
 
-if len(arguments) <> 1:
+if len(arguments) != 1:
     usage()
 
 zf = ZipFile(arguments[0], 'r')
@@ -25,24 +26,31 @@ out = '.'
 
 for zinfo in zf.infolist():
     path = zinfo.filename
-    if not isinstance(path, unicode):
-        path = path.decode('cp866')
-    recoded_path = path.encode(default_encoding)
-    print recoded_path
+    if isinstance(path, bytes):
+        recoded_path = path.decode('cp866').encode(default_encoding)
+    else:
+        recoded_path = path
+    print(recoded_path)
 
     if path.startswith('./'):
-        tgt = os.path.join(out, recoded_path[2:])
-    else:
-        tgt = os.path.join(out, recoded_path)
+        recoded_path = recoded_path[2:]
+    tgt = os.path.join(out, recoded_path)
 
     tgtdir = os.path.dirname(tgt)
     if not os.path.exists(tgtdir):
         os.makedirs(tgtdir)
 
     if not tgt.endswith('/'):
-        fp = open(tgt, 'wb')
-        fp.write(zf.read(zinfo.filename))
-        fp.close()
-    dt = time.mktime(zinfo.date_time + (0, 0, -1))
-    os.utime(tgt, (dt, dt))
+        infile = zf.open(zinfo.filename)
+        if zinfo.external_attr == 0xA1ED0000:
+            os.symlink(infile.read(), tgt)
+        else:  # regular file
+            fp = open(tgt, 'wb')
+            copyfileobj(infile, fp)
+            fp.close()
+        infile.close()
+    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()