Guest User

Untitled

a guest
Feb 19th, 2018
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.94 KB | None | 0 0
  1. import os, os.path
  2. import sys, time, re, shutil
  3. from subprocess import Popen, PIPE
  4. from threading import Thread
  5. from traceback import print_exc
  6. """The greatest Warez-Unpacking tool of all times!"""
  7.  
  8.  
  9. ## stuff to set
  10. RARPATH = "C:/Programme/WinRAR/rar.exe"
  11. RARFILEPATTERN = re.compile("Entpacke aus (.*)") ##match what file we extract from
  12. RARALLOK = re.compile("Alles OK")
  13. DELETEFILES = ['.sfv' ]
  14.  
  15. ## Nothing gets done in debug mode, except the unpacking!
  16. DEBUG = False
  17. def move( path, folder):
  18. if DEBUG:
  19. print "moving", path
  20. return
  21. if endswith(path, DELETEFILES ):
  22. return
  23. if path != folder:
  24. target = os.path.join(folder, os.path.basename(path))
  25. if os.path.isdir( path ):
  26. shutil.move(path, target)
  27. else:
  28. os.rename(path, target)
  29.  
  30. def delete(path):
  31. if DEBUG:
  32. print "deleting", path
  33. return
  34. shutil.rmtree( path )
  35.  
  36. def endswith(path, ext_list):
  37. return any(map(lambda y:path.endswith(y),ext_list))
  38.  
  39. class Reader(Thread):
  40. """Parses stdout from RAR to find out which files have been extrated from"""
  41. def __init__(self, out, contents):
  42. Thread.__init__(self)
  43. self.out = out
  44. self.contents = contents
  45. def run(self):
  46. print " ... ",
  47. ret = False
  48. while True:
  49. line = self.out.readline()
  50. if line:
  51. m = RARFILEPATTERN.match(line.strip()) ## find the file stuff was extracted from
  52. if m:
  53. self.contents.remove( m.group(1) )
  54. else:
  55. ## Unpacking ends somewhen with the RARALLOK string ..
  56. ok = RARALLOK.search(line.strip())
  57. if ok:
  58. ret = True
  59. else:
  60. break
  61. if not ret:
  62. raise Exception("Unpacking Failed")
  63. print "Done!"
  64.  
  65. def unpack( folder, root=None ):
  66. if root is None:
  67. root = folder
  68. contents = [os.path.join(folder,f) for f in os.listdir(folder)]
  69. folders = [ f for f in contents if os.path.isdir(f) ]
  70. files = [ f for f in contents if not os.path.isdir(f) ]
  71. archives = [ f for f in contents if f.endswith('.rar') ]
  72. for f in folders:
  73. unpack(f, root) ## into the depths first
  74. if len(archives)==0:
  75. ## contains no archives, simply move to root
  76. move(folder, root)
  77. else:
  78. for arch in archives:
  79. print "Unpacking", os.path.basename(arch),
  80. args = [RARPATH, 'x', '-w'+root, '-ri15:0', arch , root]
  81. p = Popen(args, shell=True, stdout=PIPE)
  82. r = Reader(p.stdout, contents)
  83. r.start()
  84.  
  85. # wait for the unpacking
  86. r.join()
  87.  
  88. ## done unpacking. It all worked file with no errors
  89. for f in contents:
  90. ## move the unused files to the root
  91. move(f, root)
  92. ## delete the folder
  93. if folder != root:
  94. delete(folder)
  95.  
  96. def install():
  97. import _winreg as winreg
  98. cmd = 'python "%s" "%%L"' % os.path.join(os.getcwdu(),sys.argv[0])
  99. winreg.SetValue( winreg.HKEY_CLASSES_ROOT,
  100. "Directory\\shell\\Unpacker",
  101. winreg.REG_SZ, "Unpack Folder")
  102. winreg.SetValue( winreg.HKEY_CLASSES_ROOT,
  103. "Directory\\shell\\Unpacker\\command",
  104. winreg.REG_SZ,
  105. cmd)
  106. print "Installed!"
  107.  
  108.  
  109.  
  110.  
  111. ## Server and clients to queue jobs on one instance
  112. ## so that multiple unpack operations dont start memory thrashing
  113.  
  114. MYPIPE = os.path.join(os.environ['TMP'], "unpacker.pipe" )
  115. class Pipe(object):
  116. """Pseudopipe because i have no idea how "real" windows pipes work
  117. Unix pipes dont work and win32.pipe are a total mystery to me ..."""
  118. def __init__(self):
  119. open(MYPIPE, "w").close() # create the "pipe"
  120. self.fp = open(MYPIPE,'r')
  121. def read(self):
  122. if not self.fp.closed:
  123. return self.fp.read()
  124. else:
  125. return None
  126.  
  127. def close(self):
  128. self.fp.close()
  129. os.remove(MYPIPE)
  130.  
  131. class Caller(object):
  132. def __init__(self, func):
  133. self.jobs = []
  134. self.func = func
  135.  
  136. def run(self):
  137. i = 0
  138. while True:
  139. if len(self.jobs)==0:
  140. print "All jobs done!"
  141. break
  142. else:
  143. print "Jobs: ", len(self.jobs), "left, ", i, "done"
  144. job = self.jobs.pop()
  145. self.func(job)
  146. i +=1
  147.  
  148. def add(self, x ):
  149. self.jobs.append( x )
  150.  
  151. def quit(self):
  152. print "Quitting!"
  153. self.jobs = []
  154.  
  155. class Server(Thread):
  156. def __init__(self, pipe, queue):
  157. Thread.__init__(self)
  158. self.queue = queue
  159. self.pipe = pipe
  160.  
  161. def run(self):
  162. #print "Server started!"
  163. while True:
  164. time.sleep(1)
  165. d = self.pipe.read()
  166. if d:
  167. self.queue.add( d )
  168.  
  169.  
  170. if __name__ == "__main__":
  171. if len(sys.argv) == 1:
  172. ## install!
  173. install()
  174. elif len(sys.argv) == 2:
  175.  
  176. if not os.path.exists( MYPIPE ):
  177. try:
  178. pipe = Pipe()
  179. caller = Caller( unpack )
  180. caller.add( sys.argv[1] )
  181. server = Server( pipe, caller )
  182. server.setDaemon(True) ## dont wait for it
  183. server.start()
  184. caller.run()
  185. except Exception, e: # something happend
  186. caller.quit()
  187. print_exc()
  188. print raw_input("Press any key ...")
  189. finally:
  190. pipe.close()
  191. else:
  192. fp = open(MYPIPE, "a")
  193. fp.write( sys.argv[1] )
  194. fp.close()
Add Comment
Please, Sign In to add comment