diff options
| author | Denis 'GNUtoo' Carikli | 2021-12-06 17:45:47 +0100 |
|---|---|---|
| committer | Denis 'GNUtoo' Carikli | 2021-12-08 18:36:39 +0100 |
| commit | 1703ed6ebbe2552990fb847d5fd5dde1d0382a37 (patch) | |
| tree | f04f456ff95aa4247c6144c69a6b1352b0064c16 /libmat2/archive.py | |
| parent | 541b3c83b2da3be57ebcf562a9a84c059de586fa (diff) | |
zip archives: keep individual files compression type
While hardcoding the compression to zipfile.ZIP_DEFLATED works for
most use cases of mat, being able to produce cleaned up uncompressed
zip files is useful for content that cannot be compressed more.
In addition it also enables to use mat2 for reproducible builds of
Android bootanimation files file that don't support compression.
Signed-off-by: Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>
Diffstat (limited to 'libmat2/archive.py')
| -rw-r--r-- | libmat2/archive.py | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/libmat2/archive.py b/libmat2/archive.py index 48c1594..29db417 100644 --- a/libmat2/archive.py +++ b/libmat2/archive.py | |||
| @@ -120,6 +120,18 @@ class ArchiveBasedAbstractParser(abstract.AbstractParser): | |||
| 120 | # pylint: disable=unused-argument | 120 | # pylint: disable=unused-argument |
| 121 | return member | 121 | return member |
| 122 | 122 | ||
| 123 | @staticmethod | ||
| 124 | def _get_member_compression(member: ArchiveMember): | ||
| 125 | """Get the compression of the archive member.""" | ||
| 126 | # pylint: disable=unused-argument | ||
| 127 | return None | ||
| 128 | |||
| 129 | @staticmethod | ||
| 130 | def _set_member_compression(member: ArchiveMember, compression) -> ArchiveMember: | ||
| 131 | """Set the compression of the archive member.""" | ||
| 132 | # pylint: disable=unused-argument | ||
| 133 | return member | ||
| 134 | |||
| 123 | def get_meta(self) -> Dict[str, Union[str, dict]]: | 135 | def get_meta(self) -> Dict[str, Union[str, dict]]: |
| 124 | meta = dict() # type: Dict[str, Union[str, dict]] | 136 | meta = dict() # type: Dict[str, Union[str, dict]] |
| 125 | 137 | ||
| @@ -184,6 +196,8 @@ class ArchiveBasedAbstractParser(abstract.AbstractParser): | |||
| 184 | original_permissions = os.stat(full_path).st_mode | 196 | original_permissions = os.stat(full_path).st_mode |
| 185 | os.chmod(full_path, original_permissions | stat.S_IWUSR | stat.S_IRUSR) | 197 | os.chmod(full_path, original_permissions | stat.S_IWUSR | stat.S_IRUSR) |
| 186 | 198 | ||
| 199 | original_compression = self._get_member_compression(item) | ||
| 200 | |||
| 187 | if self._specific_cleanup(full_path) is False: | 201 | if self._specific_cleanup(full_path) is False: |
| 188 | logging.warning("Something went wrong during deep cleaning of %s", | 202 | logging.warning("Something went wrong during deep cleaning of %s", |
| 189 | member_name) | 203 | member_name) |
| @@ -223,6 +237,7 @@ class ArchiveBasedAbstractParser(abstract.AbstractParser): | |||
| 223 | 237 | ||
| 224 | zinfo = self.member_class(member_name) # type: ignore | 238 | zinfo = self.member_class(member_name) # type: ignore |
| 225 | zinfo = self._set_member_permissions(zinfo, original_permissions) | 239 | zinfo = self._set_member_permissions(zinfo, original_permissions) |
| 240 | zinfo = self._set_member_compression(zinfo, original_compression) | ||
| 226 | clean_zinfo = self._clean_member(zinfo) | 241 | clean_zinfo = self._clean_member(zinfo) |
| 227 | self._add_file_to_archive(zout, clean_zinfo, full_path) | 242 | self._add_file_to_archive(zout, clean_zinfo, full_path) |
| 228 | 243 | ||
| @@ -368,7 +383,6 @@ class ZipParser(ArchiveBasedAbstractParser): | |||
| 368 | super().__init__(filename) | 383 | super().__init__(filename) |
| 369 | self.archive_class = zipfile.ZipFile | 384 | self.archive_class = zipfile.ZipFile |
| 370 | self.member_class = zipfile.ZipInfo | 385 | self.member_class = zipfile.ZipInfo |
| 371 | self.zip_compression_type = zipfile.ZIP_DEFLATED | ||
| 372 | 386 | ||
| 373 | def is_archive_valid(self): | 387 | def is_archive_valid(self): |
| 374 | try: | 388 | try: |
| @@ -410,7 +424,7 @@ class ZipParser(ArchiveBasedAbstractParser): | |||
| 410 | assert isinstance(member, zipfile.ZipInfo) # please mypy | 424 | assert isinstance(member, zipfile.ZipInfo) # please mypy |
| 411 | with open(full_path, 'rb') as f: | 425 | with open(full_path, 'rb') as f: |
| 412 | archive.writestr(member, f.read(), | 426 | archive.writestr(member, f.read(), |
| 413 | compress_type=self.zip_compression_type) | 427 | compress_type=member.compress_type) |
| 414 | 428 | ||
| 415 | @staticmethod | 429 | @staticmethod |
| 416 | def _get_all_members(archive: ArchiveClass) -> List[ArchiveMember]: | 430 | def _get_all_members(archive: ArchiveClass) -> List[ArchiveMember]: |
| @@ -421,3 +435,12 @@ class ZipParser(ArchiveBasedAbstractParser): | |||
| 421 | def _get_member_name(member: ArchiveMember) -> str: | 435 | def _get_member_name(member: ArchiveMember) -> str: |
| 422 | assert isinstance(member, zipfile.ZipInfo) # please mypy | 436 | assert isinstance(member, zipfile.ZipInfo) # please mypy |
| 423 | return member.filename | 437 | return member.filename |
| 438 | |||
| 439 | @staticmethod | ||
| 440 | def _get_member_compression(member: ArchiveMember): | ||
| 441 | return member.compress_type | ||
| 442 | |||
| 443 | @staticmethod | ||
| 444 | def _set_member_compression(member: ArchiveMember, compression) -> ArchiveMember: | ||
| 445 | member.compress_type = compression | ||
| 446 | return member | ||
