pythonwise / unpack

#!/usr/bin/env python
'''Unpack compressed files'''

__author__ = "Miki Tebeka <>"

from os import system
from os.path import splitext, isfile
from sys import stderr, version_info
if float("%s.%s" % version_info[:2]) < 2.3:
    raise SystemExit("need at least Python 2.3 to run")

from optparse import OptionParser
parser = OptionParser(usage="usage: %prog [options] FILE[s]")
parser.add_option("-f", "--find", help="just find program, don't unpack",
    dest="find", action="store_true", default=0)

opts, args = parser.parse_args()
if not args:
    parser.error("wrong number of arguments") # Will exit

def _stdout(cmd, file):
    return "%s \"%s\" > %s" % (cmd, file, splitext(file)[0])

def bz(file):
    return _stdout("bzip2 -d -c", file)

def gz(file):
    return _stdout("gunzip -c", file)

EXTS = []
def register(func, *extensions):
    for ext in extensions:
        EXTS.append((ext.lower(), func))

register("tar -xzvf", ".tar.gz", ".tgz", ".tar.Z")
register("tar -xjvf", "", ".tar.bz2", ".tbz")
register(bz, ".bz", ".bz2")
register("tar -xvf", ".tar")
register("unzip", ".zip", "jar", "egg")
register("unarj", ".arj")
register(gz, ".gz", ".Z")
register("unrar x", ".rar")
register("7za x", ".7z")

# We sort by length of extension, longest first
EXTS.sort(lambda e1, e2: cmp(len(e2[0]), len(e1[0])))

err = 0
for file in args:
    if (not opts.find) and (not isfile(file)):
        print >> stderr, "error: can't find", file
        err = 1
    fl = file.lower()
    for ext, cmd in EXTS:
        if fl.endswith(ext):
            if callable(cmd):
                cmd = cmd(file)
                cmd = "%s \"%s\"" % (cmd, file)
            if opts.find:
                print "%s: %s" % (file, cmd)
                if system(cmd) != 0:
                    err = 1
        print "error: can't find a program to extract", file
        err = 1

raise SystemExit(err)