Test if encoding is supported by the archive program.

This commit is contained in:
Bastian Kleineidam 2010-02-23 19:31:14 +01:00
parent ff82c2a100
commit c647f65a87
4 changed files with 49 additions and 12 deletions

View File

@ -1,3 +1,8 @@
0.3 "" (released xx.x.2010)
* Better test if encodings of archive commands are supported
(for example .tar.Z needs a decompress program).
0.2 "Birdy" (released 22.2.2010)
* Add support for LZMA and XZ archives.

View File

@ -52,6 +52,16 @@ ArchiveMimetypes = {
'application/x-xz': 'xz',
}
# List of programs supporting the given encoding
EncodingPrograms = {
'gzip': ('gzip',),
'bzip2': ('pbzip2', 'bzip2'),
'compress': ('compress',),
'lzma': ('lzma',),
'xz': ('xz',),
}
# List of programs supporting the given archive format and command.
# If command is None, the program supports all commands (list, extract, ...)
ArchivePrograms = {
@ -141,7 +151,7 @@ ProgramModules = {
def get_archive_format (filename):
"""Detect filename archive format."""
"""Detect filename archive format and optional encoding."""
mime, encoding = util.guess_mime(filename)
if not (mime or encoding):
raise util.PatoolError("unknown archive format for file `%s'" % filename)
@ -153,6 +163,9 @@ def get_archive_format (filename):
format, encoding = encoding, None
else:
raise util.PatoolError("unknown archive format for file `%s' (mime-type is `%s')" % (filename, mime))
if format == encoding:
# file cannot be in same format encoded
encoding = None
return format, encoding
@ -182,11 +195,29 @@ def find_archive_program (format, command):
for program in programs:
exe = find_executable(program)
if exe:
if program == '7z' and format == 'rar' and not p7zip_supports_rar():
continue
return exe
# no programs found
raise util.PatoolError("could not find an executable program to %s format %s; candidates are (%s)," % (command, format, ",".join(programs)))
def find_encoding_program (program, encoding):
"""Find suitable encoding program and return it. Returns None if
no encoding program could be found"""
if program in ('tar', 'star'):
for enc_program in EncodingPrograms[encoding]:
found = find_executable(enc_program)
if found:
return found
return None
def p7zip_supports_rar ():
"""Determine if the RAR codec is installed for 7z program."""
return os.path.exists('/usr/lib/p7zip/Codecs/Rar29.so')
def list_formats ():
for format in ArchiveFormats:
print format, "files:"
@ -204,7 +235,7 @@ def list_formats ():
if encs:
print "(supported encodings: %s)" % ", ".join(encs),
elif format == '7z':
if os.path.exists('/usr/lib/p7zip/Codecs/Rar29.so'):
if p7zip_supports_rar():
print "(rar archives supported)",
else:
print "(rar archives not supported)",
@ -216,7 +247,7 @@ def list_formats ():
return 0
def parse_config (format, encoding, command, **kwargs):
def parse_config (archive, format, encoding, command, **kwargs):
"""The configuration determines which program to use for which
archive format for the given command.
@raises: PatoolError if command for given format and encoding
@ -238,10 +269,9 @@ def parse_config (format, encoding, command, **kwargs):
for key, value in kwargs.items():
if value is not None:
config[key] = value
if encoding:
program = os.path.basename(config['program'])
if program in ('tar', 'star') and not find_executable(encoding):
raise util.PatoolError("cannot %s archive because program `%s' was not found" % (command, encoding))
program = os.path.basename(config['program'])
if encoding and not find_encoding_program(program, encoding):
raise util.PatoolError("cannot %s archive `%s': encoding `%s' not supported by %s" % (archive, command, encoding, program))
return config
@ -314,7 +344,7 @@ def _handle_archive (archive, command, *args, **kwargs):
format, encoding = get_archive_format(archive)
check_archive_format(format, encoding)
check_archive_command(command)
config = parse_config(format, encoding, command, **kwargs)
config = parse_config(archive, format, encoding, command, **kwargs)
if command == 'create':
# check if archive already exists
if os.path.exists(archive) and not config['force']:

View File

@ -110,7 +110,5 @@ def needs_codec (program, codec):
def find_codec (program, codec):
if program == '7z' and codec == 'rar':
return os.path.exists('/usr/lib/p7zip/Codecs/Rar29.so')
if program == 'tar':
return find_executable(codec)
return False
return patoolib.p7zip_supports_rar()
return patoolib.find_encoding_program(program, codec)

View File

@ -31,3 +31,7 @@ class TestConfiguration (unittest.TestCase):
for command in commands:
if command is not None:
self.assertTrue(command in patoolib.ArchiveCommands)
def test_encoding_programs (self):
self.assertEqual(set(patoolib.ArchiveEncodings),
set(patoolib.EncodingPrograms.keys()))