From 8848a359a43316fb346b728d1d79d7b72d27e5a0 Mon Sep 17 00:00:00 2001 From: Walter Purcaro Date: Tue, 27 Jan 2015 17:48:25 +0100 Subject: Update Extractor (again) --- module/plugins/internal/SevenZip.py | 163 ++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 module/plugins/internal/SevenZip.py (limited to 'module/plugins/internal/SevenZip.py') diff --git a/module/plugins/internal/SevenZip.py b/module/plugins/internal/SevenZip.py new file mode 100644 index 000000000..508cf9c8d --- /dev/null +++ b/module/plugins/internal/SevenZip.py @@ -0,0 +1,163 @@ +# -*- coding: utf-8 -*- + +import os +import re + +from subprocess import Popen, PIPE + +from module.plugins.internal.UnRar import UnRar, renice +from module.utils import save_join + + +class SevenZip(UnRar): + __name__ = "SevenZip" + __version__ = "0.02" + + __description__ = """7-Zip extractor plugin""" + __license__ = "GPLv3" + __authors__ = [("Michael Nowak", ""), + ("Walter Purcaro", "vuolter@gmail.com")] + + + CMD = "7z" + + EXTENSIONS = [".7z", ".xz", ".zip", ".gz", ".gzip", ".tgz", ".bz2", ".bzip2", + ".tbz2", ".tbz", ".tar", ".wim", ".swm", ".lzma", ".rar", ".cab", + ".arj", ".z", ".taz", ".cpio", ".rpm", ".deb", ".lzh", ".lha", + ".chm", ".chw", ".hxs", ".iso", ".msi", ".doc", ".xls", ".ppt", + ".dmg", ".xar", ".hfs", ".exe", ".ntfs", ".fat", ".vhd", ".mbr", + ".squashfs", ".cramfs", ".scap"] + + + #@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) + + + @classmethod + def checkDeps(cls): + if os.name == "nt": + cls.CMD = os.path.join(pypath, "7z.exe") + p = Popen([cls.CMD], stdout=PIPE, stderr=PIPE) + p.communicate() + else: + p = Popen([cls.CMD], stdout=PIPE, stderr=PIPE) + p.communicate() + + return True + + + def checkArchive(self): + p = self.call_cmd("l", "-slt", self.target) + out, err = p.communicate() + + if p.returncode > 1: + raise ArchiveError("Process terminated") + + # check if output or error macthes the 'wrong password'-Regexp + if self.re_wrongpwd.search(out): + return True + + # check if output matches 'Encrypted = +' + if self.re_wrongcrc.search(out): + return True + + # check if archive is empty + self.files = self.list() + if not self.files: + raise ArchiveError("Empty Archive") + + return False + + + def checkPassword(self, password): + p = self.call_cmd("l", self.target, password=password) + p.communicate() + return p.returncode == 0 + + + def extract(self, password=None): + command = "x" if self.fullpath else "e" + + p = self.call_cmd(command, '-o' + self.out, self.target, password=password) + + renice(p.pid, self.renice) + + progressstring = "" + while True: + c = p.stdout.read(1) + # quit loop on eof + if not c: + break + # reading a percentage sign -> set progress and restart + if c == '%': + self.notifyProgress(int(progressstring)) + progressstring = "" + # not reading a digit -> therefore restart + elif c not in digits: + progressstring = "" + # add digit to progressstring + else: + progressstring += c + + # retrieve stderr + err = p.stderr.read() + + if self.re_wrongpwd.search(err): + raise PasswordError + + elif self.re_wrongcrc.search(err): + raise CRCError + + elif err.strip(): #: raise error if anything is on stderr + raise ArchiveError(err.strip()) + + if p.returncode > 1: + raise ArchiveError("Process terminated") + + if not self.files: + self.files = self.list(password) + + + def list(self, password=None): + command = "l" if self.fullpath else "l" + + p = self.call_cmd(command, self.target, password=password) + out, err = p.communicate() + code = p.returncode + + if "Can not open" in err: + raise ArchiveError("Cannot open file") + + if code != 0: + raise ArchiveError("Process terminated unsuccessful") + + result = set() + for groups in self.re_filelist.findall(out): + f = groups[-1].strip() + result.add(save_join(self.out, f)) + + return list(result) + + + def call_cmd(self, command, *xargs, **kwargs): + args = [] + + #overwrite flag + if self.overwrite: + args.append("-y") + + #set a password + if "password" in kwargs and kwargs["password"]: + args.append("-p%s" % kwargs["password"]) + else: + args.append("-p-") + + #@NOTE: return codes are not reliable, some kind of threading, cleanup whatever issue + call = [self.cmd, command] + args + list(xargs) + + self.manager.logDebug(" ".join([decode(arg) for arg in call])) + + p = Popen(call, stdout=PIPE, stderr=PIPE) + return p -- cgit v1.2.3 From 788a06132882300a22f6db3aa7ac3a6009d4d762 Mon Sep 17 00:00:00 2001 From: Walter Purcaro Date: Thu, 29 Jan 2015 23:13:54 +0100 Subject: Update Extractor (2) --- module/plugins/internal/SevenZip.py | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) (limited to 'module/plugins/internal/SevenZip.py') diff --git a/module/plugins/internal/SevenZip.py b/module/plugins/internal/SevenZip.py index 508cf9c8d..e808e0d88 100644 --- a/module/plugins/internal/SevenZip.py +++ b/module/plugins/internal/SevenZip.py @@ -5,13 +5,13 @@ import re from subprocess import Popen, PIPE -from module.plugins.internal.UnRar import UnRar, renice -from module.utils import save_join +from module.plugins.internal.UnRar import ArchiveError, CRCError, PasswordError, UnRar, renice +from module.utils import fs_encode, save_join class SevenZip(UnRar): __name__ = "SevenZip" - __version__ = "0.02" + __version__ = "0.03" __description__ = """7-Zip extractor plugin""" __license__ = "GPLv3" @@ -48,8 +48,8 @@ class SevenZip(UnRar): return True - def checkArchive(self): - p = self.call_cmd("l", "-slt", self.target) + def check(self): + p = self.call_cmd("l", "-slt", fs_encode(self.filename)) out, err = p.communicate() if p.returncode > 1: @@ -57,22 +57,20 @@ class SevenZip(UnRar): # check if output or error macthes the 'wrong password'-Regexp if self.re_wrongpwd.search(out): - return True + raise PasswordError # check if output matches 'Encrypted = +' if self.re_wrongcrc.search(out): - return True + raise CRCError # check if archive is empty self.files = self.list() if not self.files: raise ArchiveError("Empty Archive") - return False - - def checkPassword(self, password): - p = self.call_cmd("l", self.target, password=password) + def isPassword(self, password): + p = self.call_cmd("l", fs_encode(self.filename), password=password) p.communicate() return p.returncode == 0 @@ -80,7 +78,7 @@ class SevenZip(UnRar): def extract(self, password=None): command = "x" if self.fullpath else "e" - p = self.call_cmd(command, '-o' + self.out, self.target, password=password) + p = self.call_cmd(command, '-o' + self.out, fs_encode(self.filename), password=password) renice(p.pid, self.renice) @@ -123,7 +121,7 @@ class SevenZip(UnRar): def list(self, password=None): command = "l" if self.fullpath else "l" - p = self.call_cmd(command, self.target, password=password) + p = self.call_cmd(command, fs_encode(self.filename), password=password) out, err = p.communicate() code = p.returncode -- cgit v1.2.3 From 32b3cb9d9fa6851de35f52d01f78c26012043baa Mon Sep 17 00:00:00 2001 From: Walter Purcaro Date: Thu, 29 Jan 2015 23:30:56 +0100 Subject: [SevenZip] Repair not supported --- module/plugins/internal/SevenZip.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'module/plugins/internal/SevenZip.py') diff --git a/module/plugins/internal/SevenZip.py b/module/plugins/internal/SevenZip.py index e808e0d88..6ba7cfc1f 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.03" + __version__ = "0.04" __description__ = """7-Zip extractor plugin""" __license__ = "GPLv3" @@ -75,6 +75,10 @@ class SevenZip(UnRar): return p.returncode == 0 + def repair(self): + return False + + def extract(self, password=None): command = "x" if self.fullpath else "e" -- cgit v1.2.3 From b2904e3e704ece4e891f3d2bfbcc8af2d6d8c2e1 Mon Sep 17 00:00:00 2001 From: Walter Purcaro Date: Sat, 31 Jan 2015 20:13:28 +0100 Subject: [SevenZip] Better check method + fix list method --- module/plugins/internal/SevenZip.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'module/plugins/internal/SevenZip.py') diff --git a/module/plugins/internal/SevenZip.py b/module/plugins/internal/SevenZip.py index 6ba7cfc1f..05be90702 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.04" + __version__ = "0.05" __description__ = """7-Zip extractor plugin""" __license__ = "GPLv3" @@ -36,7 +36,7 @@ class SevenZip(UnRar): @classmethod - def checkDeps(cls): + def isUsable(cls): if os.name == "nt": cls.CMD = os.path.join(pypath, "7z.exe") p = Popen([cls.CMD], stdout=PIPE, stderr=PIPE) @@ -49,7 +49,15 @@ class SevenZip(UnRar): def check(self): - p = self.call_cmd("l", "-slt", fs_encode(self.filename)) + file = fs_encode(self.filename) + + p = self.call_cmd("t", file) + p.communicate() + + if p.returncode > 1: + raise CRCError + + p = self.call_cmd("l", "-slt", file) out, err = p.communicate() if p.returncode > 1: @@ -127,12 +135,11 @@ class SevenZip(UnRar): p = self.call_cmd(command, fs_encode(self.filename), password=password) out, err = p.communicate() - code = p.returncode if "Can not open" in err: raise ArchiveError("Cannot open file") - if code != 0: + if p.returncode > 1: raise ArchiveError("Process terminated unsuccessful") result = set() -- cgit v1.2.3 From 79725268402043906f619f7c09e848e02ab8a17b Mon Sep 17 00:00:00 2001 From: Walter Purcaro Date: Sat, 31 Jan 2015 22:00:59 +0100 Subject: Spare code cosmetics --- module/plugins/internal/SevenZip.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'module/plugins/internal/SevenZip.py') diff --git a/module/plugins/internal/SevenZip.py b/module/plugins/internal/SevenZip.py index 05be90702..476348083 100644 --- a/module/plugins/internal/SevenZip.py +++ b/module/plugins/internal/SevenZip.py @@ -166,7 +166,7 @@ class SevenZip(UnRar): #@NOTE: return codes are not reliable, some kind of threading, cleanup whatever issue call = [self.cmd, command] + args + list(xargs) - self.manager.logDebug(" ".join([decode(arg) for arg in call])) + self.manager.logDebug(" ".join(map(decode, call))) p = Popen(call, stdout=PIPE, stderr=PIPE) return p -- cgit v1.2.3 From 7368881d2ba95cca3f47afbb0f4ef5861f2774df Mon Sep 17 00:00:00 2001 From: Walter Purcaro Date: Sat, 31 Jan 2015 23:19:30 +0100 Subject: Extractor final fixup --- module/plugins/internal/SevenZip.py | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) (limited to 'module/plugins/internal/SevenZip.py') diff --git a/module/plugins/internal/SevenZip.py b/module/plugins/internal/SevenZip.py index 476348083..126958829 100644 --- a/module/plugins/internal/SevenZip.py +++ b/module/plugins/internal/SevenZip.py @@ -52,16 +52,16 @@ class SevenZip(UnRar): file = fs_encode(self.filename) p = self.call_cmd("t", file) - p.communicate() + out, err = p.communicate() if p.returncode > 1: - raise CRCError + raise CRCError(err) p = self.call_cmd("l", "-slt", file) out, err = p.communicate() if p.returncode > 1: - raise ArchiveError("Process terminated") + raise ArchiveError(_("Process return code: %d") % p.returncode) # check if output or error macthes the 'wrong password'-Regexp if self.re_wrongpwd.search(out): @@ -69,12 +69,7 @@ class SevenZip(UnRar): # check if output matches 'Encrypted = +' if self.re_wrongcrc.search(out): - raise CRCError - - # check if archive is empty - self.files = self.list() - if not self.files: - raise ArchiveError("Empty Archive") + raise CRCError(_("Header protected")) def isPassword(self, password): @@ -118,13 +113,13 @@ class SevenZip(UnRar): raise PasswordError elif self.re_wrongcrc.search(err): - raise CRCError + raise CRCError(err) elif err.strip(): #: raise error if anything is on stderr - raise ArchiveError(err.strip()) + raise ArchiveError(err) if p.returncode > 1: - raise ArchiveError("Process terminated") + raise ArchiveError(_("Process return code: %d") % p.returncode) if not self.files: self.files = self.list(password) @@ -137,10 +132,10 @@ class SevenZip(UnRar): out, err = p.communicate() if "Can not open" in err: - raise ArchiveError("Cannot open file") + raise ArchiveError(_("Cannot open file")) if p.returncode > 1: - raise ArchiveError("Process terminated unsuccessful") + raise ArchiveError(_("Process return code: %d") % p.returncode) result = set() for groups in self.re_filelist.findall(out): -- cgit v1.2.3 From 8dfb7adc0fc3c858c0ddf9371c2f4580bb8be3c7 Mon Sep 17 00:00:00 2001 From: Walter Purcaro Date: Tue, 3 Feb 2015 00:10:11 +0100 Subject: Update Extractor (3) --- module/plugins/internal/SevenZip.py | 42 ++++++++++++------------------------- 1 file changed, 13 insertions(+), 29 deletions(-) (limited to 'module/plugins/internal/SevenZip.py') diff --git a/module/plugins/internal/SevenZip.py b/module/plugins/internal/SevenZip.py index 126958829..2f4dc5565 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.05" + __version__ = "0.06" __description__ = """7-Zip extractor plugin""" __license__ = "GPLv3" @@ -89,40 +89,24 @@ class SevenZip(UnRar): renice(p.pid, self.renice) - progressstring = "" - while True: - c = p.stdout.read(1) - # quit loop on eof - if not c: - break - # reading a percentage sign -> set progress and restart - if c == '%': - self.notifyProgress(int(progressstring)) - progressstring = "" - # not reading a digit -> therefore restart - elif c not in digits: - progressstring = "" - # add digit to progressstring - else: - progressstring += c - - # retrieve stderr - err = p.stderr.read() - - if self.re_wrongpwd.search(err): - raise PasswordError + # communicate and retrieve stderr + self._progress(p) + err = p.stderr.read().strip() - elif self.re_wrongcrc.search(err): - raise CRCError(err) + if err: + if self.re_wrongpwd.search(err): + raise PasswordError + + elif self.re_wrongcrc.search(err): + raise CRCError(err) - elif err.strip(): #: raise error if anything is on stderr - raise ArchiveError(err) + else: #: raise error if anything is on stderr + raise ArchiveError(err) if p.returncode > 1: raise ArchiveError(_("Process return code: %d") % p.returncode) - if not self.files: - self.files = self.list(password) + self.files = self.list(password) def list(self, password=None): -- cgit v1.2.3 From 8d8cfd57fa44cb84eb9709871bf14a3b4d13d994 Mon Sep 17 00:00:00 2001 From: Walter Purcaro Date: Tue, 3 Feb 2015 01:10:04 +0100 Subject: Update Extractor (4) --- module/plugins/internal/SevenZip.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'module/plugins/internal/SevenZip.py') diff --git a/module/plugins/internal/SevenZip.py b/module/plugins/internal/SevenZip.py index 2f4dc5565..96e664573 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.06" + __version__ = "0.07" __description__ = """7-Zip extractor plugin""" __license__ = "GPLv3" @@ -138,7 +138,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-") -- cgit v1.2.3 From 2dc3536e36956eab99fa5f7945dcf60073b5fd57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20H=C3=B6rnlein?= Date: Mon, 9 Feb 2015 23:36:10 +0100 Subject: [ExtractArchive] better Multipart behavior, new version output --- module/plugins/internal/SevenZip.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'module/plugins/internal/SevenZip.py') diff --git a/module/plugins/internal/SevenZip.py b/module/plugins/internal/SevenZip.py index 96e664573..7ad6b0d7a 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.07" + __version__ = "0.08" __description__ = """7-Zip extractor plugin""" __license__ = "GPLv3" @@ -19,7 +19,8 @@ class SevenZip(UnRar): ("Walter Purcaro", "vuolter@gmail.com")] - CMD = "7z" + CMD = "7z" + VERSION = "" EXTENSIONS = [".7z", ".xz", ".zip", ".gz", ".gzip", ".tgz", ".bz2", ".bzip2", ".tbz2", ".tbz", ".tar", ".wim", ".swm", ".lzma", ".rar", ".cab", @@ -33,6 +34,7 @@ class SevenZip(UnRar): 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) @classmethod @@ -40,10 +42,12 @@ class SevenZip(UnRar): if os.name == "nt": cls.CMD = os.path.join(pypath, "7z.exe") p = Popen([cls.CMD], stdout=PIPE, stderr=PIPE) - p.communicate() + out,err = p.communicate() else: p = Popen([cls.CMD], stdout=PIPE, stderr=PIPE) - p.communicate() + out, err = p.communicate() + + cls.VERSION = cls.re_version.search(out).group(1) return True @@ -143,9 +147,9 @@ class SevenZip(UnRar): args.append("-p-") #@NOTE: return codes are not reliable, some kind of threading, cleanup whatever issue - call = [self.cmd, command] + args + list(xargs) + call = [self.CMD, command] + args + list(xargs) - self.manager.logDebug(" ".join(map(decode, call))) + self.manager.logDebug(" ".join(call)) p = Popen(call, stdout=PIPE, stderr=PIPE) return p -- cgit v1.2.3