Allow custom unrar path. fix #3460

This commit is contained in:
Ruud
2014-06-30 22:38:18 +02:00
parent 33ad4c22c7
commit 169ddeef5d
4 changed files with 27 additions and 21 deletions

View File

@@ -1140,7 +1140,7 @@ Remove it if you want it to be renamed (again, or at least let it try again)
log.info('Archive %s found. Extracting...', os.path.basename(archive['file'])) log.info('Archive %s found. Extracting...', os.path.basename(archive['file']))
try: try:
rar_handle = RarFile(archive['file']) rar_handle = RarFile(archive['file'], custom_path = self.conf('unrar_path'))
extr_path = os.path.join(from_folder, os.path.relpath(os.path.dirname(archive['file']), folder)) extr_path = os.path.join(from_folder, os.path.relpath(os.path.dirname(archive['file']), folder))
self.makeDir(extr_path) self.makeDir(extr_path)
for packedinfo in rar_handle.infolist(): for packedinfo in rar_handle.infolist():
@@ -1282,6 +1282,11 @@ config = [{
'description': 'Extract rar files if found.', 'description': 'Extract rar files if found.',
'default': False, 'default': False,
}, },
{
'advanced': True,
'name': 'unrar_path',
'description': 'Custom path to unrar bin',
},
{ {
'name': 'cleanup', 'name': 'cleanup',
'type': 'bool', 'type': 'bool',

View File

@@ -21,7 +21,7 @@
# SOFTWARE. # SOFTWARE.
""" """
pyUnRAR2 is a ctypes based wrapper around the free UnRAR.dll. pyUnRAR2 is a ctypes based wrapper around the free UnRAR.dll.
It is an modified version of Jimmy Retzlaff's pyUnRAR - more simple, It is an modified version of Jimmy Retzlaff's pyUnRAR - more simple,
stable and foolproof. stable and foolproof.
@@ -45,8 +45,8 @@ if in_windows:
from windows import RarFileImplementation from windows import RarFileImplementation
else: else:
from unix import RarFileImplementation from unix import RarFileImplementation
import fnmatch, time, weakref import fnmatch, time, weakref
class RarInfo(object): class RarInfo(object):
@@ -62,7 +62,7 @@ class RarInfo(object):
isdir - True if the file is a directory isdir - True if the file is a directory
size - size in bytes of the uncompressed file size - size in bytes of the uncompressed file
comment - comment associated with the file comment - comment associated with the file
Note - this is not currently intended to be a Python file-like object. Note - this is not currently intended to be a Python file-like object.
""" """
@@ -74,7 +74,7 @@ class RarInfo(object):
self.size = data['size'] self.size = data['size']
self.datetime = data['datetime'] self.datetime = data['datetime']
self.comment = data['comment'] self.comment = data['comment']
def __str__(self): def __str__(self):
@@ -86,7 +86,7 @@ class RarInfo(object):
class RarFile(RarFileImplementation): class RarFile(RarFileImplementation):
def __init__(self, archiveName, password=None): def __init__(self, archiveName, password=None, custom_path = None):
"""Instantiate the archive. """Instantiate the archive.
archiveName is the name of the RAR file. archiveName is the name of the RAR file.
@@ -99,7 +99,7 @@ class RarFile(RarFileImplementation):
This is a test. This is a test.
""" """
self.archiveName = archiveName self.archiveName = archiveName
RarFileImplementation.init(self, password) RarFileImplementation.init(self, password, custom_path)
def __del__(self): def __del__(self):
self.destruct() self.destruct()
@@ -130,31 +130,31 @@ class RarFile(RarFileImplementation):
"""Read specific files from archive into memory. """Read specific files from archive into memory.
If "condition" is a list of numbers, then return files which have those positions in infolist. If "condition" is a list of numbers, then return files which have those positions in infolist.
If "condition" is a string, then it is treated as a wildcard for names of files to extract. If "condition" is a string, then it is treated as a wildcard for names of files to extract.
If "condition" is a function, it is treated as a callback function, which accepts a RarInfo object If "condition" is a function, it is treated as a callback function, which accepts a RarInfo object
and returns boolean True (extract) or False (skip). and returns boolean True (extract) or False (skip).
If "condition" is omitted, all files are returned. If "condition" is omitted, all files are returned.
Returns list of tuples (RarInfo info, str contents) Returns list of tuples (RarInfo info, str contents)
""" """
checker = condition2checker(condition) checker = condition2checker(condition)
return RarFileImplementation.read_files(self, checker) return RarFileImplementation.read_files(self, checker)
def extract(self, condition='*', path='.', withSubpath=True, overwrite=True): def extract(self, condition='*', path='.', withSubpath=True, overwrite=True):
"""Extract specific files from archive to disk. """Extract specific files from archive to disk.
If "condition" is a list of numbers, then extract files which have those positions in infolist. If "condition" is a list of numbers, then extract files which have those positions in infolist.
If "condition" is a string, then it is treated as a wildcard for names of files to extract. If "condition" is a string, then it is treated as a wildcard for names of files to extract.
If "condition" is a function, it is treated as a callback function, which accepts a RarInfo object If "condition" is a function, it is treated as a callback function, which accepts a RarInfo object
and returns either boolean True (extract) or boolean False (skip). and returns either boolean True (extract) or boolean False (skip).
DEPRECATED: If "condition" callback returns string (only supported for Windows) - DEPRECATED: If "condition" callback returns string (only supported for Windows) -
that string will be used as a new name to save the file under. that string will be used as a new name to save the file under.
If "condition" is omitted, all files are extracted. If "condition" is omitted, all files are extracted.
"path" is a directory to extract to "path" is a directory to extract to
"withSubpath" flag denotes whether files are extracted with their full path in the archive. "withSubpath" flag denotes whether files are extracted with their full path in the archive.
"overwrite" flag denotes whether extracted files will overwrite old ones. Defaults to true. "overwrite" flag denotes whether extracted files will overwrite old ones. Defaults to true.
Returns list of RarInfos for extracted files.""" Returns list of RarInfos for extracted files."""
checker = condition2checker(condition) checker = condition2checker(condition)
return RarFileImplementation.extract(self, checker, path, withSubpath, overwrite) return RarFileImplementation.extract(self, checker, path, withSubpath, overwrite)

View File

@@ -46,11 +46,12 @@ if os.path.isfile(osx_unrar) and 'darwin' in platform.platform().lower():
except: except:
pass pass
def call_unrar(params): def call_unrar(params, custom_path = None):
"Calls rar/unrar command line executable, returns stdout pipe" "Calls rar/unrar command line executable, returns stdout pipe"
global rar_executable_cached global rar_executable_cached
if rar_executable_cached is None: if rar_executable_cached is None:
for command in ('unrar', 'rar', osx_unrar): for command in (custom_path, 'unrar', 'rar', osx_unrar):
if not command: continue
try: try:
subprocess.Popen([command], stdout = subprocess.PIPE) subprocess.Popen([command], stdout = subprocess.PIPE)
rar_executable_cached = command rar_executable_cached = command
@@ -70,10 +71,10 @@ def call_unrar(params):
class RarFileImplementation(object): class RarFileImplementation(object):
def init(self, password = None): def init(self, password = None, custom_path = None):
global rar_executable_version global rar_executable_version
self.password = password self.password = password
self.custom_path = custom_path
stdoutdata, stderrdata = self.call('v', []).communicate() stdoutdata, stderrdata = self.call('v', []).communicate()
@@ -129,7 +130,7 @@ class RarFileImplementation(object):
def call(self, cmd, options = [], files = []): def call(self, cmd, options = [], files = []):
options2 = options + ['p' + self.escaped_password()] options2 = options + ['p' + self.escaped_password()]
soptions = ['-' + x for x in options2] soptions = ['-' + x for x in options2]
return call_unrar([cmd] + soptions + ['--', self.archiveName] + files) return call_unrar([cmd] + soptions + ['--', self.archiveName] + files, self.custom_path)
def infoiter(self): def infoiter(self):

View File

@@ -237,7 +237,7 @@ def generate_password_provider(password):
class RarFileImplementation(object): class RarFileImplementation(object):
def init(self, password=None): def init(self, password=None, custom_path = None):
self.password = password self.password = password
archiveData = RAROpenArchiveDataEx(ArcNameW=self.archiveName, OpenMode=RAR_OM_EXTRACT) archiveData = RAROpenArchiveDataEx(ArcNameW=self.archiveName, OpenMode=RAR_OM_EXTRACT)
self._handle = RAROpenArchiveEx(ctypes.byref(archiveData)) self._handle = RAROpenArchiveEx(ctypes.byref(archiveData))