You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

129 lines
4.0 KiB

  1. import os, time
  2. from libarchive import is_archive, Entry, SeekableArchive
  3. from zipfile import ZIP_STORED, ZIP_DEFLATED
  4. def is_zipfile(filename):
  5. return is_archive(filename, formats=('zip',))
  6. class ZipEntry(Entry):
  7. def __init__(self, *args, **kwargs):
  8. super(ZipEntry, self).__init__(*args, **kwargs)
  9. def get_filename(self):
  10. return self.pathname
  11. def set_filename(self, value):
  12. self.pathname = value
  13. filename = property(get_filename, set_filename)
  14. def get_file_size(self):
  15. return self.size
  16. def set_file_size(self, value):
  17. assert isinstance(value, int), 'Please provide size as int or long.'
  18. self.size = value
  19. file_size = property(get_file_size, set_file_size)
  20. def get_date_time(self):
  21. return time.localtime(self.mtime)[0:6]
  22. def set_date_time(self, value):
  23. assert isinstance(value, tuple), 'mtime should be tuple (year, month, day, hour, minute, second).'
  24. assert len(value) == 6, 'mtime should be tuple (year, month, day, hour, minute, second).'
  25. self.mtime = time.mktime(value + (0, 0, 0))
  26. date_time = property(get_date_time, set_date_time)
  27. header_offset = Entry.header_position
  28. def _get_missing(self):
  29. raise NotImplemented()
  30. def _set_missing(self, value):
  31. raise NotImplemented()
  32. compress_type = property(_get_missing, _set_missing)
  33. comment = property(_get_missing, _set_missing)
  34. extra = property(_get_missing, _set_missing)
  35. create_system = property(_get_missing, _set_missing)
  36. create_version = property(_get_missing, _set_missing)
  37. extract_version = property(_get_missing, _set_missing)
  38. reserved = property(_get_missing, _set_missing)
  39. flag_bits = property(_get_missing, _set_missing)
  40. volume = property(_get_missing, _set_missing)
  41. internal_attr = property(_get_missing, _set_missing)
  42. external_attr = property(_get_missing, _set_missing)
  43. CRC = property(_get_missing, _set_missing)
  44. compress_size = property(_get_missing, _set_missing)
  45. class ZipFile(SeekableArchive):
  46. def __init__(self, f, mode='r', compression=ZIP_DEFLATED, allowZip64=False, password=None):
  47. super(ZipFile, self).__init__(
  48. f, mode=mode, format='zip', entry_class=ZipEntry, encoding='CP437', password=password
  49. )
  50. if mode == 'w' and compression == ZIP_STORED:
  51. # Disable compression for writing.
  52. _libarchive.archive_write_set_format_option(self.archive._a, "zip", "compression", "store")
  53. self.compression = compression
  54. getinfo = SeekableArchive.getentry
  55. def namelist(self):
  56. return list(self.iterpaths())
  57. def infolist(self):
  58. return list(self)
  59. def open(self, name, mode, pwd=None):
  60. if mode == 'r':
  61. if pwd:
  62. self.add_passphrase(pwd)
  63. return self.readstream(name)
  64. else:
  65. return self.writestream(name)
  66. def extract(self, name, path=None, pwd=None):
  67. if pwd:
  68. self.add_passphrase(pwd)
  69. if not path:
  70. path = os.getcwd()
  71. return self.readpath(name, os.path.join(path, name))
  72. def extractall(self, path, names=None, pwd=None):
  73. if pwd:
  74. self.add_passphrase(pwd)
  75. if not names:
  76. names = self.namelist()
  77. if names:
  78. for name in names:
  79. self.extract(name, path)
  80. def read(self, name, pwd=None):
  81. if pwd:
  82. self.add_passphrase(pwd)
  83. return self.read(name)
  84. def writestr(self, member, data, compress_type=None):
  85. if compress_type != self.compression:
  86. raise Exception('Cannot change compression type for individual entries.')
  87. return self.write(member, data)
  88. def setpassword(self, pwd):
  89. return self.set_passphrase(pwd)
  90. def testzip(self):
  91. raise NotImplemented()
  92. def _get_missing(self):
  93. raise NotImplemented()
  94. def _set_missing(self, value):
  95. raise NotImplemented()
  96. comment = property(_get_missing, _set_missing)