diff options
Diffstat (limited to 'module/plugins/internal/UnRar.py')
-rw-r--r-- | module/plugins/internal/UnRar.py | 90 |
1 files changed, 46 insertions, 44 deletions
diff --git a/module/plugins/internal/UnRar.py b/module/plugins/internal/UnRar.py index 67f95b018..a1bfef42f 100644 --- a/module/plugins/internal/UnRar.py +++ b/module/plugins/internal/UnRar.py @@ -19,17 +19,11 @@ import os from os.path import join - +from glob import glob from subprocess import Popen, PIPE from module.plugins.hooks.ExtractArchive import AbtractExtractor -from module.utils import save_join - -try: - import pexpect #used for progress - PEXPECT = True -except ImportError: - PEXPECT = False +from module.utils import save_join, decode import re @@ -37,11 +31,22 @@ class UnRar(AbtractExtractor): __name__ = "UnRar" __version__ = "0.1" - re_splitfile = re.compile("(.*)\.part(\d+)\.rar$") + # there are some more uncovered rar formats + re_splitfile = re.compile(r"(.*)\.part(\d+)\.rar$") + re_filelist = re.compile(r"(.+)\s+(\d+)\s+(\d+)\s+") + + WRONG_PWD = "Corrupt file or wrong password." @staticmethod def checkDeps(): - return True #TODO + if os.name == "nt": + cmd = join(pypath, "UnRAR.exe") + else: + cmd = "unrar" + + p = Popen([cmd], stdout=PIPE, stderr=PIPE) + p.communicate() + return True @staticmethod def getTargets(files_ids): @@ -70,11 +75,17 @@ class UnRar(AbtractExtractor): def checkArchive(self): p = self.call_unrar("l", "-v", self.file) out, err = p.communicate() - if "Corrupt file or wrong password." in err: + if self.WRONG_PWD in err: self.passwordProtected = True self.headerProtected = True return True + # output only used to check if passworded files are present + for name, size, packed in self.re_filelist.findall(out): + if name.startswith("*"): + self.passwordProtected = True + return True + self.listContent() if not self.files: self.m.archiveError("Empty Archive") @@ -82,12 +93,11 @@ class UnRar(AbtractExtractor): return False def checkPassword(self, password): - if not self.passwordProtected: return True - + #at this point we can only verify header protected files if self.headerProtected: p = self.call_unrar("l", "-v", self.file, password=password) out, err = p.communicate() - if "Corrupt file or wrong password." in err: + if self.WRONG_PWD in err: return False return True @@ -96,45 +106,41 @@ class UnRar(AbtractExtractor): def extract(self, progress, password=None): command = "x" if self.fullpath else "e" - if PEXPECT: - p = self.call_unrar(command, self.file, self.out, password=password, pexpect=True) - #renice(p.pid, self.renice) - - cpl = p.compile_pattern_list([pexpect.EOF, "(\d+)\s?%"]) - while True: - i = p.expect_list(cpl, timeout=None) - if i == 0: # EOF - break #exited - elif i == 1: - perc = p.match.group(1) - progress(int(perc)) - # pexpect thinks process is still alive (just like popen) - very strange behavior - p.terminated = True + # popen thinks process is still alive (just like pexpect) - very strange behavior + # so for now progress can not be determined correctly + p = self.call_unrar(command, self.file, self.out, password=password) + renice(p.pid, self.renice) - else: - #subprocess - no progress - p = self.call_unrar(command, self.file, self.out, password=password) - renice(p.pid, self.renice) + progress(0) + out, err = p.communicate() #wait for process + progress(100) - progress(0) - out, err = p.communicate() #wait for process - progress(100) + if "CRC failed" in err and not password and not self.passwordProtected: + self.m.crcError() + elif "CRC failed" in err: + self.m.wrongPassword() - #TODO, check for errors + if not self.files: + self.password = password + self.listContent() def getDeleteFiles(self): - #TODO - return [] + if ".part" in self.file: + return glob(self.file.replace("0", "*").replace("1", "*")) + return [self.file] def listContent(self): command = "vb" if self.fullpath else "lb" p = self.call_unrar(command, "-v", self.file, password=self.password) out, err = p.communicate() + if "Cannot open" in err: + self.m.archiveError("Cannot open file") + result = set() - for f in out.splitlines(): + for f in decode(out).splitlines(): f = f.strip() result.add(save_join(self.out, f)) @@ -166,11 +172,7 @@ class UnRar(AbtractExtractor): call = [cmd, command] + args + list(xargs) self.m.logDebug(" ".join(call)) - if PEXPECT and "pexpect" in kwargs: - #use pexpect if available - p = pexpect.spawn(" ".join(call)) - else: - p = Popen(call, stdout=PIPE, stderr=PIPE) + p = Popen(call, stdout=PIPE, stderr=PIPE) return p |