Пример #1
0
    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)
Пример #2
0
    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)
Пример #3
0
    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
Пример #4
0
    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()
Пример #5
0
    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
Пример #6
0
    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))
Пример #7
0
    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)
Пример #8
0
    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)
Пример #9
0
    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)
Пример #10
0
    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)