From c129b477f961392eaac04c9f6daec2c8a35cde7e Mon Sep 17 00:00:00 2001 From: Bastian Kleineidam Date: Sat, 9 Nov 2024 21:44:35 +0100 Subject: [PATCH] Added UDF support with 7z --- README.md | 2 +- doc/changelog.txt | 3 ++- doc/patool.1 | 2 +- doc/patool.txt | 6 +++--- doc/web/source/index.md | 2 +- patoolib/__init__.py | 14 ++++++++++++++ patoolib/programs/p7zip.py | 14 +++++++------- patoolib/programs/p7zz.py | 14 +++++++------- tests/archives/test_7z.py | 3 +++ tests/data/t.udf | Bin 0 -> 864256 bytes 10 files changed, 39 insertions(+), 21 deletions(-) create mode 100644 tests/data/t.udf diff --git a/README.md b/README.md index c6efa569..ce1240a0 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ APE (.ape), AR (.a), ARC (.arc), ARJ (.arj), BZIP2 (.bz2), BZIP3 (.bz3), CAB (.cab), CHM (.chm), COMPRESS (.Z), CPIO (.cpio), DEB (.deb), DMS (.dms), FLAC (.flac), GZIP (.gz), ISO (.iso), LRZIP (.lrz), LZH (.lha, .lzh), LZIP (.lz), LZMA (.lzma), LZOP (.lzo), RPM (.rpm), RAR (.rar, .cbr), -RZIP (.rz), SHN (.shn), TAR (.tar, .cbt), XZ (.xz), +RZIP (.rz), SHN (.shn), TAR (.tar, .cbt), UDF (.udf), XZ (.xz), ZIP (.zip, .jar, .cbz), ZOO (.zoo) and ZSTANDARD (.zst) archive formats. It relies on helper applications to handle those archive formats diff --git a/doc/changelog.txt b/doc/changelog.txt index e66d9558..c8c2cecb 100644 --- a/doc/changelog.txt +++ b/doc/changelog.txt @@ -1,5 +1,6 @@ 3.0.4 (released xx.xx.xxxx) - * + * Added support for UDF (.udf) archives with 7z. + Closes: GH bug #80 3.0.3 (released 04.11.2024) * Fix UnicodeDecode errors when logging, especially on windows systems. diff --git a/doc/patool.1 b/doc/patool.1 index c169c0df..ec7c79cb 100644 --- a/doc/patool.1 +++ b/doc/patool.1 @@ -31,7 +31,7 @@ BZIP3 (.bz3), CAB (.cab), CHM (.chm), COMPRESS (.Z), CPIO (.cpio), DEB (.deb), DMS (.dms), FLAC (.flac), GZIP (.gz), ISO (.iso), LRZIP (.lrz), LZH (.lha, .lzh), LZIP (.lz), LZMA (.lzma), LZOP (.lzo), RPM (.rpm), RAR (.rar, .cbr), -RZIP (.rz), SHN (.shn), TAR (.tar, .cbt), XZ (.xz), ZIP (.zip, .jar, .cbz), +RZIP (.rz), SHN (.shn), TAR (.tar, .cbt), UDF (.udf), XZ (.xz), ZIP (.zip, .jar, .cbz), ZOO (.zoo), ZPAQ (.zpaq) and ZSTANDARD (.zst) archive formats. .br It relies on helper applications to handle those archive formats diff --git a/doc/patool.txt b/doc/patool.txt index bab70283..821f3ef5 100644 --- a/doc/patool.txt +++ b/doc/patool.txt @@ -23,9 +23,9 @@ DESCRIPTION (.Z), CPIO (.cpio), DEB (.deb), DMS (.dms), FLAC (.flac), GZIP (.gz), ISO (.iso), LRZIP (.lrz), LZH (.lha, .lzh), LZIP (.lz), LZMA (.lzma), LZOP (.lzo), RPM (.rpm), RAR (.rar, .cbr), RZIP - (.rz), SHN (.shn), TAR (.tar, .cbt), XZ (.xz), ZIP (.zip, .jar, - .cbz), ZOO (.zoo), ZPAQ (.zpaq) and ZSTANDARD (.zst) archive - formats. + (.rz), SHN (.shn), TAR (.tar, .cbt), UDF (.udf), XZ (.xz), ZIP + (.zip, .jar, .cbz), ZOO (.zoo), ZPAQ (.zpaq) and ZSTANDARD + (.zst) archive formats. It relies on helper applications to handle those archive for‐ mats (for example xz for XZ (.xz) archives). diff --git a/doc/web/source/index.md b/doc/web/source/index.md index 755a30c5..96f38c44 100644 --- a/doc/web/source/index.md +++ b/doc/web/source/index.md @@ -25,7 +25,7 @@ APE (.ape), AR (.a), ARC (.arc), ARJ (.arj), BZIP2 (.bz2), BZIP3 (.bz3), CAB (.cab), CHM (.chm), COMPRESS (.Z), CPIO (.cpio), DEB (.deb), DMS (.dms), FLAC (.flac), GZIP (.gz), ISO (.iso), LRZIP (.lrz), LZH (.lha, .lzh), LZIP (.lz), LZMA (.lzma), LZOP (.lzo), RPM (.rpm), RAR (.rar, .cbr), -RZIP (.rz), SHN (.shn), TAR (.tar, .cbt), XZ (.xz), +RZIP (.rz), SHN (.shn), TAR (.tar, .cbt), UDF (.udf), XZ (.xz), ZIP (.zip, .jar, .cbz), ZOO (.zoo) and ZSTANDARD (.zst) archive formats. It relies on helper applications to handle those archive formats diff --git a/patoolib/__init__.py b/patoolib/__init__.py index d7bfce77..d665a28a 100644 --- a/patoolib/__init__.py +++ b/patoolib/__init__.py @@ -82,6 +82,7 @@ 'shar', 'shn', 'tar', + 'udf', 'vhd', 'wim', 'xz', @@ -142,6 +143,7 @@ 'application/x-rzip': 'rzip', 'application/x-shar': 'shar', 'application/x-tar': 'tar', + 'application/x-iso13346-image': 'udf', 'application/x-vhd': 'vhd', 'application/x-xz': 'xz', 'application/x-zip-compressed': 'zip', @@ -329,6 +331,11 @@ None: ('tar', 'star', 'bsdtar', 'py_tarfile'), 'extract': ('unar',), }, + 'udf': { + 'extract': ('7z',), + 'list': ('7z',), + 'test': ('7z',), + }, 'vhd': { 'extract': ( '7z', @@ -444,6 +451,13 @@ '7zzs', ) }, + 'udf': { + None: ( + '7z', + '7zz', + '7zzs', + ) + }, 'vhd': { None: ( '7z', diff --git a/patoolib/programs/p7zip.py b/patoolib/programs/p7zip.py index 69257d41..837f36f0 100644 --- a/patoolib/programs/p7zip.py +++ b/patoolib/programs/p7zip.py @@ -54,7 +54,7 @@ def extract_7z_singlefile( extract_zip = extract_rar = extract_cab = extract_chm = extract_arj = extract_cpio = ( extract_rpm -) = extract_deb = extract_iso = extract_vhd = extract_wim = extract_7z +) = extract_deb = extract_iso = extract_udf = extract_vhd = extract_wim = extract_7z def list_7z(archive, compression, cmd, verbosity, interactive, password=None): @@ -72,9 +72,9 @@ def list_7z(archive, compression, cmd, verbosity, interactive, password=None): list_bzip2 = list_gzip = list_zip = list_compress = list_rar = list_cab = list_chm = ( list_arj -) = list_cpio = list_rpm = list_deb = list_iso = list_xz = list_lzma = list_vhd = ( - list_wim -) = list_7z +) = list_cpio = list_rpm = list_deb = list_iso = list_xz = list_lzma = list_udf = ( + list_vhd +) = list_wim = list_7z def test_7z(archive, compression, cmd, verbosity, interactive, password=None): @@ -92,9 +92,9 @@ def test_7z(archive, compression, cmd, verbosity, interactive, password=None): test_bzip2 = test_gzip = test_zip = test_compress = test_rar = test_cab = test_chm = ( test_arj -) = test_cpio = test_rpm = test_deb = test_iso = test_xz = test_lzma = test_vhd = ( - test_wim -) = test_7z +) = test_cpio = test_rpm = test_deb = test_iso = test_xz = test_lzma = test_udf = ( + test_vhd +) = test_wim = test_7z def create_7z( diff --git a/patoolib/programs/p7zz.py b/patoolib/programs/p7zz.py index 1fce8b41..4895c2ee 100644 --- a/patoolib/programs/p7zz.py +++ b/patoolib/programs/p7zz.py @@ -28,23 +28,23 @@ extract_zip = extract_rar = extract_cab = extract_chm = extract_arj = extract_cpio = ( extract_rpm -) = extract_deb = extract_iso = extract_vhd = extract_wim = extract_7z +) = extract_deb = extract_iso = extract_udf = extract_vhd = extract_wim = extract_7z from .p7zip import list_7z list_bzip2 = list_gzip = list_zip = list_compress = list_rar = list_cab = list_chm = ( list_arj -) = list_cpio = list_rpm = list_deb = list_iso = list_xz = list_lzma = list_vhd = ( - list_wim -) = list_7z +) = list_cpio = list_rpm = list_deb = list_iso = list_xz = list_lzma = list_udf = ( + list_vhd +) = list_wim = list_7z from .p7zip import test_7z test_bzip2 = test_gzip = test_zip = test_compress = test_rar = test_cab = test_chm = ( test_arj -) = test_cpio = test_rpm = test_deb = test_iso = test_xz = test_lzma = test_vhd = ( - test_wim -) = test_7z +) = test_cpio = test_rpm = test_deb = test_iso = test_xz = test_lzma = test_udf = ( + test_vhd +) = test_wim = test_7z # ruff: noqa: F401 from .p7zip import ( diff --git a/tests/archives/test_7z.py b/tests/archives/test_7z.py index 960fd21f..ec69a8cd 100644 --- a/tests/archives/test_7z.py +++ b/tests/archives/test_7z.py @@ -44,6 +44,7 @@ def test_7z(self): self.archive_list('t.rpm') self.archive_list('t.deb') self.archive_list('t.iso') + self.archive_list('t.udf') self.archive_list('t.vhd') self.archive_extract('t.txt.gz', check=Content.Singlefile) self.archive_extract('t.txt.bz2', check=Content.Singlefile) @@ -57,6 +58,7 @@ def test_7z(self): self.archive_extract('t.rpm', check=None) self.archive_extract('t.deb', check=None) self.archive_extract('t.iso') + self.archive_extract('t.udf') self.archive_extract('t.vhd', check=None) self.archive_test('t.txt.gz') self.archive_test('t.txt.bz2') @@ -70,6 +72,7 @@ def test_7z(self): self.archive_test('t.rpm') self.archive_test('t.deb') self.archive_test('t.iso') + self.archive_test('t.udf') self.archive_test('t.vhd') self.archive_create('t.txt.gz', check=Content.Singlefile) self.archive_create('t.txt.bz2', check=Content.Singlefile) diff --git a/tests/data/t.udf b/tests/data/t.udf new file mode 100644 index 0000000000000000000000000000000000000000..5c46bbbe55929b503a01b86ae81c9acca348749e GIT binary patch literal 864256 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 z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N 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 F{68|%Ihz0g literal 0 HcmV?d00001