#!/usr/bin/python2.4 #vim: set nu #!/usr/bin/env python """ *note*: %n = name archive %e = ext of archive (.zip, .gz, etc) options for each archiver that anyone would care about: unarchive to stdout unarchive to current directory [default] unarchive to ./%n/ unarchive flat (no dirs) and some stats: list files compression ratio """ import sys, traceback, threading, time from optparse import OptionParser import rcfile, wraplib usage = "usage: %prog [options] file ..." version = "%prog 0.1" _debug = False parser = OptionParser(usage=usage, version=version) parser.add_option("-v", "--verbose", action="store_true", dest="verbose", help="be verbose with output") parser.add_option("-c", "--stdout", action="store_true", dest="stdout", help="unarchive to standard out") parser.add_option("-d", "--destdir", dest="destdir", metavar="DIR", help="unarchive to DIR") parser.add_option("-f", "--flat", action="store_true", dest="flat", help="unarchive flat (files only, no dirs)") parser.add_option("-l", "--list", action="store_true", dest="list", help="list contents of the archive") parser.add_option("-s", "--stats", action="store_true", dest="stats", help="show stats on available archive programs") parser.add_option("-r", "--rar", action="store_true", dest="rar", help="force usage of 'rar'") parser.add_option("-z", "--zip", action="store_true", dest="zip", help="force usage of 'zip'") parser.add_option("-g", "--gzip", action="store_true", dest="gzip", help="force usage of 'gzip'") parser.add_option("-t", "--tar", action="store_true", dest="tar", help="force usage of 'tar'") parser.add_option("-7", "--7zip", action="store_true", dest="7zip", help="force usage of '7zip'") parser.add_option("-a", "--ace", action="store_true", dest="ace", help="force usage of 'ace'") parser.add_option("-b", "--bzip2", action="store_true", dest="bzip2", help="force usage of 'bzip2'") (options, args) = parser.parse_args() # if no non options are passed, print help & exit if len(args) < 1: parser.print_help() sys.exit(1) settings = rcfile.rcFile() def print_debug(string): global _debug if _debug: print str(string) def printv(string): global options if options.verbose: print str(string) def destdir(opts, rcfile, filetype=''): if opts.destdir: return opts.destdir elif rcfile[filetype + '_destdir']: return rcfile[filetype + '_destdir'] elif rcfile['destdir']: return rcfile['destdir'] return None # has a simple, non-polling mainloop class Program: "main Program timed poller and mainloop" def __init__(self, archiver): global print_debug, printv, options if not archiver: return self.archiver = archiver self.interval = 0.01 # 100 milliseconds self.print_debug = print_debug self.printv = printv self.q = wraplib.MSG_QUEUE self.options = options def start(self): try: self.archiver.start() self.setupTimer() while self.archiver.isAlive(): time.sleep(self.interval) self.processQueue() self.stopTimer() except KeyboardInterrupt: self.stopTimer() wraplib.CMD_QUEUE.put('close pls kthx') archiver.join(1.0) except: print "ERROR:" traceback.print_exc(file=sys.stdout) self.stopTimer() wraplib.CMD_QUEUE.put('close pls kthx') archiver.join(1.0) raise def setupTimer(self): self.timer = threading.Timer(self.interval, self.processQueue) self.timer.start() def stopTimer(self): self.timer.cancel() self.timer = None def processQueue(self): try: while 1: msg = self.q.get(False) # raise exception if empty self.processMsg(msg) except: # we don't catch Queue.Empty so we don't have to import if self.timer: self.setupTimer() def processMsg(self, msg): print msg filename = args[0] filetype = wraplib.filetype(filename) filebase = filename.strip(filetype)[:-1] # strip off last '.' opts = {} archiver = None dd = destdir(options, settings, filetype=filetype) print_debug("Options:" + str(options)) print_debug("Settings: %s" % (settings)) print_debug("filename: %s\nfilebase: %s" % (filename, filebase)) print_debug("file type '%s' detected..." % (filetype)) print_debug("destdir: %s" % (dd)) if dd: opts['destdir'] = dd if options.verbose: opts['verbose'] = True if options.list: opts['list'] = True if options.flat: opts['flat'] = True if filetype in ['tar', 'tgz', 'tbz']: if settings['tar_mode']: pass archiver = wraplib.Tar(opts, filename) # bzip2 and gzip shouldn't actually have destdir abilities anyway elif filetype == 'bzip2': if opts['destdir'] == '.': opts['destdir'] = False archiver = wraplib.Bzip2(opts, filename) elif filetype == 'gzip': if opts['destdir'] == '.': opts['destdir'] = False archiver = wraplib.Gzip(opts, filename) elif filetype == 'zip': if settings['zip_mode']: print_debug('zip mode: ' + settings['zip_mode']) archiver = wraplib.Zip(opts, filename) elif filetype == 'rar': if settings['rar_mode']: print_debug('rar mode: ' + settings['rar_mode']) archiver = wraplib.Rar(opts, filename) else: print "Error: filetype not yet supported." sys.exit() pg = Program(archiver) pg.start()