def extract(self, password=None): command = "x" if self.fullpath else "e" p = self.call_cmd(command, self.filename, self.dest, password=password) #: Communicate and retrieve stderr self.progress(p) out, err = (to_str(r).strip() if r else "" for r in p.communicate()) if err: if self._RE_BADPWD.search(err): raise PasswordError elif self._RE_BADCRC.search(err): raise CRCError(err) elif self.config.get("ignore_warnings", False) and err.startswith( "WARNING:" ): pass else: #: Raise error if anything is on stderr raise ArchiveError(err) if p.returncode: raise ArchiveError(self._("Process return code: {}").format(p.returncode)) return self.list(password)
def extract(self, password=None): size_total = 0 name = os.path.basename(self.filename)[:-4] chunks = sorted(self.chunks()) num_chunks = len(chunks) #: Verify HjSplit consistency if len(chunks) == 1: raise ArchiveError(f"Cannot merge just one chunk '{chunks[0]}'") for i in range(0, num_chunks): if not os.path.isfile(chunks[i]): raise ArchiveError(f"Chunk '{chunks[i]}' not found") if i == 0: chunk_size = os.path.getsize(chunks[i]) else: if int(chunks[i][-3:]) != i + 1: missing_chunk = "{}.{:0>3d}".format( os.path.splitext(chunks[i])[0], i + 1) raise ArchiveError(f"Chunk '{missing_chunk}' is missing") if i < num_chunks - 1: if os.path.getsize(chunks[i]) != chunk_size: raise ArchiveError( f"Invalid chunk size for chunk '{chunks[i]}'") size_total += chunk_size else: size_total += os.path.getsize(chunks[i]) #: Now do the actual merge with open(os.path.join(self.dest, name), "wb") as output_file: size_written = 0 for part_filename in chunks: self.log_debug("Merging part", part_filename) with open(part_filename, "rb") as part_file: while True: f_buffer = part_file.read(self.BUFFER_SIZE) if f_buffer: output_file.write(f_buffer) size_written += len(f_buffer) self.pyfile.set_progress( (size_written * 100) // size_total) else: break self.log_debug("Finished merging part", part_filename) self.pyfile.set_progress(100)
def list(self, password=None): command = "v" if self.fullpath else "l" p = self.call_cmd(command, "-v", self.filename, password=password) out, err = (to_str(r, "utf-16").strip() if r else "" for r in p.communicate()) if "Cannot open" in err: raise ArchiveError(self._("Cannot open file")) if err: #: Only log error at this point self.log_error(err) files = set() f_grp = 5 if float(self.VERSION) >= 5 else 1 for groups in self._RE_FILES.findall(out): f = groups[f_grp].strip() if not self.fullpath: f = os.path.basename(f) files.add(os.path.join(self.dest, f)) self.files = list(files) return self.files
def verify(self, password=None): try: t = tarfile.open(self.filename, errorlevel=1) except tarfile.CompressionError as exc: raise CRCError(exc) except (OSError, tarfile.TarError) as exc: raise ArchiveError(exc) else: t.close()
def list(self, password=None): p = self.call_cmd("l", self.filename, password=password) out, err = (to_str(r).strip() if r else "" for r in p.communicate()) if any(e in err for e in ("Can not open", "cannot find the file")): raise ArchiveError(self._("Cannot open file")) if p.returncode > 1: raise ArchiveError(self._("Process return code: {}").format(p.returncode)) files = set() for groups in self._RE_FILES.findall(out): f = groups[-1].strip() if not self.fullpath: f = os.path.basename(f) files.add(os.path.join(self.dest, f)) self.files = list(files) return self.files
def extract(self, password=None): command = "x" if self.fullpath else "e" p = self.call_cmd(command, "-o" + self.dest, self.filename, password=password) #: Communicate and retrieve stderr self.progress(p) out, err = (to_str(r).strip() if r else "" for r in p.communicate()) if err: if self._RE_BADPWD.search(err): raise PasswordError elif self._RE_BADCRC.search(err): raise CRCError(err) else: #: Raise error if anything is on stderr raise ArchiveError(err) if p.returncode > 1: raise ArchiveError(self._("Process return code: {}").format(p.returncode))
def extract(self, password=None): self.verify(password) try: with zipfile.ZipFile(self.filename, "r") as z: z.setpassword(password) z.extractall(self.dest) self.files = [os.path.join(self.dest, _f) for _f in z.namelist() if _f[-1] != os.path.sep] return self.files except RuntimeError as exc: raise ArchiveError(exc)
def verify(self, password=None): try: with zipfile.ZipFile(self.filename, "r") as z: z.setpassword(password) badfile = z.testzip() if badfile is not None: raise CRCError(badfile) except (zipfile.BadZipfile, zipfile.LargeZipFile) as exc: raise ArchiveError(exc) except RuntimeError as exc: if "encrypted" in exc.args[0] or "Bad password" in exc.args[0]: raise PasswordError(exc) else: raise CRCError(exc)
def extract(self, password=None): self.verify(password) try: with tarfile.open(self.filename, errorlevel=2) as t: t.extractall(self.dest) self.files = t.getnames() return self.files except tarfile.ExtractError as exc: self.log_warning(exc) except tarfile.CompressionError as exc: raise CRCError(exc) except (OSError, tarfile.TarError) as exc: raise ArchiveError(exc)
def extract(self, password=None): self.verify(password) try: with zipfile.ZipFile(self.filename, "r") as z: z.setpassword(password) members = (member for member in z.namelist() if not any(fnmatch.fnmatch(member, exclusion) for exclusion in self.excludefiles)) z.extractall(self.dest, members = members) self.files = [os.path.join(self.dest, _f) for _f in z.namelist() if _f[-1] != os.path.sep and _f in members] return self.files except RuntimeError as exc: raise ArchiveError(exc)