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.
 
 
 
 
 

127 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):
  47. super(ZipFile, self).__init__(f, mode=mode, format='zip', entry_class=ZipEntry, encoding='CP437')
  48. if mode == 'w' and compression == ZIP_STORED:
  49. # Disable compression for writing.
  50. _libarchive.archive_write_set_format_option(self.archive._a, "zip", "compression", "store")
  51. self.compression = compression
  52. getinfo = SeekableArchive.getentry
  53. def namelist(self):
  54. return list(self.iterpaths)
  55. def infolist(self):
  56. return list(self)
  57. def open(self, name, mode, pwd=None):
  58. if pwd:
  59. raise NotImplemented('Encryption not supported.')
  60. if mode == 'r':
  61. return self.readstream(name)
  62. else:
  63. return self.writestream(name)
  64. def extract(self, name, path=None, pwd=None):
  65. if pwd:
  66. raise NotImplemented('Encryption not supported.')
  67. if not path:
  68. path = os.getcwd()
  69. return self.readpath(name, os.path.join(path, name))
  70. def extractall(self, path, names=None, pwd=None):
  71. if pwd:
  72. raise NotImplemented('Encryption not supported.')
  73. if not names:
  74. names = self.namelist()
  75. if names:
  76. for name in names:
  77. self.extract(name, path)
  78. def read(self, name, pwd=None):
  79. if pwd:
  80. raise NotImplemented('Encryption not supported.')
  81. return self.read(name)
  82. def writestr(self, member, data, compress_type=None):
  83. if compress_type != self.compression:
  84. raise Exception('Cannot change compression type for individual entries.')
  85. return self.write(member, data)
  86. def setpassword(self, pwd):
  87. raise NotImplemented('Encryption not supported.')
  88. def testzip(self):
  89. raise NotImplemented()
  90. def _get_missing(self):
  91. raise NotImplemented()
  92. def _set_missing(self, value):
  93. raise NotImplemented()
  94. comment = property(_get_missing, _set_missing)