Guest User

Untitled

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