def extract_file_io(self, chosen): """Extract the file named <name> to the destination directory, mark the file as "ready", then signal a notify() on the Condition returned by setup(). """ if os.path.exists(os.path.join(self._dst, chosen)): cStringIO.StringIO( open(os.path.join(self._dst, chosen), 'rb').read()) if self._type == ZIP: return cStringIO.StringIO(self._zfile.read(chosen)) elif self._type in [TAR, GZIP, BZIP2]: return cStringIO.StringIO(self._tfile.extractfile(chosen).read()) elif self._type == RAR: proc = process.Process( [_rar_exec, 'p', '-inul', '-p-', '--', self._src, chosen]) fobj = proc.spawn() return cStringIO.StringIO(fobj.read()) elif self._type == SEVENZIP: if Archive7z is not None: return cStringIO.StringIO( self._szfile.getmember(chosen).read()) elif _7z_exec is not None: proc = process.Process( [_7z_exec, 'e', '-bd', '-p-', '-so', self._src, chosen]) fobj = proc.spawn() return cStringIO.StringIO(fobj.read())
def _thread_extract(self): """Extract the files in the file list one by one.""" # Extract 7z and rar whole archive - if it SOLID - extract one file is SLOW if self._type in (SEVENZIP, ) and _7z_exec is not None: cmd = [ _7z_exec, 'x', '-bd', '-p-', '-o' + self._dst, '-y', self._src ] proc = process.Process(cmd) proc.spawn() proc.wait() self._condition.acquire() for name in self._files: self._extracted[name] = True self._condition.notify() self._condition.release() if self._type in (RAR, ) and _rar_exec is not None: cwd = os.getcwd() os.chdir(self._dst) cmd = [ _rar_exec, 'x', '-kb', '-p-', '-o-', '-inul', '--', self._src ] proc = process.Process(cmd) proc.spawn() proc.wait() os.chdir(cwd) self._condition.acquire() for name in self._files: self._extracted[name] = True self._condition.notify() self._condition.release() else: for name in self._files: self._extract_file(name) self.close()
def _extract_file(self, name): """Extract the file named <name> to the destination directory, mark the file as "ready", then signal a notify() on the Condition returned by setup(). """ if self._stop: self.close() sys.exit(0) try: if self._type in (ZIP, SEVENZIP): dst_path = os.path.join(self._dst, name) if not os.path.exists(os.path.dirname(dst_path)): os.makedirs(os.path.dirname(dst_path)) new = open(dst_path, 'wb') if self._type == ZIP: new.write(self._zfile.read(name, '-')) elif self._type == SEVENZIP: if Archive7z is not None: new.write(self._szfile.getmember(name).read()) else: if _7z_exec is not None: proc = process.Process([_7z_exec, 'x', '-bd', '-p-', '-o' + self._dst, '-y', self._src, name]) proc.spawn() proc.wait() else: print('! Could not find 7Z file extractor.') new.close() elif self._type in (TAR, GZIP, BZIP2): if os.path.normpath(os.path.join(self._dst, name)).startswith( self._dst): self._tfile.extract(name, self._dst) else: print('! Non-local tar member: {}\n'.format(name)) elif self._type == RAR: if _rar_exec is not None: cwd = os.getcwd() os.chdir(self._dst) proc = process.Process([_rar_exec, 'x', '-kb', '-p-', '-o-', '-inul', '--', self._src, name]) proc.spawn() proc.wait() os.chdir(cwd) else: print('! Could not find RAR file extractor.') elif self._type == MOBI: dst_path = os.path.join(self._dst, name) self._mobifile.extract(name, dst_path) except Exception: # Better to ignore any failed extractions (e.g. from a corrupt # archive) than to crash here and leave the main thread in a # possible infinite block. Damaged or missing files *should* be # handled gracefully by the main program anyway. pass self._condition.acquire() self._extracted[name] = True self._condition.notify() self._condition.release()
def _get_7z_exec(): """Return the name of the RAR file extractor executable, or None if no such executable is found. """ for command in ('7z', '7za', '7zr'): if process.Process([command]).spawn() is not None: return command return None
def setup(self, src, dst): """Setup the extractor with archive <src> and destination dir <dst>. Return a threading.Condition related to the is_ready() method, or None if the format of <src> isn't supported. """ self._src = src self._dst = dst self._type = archive_mime_type(src) self._files = [] self._extracted = {} self._stop = False self._extract_thread = None self._condition = threading.Condition() if self._type == ZIP: self._zfile = zipfile.ZipFile(src, 'r') self._files = self._zfile.namelist() elif self._type in (TAR, GZIP, BZIP2): self._tfile = tarfile.open(src, 'r') self._files = self._tfile.getnames() elif self._type == RAR: global _rar_exec if _rar_exec is None: _rar_exec = _get_rar_exec() if _rar_exec is None: print('! Could not find RAR file extractor.') dialog = gtk.MessageDialog( None, 0, gtk.MESSAGE_WARNING, gtk.BUTTONS_CLOSE, _("Could not find RAR file extractor!")) dialog.format_secondary_markup( _("You need either the <i>rar</i> or the" " <i>unrar</i> program installed in order " "to read RAR (.cbr) files.")) dialog.run() dialog.destroy() return None proc = process.Process([_rar_exec, 'vb', '-p-', '--', src]) fd = proc.spawn() self._files = [name.rstrip(os.linesep) for name in fd.readlines()] fd.close() proc.wait() elif self._type == SEVENZIP: global _7z_exec, Archive7z if not Archive7z: # lib import failed print(': pylzma is not installed... will try 7z tool...') if _7z_exec is None: _7z_exec = _get_7z_exec() else: try: self._szfile = Archive7z(open(src, 'rb'), '-') self._files = self._szfile.getnames() except: Archive7z = None # pylzma can fail on new 7z if _7z_exec is None: _7z_exec = _get_7z_exec() if _7z_exec is None: print('! Could not find 7Z file extractor.') elif not Archive7z: proc = process.Process( [_7z_exec, 'l', '-bd', '-slt', '-p-', src]) fd = proc.spawn() self._files = self._process_7z_names(fd) fd.close() proc.wait() if not _7z_exec and not Archive7z: dialog = gtk.MessageDialog( None, 0, gtk.MESSAGE_WARNING, gtk.BUTTONS_CLOSE, _("Could not find 7Z file extractor!")) dialog.format_secondary_markup( _("You need either the <i>pylzma</i> " "or the <i>p7zip</i> program installed " "in order to read 7Z (.cb7) files.")) dialog.run() dialog.destroy() return None elif self._type == MOBI: self._mobifile = None try: self._mobifile = mobiunpack.MobiFile(src) self._files = self._mobifile.getnames() except mobiunpack.unpackException as e: print('! Failed to unpack MobiPocket: {}'.format(e)) return None else: print('! Non-supported archive format: {}'.format(src)) return None self._setupped = True return self._condition
def testProcInit(self): p = process.Process() self.assertEquals(0, p.Time) self.assertEquals(0, p.frameRate) self.assertEquals(0, p.signal)