Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import os, os.path
- import sys, time, re, shutil
- from subprocess import Popen, PIPE
- from threading import Thread
- from traceback import print_exc
- """The greatest Warez-Unpacking tool of all times!"""
- ## stuff to set
- RARPATH = "C:/Programme/WinRAR/rar.exe"
- RARFILEPATTERN = re.compile("Entpacke aus (.*)") ##match what file we extract from
- RARALLOK = re.compile("Alles OK")
- DELETEFILES = ['.sfv' ]
- ## Nothing gets done in debug mode, except the unpacking!
- DEBUG = False
- def move( path, folder):
- if DEBUG:
- print "moving", path
- return
- if endswith(path, DELETEFILES ):
- return
- if path != folder:
- target = os.path.join(folder, os.path.basename(path))
- if os.path.isdir( path ):
- shutil.move(path, target)
- else:
- os.rename(path, target)
- def delete(path):
- if DEBUG:
- print "deleting", path
- return
- shutil.rmtree( path )
- def endswith(path, ext_list):
- return any(map(lambda y:path.endswith(y),ext_list))
- class Reader(Thread):
- """Parses stdout from RAR to find out which files have been extrated from"""
- def __init__(self, out, contents):
- Thread.__init__(self)
- self.out = out
- self.contents = contents
- def run(self):
- print " ... ",
- ret = False
- while True:
- line = self.out.readline()
- if line:
- m = RARFILEPATTERN.match(line.strip()) ## find the file stuff was extracted from
- if m:
- self.contents.remove( m.group(1) )
- else:
- ## Unpacking ends somewhen with the RARALLOK string ..
- ok = RARALLOK.search(line.strip())
- if ok:
- ret = True
- else:
- break
- if not ret:
- raise Exception("Unpacking Failed")
- print "Done!"
- def unpack( folder, root=None ):
- if root is None:
- root = folder
- contents = [os.path.join(folder,f) for f in os.listdir(folder)]
- folders = [ f for f in contents if os.path.isdir(f) ]
- files = [ f for f in contents if not os.path.isdir(f) ]
- archives = [ f for f in contents if f.endswith('.rar') ]
- for f in folders:
- unpack(f, root) ## into the depths first
- if len(archives)==0:
- ## contains no archives, simply move to root
- move(folder, root)
- else:
- for arch in archives:
- print "Unpacking", os.path.basename(arch),
- args = [RARPATH, 'x', '-w'+root, '-ri15:0', arch , root]
- p = Popen(args, shell=True, stdout=PIPE)
- r = Reader(p.stdout, contents)
- r.start()
- # wait for the unpacking
- r.join()
- ## done unpacking. It all worked file with no errors
- for f in contents:
- ## move the unused files to the root
- move(f, root)
- ## delete the folder
- if folder != root:
- delete(folder)
- def install():
- import _winreg as winreg
- cmd = 'python "%s" "%%L"' % os.path.join(os.getcwdu(),sys.argv[0])
- winreg.SetValue( winreg.HKEY_CLASSES_ROOT,
- "Directory\\shell\\Unpacker",
- winreg.REG_SZ, "Unpack Folder")
- winreg.SetValue( winreg.HKEY_CLASSES_ROOT,
- "Directory\\shell\\Unpacker\\command",
- winreg.REG_SZ,
- cmd)
- print "Installed!"
- ## Server and clients to queue jobs on one instance
- ## so that multiple unpack operations dont start memory thrashing
- MYPIPE = os.path.join(os.environ['TMP'], "unpacker.pipe" )
- class Pipe(object):
- """Pseudopipe because i have no idea how "real" windows pipes work
- Unix pipes dont work and win32.pipe are a total mystery to me ..."""
- def __init__(self):
- open(MYPIPE, "w").close() # create the "pipe"
- self.fp = open(MYPIPE,'r')
- def read(self):
- if not self.fp.closed:
- return self.fp.read()
- else:
- return None
- def close(self):
- self.fp.close()
- os.remove(MYPIPE)
- class Caller(object):
- def __init__(self, func):
- self.jobs = []
- self.func = func
- def run(self):
- i = 0
- while True:
- if len(self.jobs)==0:
- print "All jobs done!"
- break
- else:
- print "Jobs: ", len(self.jobs), "left, ", i, "done"
- job = self.jobs.pop()
- self.func(job)
- i +=1
- def add(self, x ):
- self.jobs.append( x )
- def quit(self):
- print "Quitting!"
- self.jobs = []
- class Server(Thread):
- def __init__(self, pipe, queue):
- Thread.__init__(self)
- self.queue = queue
- self.pipe = pipe
- def run(self):
- #print "Server started!"
- while True:
- time.sleep(1)
- d = self.pipe.read()
- if d:
- self.queue.add( d )
- if __name__ == "__main__":
- if len(sys.argv) == 1:
- ## install!
- install()
- elif len(sys.argv) == 2:
- if not os.path.exists( MYPIPE ):
- try:
- pipe = Pipe()
- caller = Caller( unpack )
- caller.add( sys.argv[1] )
- server = Server( pipe, caller )
- server.setDaemon(True) ## dont wait for it
- server.start()
- caller.run()
- except Exception, e: # something happend
- caller.quit()
- print_exc()
- print raw_input("Press any key ...")
- finally:
- pipe.close()
- else:
- fp = open(MYPIPE, "a")
- fp.write( sys.argv[1] )
- fp.close()
Add Comment
Please, Sign In to add comment