Support TAR file handling with the Python tarfile module.

This commit is contained in:
Bastian Kleineidam 2012-05-12 09:00:55 +02:00
parent ac76a91d2d
commit e7f8e00bc5
6 changed files with 109 additions and 6 deletions

View File

@ -14,6 +14,7 @@
* Support extraction of BZIP2 (.bz2) files with the Python bz2 module.
* Support extraction of GZIP (.gz) files with the Python gzip module.
* Support extraction of ZIP (.zip) files with the Python zipfile module.
* Support extraction of TAR (.tar) files with the Python tarfile module.
0.15 "Contraband" (released 8.4.2012)

View File

@ -106,7 +106,7 @@ ArchivePrograms = {
'list': ('echo',),
},
'tar': {
None: ('tar', 'star',),
None: ('tar', 'star', 'pytarfile'),
},
'zip': {
None: ('7z', '7za', 'pyzipfile'),
@ -272,6 +272,8 @@ def find_encoding_program (program, encoding):
found = util.find_program(enc_program)
if found:
return found
elif program == 'pytarfile':
return encoding in ('gzip', 'bzip2')
return None

View File

@ -0,0 +1,79 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2012 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 <http://www.gnu.org/licenses/>.
"""Archive commands for the tarfile Python module."""
from patoolib import util
import tarfile
READ_SIZE_BYTES = 1024*1024
def list_tar (archive, encoding, cmd, **kwargs):
"""List a TAR archive with the tarfile Python module."""
verbose = kwargs['verbose']
if verbose:
util.log_info('listing %s...' % archive)
tfile = tarfile.open(archive)
try:
tfile.list(verbose=verbose)
finally:
tfile.close()
return None
test_tar = list_tar
def extract_tar (archive, encoding, cmd, **kwargs):
"""Extract a TAR archive with the tarfile Python module."""
verbose = kwargs['verbose']
outdir = kwargs['outdir']
# XXX honor outdir
if verbose:
util.log_info('extracting %s...' % archive)
tfile = tarfile.open(archive)
try:
tfile.extractall()
finally:
tfile.close()
if verbose:
util.log_info('... extracted to %s' % outdir)
return None
def create_tar (archive, encoding, cmd, *args, **kwargs):
"""Create a TAR archive with the tarfile Python module."""
verbose = kwargs['verbose']
if verbose:
util.log_info('creating %s...' % archive)
mode = get_tar_mode(encoding)
tfile = tarfile.open(archive, mode)
try:
for filename in args:
tfile.add(filename)
finally:
tfile.close()
return None
def get_tar_mode (compression):
"""Determine tarfile open mode according to the given compression."""
if compression == 'gzip':
return 'w:gz'
if compression == 'bzip2':
return 'w:bz2'
if compression:
msg = 'pytarfile does not support %s for tar compression'
util.log_error(msg % compression)
# no compression
return 'w'

View File

@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Archive commands for the bz2 Python module."""
"""Archive commands for the zipfile Python module."""
from patoolib import util
import zipfile
@ -21,6 +21,7 @@ READ_SIZE_BYTES = 1024*1024
def list_zip (archive, encoding, cmd, **kwargs):
"""List member of a ZIP archive with the zipfile Python module."""
verbose = kwargs['verbose']
if verbose:
util.log_info('listing %s...' % archive)

View File

@ -102,8 +102,10 @@ class ArchiveTest (unittest.TestCase):
command = 'test'
program = self.program
# special case for programs that cannot test what they create
if self.program == 'compress':
if self.program in ('compress', 'pygzip'):
program = 'gzip'
elif self.program == 'pybz2':
program = 'bzip2'
elif self.program == 'zip':
program = 'unzip'
elif self.program == 'rzip':

View File

@ -96,6 +96,20 @@ class TestArchives (ArchiveTest):
self.program = 'star'
self.archive_commands('t.tar.xz')
def test_pytarfile (self):
self.program = 'pytarfile'
self.archive_commands('t.tar')
def test_pytarfile_gz (self):
self.program = 'pytarfile'
self.archive_commands('t.tar.gz')
self.archive_commands('t.tgz')
def test_pytarfile_bz2 (self):
self.program = 'pytarfile'
self.archive_commands('t.tar.bz2')
self.archive_commands('t.tbz2')
@needs_program('bzip2')
def test_bzip2 (self):
self.program = 'bzip2'
@ -103,9 +117,12 @@ class TestArchives (ArchiveTest):
self.archive_test('t .bz2')
self.archive_create('t .bz2', singlefile=True)
@needs_program('bzip2')
def test_pybz2 (self):
self.program = 'pybz2'
self.archive_extract('t .bz2')
# bzip2 is used to test the created archive
self.archive_create('t .bz2', singlefile=True)
@needs_program('pbzip2')
def test_pbzip2 (self):
@ -147,9 +164,7 @@ class TestArchives (ArchiveTest):
def test_pyzipfile (self):
self.program = 'pyzipfile'
self.archive_create('t.zip')
self.archive_extract('t.zip')
self.archive_list('t.zip')
self.archive_commands('t.zip')
@needs_program('gzip')
def test_gzip (self):
@ -158,10 +173,13 @@ class TestArchives (ArchiveTest):
self.archive_commands('t.txt.gz', singlefile=True)
self.archive_extract('t.Z')
@needs_program('gzip')
def test_pygzip (self):
self.program = 'pygzip'
self.archive_extract('t.gz')
self.archive_extract('t.txt.gz')
# gzip is used to test the created archive
self.archive_create('t.gz', singlefile=True)
@needs_program('pigz')
def test_pigz (self):