diff options
Diffstat (limited to 'module/plugins/internal')
-rw-r--r-- | module/plugins/internal/Extractor.py | 30 | ||||
-rw-r--r-- | module/plugins/internal/SevenZip.py | 38 | ||||
-rw-r--r-- | module/plugins/internal/UnRar.py | 71 | ||||
-rw-r--r-- | module/plugins/internal/UnZip.py | 8 |
4 files changed, 76 insertions, 71 deletions
diff --git a/module/plugins/internal/Extractor.py b/module/plugins/internal/Extractor.py index b445f1497..8bf1875cf 100644 --- a/module/plugins/internal/Extractor.py +++ b/module/plugins/internal/Extractor.py @@ -19,7 +19,7 @@ class PasswordError(Exception): class Extractor: __name__ = "Extractor" - __version__ = "0.20" + __version__ = "0.21" __description__ = """Base extractor plugin""" __license__ = "GPLv3" @@ -30,6 +30,7 @@ class Extractor: EXTENSIONS = [] VERSION = "" + REPAIR = False @classmethod @@ -90,23 +91,24 @@ class Extractor: def check(self): - """Check if password if needed. Raise ArchiveError if integrity is - questionable. + """Quick Check by listing content of archive. + Raises error if password is needed, integrity is questionable or else. - :return: boolean + :raises PasswordError + :raises CRCError :raises ArchiveError """ - raise PasswordError - - - def isPassword(self, password): - """ Check if the given password is/might be correct. - If it can not be decided at this point return true. - - :param password: - :return: boolean + raise NotImplementedError + + def test(self): + """Testing with Extractors buildt-in method + Raises error if password is needed, integrity is questionable or else. + + :raises PasswordError + :raises CRCError + :raises ArchiveError """ - return None + raise NotImplementedError def repair(self): diff --git a/module/plugins/internal/SevenZip.py b/module/plugins/internal/SevenZip.py index 7ad6b0d7a..bfa7f3943 100644 --- a/module/plugins/internal/SevenZip.py +++ b/module/plugins/internal/SevenZip.py @@ -11,7 +11,7 @@ from module.utils import fs_encode, save_join class SevenZip(UnRar): __name__ = "SevenZip" - __version__ = "0.08" + __version__ = "0.09" __description__ = """7-Zip extractor plugin""" __license__ = "GPLv3" @@ -32,9 +32,9 @@ class SevenZip(UnRar): #@NOTE: there are some more uncovered 7z formats re_filelist = re.compile(r'([\d\:]+)\s+([\d\:]+)\s+([\w\.]+)\s+(\d+)\s+(\d+)\s+(.+)') - re_wrongpwd = re.compile(r'(Can not open encrypted archive|Wrong password)', re.I) - re_wrongcrc = re.compile(r'Encrypted\s+\=\s+\+', re.I) - re_version = re.compile(r'7-Zip\s(?:\[64\]\s)?(\d+\.\d+)', re.I) + re_wrongpwd = re.compile(r'(Can not open encrypted archive|Wrong password|Encrypted\s+\=\s+\+)', re.I) + re_wrongcrc = re.compile(r'CRC Failed|Can not open file', re.I) + re_version = re.compile(r'7-Zip\s(?:\[64\]\s)?(\d+\.\d+)', re.I) @classmethod @@ -52,36 +52,38 @@ class SevenZip(UnRar): return True - def check(self): + def test(self, password): file = fs_encode(self.filename) - p = self.call_cmd("t", file) + # 7z can't distinguish crc and pw error in test + p = self.call_cmd("l", "-slt", file) out, err = p.communicate() - if p.returncode > 1: + if self.re_wrongpwd.search(out): + raise PasswordError + + if self.re_wrongpwd.search(err): + raise PasswordError + + if self.re_wrongcrc.search(err): raise CRCError(err) + + + def check(self, password): + file = fs_encode(self.filename) + p = self.call_cmd("l", "-slt", file) out, err = p.communicate() - if p.returncode > 1: - raise ArchiveError(_("Process return code: %d") % p.returncode) - # check if output or error macthes the 'wrong password'-Regexp if self.re_wrongpwd.search(out): raise PasswordError - # check if output matches 'Encrypted = +' if self.re_wrongcrc.search(out): raise CRCError(_("Header protected")) - def isPassword(self, password): - p = self.call_cmd("l", fs_encode(self.filename), password=password) - p.communicate() - return p.returncode == 0 - - def repair(self): return False @@ -142,7 +144,7 @@ class SevenZip(UnRar): #set a password if "password" in kwargs and kwargs["password"]: - args.append("-p'%s'" % kwargs["password"]) + args.append("-p%s" % kwargs["password"]) else: args.append("-p-") diff --git a/module/plugins/internal/UnRar.py b/module/plugins/internal/UnRar.py index 54d64c430..ca8fdd326 100644 --- a/module/plugins/internal/UnRar.py +++ b/module/plugins/internal/UnRar.py @@ -22,7 +22,7 @@ def renice(pid, value): class UnRar(Extractor): __name__ = "UnRar" - __version__ = "1.13" + __version__ = "1.14" __description__ = """Rar extractor plugin""" __license__ = "GPLv3" @@ -33,34 +33,40 @@ class UnRar(Extractor): CMD = "unrar" VERSION = "" - EXTENSIONS = [".rar"] - re_multipart = re.compile(r'\.(part|r)(\d+)(?:\.rar)?',re.I) + re_multipart = re.compile(r'\.(part|r)(\d+)(?:\.rar)?(\.rev|\.bad)?',re.I) re_filefixed = re.compile(r'Building (.+)') re_filelist = re.compile(r'^(.)(\s*[\w\.\-]+)\s+(\d+\s+)+(?:\d+\%\s+)?[\d\-]{8}\s+[\d\:]{5}', re.M|re.I) re_wrongpwd = re.compile(r'password', re.I) - re_wrongcrc = re.compile(r'encrypted|damaged|CRC failed|checksum error', re.I) + re_wrongcrc = re.compile(r'encrypted|damaged|CRC failed|checksum error|corrupt', re.I) - re_version = re.compile(r'UNRAR\s(\d+\.\d+)', re.I) + re_version = re.compile(r'(?:UN)?RAR\s(\d+\.\d+)', re.I) @classmethod def isUsable(cls): if os.name == "nt": - cls.CMD = os.path.join(pypath, "UnRAR.exe") - p = Popen([cls.CMD], stdout=PIPE, stderr=PIPE) - out, err = p.communicate() - else: try: + cls.CMD = os.path.join(pypath, "RAR.exe") p = Popen([cls.CMD], stdout=PIPE, stderr=PIPE) out, err = p.communicate() - - except OSError: #: fallback to rar - cls.CMD = "rar" + cls.__name__ = "RAR" + cls.REPAIR = True + except OSError: + cls.CMD = os.path.join(pypath, "UnRAR.exe") + p = Popen([cls.CMD], stdout=PIPE, stderr=PIPE) + out, err = p.communicate() + else: + try: + p = Popen(["rar"], stdout=PIPE, stderr=PIPE) + out, err = p.communicate() + cls.__name__ = "RAR" + cls.REPAIR = True + except OSError: #: fallback to unrar p = Popen([cls.CMD], stdout=PIPE, stderr=PIPE) out, err = p.communicate() @@ -74,13 +80,25 @@ class UnRar(Extractor): multipart = cls.re_multipart.search(filename) if multipart: # First Multipart file (part1.rar for *.part1-9.rar format or *.rar for .r1-9 format) handled as normal Archive - return False if (multipart.group(1) == "part" and int(multipart.group(2)) == 1) else True + return False if (multipart.group(1) == "part" and int(multipart.group(2)) == 1 and not multipart.group(3)) else True return False - def check(self): - p = self.call_cmd("l", "-v", fs_encode(self.filename)) + def test(self, password): + p = self.call_cmd("t", "-v", fs_encode(self.filename), password=password) + self._progress(p) + err = p.stderr.read().strip() + + if self.re_wrongpwd.search(err): + raise PasswordError + + if self.re_wrongcrc.search(err): + raise CRCError(err) + + + def check(self, password): + p = self.call_cmd("l", "-v", fs_encode(self.filename), password=password) out, err = p.communicate() if self.re_wrongpwd.search(err): @@ -95,35 +113,14 @@ class UnRar(Extractor): raise PasswordError - def isPassword(self, password): - # at this point we can only verify header protected files - p = self.call_cmd("l", "-v", fs_encode(self.filename), password=password) - out, err = p.communicate() - return False if self.re_wrongpwd.search(err) else True - - def repair(self): p = self.call_cmd("rc", fs_encode(self.filename)) # communicate and retrieve stderr self._progress(p) err = p.stderr.read().strip() - if err or p.returncode: - p = self.call_cmd("r", fs_encode(self.filename)) - - # communicate and retrieve stderr - self._progress(p) - err = p.stderr.read().strip() - - if err or p.returncode: - return False - else: - dir = os.path.dirname(filename) - name = re_filefixed.search(out).group(1) - - self.filename = os.path.join(dir, name) - + return False return True diff --git a/module/plugins/internal/UnZip.py b/module/plugins/internal/UnZip.py index 704b49ca0..d95afbc70 100644 --- a/module/plugins/internal/UnZip.py +++ b/module/plugins/internal/UnZip.py @@ -12,7 +12,7 @@ from module.utils import fs_encode class UnZip(Extractor): __name__ = "UnZip" - __version__ = "1.10" + __version__ = "1.11" __description__ = """Zip extractor plugin""" __license__ = "GPLv3" @@ -34,7 +34,11 @@ class UnZip(Extractor): return z.namelist() - def check(self): + def check(self, password): + pass + + + def test(self): with zipfile.ZipFile(fs_encode(self.filename), 'r', allowZip64=True) as z: badfile = z.testzip() |