Skip to content

Commit

Permalink
.extract(), .extractall(), .testrar() methods
Browse files Browse the repository at this point in the history
  • Loading branch information
markokr committed Jul 14, 2010
1 parent 1d86e6d commit ac41aa0
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 10 deletions.
11 changes: 10 additions & 1 deletion dumprar.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ def show_item(h):
cf_charset = None
cf_extract = 0
cf_test_read = 0
cf_test_unrar = 0

def test_read_long(r, inf):
f = r.open(inf.filename)
Expand Down Expand Up @@ -234,9 +235,15 @@ def test(fn, psw):
if cf_test_read:
test_read(r, inf)

if cf_test_unrar:
try:
r.testrar()
except rf.BadRarFile:
print '\ntestrar() failed'

def main():
global cf_verbose, cf_show_comment, cf_charset
global cf_extract, cf_test_read
global cf_extract, cf_test_read, cf_test_unrar

# parse args
args = []
Expand Down Expand Up @@ -266,6 +273,8 @@ def main():
cf_extract = 1
elif a == '-t':
cf_test_read = 1
elif a == '-T':
cf_test_unrar = 1
elif a[1] == 'C':
cf_charset = a[2:]
else:
Expand Down
95 changes: 86 additions & 9 deletions rarfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,18 +57,24 @@ def bytes(foo, enc):
DEFAULT_CHARSET = "windows-1252"

# 'unrar', 'rar' or full path to either one
EXTRACT_TOOL = "unrar"
UNRAR_TOOL = "unrar"

# Must be 'rar', because 'unrar' does not have 'cw' command.
# Can be full path, or None to disable comment extraction
COMMENT_TOOL = "rar"
# For comment extraction we need 'rar'.
# Can be full path, or None to disable
RAR_TOOL = "rar"

# command line args to use for extracting. (rar, file) will be added.
EXTRACT_ARGS = ('p', '-inul')
# Command line args to use for opening file for reading.
OPEN_ARGS = ('p', '-inul')

# Command line args to use for extracting file to disk.
EXTRACT_ARGS = ('x', '-y', '-idq')

# how to extract comment from archive. (rar, tmpfile) will be added.
COMMENT_ARGS = ('cw', '-y', '-inul', '-p-')

# args for testrar()
TEST_ARGS = ('t', '-idq')

# whether to speed up decompression by using tmp archive
USE_EXTRACT_HACK = 1

Expand Down Expand Up @@ -383,6 +389,52 @@ def printdir(self):
for f in self._info_list:
print(f.filename)

def extract(self, member, path=None, pwd=None):
"""Extract single file into current directory.
@param member: filename or RarInfo instance
@param path: optional destination path
@param pwd: optional password to use
"""
if isinstance(member, RarInfo):
fname = member.filename
else:
fname = member
self._extract([fname], path, pwd)

def extractall(self, path=None, members=None, pwd=None):
"""Extract all files into current directory.
@param path: optional destination path
@param members: optional filename or RarInfo instance list to extract
@param pwd: optional password to use
"""
fnlist = []
if members is not None:
for m in members:
if isinstance(m, RarInfo):
fnlist.append(m.filename)
else:
fnlist.append(m)
self._extract(fnlist, path, pwd)

def testrar(self):
"""Let 'unrar' test the archive.
"""
cmd = [UNRAR_TOOL] + list(TEST_ARGS)
if self._password is not None:
cmd.append('-p' + self._password)
else:
cmd.append('-p-')
cmd.append(self.rarfile)
p = Popen(cmd)
if p.wait() != 0:
raise BadRarFile("Testing failed")

##
## private methods
##

# store entry
def _process_entry(self, item):
# RAR_BLOCK_NEWSUB has files too: CMT, RR
Expand Down Expand Up @@ -669,7 +721,7 @@ def _open_hack(self, inf, psw = None):

# extract using unrar
def _open_unrar(self, rarfile, inf, psw = None, tmpfile = None):
cmd = [EXTRACT_TOOL] + list(EXTRACT_ARGS)
cmd = [UNRAR_TOOL] + list(OPEN_ARGS)
if psw is not None:
cmd.append("-p" + psw)
cmd.append(rarfile)
Expand All @@ -694,11 +746,11 @@ def _open_unrar(self, rarfile, inf, psw = None, tmpfile = None):
return PipeReader(self, inf, p, tmpfile)

def _read_comment(self):
if not COMMENT_TOOL:
if not RAR_TOOL:
return
tmpfd, tmpname = mkstemp(suffix='.txt')
try:
cmd = [COMMENT_TOOL] + list(COMMENT_ARGS)
cmd = [RAR_TOOL] + list(COMMENT_ARGS)
cmd.append(self.rarfile)
cmd.append(tmpname)
try:
Expand All @@ -715,6 +767,31 @@ def _read_comment(self):
finally:
os.unlink(tmpname)

# call unrar to extract a file
def _extract(self, fnlist, path=None, psw=None):
cmd = [UNRAR_TOOL] + list(EXTRACT_ARGS)

# pasoword
psw = psw or self._password
if psw is not None:
cmd.append('-p' + psw)
else:
cmd.append('-p-')

# rar file
cmd.append(self.rarfile)

# file list
cmd += fnlist

# destination path
if path is not None:
cmd.append(path + os.sep)

# call
p = Popen(cmd)
p.communicate()

# handle unicode filename compression
class _UnicodeFilename:
def __init__(self, name, encdata):
Expand Down

0 comments on commit ac41aa0

Please sign in to comment.