From cab43b1238567ae802ed696d8b1f59238e35cd43 Mon Sep 17 00:00:00 2001 From: Bastian Kleineidam Date: Thu, 4 Mar 2010 16:42:37 +0100 Subject: [PATCH] Added support for LZIP archives. --- doc/changelog.txt | 1 + doc/todo.txt | 1 - patoolib/__init__.py | 12 ++++++-- patoolib/programs/echo.py | 4 +++ patoolib/programs/lzip.py | 56 +++++++++++++++++++++++++++++++++++++ patoolib/programs/star.py | 4 +-- patoolib/programs/tar.py | 23 ++++++++------- patoolib/util.py | 3 ++ tests/data/t.tar.lz | Bin 0 -> 166 bytes tests/data/t.tar.lz.foo | Bin 0 -> 166 bytes tests/data/t.txt.lz | Bin 0 -> 39 bytes tests/data/t.txt.lz.foo | Bin 0 -> 39 bytes tests/test_archives.py | 19 ++++++++++++- tests/test_foo_archives.py | 21 ++++++++++++++ tests/test_mime.py | 4 +++ 15 files changed, 132 insertions(+), 16 deletions(-) create mode 100644 patoolib/programs/lzip.py create mode 100644 tests/data/t.tar.lz create mode 100644 tests/data/t.tar.lz.foo create mode 100644 tests/data/t.txt.lz create mode 100644 tests/data/t.txt.lz.foo diff --git a/doc/changelog.txt b/doc/changelog.txt index 5493060..c3ac266 100644 --- a/doc/changelog.txt +++ b/doc/changelog.txt @@ -1,6 +1,7 @@ 0.5 "" (released xx.xx.2010) * Ported to Python 2.4. + * Added support for LZIP (.lz) archives. 0.4 "Nikita" (released 3.3.2010) diff --git a/doc/todo.txt b/doc/todo.txt index 2339cc7..8d50c03 100644 --- a/doc/todo.txt +++ b/doc/todo.txt @@ -1,2 +1 @@ -- Support lzip archives - Support zoo archives diff --git a/patoolib/__init__.py b/patoolib/__init__.py index 9b9a02a..d662382 100644 --- a/patoolib/__init__.py +++ b/patoolib/__init__.py @@ -22,11 +22,11 @@ ArchiveCommands = ('list', 'extract', 'test', 'create') # Supported archive formats ArchiveFormats = ('gzip', 'bzip2', 'tar', 'zip', 'compress', '7z', 'rar', - 'cab', 'arj', 'cpio', 'rpm', 'deb', 'lzop', 'lzma', 'xz') + 'cab', 'arj', 'cpio', 'rpm', 'deb', 'lzop', 'lzma', 'xz', 'lzip') # Supported encodings (used with tar for example) # Note that all encodings must also be archive formats -ArchiveEncodings = ('gzip', 'bzip2', 'compress', 'lzma', 'xz') +ArchiveEncodings = ('gzip', 'bzip2', 'compress', 'lzma', 'xz', 'lzip') # Map MIME types to archive format ArchiveMimetypes = { @@ -49,6 +49,7 @@ ArchiveMimetypes = { 'application/x-lzop': 'lzop', 'application/x-lzma': 'lzma', 'application/x-xz': 'xz', + 'application/x-lzip': 'lzip', } # List of programs supporting the given encoding @@ -59,6 +60,7 @@ EncodingPrograms = { 'compress': ('compress',), 'lzma': ('lzma',), 'xz': ('xz',), + 'lzip': ('lzip',), } # List of programs supporting the given archive format and command. @@ -82,6 +84,12 @@ ArchivePrograms = { 'gzip': { None: ('gzip', '7z'), }, + 'lzip': { + 'extract': ('lzip',), + 'list': ('echo',), + 'test': ('lzip',), + 'create': ('lzip',), + }, 'compress': { 'extract': ('gzip', '7z', 'uncompress.real'), 'list': ('7z', 'echo',), diff --git a/patoolib/programs/echo.py b/patoolib/programs/echo.py index dab8e25..ff43f2c 100644 --- a/patoolib/programs/echo.py +++ b/patoolib/programs/echo.py @@ -34,6 +34,10 @@ def list_xz (archive, encoding, cmd, **kwargs): """List a XZ archive.""" return stripext(cmd, archive) +def list_lzip (archive, encoding, cmd, **kwargs): + """List a LZIP archive.""" + return stripext(cmd, archive) + def stripext (cmd, archive): """Echo the name without suffix.""" return [cmd, util.stripext(archive)] diff --git a/patoolib/programs/lzip.py b/patoolib/programs/lzip.py new file mode 100644 index 0000000..725ee85 --- /dev/null +++ b/patoolib/programs/lzip.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2010 Bastian Kleineidam +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +"""Archive commands for the lzip program.""" +from patoolib import util + + +def extract_lzip (archive, encoding, cmd, **kwargs): + """Extract a LZIP archive.""" + cmdlist = [cmd] + if kwargs['verbose']: + cmdlist.append('-v') + cmdlist.extend(['-c', '-d']) + cmdlist.append('--') + outfile = util.get_single_outfile(kwargs['outdir'], archive) + cmdlist.extend([archive, '>', outfile]) + # note that for shell calls the command must be a string + cmd = " ".join([util.shell_quote(x) for x in cmdlist]) + return (cmd, {'shell': True}) + + +def test_lzip (archive, encoding, cmd, **kwargs): + """Test a LZIP archive.""" + cmdlist = [cmd] + if kwargs['verbose']: + cmdlist.append('-v') + cmdlist.append('-t') + cmdlist.append('--') + cmdlist.append(archive) + return cmdlist + + +def create_lzip (archive, encoding, cmd, *args, **kwargs): + """Create a LZIP archive.""" + cmdlist = [cmd] + if kwargs['verbose']: + cmdlist.append('-v') + cmdlist.append('-c') + cmdlist.append('--') + cmdlist.extend(args) + cmdlist.extend(['>', archive]) + # note that for shell calls the command must be a string + cmd = " ".join([util.shell_quote(x) for x in cmdlist]) + return (cmd, {'shell': True}) diff --git a/patoolib/programs/star.py b/patoolib/programs/star.py index 5b3abbf..740b5a4 100644 --- a/patoolib/programs/star.py +++ b/patoolib/programs/star.py @@ -41,14 +41,14 @@ def create_tar (archive, encoding, cmd, *args, **kwargs): def add_star_opts (cmdlist, encoding, verbose): # Note that star autodetects encoding compression, but displays a warning - # which we want to avoie. + # which we want to avoid. if encoding == 'gzip': cmdlist.append('-z') elif encoding == 'compress': cmdlist.append('-Z') elif encoding == 'bzip2': cmdlist.append('-bz') - elif encoding in ('lzma', 'xz'): + elif encoding in ('lzma', 'xz', 'lzip'): # use compress-program option cmdlist.append('compress-program=%s' % encoding) if verbose: diff --git a/patoolib/programs/tar.py b/patoolib/programs/tar.py index 8abccda..27259e9 100644 --- a/patoolib/programs/tar.py +++ b/patoolib/programs/tar.py @@ -18,20 +18,14 @@ def extract_tar (archive, encoding, cmd, **kwargs): """Extract a TAR archive.""" cmdlist = [cmd, '--extract'] - if encoding: - cmdlist.append('--%s' % encoding) - if kwargs['verbose']: - cmdlist.append('--verbose') + add_tar_opts(cmdlist, encoding, kwargs['verbose']) cmdlist.extend(["--file", archive, '--directory', kwargs['outdir']]) return cmdlist def list_tar (archive, encoding, cmd, **kwargs): """List a TAR archive.""" cmdlist = [cmd, '--list'] - if encoding: - cmdlist.append('--%s' % encoding) - if kwargs['verbose']: - cmdlist.append('--verbose') + add_tar_opts(cmdlist, encoding, kwargs['verbose']) cmdlist.extend(["--file", archive]) return cmdlist @@ -40,8 +34,17 @@ test_tar = list_tar def create_tar (archive, encoding, cmd, *args, **kwargs): """Create a TAR archive.""" cmdlist = [cmd, '--create'] - if encoding: - cmdlist.append('--%s' % encoding) + add_tar_opts(cmdlist, encoding, kwargs['verbose']) cmdlist.extend(["--file", archive, '--']) cmdlist.extend(args) return cmdlist + + +def add_tar_opts (cmdlist, encoding, verbose): + if encoding == 'lzip': + # use compress-program option + cmdlist.extend(['--use-compress-program', encoding]) + elif encoding: + cmdlist.append('--%s' % encoding) + if verbose: + cmdlist.append('--verbose') diff --git a/patoolib/util.py b/patoolib/util.py index cd7345d..597908d 100644 --- a/patoolib/util.py +++ b/patoolib/util.py @@ -27,6 +27,7 @@ mimedb = mimetypes.MimeTypes(strict=False) mimedb.encodings_map['.bz2'] = 'bzip2' mimedb.encodings_map['.lzma'] = 'lzma' mimedb.encodings_map['.xz'] = 'xz' +mimedb.encodings_map['.lz'] = 'lzip' mimedb.suffix_map['.tbz2'] = '.tar.bz2' mimedb.add_type('application/x-lzop', '.lzo', strict=False) mimedb.add_type('application/x-arj', '.arj', strict=False) @@ -115,6 +116,7 @@ Encoding2Mime = { 'bzip2': "application/x-bzip2", 'compress': "application/x-compress", 'lzma': "application/x-lzma", + 'lzip': "application/x-lzip", 'xz': "application/x-xz", } Mime2Encoding = dict([(value, key) for key, value in Encoding2Mime.items()]) @@ -185,6 +187,7 @@ FileText2Mime = { "xz compressed data": "application/x-xz", "Zip archive data": "application/zip", "compress'd data": "application/x-compress", + "lzip compressed data": "application/x-lzip", } def guess_mime_file (file_prog, filename): diff --git a/tests/data/t.tar.lz b/tests/data/t.tar.lz new file mode 100644 index 0000000000000000000000000000000000000000..c1c9500fdf8231f49a791f9469324dd17e722830 GIT binary patch literal 166 zcmeZ?@(f@+$6&?1M|ydWiOa+7)7&K^_`W^x;$Xj8;Vq`{;M0+6?+a$ QIJcRJL4yGdmO&^60D?S7@Bjb+ literal 0 HcmV?d00001 diff --git a/tests/data/t.tar.lz.foo b/tests/data/t.tar.lz.foo new file mode 100644 index 0000000000000000000000000000000000000000..c1c9500fdf8231f49a791f9469324dd17e722830 GIT binary patch literal 166 zcmeZ?@(f@+$6&?1M|ydWiOa+7)7&K^_`W^x;$Xj8;Vq`{;M0+6?+a$ QIJcRJL4yGdmO&^60D?S7@Bjb+ literal 0 HcmV?d00001 diff --git a/tests/data/t.txt.lz b/tests/data/t.txt.lz new file mode 100644 index 0000000000000000000000000000000000000000..92fe36a98b075de293791109ec38ecdc1ef1dfa8 GIT binary patch literal 39 lcmeZ?@(f_)VUXgfjaq&G|NrlY7#IvS+b%LQK!7@w1_1M031$EQ literal 0 HcmV?d00001 diff --git a/tests/data/t.txt.lz.foo b/tests/data/t.txt.lz.foo new file mode 100644 index 0000000000000000000000000000000000000000..92fe36a98b075de293791109ec38ecdc1ef1dfa8 GIT binary patch literal 39 lcmeZ?@(f_)VUXgfjaq&G|NrlY7#IvS+b%LQK!7@w1_1M031$EQ literal 0 HcmV?d00001 diff --git a/tests/test_archives.py b/tests/test_archives.py index b8d39eb..18df0c3 100644 --- a/tests/test_archives.py +++ b/tests/test_archives.py @@ -45,6 +45,11 @@ class TestArchives (ArchiveTest): self.program = 'tar' self.archive_commands('t.tar.lzma') + @needs_codec('tar', 'lzip') + def test_tar_lzip (self): + self.program = 'tar' + self.archive_commands('t.tar.lz') + @needs_codec('tar', 'xz') def test_tar_xz (self): self.program = 'tar' @@ -78,6 +83,11 @@ class TestArchives (ArchiveTest): self.program = 'star' self.archive_commands('t.tar.lzma') + @needs_codec('tar', 'lzip') + def test_star_lzip (self): + self.program = 'star' + self.archive_commands('t.tar.lz') + @needs_codec('tar', 'xz') def test_star_xz (self): self.program = 'star' @@ -103,6 +113,7 @@ class TestArchives (ArchiveTest): self.archive_list('t.bz2') self.archive_list('t.Z') self.archive_list('t.lzma') + self.archive_list('t.txt.lz') @needs_program('unzip') def test_unzip (self): @@ -242,10 +253,16 @@ class TestArchives (ArchiveTest): self.archive_extract('t.lzma') self.archive_create('t.lzma', singlefile=True) + @needs_program('lzip') + def test_lzip (self): + self.program = 'lzip' + self.archive_test('t.txt.lz') + self.archive_extract('t.txt.lz') + self.archive_create('t.txt.lz', singlefile=True) + @needs_program('xz') def test_xz (self): self.program = 'xz' self.archive_test('t.xz') self.archive_extract('t.xz') self.archive_create('t.xz', singlefile=True) - diff --git a/tests/test_foo_archives.py b/tests/test_foo_archives.py index 624427e..958b48d 100644 --- a/tests/test_foo_archives.py +++ b/tests/test_foo_archives.py @@ -51,6 +51,12 @@ class TestArchives (ArchiveTest): # self.program = 'tar' # self.archive_commands('t.tar.lzma.foo', format="tar", encoding="lzma") + @needs_program('file') + @needs_codec('tar', 'lzip') + def test_tar_lzip (self): + self.program = 'tar' + self.archive_commands('t.tar.lz.foo', format="tar", encoding="lzip") + @needs_program('file') @needs_codec('tar', 'xz') def test_tar_xz (self): @@ -91,6 +97,12 @@ class TestArchives (ArchiveTest): # self.program = 'star' # self.archive_commands('t.tar.lzma.foo', format="tar", encoding="lzma") + @needs_program('file') + @needs_codec('tar', 'lzip') + def test_star_lzip (self): + self.program = 'star' + self.archive_commands('t.tar.lz.foo', format="tar", encoding="lzip") + @needs_program('file') @needs_codec('tar', 'xz') def test_star_xz (self): @@ -121,6 +133,7 @@ class TestArchives (ArchiveTest): self.archive_list('t.Z.foo') # file(1) does not recognize .lzma files #self.archive_list('t.lzma.foo') + self.archive_list('t.txt.lz.foo') @needs_program('file') @needs_program('unzip') @@ -278,6 +291,14 @@ class TestArchives (ArchiveTest): # self.archive_extract('t.lzma.foo') # self.archive_create('t.lzma.foo', format="lzma", singlefile=True) + @needs_program('file') + @needs_program('lzip') + def test_lzip (self): + self.program = 'lzip' + self.archive_test('t.txt.lz.foo') + self.archive_extract('t.txt.lz.foo') + self.archive_create('t.txt.lz.foo', format="lzip", singlefile=True) + @needs_program('file') @needs_program('xz') def test_xz (self): diff --git a/tests/test_mime.py b/tests/test_mime.py index f28ac65..6ccb541 100644 --- a/tests/test_mime.py +++ b/tests/test_mime.py @@ -49,6 +49,8 @@ class TestMime (unittest.TestCase): self.mime_test("t.lzma", "application/x-lzma", None) # file(1) does not recognize .lzma files #self.mime_test("t.lzma.foo", "application/x-lzma", None) + self.mime_test("t.txt.lz", "application/x-lzip", None) + self.mime_test("t.txt.lz.foo", "application/x-lzip", None) self.mime_test("t.lzo", "application/x-lzop", None) self.mime_test("t.lzo.foo", "application/x-lzop", None) self.mime_test("t.rar", "application/x-rar", None) @@ -66,6 +68,8 @@ class TestMime (unittest.TestCase): #self.mime_test("t.tar.lzma.foo", "application/x-tar", "lzma") self.mime_test("t.tar.xz", "application/x-tar", "xz") self.mime_test("t.tar.xz.foo", "application/x-tar", "xz") + self.mime_test("t.tar.lz", "application/x-tar", "lzip") + self.mime_test("t.tar.lz.foo", "application/x-tar", "lzip") self.mime_test("t.tar.Z", "application/x-tar", "compress") self.mime_test("t.tar.Z.foo", "application/x-tar", "compress") self.mime_test("t.taz", "application/x-tar", "compress")