If it won't be simple, it simply won't be. [Hire me, source code] by Miki Tebeka, CEO, 353Solutions

Thursday, September 28, 2006

unpack

I always have trouble remembering which command opens which archive (.tar.gz, .bz2, .zip ...). This is why I have a handy little utility the called "unpack" that knows by the file extension which command to call:

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

Create a symbolic link called "zview" to this file or specify -l to view
'''

__author__ = "Miki Tebeka <miki.tebeka@gmail.com>"

from os import system
from os.path import splitext, isfile
from operator import itemgetter

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

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

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

class Archive:
extensions = {} # Extension -> instance

def __init__(self, unpack, list, extensions):
self.unpack = unpack
self.list = list
for ext in extensions:
Archive.extensions[ext] = self

Archive("tar -xzvf", "tar -tzf", [".tar.gz", ".tgz", ".tar.z"]),
Archive("tar -xjvf", "tar -tjf", [".tar.bz", ".tar.bz2"]),
Archive(bz, "", [".bz", ".bz2"]),
Archive("tar -xvf", "tar -tf", [".tar"]),
Archive("unzip", "unzip -l", [".zip", "jar", "egg"]),
Archive("unarj e", "unarj l", [".arj"]),
Archive(gz, "", [".gz", ".Z"]),
Archive("unrar x", "unrar lb", [".rar"]),
Archive("7za x", "7za l", [".7z"])

def find_archive(filename):
# Find *longest* matching extension
for ext in sorted(Archive.extensions, reverse=1, key=len):
if filename.lower().endswith(ext):
return Archive.extensions[ext]

def main(argv=None):
if argv is None:
import sys
argv = sys.argv

from optparse import OptionParser
parser = OptionParser(usage="usage: %prog [options] FILE")
parser.add_option("-s", "--show", help="just show command, don't run",
dest="show", action="store_true", default=0)
parser.add_option("-l", "--list", help="list files in archive",
dest="list", action="store_true", default=0)


opts, args = parser.parse_args(argv[1:])
if len(args) != 1:
parser.error("wrong number of arguments") # Will exit

infile = args[0]
if (not opts.show) and (not isfile(infile)):
raise SystemExit("error: can't find %s" % infile)

archive = find_archive(infile)
if not archive:
raise SystemExit("error: don't know how to handle %s" % infile)
list = opts.list or ("zview" in __file__)
command = archive.list if list else archive.unpack

infile = infile.replace("'", "\\'")

if callable(command):
command = command(infile)
else:
command = "%s '%s'" % (command, infile)

if opts.show:
print command
raise SystemExit

raise SystemExit(system(command))

if __name__ == "__main__":
main()



There is also a similar one for viewing zip content.

1 comment:

shoogle said...

nice & cool script...

Blog Archive