Last active
January 24, 2022 00:49
-
-
Save hhsprings/88b67c47ace511b662a15268aaaada41 to your computer and use it in GitHub Desktop.
convert zip to other
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! py -3 | |
# -*- coding: utf-8 -*- | |
import sys | |
import os | |
import tarfile | |
import zipfile | |
import calendar | |
import datetime | |
import getpass | |
from io import BytesIO | |
_ts = int((datetime.datetime.now() - | |
datetime.datetime.utcnow()).total_seconds()) | |
def _process_one_zip( | |
zfn, | |
remove_original_zip, | |
compressor, | |
compresslevel, | |
format=tarfile.PAX_FORMAT): | |
opkw = dict(format=tarfile.PAX_FORMAT) | |
if compressor in ("bz2", "tbz2"): | |
op = tarfile.open | |
opkw.update(dict(mode="w:bz2", compresslevel=compresslevel)) | |
ext = ".tar.bz2" if compressor == "bz2" else ".tbz2" | |
elif compressor in ("gz", "tgz"): | |
op = tarfile.open | |
opkw.update(dict(mode="w:gz", compresslevel=compresslevel)) | |
ext = ".tar.gz" if compressor == "gz" else ".tgz" | |
else: #elif compressor == "xz": | |
op = tarfile.open | |
opkw.update(dict(mode="w:xz", preset=compresslevel)) | |
ext = ".xz" | |
with zipfile.ZipFile(zfn, 'r') as zf: | |
with op( | |
os.path.splitext(zfn)[0] + ext, **opkw) as tf: | |
for zi in sorted(zf.infolist(), key=lambda zi: (not zi.filename[-1] == "/", zi.filename)): | |
ti = tarfile.TarInfo(zi.filename) | |
if zi.filename[-1] == "/": # Python 3's ZipInfo has a method 'is_dir' but Python 2's doesn't | |
ti.type = tarfile.DIRTYPE | |
cont = None | |
else: | |
ti.type = tarfile.REGTYPE | |
d = zf.read(zi) | |
ti.size = zi.file_size | |
cont = BytesIO(d) | |
ti.uname = getpass.getuser() | |
ti.gname = getpass.getuser() | |
ti.mtime = calendar.timegm(zi.date_time) - _ts | |
tf.addfile(ti, cont) | |
print("%s: %s" % (zi.file_size, zi.filename)) | |
if remove_original_zip: | |
try: | |
os.unlink(zfn) | |
print("remove %s" % zfn) | |
except IOError as e: | |
print(str(e)) | |
if __name__ == '__main__': | |
import argparse | |
parser = argparse.ArgumentParser() | |
parser.add_argument('zipfile', nargs='+') | |
parser.add_argument( | |
'--remove-original-zip', action='store_true', default=False) | |
parser.add_argument( | |
'--level', type=int, default=9) | |
parser.add_argument( | |
'--format', | |
type=int, | |
choices=[tarfile.PAX_FORMAT, tarfile.GNU_FORMAT, tarfile.USTAR_FORMAT], | |
default=tarfile.PAX_FORMAT) | |
try: | |
import lzma | |
parser.add_argument( | |
'--compressor', choices=["bz2", "gz", "tbz2", "tgz", "xz"], default="bz2") | |
except ImportError: # maybe you are using python 2.x or before 3.3 | |
parser.add_argument( | |
'--compressor', choices=["bz2", "gz", "tbz2", "tgz"], default="bz2") | |
args = parser.parse_args(sys.argv[1:]) | |
for zfn in args.zipfile: | |
_process_one_zip( | |
zfn, | |
args.remove_original_zip, | |
args.compressor, | |
args.level, args.format) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment