Skip to content

Instantly share code, notes, and snippets.

@slavanap
Created January 8, 2025 06:43
Show Gist options
  • Save slavanap/2950028c459fc15800981d05f0253b65 to your computer and use it in GitHub Desktop.
Save slavanap/2950028c459fc15800981d05f0253b65 to your computer and use it in GitHub Desktop.
Unzip files packed in systems non-standard encoding (shiftjis in particular)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import argparse
import datetime
import os
import shutil
import time
import zipfile
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('fn', type=str, help='filename')
parser.add_argument('--path', type=str, help='target path')
parser.add_argument('--encoding', type=str, default='shift-jis', help='names encoding')
args = parser.parse_args()
zfile = zipfile.ZipFile(args.fn)
path = os.fspath(args.path) if args.path else os.getcwd()
for member in zfile.infolist():
arcname = member.filename
arcname = arcname.encode('cp437').decode(args.encoding)
arcname = arcname.replace('/', os.path.sep)
if os.path.altsep:
arcname = arcname.replace(os.path.altsep, os.path.sep)
arcname = os.path.splitdrive(arcname)[1]
invalid_path_parts = ('', os.path.curdir, os.path.pardir)
arcname = os.path.sep.join(x for x in arcname.split(os.path.sep)
if x not in invalid_path_parts)
targetpath = os.path.join(path, arcname)
targetpath = os.path.normpath(targetpath)
# Create all upper directories if necessary.
upperdirs = os.path.dirname(targetpath)
if upperdirs and not os.path.exists(upperdirs):
os.makedirs(upperdirs)
if member.is_dir():
if not os.path.isdir(targetpath):
os.mkdir(targetpath)
else:
with zfile.open(member) as source, \
open(targetpath, "wb") as target:
shutil.copyfileobj(source, target)
mtime = time.mktime(datetime.datetime(*member.date_time).timetuple())
os.utime(targetpath, (mtime, mtime))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment