uz 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. #!/usr/bin/env python
  2. # Extracts a zip archive while converting file names from Shift-JIS encoding to UTF-8.
  3. #
  4. # Example:
  5. # python unzip-jp.py archive.zip
  6. #
  7. # Creates a directory `archive` and extracts the archive there.
  8. #
  9. import zipfile
  10. import sys
  11. import os
  12. import codecs
  13. if len(sys.argv) < 2:
  14. print('No archive name.')
  15. print('')
  16. print('Usage: unzip-jp archive [password]')
  17. exit(1)
  18. name = sys.argv[1]
  19. if len(sys.argv) > 2:
  20. password = sys.argv[2]
  21. else:
  22. password = None
  23. directory = os.path.splitext(os.path.basename(name))[0]
  24. if not os.path.exists(directory):
  25. os.makedirs(directory)
  26. with zipfile.ZipFile(name, 'r') as z:
  27. if password:
  28. z.setpassword(password.encode('cp850','replace'))
  29. for f in z.infolist():
  30. bad_filename = f.filename
  31. if bytes != str:
  32. # Python 3 - decode filename into bytes
  33. # assume CP437 - these zip files were from Windows anyway
  34. bad_filename = bytes(bad_filename, 'cp437')
  35. try:
  36. uf = codecs.decode(bad_filename, 'sjis')
  37. except:
  38. uf = codecs.decode(bad_filename, 'shift_jisx0213')
  39. # need to print repr in Python 2 as we may encounter UnicodeEncodeError
  40. # when printing to a Windows console
  41. print(repr(uf))
  42. filename=os.path.join(directory, uf)
  43. # create directories if necessary
  44. if not os.path.exists(os.path.dirname(filename)):
  45. try:
  46. os.makedirs(os.path.dirname(filename))
  47. except OSError as exc: # Guard against race condition
  48. if exc.errno != errno.EEXIST:
  49. raise
  50. # don't try to write to directories
  51. if not filename.endswith('/'):
  52. with open(filename, 'wb') as dest:
  53. dest.write(z.read(f))