Skip to content

Instantly share code, notes, and snippets.

@cmtsij
Created September 25, 2012 02:09
Show Gist options
  • Save cmtsij/3779569 to your computer and use it in GitHub Desktop.
Save cmtsij/3779569 to your computer and use it in GitHub Desktop.
unzip ebill with filenames encoded by big5.
#!/usr/bin/env python
# -*- python -*-
# -*- coding: utf-8 -*-
import sys
import os
import zipfile
import getpass
def usage():
print(
"""Usage:
%s file.zip
"""%sys.argv[0] )
sys.exit(-1)
def unicoded(obj,encoding='utf-8'):
try:
obj=unicode(obj,encoding)
except:
pass
return obj
def main(filename,path=os.getcwd(),codepage='BIG5'):
path=path.decode(sys.getfilesystemencoding())
# check zip type
if not zipfile.is_zipfile(filename):
print("%s is not a valid zip file."%(filename))
# open zip
zip=zipfile.ZipFile(filename)
## print file name in unicode
'''
for name in zip.namelist():
name=unicoded(name,codepage)
#name=i.decode(codepage)
'''
iszdir = lambda name: name[-1] in [os.path.sep,os.path.altsep]
password_retry = 3
for name in zip.namelist():
fullname=os.path.normpath(os.path.join(path,unicoded(name,codepage)))
if iszdir(name):
print(" mkdir: "+fullname)
# dir
if not os.path.exists(fullname):
os.makedirs(fullname)
else:
print("extract: "+fullname)
# file
dirname=os.path.dirname(fullname)
if not os.path.exists(dirname):
os.makedirs(dirname)
while password_retry > 0:
try:
bytes=zip.read(name)
with open(fullname,"w+") as f:
f.write(bytes)
break
except Exception as e:
password_retry=password_retry-1
if str(e).find("Bad password") > 0:
errmsg=unicoded(": ".join(eval(str(e))),codepage)
print(errmsg)
elif str(e).find("encrypted") > 0 or str(e).find("Bad password") > 0:
print(unicoded(str(e),codepage))
else:
print(unicoded(str(e),codepage))
sys.exit(1)
zip.setpassword(getpass.getpass("Enter Password: "))
else:
print("fail to extract zip")
sys.exit(1)
if __name__ == '__main__':
if len(sys.argv) == 2:
main(filename=sys.argv[1])
elif len(sys.argv) == 3:
main(filename=sys.argv[1],path=sys.argv[2])
elif len(sys.argv) == 4:
main(filename=sys.argv[1],path=sys.argv[2],codepage=sys.argv[3])
else:
usage()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment