mirror of
https://github.com/ciromattia/kcc
synced 2025-12-18 12:11:46 +00:00
Updated UnRAR
This commit is contained in:
@@ -178,6 +178,23 @@ EXTRACT_ARGS = ('x', '-y', '-idq')
|
|||||||
#: args for testrar()
|
#: args for testrar()
|
||||||
TEST_ARGS = ('t', '-idq')
|
TEST_ARGS = ('t', '-idq')
|
||||||
|
|
||||||
|
#
|
||||||
|
# Allow use of tool that is not compatible with unrar.
|
||||||
|
#
|
||||||
|
# By default use 'bsdtar' which is 'tar' program that
|
||||||
|
# sits on top of libarchive.
|
||||||
|
#
|
||||||
|
# Problems with libarchive RAR backend:
|
||||||
|
# - Does not support solid archives.
|
||||||
|
# - Does not support password-protected archives.
|
||||||
|
#
|
||||||
|
|
||||||
|
ALT_TOOL = 'bsdtar'
|
||||||
|
ALT_OPEN_ARGS = ('-x', '--to-stdout', '-f')
|
||||||
|
ALT_EXTRACT_ARGS = ('-x', '-f')
|
||||||
|
ALT_TEST_ARGS = ('-t', '-f')
|
||||||
|
ALT_CHECK_ARGS = ('--help',)
|
||||||
|
|
||||||
#: whether to speed up decompression by using tmp archive
|
#: whether to speed up decompression by using tmp archive
|
||||||
USE_EXTRACT_HACK = 1
|
USE_EXTRACT_HACK = 1
|
||||||
|
|
||||||
@@ -336,6 +353,8 @@ class RarUnknownError(RarExecError):
|
|||||||
"""Unknown exit code"""
|
"""Unknown exit code"""
|
||||||
class RarSignalExit(RarExecError):
|
class RarSignalExit(RarExecError):
|
||||||
"""Unrar exited with signal"""
|
"""Unrar exited with signal"""
|
||||||
|
class RarCannotExec(RarExecError):
|
||||||
|
"""Executable not found."""
|
||||||
|
|
||||||
|
|
||||||
def is_rarfile(xfile):
|
def is_rarfile(xfile):
|
||||||
@@ -693,10 +712,7 @@ class RarFile(object):
|
|||||||
"""Let 'unrar' test the archive.
|
"""Let 'unrar' test the archive.
|
||||||
"""
|
"""
|
||||||
cmd = [UNRAR_TOOL] + list(TEST_ARGS)
|
cmd = [UNRAR_TOOL] + list(TEST_ARGS)
|
||||||
if self._password is not None:
|
add_password_arg(cmd, self._password)
|
||||||
cmd.append('-p' + self._password)
|
|
||||||
else:
|
|
||||||
cmd.append('-p-')
|
|
||||||
cmd.append(self.rarfile)
|
cmd.append(self.rarfile)
|
||||||
p = custom_popen(cmd)
|
p = custom_popen(cmd)
|
||||||
output = p.communicate()[0]
|
output = p.communicate()[0]
|
||||||
@@ -1172,8 +1188,7 @@ class RarFile(object):
|
|||||||
if is_filelike(rarfile):
|
if is_filelike(rarfile):
|
||||||
raise ValueError("Cannot use unrar directly on memory buffer")
|
raise ValueError("Cannot use unrar directly on memory buffer")
|
||||||
cmd = [UNRAR_TOOL] + list(OPEN_ARGS)
|
cmd = [UNRAR_TOOL] + list(OPEN_ARGS)
|
||||||
if psw is not None:
|
add_password_arg(cmd, psw)
|
||||||
cmd.append("-p" + psw)
|
|
||||||
cmd.append(rarfile)
|
cmd.append(rarfile)
|
||||||
|
|
||||||
# not giving filename avoids encoding related problems
|
# not giving filename avoids encoding related problems
|
||||||
@@ -1205,10 +1220,7 @@ class RarFile(object):
|
|||||||
|
|
||||||
# pasoword
|
# pasoword
|
||||||
psw = psw or self._password
|
psw = psw or self._password
|
||||||
if psw is not None:
|
add_password_arg(cmd, psw)
|
||||||
cmd.append('-p' + psw)
|
|
||||||
else:
|
|
||||||
cmd.append('-p-')
|
|
||||||
|
|
||||||
# rar file
|
# rar file
|
||||||
cmd.append(self.rarfile)
|
cmd.append(self.rarfile)
|
||||||
@@ -1830,10 +1842,7 @@ def rar_decompress(vers, meth, data, declen=0, flags=0, crc=0, psw=None, salt=No
|
|||||||
tmpf.close()
|
tmpf.close()
|
||||||
|
|
||||||
cmd = [UNRAR_TOOL] + list(OPEN_ARGS)
|
cmd = [UNRAR_TOOL] + list(OPEN_ARGS)
|
||||||
if psw is not None and (flags & RAR_FILE_PASSWORD):
|
add_password_arg(cmd, psw, (flags & RAR_FILE_PASSWORD))
|
||||||
cmd.append("-p" + psw)
|
|
||||||
else:
|
|
||||||
cmd.append("-p-")
|
|
||||||
cmd.append(tmpname)
|
cmd.append(tmpname)
|
||||||
|
|
||||||
p = custom_popen(cmd)
|
p = custom_popen(cmd)
|
||||||
@@ -1902,10 +1911,27 @@ def custom_popen(cmd):
|
|||||||
except OSError:
|
except OSError:
|
||||||
ex = sys.exc_info()[1]
|
ex = sys.exc_info()[1]
|
||||||
if ex.errno == errno.ENOENT:
|
if ex.errno == errno.ENOENT:
|
||||||
raise RarExecError("Unrar not installed? (rarfile.UNRAR_TOOL=%r)" % UNRAR_TOOL)
|
raise RarCannotExec("Unrar not installed? (rarfile.UNRAR_TOOL=%r)" % UNRAR_TOOL)
|
||||||
raise
|
raise
|
||||||
return p
|
return p
|
||||||
|
|
||||||
|
def custom_check(cmd, ignore_retcode=False):
|
||||||
|
"""Run command, collect output, raise error if needed."""
|
||||||
|
p = custom_popen(cmd)
|
||||||
|
out, err = p.communicate()
|
||||||
|
if p.returncode and not ignore_retcode:
|
||||||
|
raise RarExecError("Check-run failed")
|
||||||
|
return out
|
||||||
|
|
||||||
|
def add_password_arg(cmd, psw, required=False):
|
||||||
|
"""Append password switch to commandline."""
|
||||||
|
if UNRAR_TOOL == ALT_TOOL:
|
||||||
|
return
|
||||||
|
if psw is not None:
|
||||||
|
cmd.append('-p' + psw)
|
||||||
|
else:
|
||||||
|
cmd.append('-p-')
|
||||||
|
|
||||||
def check_returncode(p, out):
|
def check_returncode(p, out):
|
||||||
"""Raise exception according to unrar exit code"""
|
"""Raise exception according to unrar exit code"""
|
||||||
|
|
||||||
@@ -1920,6 +1946,8 @@ def check_returncode(p, out):
|
|||||||
RarWarning, RarFatalError, RarCRCError, RarLockedArchiveError,
|
RarWarning, RarFatalError, RarCRCError, RarLockedArchiveError,
|
||||||
RarWriteError, RarOpenError, RarUserError, RarMemoryError,
|
RarWriteError, RarOpenError, RarUserError, RarMemoryError,
|
||||||
RarCreateError, RarNoFilesError] # codes from rar.txt
|
RarCreateError, RarNoFilesError] # codes from rar.txt
|
||||||
|
if UNRAR_TOOL == ALT_TOOL:
|
||||||
|
errmap = [None]
|
||||||
if code > 0 and code < len(errmap):
|
if code > 0 and code < len(errmap):
|
||||||
exc = errmap[code]
|
exc = errmap[code]
|
||||||
elif code == 255:
|
elif code == 255:
|
||||||
@@ -1936,3 +1964,24 @@ def check_returncode(p, out):
|
|||||||
msg = "%s [%d]" % (exc.__doc__, p.returncode)
|
msg = "%s [%d]" % (exc.__doc__, p.returncode)
|
||||||
|
|
||||||
raise exc(msg)
|
raise exc(msg)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Check if unrar works
|
||||||
|
#
|
||||||
|
|
||||||
|
try:
|
||||||
|
# does UNRAR_TOOL work?
|
||||||
|
custom_check([UNRAR_TOOL], True)
|
||||||
|
except RarCannotExec:
|
||||||
|
try:
|
||||||
|
# does ALT_TOOL work?
|
||||||
|
custom_check([ALT_TOOL] + list(ALT_CHECK_ARGS), True)
|
||||||
|
# replace config
|
||||||
|
UNRAR_TOOL = ALT_TOOL
|
||||||
|
OPEN_ARGS = ALT_OPEN_ARGS
|
||||||
|
EXTRACT_ARGS = ALT_EXTRACT_ARGS
|
||||||
|
TEST_ARGS = ALT_TEST_ARGS
|
||||||
|
except RarCannotExec:
|
||||||
|
# no usable tool, only uncompressed archives work
|
||||||
|
pass
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user