Пример #1
0
    def _extract_members(self, members, targetpath, pwd):
        """Extract the RarInfo objects 'members' to a physical
           file on the path targetpath.
        """
        archive = unrarlib.RAROpenArchiveDataEx(self.filename,
                                                mode=constants.RAR_OM_EXTRACT)
        handle = self._open(archive)

        password = pwd or self.pwd
        if password is not None:
            unrarlib.RARSetPassword(handle, b(password))

        try:
            rarinfo = self._read_header(handle)
            while rarinfo is not None:
                if rarinfo.filename in members:
                    self._process_current(handle, constants.RAR_EXTRACT,
                                          targetpath)
                else:
                    self._process_current(handle, constants.RAR_SKIP)
                rarinfo = self._read_header(handle)
        except unrarlib.MissingPassword:
            raise RuntimeError("File is encrypted, password required")
        except unrarlib.BadPassword:
            raise RuntimeError("Bad password for File")
        except unrarlib.BadDataError:
            raise RuntimeError("File CRC Error")
        except unrarlib.UnrarException as e:
            raise BadRarFile("Bad RAR archive data: %s" % str(e))
        finally:
            self._close(handle)
Пример #2
0
    def _extract_members(self, members, targetpath, pwd):
        """Extract the RarInfo objects 'members' to a physical
           file on the path targetpath.
        """
        archive = unrarlib.RAROpenArchiveDataEx(self.filename,
                                                mode=constants.RAR_OM_EXTRACT)
        handle = self._open(archive)

        password = pwd or self.pwd
        if password is not None:
            unrarlib.RARSetPassword(handle, b(password))

        try:
            rarinfo = self._read_header(handle)
            while rarinfo is not None:
                if rarinfo.filename in members:
                    self._process_current(handle, constants.RAR_EXTRACT,
                                          targetpath)
                else:
                    self._process_current(handle, constants.RAR_SKIP)
                rarinfo = self._read_header(handle)
        except unrarlib.UnrarException:
            raise BadRarFile("Bad RAR archive data.")
        finally:
            self._close(handle)
Пример #3
0
    def open(self, member):
        #print "opening %s..." % member
        # based on https://github.com/matiasb/python-unrar/pull/4/files
        if isinstance(member, rarfile.RarInfo):
            member = member.filename
        archive = unrarlib.RAROpenArchiveDataEx(self.filename,
                                                mode=constants.RAR_OM_EXTRACT)
        handle = self._open(archive)
        found, buf = False, []

        def _callback(msg, UserData, P1, P2):
            if msg == constants.UCM_PROCESSDATA:
                data = (ctypes.c_char * P2).from_address(P1).raw
                buf.append(data)
            return 1

        c_callback = unrarlib.UNRARCALLBACK(_callback)
        unrarlib.RARSetCallback(handle, c_callback, 1)
        try:
            rarinfo = self._read_header(handle)
            while rarinfo is not None:
                #print "checking rar archive %s against %s" % (rarinfo.filename, member)
                if rarinfo.filename == member:
                    self._process_current(handle, constants.RAR_TEST)
                    found = True
                else:
                    self._process_current(handle, constants.RAR_SKIP)
                rarinfo = self._read_header(handle)
        except unrarlib.UnrarException:
            raise rarfile.BadRarFile("Bad RAR archive data.")
        finally:
            self._close(handle)
        if not found:
            raise KeyError('There is no item named %r in the archive' % member)
        return b''.join(buf)
Пример #4
0
def is_rarfile(filename):
    """Return true if file is a valid RAR file."""
    mode = constants.RAR_OM_LIST_INCSPLIT
    archive = unrarlib.RAROpenArchiveDataEx(filename, mode=mode)
    try:
        handle = unrarlib.RAROpenArchiveEx(ctypes.byref(archive))
    except unrarlib.UnrarException:
        return False
    unrarlib.RARCloseArchive(handle)
    return (archive.OpenResult == constants.SUCCESS)
Пример #5
0
    def open(self, member, pwd=None):
        """Return file-like object for 'member'.

           'member' may be a filename or a RarInfo object.
        """
        if isinstance(member, RarInfo):
            member = member.filename

        archive = unrarlib.RAROpenArchiveDataEx(self.filename,
                                                mode=constants.RAR_OM_EXTRACT)
        handle = self._open(archive)

        password = pwd or self.pwd
        if password is not None:
            unrarlib.RARSetPassword(handle, b(password))

        # based on BrutuZ (https://github.com/matiasb/python-unrar/pull/4)
        # and Cubixmeister work
        data = _ReadIntoMemory()
        c_callback = unrarlib.UNRARCALLBACK(data._callback)
        unrarlib.RARSetCallback(handle, c_callback, 0)

        try:
            rarinfo = self._read_header(handle)
            while rarinfo is not None:
                if rarinfo.filename == member:
                    self._process_current(handle, constants.RAR_TEST)
                    break
                else:
                    self._process_current(handle, constants.RAR_SKIP)
                rarinfo = self._read_header(handle)

            if rarinfo is None:
                data = None

        except unrarlib.MissingPassword:
            raise RuntimeError("File is encrypted, password required")
        except unrarlib.BadPassword:
            raise RuntimeError("Bad password for File")
        except unrarlib.BadDataError:
            if password is not None:
                raise RuntimeError("File CRC error or incorrect password")
            else:
                raise RuntimeError("File CRC error")
        except unrarlib.UnrarException as e:
            raise BadRarFile("Bad RAR archive data: %s" % str(e))
        finally:
            self._close(handle)

        if data is None:
            raise KeyError('There is no item named %r in the archive' % member)

        # return file-like object
        return data.get_bytes()
Пример #6
0
    def __init__(self, filename, mode='r', pwd=None):
        """Load RAR archive file with mode read only "r"."""
        self.filename = filename
        mode = constants.RAR_OM_LIST_INCSPLIT

        archive = unrarlib.RAROpenArchiveDataEx(filename, mode=mode)
        handle = self._open(archive)

        # assert(archive.OpenResult == constants.SUCCESS)
        self.pwd = pwd
        self.filelist = []
        self.NameToInfo = {}
        if archive.CmtState == constants.RAR_COMMENTS_SUCCESS:
            self.comment = archive.CmtBuf.value
        else:
            self.comment = None
        self._load_metadata(handle)
        self._close(handle)
Пример #7
0
    def testrar(self):
        """Read all the files and check the CRC."""
        error = None
        rarinfo = None
        archive = unrarlib.RAROpenArchiveDataEx(self.filename,
                                                mode=constants.RAR_OM_EXTRACT)
        handle = self._open(archive)

        if self.pwd:
            unrarlib.RARSetPassword(handle, b(self.pwd))

        try:
            rarinfo = self._read_header(handle)
            while rarinfo is not None:
                self._process_current(handle, constants.RAR_TEST)
                rarinfo = self._read_header(handle)
        except unrarlib.UnrarException:
            error = rarinfo.filename if rarinfo else self.filename
        finally:
            self._close(handle)
        return error
Пример #8
0
 def read_files(self, member):
     res = []
     if isinstance(member, RarInfo):
         member = member.filename
     archive = unrarlib.RAROpenArchiveDataEx(self.filename, mode=constants.RAR_OM_EXTRACT)
     handle = self._open(archive)
     reader = PassiveReader()
     c_callback = unrarlib.UNRARCALLBACK(reader._callback)
     unrarlib.RARSetCallback(handle, c_callback, 1)
     try:
         rarinfo = self._read_header(handle)
         while rarinfo is not None:
             if rarinfo.filename in member:
                 self._process_current(handle, constants.RAR_TEST)
             else:
                 self._process_current(handle, constants.RAR_SKIP)
             rarinfo = self._read_header(handle)
     except unrarlib.UnrarException:
         raise BadRarFile("Bad RAR archive data.")
     finally:
         self._close(handle)
     res.append((member, reader.get_result()))
     return res