From 1d3e8e2c893b077f05d054d5cc3fba20adfa627a Mon Sep 17 00:00:00 2001 From: Vladimir Oprya Date: Wed, 4 Nov 2020 12:43:12 +0300 Subject: [PATCH 1/5] Added password support for all archivers, which support work with password: arc, arj, p7zip, py_zipfile, rar, unace, unalz, unzip, xdms. Added tests for those, which support creation and test files in data folder for it. --- patool | 18 ++-- patoolib/__init__.py | 147 ++++++++++++++++++++++++------- patoolib/programs/arc.py | 29 ++++-- patoolib/programs/arj.py | 23 ++++- patoolib/programs/p7zip.py | 36 ++++++-- patoolib/programs/py_zipfile.py | 10 ++- patoolib/programs/rar.py | 16 +++- patoolib/programs/unace.py | 16 +++- patoolib/programs/unalz.py | 16 +++- patoolib/programs/unzip.py | 12 ++- patoolib/programs/xdms.py | 20 +++-- tests/archives/__init__.py | 16 ++-- tests/archives/test_7z.py | 47 +++++++++- tests/archives/test_arc.py | 9 +- tests/archives/test_arj.py | 9 +- tests/archives/test_pyzipfile.py | 12 ++- tests/archives/test_rar.py | 13 ++- tests/archives/test_unace.py | 31 ++++--- tests/archives/test_unzip.py | 25 ++++++ tests/data/p .7z | Bin 0 -> 186 bytes tests/data/p.7z.foo | Bin 0 -> 186 bytes tests/data/p.arc | Bin 0 -> 64 bytes tests/data/p.arc.foo | Bin 0 -> 64 bytes tests/data/p.arj | Bin 0 -> 129 bytes tests/data/p.arj.foo | Bin 0 -> 129 bytes tests/data/p.cbz | Bin 0 -> 278 bytes tests/data/p.cbz.foo | Bin 0 -> 278 bytes tests/data/p.rar | Bin 0 -> 158 bytes tests/data/p.rar.foo | Bin 0 -> 158 bytes tests/data/p.zip | Bin 0 -> 278 bytes tests/data/p.zip.foo | Bin 0 -> 278 bytes 31 files changed, 387 insertions(+), 118 deletions(-) create mode 100644 tests/data/p .7z create mode 100644 tests/data/p.7z.foo create mode 100644 tests/data/p.arc create mode 100644 tests/data/p.arc.foo create mode 100644 tests/data/p.arj create mode 100644 tests/data/p.arj.foo create mode 100644 tests/data/p.cbz create mode 100644 tests/data/p.cbz.foo create mode 100644 tests/data/p.rar create mode 100644 tests/data/p.rar.foo create mode 100644 tests/data/p.zip create mode 100644 tests/data/p.zip.foo diff --git a/patool b/patool index 0bc523d..6e9c83d 100755 --- a/patool +++ b/patool @@ -30,7 +30,7 @@ def run_extract(args): res = 0 for archive in args.archive: try: - patoolib.extract_archive(archive, verbosity=args.verbosity, interactive=args.interactive, outdir=args.outdir) + patoolib.extract_archive(archive, verbosity=args.verbosity, interactive=args.interactive, outdir=args.outdir, password=args.password) except PatoolError as msg: log_error("error extracting %s: %s" % (archive, msg)) res += 1 @@ -44,7 +44,7 @@ def run_list(args): try: # increase default verbosity since the listing output should be visible verbosity = args.verbosity + 1 - patoolib.list_archive(archive, verbosity=verbosity, interactive=args.interactive) + patoolib.list_archive(archive, verbosity=verbosity, interactive=args.interactive, password=args.password) except PatoolError as msg: log_error("error listing %s: %s" % (archive, msg)) res += 1 @@ -56,7 +56,7 @@ def run_test(args): res = 0 for archive in args.archive: try: - patoolib.test_archive(archive, verbosity=args.verbosity, interactive=args.interactive) + patoolib.test_archive(archive, verbosity=args.verbosity, interactive=args.interactive, password=args.password) except PatoolError as msg: log_error("error testing %s: %s" % (archive, msg)) res += 1 @@ -67,7 +67,7 @@ def run_create(args): """Create an archive from given files.""" res = 0 try: - patoolib.create_archive(args.archive, args.filename, verbosity=args.verbosity, interactive=args.interactive) + patoolib.create_archive(args.archive, args.filename, verbosity=args.verbosity, interactive=args.interactive, password=args.password) except PatoolError as msg: log_error("error creating %s: %s" % (args.archive, msg)) res = 1 @@ -87,7 +87,7 @@ def run_diff(args): def run_search(args): """Search for pattern in given archive.""" try: - res = patoolib.search_archive(args.pattern, args.archive, verbosity=args.verbosity, interactive=args.interactive) + res = patoolib.search_archive(args.pattern, args.archive, verbosity=args.verbosity, interactive=args.interactive, password=args.password) except PatoolError as msg: log_error("error searching %s: %s" % (args.archive, msg)) res = 2 @@ -109,7 +109,7 @@ def run_recompress(args): """Recompress an archive to smaller size.""" res = 0 try: - patoolib.recompress_archive(args.archive, verbosity=args.verbosity, interactive=args.interactive) + patoolib.recompress_archive(args.archive, verbosity=args.verbosity, interactive=args.interactive, password=args.password) except PatoolError as msg: log_error("error recompressing %s: %s" % (args.archive, msg)) res = 1 @@ -164,16 +164,20 @@ def create_argparser(): # extract parser_extract = subparsers.add_parser('extract', help='extract one or more archives') parser_extract.add_argument('--outdir', help="output directory to extract to") + parser_extract.add_argument('--password', help="password for encrypted files") parser_extract.add_argument('archive', nargs='+', help="an archive file") # list parser_list = subparsers.add_parser('list', help='list members or one or more archives') + parser_list.add_argument('--password', help="password for encrypted files") parser_list.add_argument('archive', nargs='+', help="an archive file") # create parser_create = subparsers.add_parser('create', help='create an archive') + parser_create.add_argument('--password', help="password to encrypt files") parser_create.add_argument('archive', help="the archive file; the file extension determines the archive program") parser_create.add_argument('filename', nargs='+', help="a file or directory to add to the archive; note that some archive programs do not support directories") # test parser_test = subparsers.add_parser('test', help='test an archive') + parser_test.add_argument('--password', help="password for encrypted files") parser_test.add_argument('archive', nargs='+', help='an archive file') # repack parser_repack = subparsers.add_parser('repack', help='repack an archive to a different format') @@ -181,6 +185,7 @@ def create_argparser(): parser_repack.add_argument('archive_dst', help='target archive file') # recompress parser_recompress = subparsers.add_parser('recompress', help='recompress an archive to smaller size') + parser_recompress.add_argument('--password', help="password for encrypted files") parser_recompress.add_argument('archive', help='an archive file') # diff parser_diff = subparsers.add_parser('diff', help='show differences between two archives') @@ -188,6 +193,7 @@ def create_argparser(): parser_diff.add_argument('archive2', help='the second archive file') # search parser_search = subparsers.add_parser('search', help="search contents of archive members") + parser_search.add_argument('--password', help="password for encrypted files") parser_search.add_argument('pattern', help='the grep(1) compatible search pattern') parser_search.add_argument('archive', help='the archive file') # formats diff --git a/patoolib/__init__.py b/patoolib/__init__.py index 1b15d0a..e88e9ea 100644 --- a/patoolib/__init__.py +++ b/patoolib/__init__.py @@ -273,6 +273,46 @@ ArchivePrograms = { }, } +# List of programs by archive type, which don't support password use +NoPasswordSupportArchivePrograms = { + 'bzip2': { + None: ('7z', ) + }, + 'cab': { + None: ('7z', ) + }, + 'zip': { + 'create': ('py_zipfile', ), + }, + 'arj': { + None: ('7z',) + }, + 'gzip': { + None: ('7z',) + }, + 'iso': { + None: ('7z',) + }, + 'cpio': { + None: ('7z', ) + }, + 'rpm': { + None: ('7z', ) + }, + 'deb': { + None: ('7z', ) + }, + 'lzma': { + None: ('7z', ) + }, + 'vhd': { + None: ('7z', ) + }, + 'xz': { + None: ('7z',) + }, +} + # List those programs that have different python module names because of # Python module naming restrictions. ProgramModules = { @@ -322,7 +362,7 @@ def check_archive_format (format, compression): raise util.PatoolError("unkonwn archive compression `%s'" % compression) -def find_archive_program (format, command, program=None): +def find_archive_program (format, command, program=None, password=None): """Find suitable archive program for given format and mode.""" commands = ArchivePrograms[format] programs = [] @@ -333,6 +373,8 @@ def find_archive_program (format, command, program=None): for key in (None, command): if key in commands: programs.extend(commands[key]) + if password is not None: + programs = _remove_command_without_password_support(programs, format, command) if not programs: raise util.PatoolError("%s archive format `%s' is not supported" % (command, format)) # return the first existing program @@ -349,6 +391,26 @@ def find_archive_program (format, command, program=None): raise util.PatoolError("could not find an executable program to %s format %s; candidates are (%s)," % (command, format, ",".join(programs))) +def _remove_command_without_password_support(programs, format, command): + """Remove programs if they don't support work with password for current + format and command.""" + if format not in NoPasswordSupportArchivePrograms: + return programs + no_password_support_commands = NoPasswordSupportArchivePrograms[format] + no_password_support_programs = set() + for key in (None, command): + if key in no_password_support_commands: + for program in no_password_support_commands[key]: + no_password_support_programs.add(program) + programs_with_support = [] + for program in programs: + if program not in no_password_support_programs: + programs_with_support.append(program) + if not programs_with_support and programs: + raise util.PatoolError("%s archive format `%s' with password is not supported" % (command, format)) + return programs_with_support + + def list_formats (): """Print information about available archive formats to stdout.""" print("Archive programs of", App) @@ -463,14 +525,14 @@ def cleanup_outdir (outdir, archive): def _extract_archive(archive, verbosity=0, interactive=True, outdir=None, - program=None, format=None, compression=None): + program=None, format=None, compression=None, password=None): """Extract an archive. @return: output directory if command is 'extract', else None """ if format is None: format, compression = get_archive_format(archive) check_archive_format(format, compression) - program = find_archive_program(format, 'extract', program=program) + program = find_archive_program(format, 'extract', program=program, password=password) check_program_compression(archive, 'extract', program, compression) get_archive_cmdlist = get_archive_cmdlist_func(program, 'extract', format) if outdir is None: @@ -479,7 +541,7 @@ def _extract_archive(archive, verbosity=0, interactive=True, outdir=None, else: do_cleanup_outdir = False try: - cmdlist = get_archive_cmdlist(archive, compression, program, verbosity, interactive, outdir) + cmdlist = get_archive_cmdlist(archive, compression, program, verbosity, interactive, outdir, password=password) if cmdlist: # an empty command list means the get_archive_cmdlist() function # already handled the command (eg. when it's a builtin Python @@ -502,12 +564,12 @@ def _extract_archive(archive, verbosity=0, interactive=True, outdir=None, def _create_archive(archive, filenames, verbosity=0, interactive=True, - program=None, format=None, compression=None): + program=None, format=None, compression=None, password=None): """Create an archive.""" if format is None: format, compression = get_archive_format(archive) check_archive_format(format, compression) - program = find_archive_program(format, 'create', program=program) + program = find_archive_program(format, 'create', program=program, password=password) check_program_compression(archive, 'create', program, compression) get_archive_cmdlist = get_archive_cmdlist_func(program, 'create', format) origarchive = None @@ -516,7 +578,7 @@ def _create_archive(archive, filenames, verbosity=0, interactive=True, # the arc program mangles the archive name if it contains ".arc" origarchive = archive archive = util.tmpfile(dir=os.path.dirname(archive), suffix=".arc") - cmdlist = get_archive_cmdlist(archive, compression, program, verbosity, interactive, filenames) + cmdlist = get_archive_cmdlist(archive, compression, program, verbosity, interactive, filenames, password=password) if cmdlist: # an empty command list means the get_archive_cmdlist() function # already handled the command (eg. when it's a builtin Python @@ -527,18 +589,18 @@ def _create_archive(archive, filenames, verbosity=0, interactive=True, def _handle_archive(archive, command, verbosity=0, interactive=True, - program=None, format=None, compression=None): + program=None, format=None, compression=None, password=None): """Test and list archives.""" if format is None: format, compression = get_archive_format(archive) check_archive_format(format, compression) if command not in ('list', 'test'): raise util.PatoolError("invalid archive command `%s'" % command) - program = find_archive_program(format, command, program=program) + program = find_archive_program(format, command, program=program, password=password) check_program_compression(archive, command, program, compression) get_archive_cmdlist = get_archive_cmdlist_func(program, command, format) # prepare keyword arguments for command list - cmdlist = get_archive_cmdlist(archive, compression, program, verbosity, interactive) + cmdlist = get_archive_cmdlist(archive, compression, program, verbosity, interactive, password=password) if cmdlist: # an empty command list means the get_archive_cmdlist() function # already handled the command (eg. when it's a builtin Python @@ -558,7 +620,25 @@ def get_archive_cmdlist_func (program, command, format): raise util.PatoolError(msg) # get archive handler function (eg. patoolib.programs.star.extract_tar) try: - return getattr(module, '%s_%s' % (command, format)) + archive_cmdlist_func = getattr(module, '%s_%s' % (command, format)) + def check_for_password_before_cmdlist_func_call(*args, **kwargs): + """ If password is None, or not set, run command as usual. + If password is set, but can't be accepted raise appropriate + message. + """ + util.log_info("... cmdlist_func = %s %s" % (archive_cmdlist_func, '')) + util.log_info("... kwargs=%s args=%s" % (kwargs, args)) + if 'password' in kwargs and kwargs['password'] is None: + kwargs.pop('password') + if 'password' not in kwargs: + return archive_cmdlist_func(*args, **kwargs) + else: + try: + return archive_cmdlist_func(*args, **kwargs) + except TypeError as msg: + if "unexpected keyword argument 'password'" in str(msg): + raise util.PatoolError('There is no support for password in %s' % program) + return check_for_password_before_cmdlist_func_call except AttributeError as msg: raise util.PatoolError(msg) @@ -593,7 +673,7 @@ def _diff_archives (archive1, archive2, verbosity=0, interactive=True): shutil.rmtree(tmpdir1, onerror=rmtree_log_error) -def _search_archive(pattern, archive, verbosity=0, interactive=True): +def _search_archive(pattern, archive, verbosity=0, interactive=True, password=None): """Search for given pattern in an archive.""" grep = util.find_program("grep") if not grep: @@ -601,13 +681,13 @@ def _search_archive(pattern, archive, verbosity=0, interactive=True): raise util.PatoolError(msg) tmpdir = util.tmpdir() try: - path = _extract_archive(archive, outdir=tmpdir, verbosity=-1) + path = _extract_archive(archive, outdir=tmpdir, verbosity=-1, password=password) return util.run_checked([grep, "-r", "-e", pattern, "."], ret_ok=(0, 1), verbosity=1, cwd=path) finally: shutil.rmtree(tmpdir, onerror=rmtree_log_error) -def _repack_archive (archive1, archive2, verbosity=0, interactive=True): +def _repack_archive (archive1, archive2, verbosity=0, interactive=True, password=None): """Repackage an archive to a different format.""" format1, compression1 = get_archive_format(archive1) format2, compression2 = get_archive_format(archive2) @@ -617,7 +697,7 @@ def _repack_archive (archive1, archive2, verbosity=0, interactive=True): return tmpdir = util.tmpdir() try: - kwargs = dict(verbosity=verbosity, outdir=tmpdir) + kwargs = dict(verbosity=verbosity, outdir=tmpdir, password=password) same_format = (format1 == format2 and compression1 and compression2) if same_format: # only decompress since the format is the same @@ -628,7 +708,7 @@ def _repack_archive (archive1, archive2, verbosity=0, interactive=True): olddir = os.getcwd() os.chdir(path) try: - kwargs = dict(verbosity=verbosity, interactive=interactive) + kwargs = dict(verbosity=verbosity, interactive=interactive, password=password) if same_format: # only compress since the format is the same kwargs['format'] = compression2 @@ -639,7 +719,7 @@ def _repack_archive (archive1, archive2, verbosity=0, interactive=True): shutil.rmtree(tmpdir, onerror=rmtree_log_error) -def _recompress_archive(archive, verbosity=0, interactive=True): +def _recompress_archive(archive, verbosity=0, interactive=True, password=None): """Try to recompress an archive to smaller size.""" format, compression = get_archive_format(archive) if compression: @@ -651,13 +731,13 @@ def _recompress_archive(archive, verbosity=0, interactive=True): archive2 = util.get_single_outfile(tmpdir2, base, extension=ext) try: # extract - kwargs = dict(verbosity=verbosity, format=format, outdir=tmpdir) + kwargs = dict(verbosity=verbosity, format=format, outdir=tmpdir, password=password) path = _extract_archive(archive, **kwargs) # compress to new file olddir = os.getcwd() os.chdir(path) try: - kwargs = dict(verbosity=verbosity, interactive=interactive, format=format) + kwargs = dict(verbosity=verbosity, interactive=interactive, format=format, password=password) files = tuple(os.listdir(path)) _create_archive(archive2, files, **kwargs) finally: @@ -679,44 +759,43 @@ def _recompress_archive(archive, verbosity=0, interactive=True): # the patool library API -def extract_archive(archive, verbosity=0, outdir=None, program=None, interactive=True): +def extract_archive(archive, verbosity=0, outdir=None, program=None, interactive=True, password=None): """Extract given archive.""" util.check_existing_filename(archive) if verbosity >= 0: util.log_info("Extracting %s ..." % archive) - return _extract_archive(archive, verbosity=verbosity, interactive=interactive, outdir=outdir, program=program) + return _extract_archive(archive, verbosity=verbosity, interactive=interactive, outdir=outdir, program=program, password=password) -def list_archive(archive, verbosity=1, program=None, interactive=True): +def list_archive(archive, verbosity=1, program=None, interactive=True, password=None): """List given archive.""" # Set default verbosity to 1 since the listing output should be visible. util.check_existing_filename(archive) if verbosity >= 0: util.log_info("Listing %s ..." % archive) - return _handle_archive(archive, 'list', verbosity=verbosity, - interactive=interactive, program=program) + return _handle_archive(archive, 'list', verbosity=verbosity, interactive=interactive, program=program, password=password) -def test_archive(archive, verbosity=0, program=None, interactive=True): +def test_archive(archive, verbosity=0, program=None, interactive=True, password=None): """Test given archive.""" util.check_existing_filename(archive) if verbosity >= 0: util.log_info("Testing %s ..." % archive) res = _handle_archive(archive, 'test', verbosity=verbosity, - interactive=interactive, program=program) + interactive=interactive, program=program, password=password) if verbosity >= 0: util.log_info("... tested ok.") return res -def create_archive(archive, filenames, verbosity=0, program=None, interactive=True): +def create_archive(archive, filenames, verbosity=0, program=None, interactive=True, password=None): """Create given archive with given files.""" util.check_new_filename(archive) util.check_archive_filelist(filenames) if verbosity >= 0: util.log_info("Creating %s ..." % archive) res = _create_archive(archive, filenames, verbosity=verbosity, - interactive=interactive, program=program) + interactive=interactive, program=program, password=password) if verbosity >= 0: util.log_info("... %s created." % archive) return res @@ -733,38 +812,38 @@ def diff_archives(archive1, archive2, verbosity=0, interactive=True): util.log_info("... no differences found.") -def search_archive(pattern, archive, verbosity=0, interactive=True): +def search_archive(pattern, archive, verbosity=0, interactive=True, password=None): """Search pattern in archive members.""" if not pattern: raise util.PatoolError("empty search pattern") util.check_existing_filename(archive) if verbosity >= 0: util.log_info("Searching %r in %s ..." % (pattern, archive)) - res = _search_archive(pattern, archive, verbosity=verbosity, interactive=interactive) + res = _search_archive(pattern, archive, verbosity=verbosity, interactive=interactive, password=password) if res == 1 and verbosity >= 0: util.log_info("... %r not found" % pattern) return res -def repack_archive (archive, archive_new, verbosity=0, interactive=True): +def repack_archive (archive, archive_new, verbosity=0, interactive=True, password=None): """Repack archive to different file and/or format.""" util.check_existing_filename(archive) util.check_new_filename(archive_new) if verbosity >= 0: util.log_info("Repacking %s to %s ..." % (archive, archive_new)) - res = _repack_archive(archive, archive_new, verbosity=verbosity, interactive=interactive) + res = _repack_archive(archive, archive_new, verbosity=verbosity, interactive=interactive, password=password) if verbosity >= 0: util.log_info("... repacking successful.") return res -def recompress_archive(archive, verbosity=0, interactive=True): +def recompress_archive(archive, verbosity=0, interactive=True, password=None): """Recompress an archive to hopefully smaller size.""" util.check_existing_filename(archive) util.check_writable_filename(archive) if verbosity >= 0: util.log_info("Recompressing %s ..." % (archive,)) - res = _recompress_archive(archive, verbosity=verbosity, interactive=interactive) + res = _recompress_archive(archive, verbosity=verbosity, interactive=interactive, password=password) if res and verbosity >= 0: util.log_info(res) return 0 diff --git a/patoolib/programs/arc.py b/patoolib/programs/arc.py index cce9679..c89dba9 100644 --- a/patoolib/programs/arc.py +++ b/patoolib/programs/arc.py @@ -15,30 +15,41 @@ # along with this program. If not, see . """Archive commands for the arc program.""" import os +from ..util import PatoolError -def extract_arc (archive, compression, cmd, verbosity, interactive, outdir): +def _add_password_to_options(options, password): + """Check password and add it to ARC options.""" + if password is None: + return options + if ' ' in password: + raise PatoolError("Password for ARC can't contain spaces.") + options += 'g%s' % password + return options + +def extract_arc (archive, compression, cmd, verbosity, interactive, outdir, password=None): """Extract a ARC archive.""" # Since extracted files will be placed in the current directory, # the cwd argument has to be the output directory. - cmdlist = [cmd, 'x', os.path.abspath(archive)] + options = _add_password_to_options('x', password) + cmdlist = [cmd, options, os.path.abspath(archive)] return (cmdlist, {'cwd': outdir}) -def list_arc (archive, compression, cmd, verbosity, interactive): +def list_arc (archive, compression, cmd, verbosity, interactive, password=None): """List a ARC archive.""" cmdlist = [cmd] if verbosity > 1: - cmdlist.append('v') + cmdlist.append(_add_password_to_options('v', password)) else: - cmdlist.append('l') + cmdlist.append(_add_password_to_options('l', password)) cmdlist.append(archive) return cmdlist -def test_arc (archive, compression, cmd, verbosity, interactive): +def test_arc (archive, compression, cmd, verbosity, interactive, password=None): """Test a ARC archive.""" - return [cmd, 't', archive] + return [cmd, _add_password_to_options('t', password), archive] -def create_arc (archive, compression, cmd, verbosity, interactive, filenames): +def create_arc (archive, compression, cmd, verbosity, interactive, filenames, password=None): """Create a ARC archive.""" - cmdlist = [cmd, 'a', archive] + cmdlist = [cmd, _add_password_to_options('a', password), archive] cmdlist.extend(filenames) return cmdlist diff --git a/patoolib/programs/arj.py b/patoolib/programs/arj.py index 2547c0e..d1f5e33 100644 --- a/patoolib/programs/arj.py +++ b/patoolib/programs/arj.py @@ -14,19 +14,30 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . """Archive commands for the arj program.""" +from ..util import PatoolError -def extract_arj (archive, compression, cmd, verbosity, interactive, outdir): +def _get_password_switch(password): + """Check password and return password switch for ARJ.""" + if ' ' in password: + raise PatoolError("Password for ARJ can't contain spaces.") + return '-g%s' % password + +def extract_arj (archive, compression, cmd, verbosity, interactive, outdir, password=None): """Extract an ARJ archive.""" cmdlist = [cmd, 'x', '-r'] + if password: + cmdlist.append(_get_password_switch(password)) if not interactive: cmdlist.append('-y') cmdlist.extend([archive, outdir]) return cmdlist -def list_arj (archive, compression, cmd, verbosity, interactive): +def list_arj (archive, compression, cmd, verbosity, interactive, password=None): """List an ARJ archive.""" cmdlist = [cmd] + if password: + cmdlist.append(_get_password_switch(password)) if verbosity > 1: cmdlist.append('v') else: @@ -37,18 +48,22 @@ def list_arj (archive, compression, cmd, verbosity, interactive): return cmdlist -def test_arj (archive, compression, cmd, verbosity, interactive): +def test_arj (archive, compression, cmd, verbosity, interactive, password=None): """Test an ARJ archive.""" cmdlist = [cmd, 't', '-r'] + if password: + cmdlist.append(_get_password_switch(password)) if not interactive: cmdlist.append('-y') cmdlist.append(archive) return cmdlist -def create_arj (archive, compression, cmd, verbosity, interactive, filenames): +def create_arj (archive, compression, cmd, verbosity, interactive, filenames, password=None): """Create an ARJ archive.""" cmdlist = [cmd, 'a', '-r'] + if password: + cmdlist.append(_get_password_switch(password)) if not interactive: cmdlist.append('-y') cmdlist.append(archive) diff --git a/patoolib/programs/p7zip.py b/patoolib/programs/p7zip.py index dd23c77..45e8483 100644 --- a/patoolib/programs/p7zip.py +++ b/patoolib/programs/p7zip.py @@ -15,21 +15,25 @@ # along with this program. If not, see . """Archive commands for the 7z program.""" -def extract_7z(archive, compression, cmd, verbosity, interactive, outdir): +def extract_7z(archive, compression, cmd, verbosity, interactive, outdir, password=None): """Extract a 7z archive.""" cmdlist = [cmd, 'x'] if not interactive: cmdlist.append('-y') + if password: + cmdlist.append('-p%s' % password) cmdlist.extend(['-o%s' % outdir, '--', archive]) return cmdlist -def extract_7z_singlefile(archive, compression, cmd, verbosity, interactive, outdir): +def extract_7z_singlefile(archive, compression, cmd, verbosity, interactive, outdir, password=None): """Extract a singlefile archive (eg. gzip or bzip2) with '7z e'. This makes sure a single file and no subdirectories are created, which would cause errors with patool repack.""" cmdlist = [cmd, 'e'] if not interactive: cmdlist.append('-y') + if password: + cmdlist.append('-p%s' % password) cmdlist.extend(['-o%s' % outdir, '--', archive]) return cmdlist @@ -51,11 +55,13 @@ extract_zip = \ extract_vhd = \ extract_7z -def list_7z (archive, compression, cmd, verbosity, interactive): +def list_7z (archive, compression, cmd, verbosity, interactive, password=None): """List a 7z archive.""" cmdlist = [cmd, 'l'] if not interactive: cmdlist.append('-y') + if password: + cmdlist.append('-p%s' % password) cmdlist.extend(['--', archive]) return cmdlist @@ -76,11 +82,13 @@ list_bzip2 = \ list_7z -def test_7z (archive, compression, cmd, verbosity, interactive): +def test_7z (archive, compression, cmd, verbosity, interactive, password=None): """Test a 7z archive.""" cmdlist = [cmd, 't'] if not interactive: cmdlist.append('-y') + if password: + cmdlist.append('-p%s' % password) cmdlist.extend(['--', archive]) return cmdlist @@ -101,51 +109,61 @@ test_bzip2 = \ test_7z -def create_7z(archive, compression, cmd, verbosity, interactive, filenames): +def create_7z(archive, compression, cmd, verbosity, interactive, filenames, password=None): """Create a 7z archive.""" cmdlist = [cmd, 'a'] if not interactive: cmdlist.append('-y') + if password: + cmdlist.append('-p%s' % password) cmdlist.extend(['-t7z', '-mx=9', '--', archive]) cmdlist.extend(filenames) return cmdlist -def create_zip(archive, compression, cmd, verbosity, interactive, filenames): +def create_zip(archive, compression, cmd, verbosity, interactive, filenames, password=None): """Create a ZIP archive.""" cmdlist = [cmd, 'a'] if not interactive: cmdlist.append('-y') + if password: + cmdlist.append('-p%s' % password) cmdlist.extend(['-tzip', '-mx=9', '--', archive]) cmdlist.extend(filenames) return cmdlist -def create_xz(archive, compression, cmd, verbosity, interactive, filenames): +def create_xz(archive, compression, cmd, verbosity, interactive, filenames, password=None): """Create an XZ archive.""" cmdlist = [cmd, 'a'] if not interactive: cmdlist.append('-y') + if password: + cmdlist.append('-p%s' % password) cmdlist.extend(['-txz', '-mx=9', '--', archive]) cmdlist.extend(filenames) return cmdlist -def create_gzip(archive, compression, cmd, verbosity, interactive, filenames): +def create_gzip(archive, compression, cmd, verbosity, interactive, filenames, password=None): """Create a GZIP archive.""" cmdlist = [cmd, 'a'] if not interactive: cmdlist.append('-y') + if password: + cmdlist.append('-p%s' % password) cmdlist.extend(['-tgzip', '-mx=9', '--', archive]) cmdlist.extend(filenames) return cmdlist -def create_bzip2(archive, compression, cmd, verbosity, interactive, filenames): +def create_bzip2(archive, compression, cmd, verbosity, interactive, filenames, password=None): """Create a BZIP2 archive.""" cmdlist = [cmd, 'a'] if not interactive: cmdlist.append('-y') + if password: + cmdlist.append('-p%s' % password) cmdlist.extend(['-tbzip2', '-mx=9', '--', archive]) cmdlist.extend(filenames) return cmdlist diff --git a/patoolib/programs/py_zipfile.py b/patoolib/programs/py_zipfile.py index 73daf98..4529036 100644 --- a/patoolib/programs/py_zipfile.py +++ b/patoolib/programs/py_zipfile.py @@ -22,10 +22,12 @@ import os READ_SIZE_BYTES = 1024*1024 -def list_zip(archive, compression, cmd, verbosity, interactive): +def list_zip(archive, compression, cmd, verbosity, interactive, password=None): """List member of a ZIP archive with the zipfile Python module.""" try: with zipfile.ZipFile(archive, "r") as zfile: + if password: + zfile.setpassword(pwd=password.encode()) for name in zfile.namelist(): if verbosity >= 0: print(name) @@ -36,11 +38,13 @@ def list_zip(archive, compression, cmd, verbosity, interactive): test_zip = list_zip -def extract_zip(archive, compression, cmd, verbosity, interactive, outdir): +def extract_zip(archive, compression, cmd, verbosity, interactive, outdir, password=None): """Extract a ZIP archive with the zipfile Python module.""" try: + if password: + password = password.encode() with zipfile.ZipFile(archive) as zfile: - zfile.extractall(outdir) + zfile.extractall(outdir, pwd=password) except Exception as err: msg = "error extracting %s: %s" % (archive, err) raise util.PatoolError(msg) diff --git a/patoolib/programs/rar.py b/patoolib/programs/rar.py index b635e7c..96d1f46 100644 --- a/patoolib/programs/rar.py +++ b/patoolib/programs/rar.py @@ -16,15 +16,17 @@ """Archive commands for the rar program.""" import os -def extract_rar (archive, compression, cmd, verbosity, interactive, outdir): +def extract_rar (archive, compression, cmd, verbosity, interactive, outdir, password=None): """Extract a RAR archive.""" cmdlist = [cmd, 'x'] if not interactive: cmdlist.extend(['-p-', '-y']) + if password: + cmdlist.append('-p%s' % password) cmdlist.extend(['--', os.path.abspath(archive)]) return (cmdlist, {'cwd': outdir}) -def list_rar (archive, compression, cmd, verbosity, interactive): +def list_rar (archive, compression, cmd, verbosity, interactive, password=None): """List a RAR archive.""" cmdlist = [cmd] if verbosity > 1: @@ -33,22 +35,28 @@ def list_rar (archive, compression, cmd, verbosity, interactive): cmdlist.append('l') if not interactive: cmdlist.extend(['-p-', '-y']) + if password: + cmdlist.append('-p%s' % password) cmdlist.extend(['--', archive]) return cmdlist -def test_rar (archive, compression, cmd, verbosity, interactive): +def test_rar (archive, compression, cmd, verbosity, interactive, password=None): """Test a RAR archive.""" cmdlist = [cmd, 't'] if not interactive: cmdlist.extend(['-p-', '-y']) + if password: + cmdlist.append('-p%s' % password) cmdlist.extend(['--', archive]) return cmdlist -def create_rar (archive, compression, cmd, verbosity, interactive, filenames): +def create_rar (archive, compression, cmd, verbosity, interactive, filenames, password=None): """Create a RAR archive.""" cmdlist = [cmd, 'a'] if not interactive: cmdlist.append('-y') + if password: + cmdlist.append('-p%s' % password) cmdlist.extend(['-r', '-m5', '--', archive]) cmdlist.extend(filenames) return cmdlist diff --git a/patoolib/programs/unace.py b/patoolib/programs/unace.py index 845b985..2daf232 100644 --- a/patoolib/programs/unace.py +++ b/patoolib/programs/unace.py @@ -15,24 +15,32 @@ # along with this program. If not, see . """Archive commands for the unace program.""" -def extract_ace (archive, compression, cmd, verbosity, interactive, outdir): +def extract_ace (archive, compression, cmd, verbosity, interactive, outdir, password=None): """Extract an ACE archive.""" cmdlist = [cmd, 'x'] if not outdir.endswith('/'): outdir += '/' + if password: + cmdlist.append('-p%s' % password) cmdlist.extend([archive, outdir]) return cmdlist -def list_ace (archive, compression, cmd, verbosity, interactive): +def list_ace (archive, compression, cmd, verbosity, interactive, password=None): """List an ACE archive.""" cmdlist = [cmd] if verbosity > 1: cmdlist.append('v') else: cmdlist.append('l') + if password: + cmdlist.append('-p%s' % password) cmdlist.append(archive) return cmdlist -def test_ace (archive, compression, cmd, verbosity, interactive): +def test_ace (archive, compression, cmd, verbosity, interactive, password=None): """Test an ACE archive.""" - return [cmd, 't', archive] + cmdlist = [cmd, 't'] + if password: + cmdlist.append('-p%s' % password) + cmdlist.append(archive) + return cmdlist diff --git a/patoolib/programs/unalz.py b/patoolib/programs/unalz.py index 4255f26..9e2f69c 100644 --- a/patoolib/programs/unalz.py +++ b/patoolib/programs/unalz.py @@ -15,13 +15,21 @@ # along with this program. If not, see . """Archive commands for the unalz program.""" -def extract_alzip (archive, compression, cmd, verbosity, interactive, outdir): +def extract_alzip (archive, compression, cmd, verbosity, interactive, outdir, password=None): """Extract a ALZIP archive.""" - return [cmd, '-d', outdir, archive] + cmdlist = [cmd, '-d', outdir] + if password: + cmdlist.extend(['-pwd', password]) + cmdlist.append(archive) + return cmdlist -def list_alzip (archive, compression, cmd, verbosity, interactive): +def list_alzip (archive, compression, cmd, verbosity, interactive, password=None): """List a ALZIP archive.""" - return [cmd, '-l', archive] + cmdlist = [cmd, '-l'] + if password: + cmdlist.extend(['-pwd', password]) + cmdlist.append(archive) + return cmdlist test_alzip = list_alzip diff --git a/patoolib/programs/unzip.py b/patoolib/programs/unzip.py index 1768f72..2b875b9 100644 --- a/patoolib/programs/unzip.py +++ b/patoolib/programs/unzip.py @@ -15,26 +15,32 @@ # along with this program. If not, see . """Archive commands for the unzip program.""" -def extract_zip (archive, compression, cmd, verbosity, interactive, outdir): +def extract_zip (archive, compression, cmd, verbosity, interactive, outdir, password=None): """Extract a ZIP archive.""" cmdlist = [cmd] if verbosity > 1: cmdlist.append('-v') + if password: + cmdlist.extend(['-P', password]) cmdlist.extend(['--', archive, '-d', outdir]) return cmdlist -def list_zip (archive, compression, cmd, verbosity, interactive): +def list_zip (archive, compression, cmd, verbosity, interactive, password=None): """List a ZIP archive.""" cmdlist = [cmd, '-l'] if verbosity > 1: cmdlist.append('-v') + if password: + cmdlist.extend(['-P', password]) cmdlist.extend(['--', archive]) return cmdlist -def test_zip (archive, compression, cmd, verbosity, interactive): +def test_zip (archive, compression, cmd, verbosity, interactive, password=None): """Test a ZIP archive.""" cmdlist = [cmd, '-t'] if verbosity > 1: cmdlist.append('-v') + if password: + cmdlist.extend(['-P', password]) cmdlist.extend(['--', archive]) return cmdlist diff --git a/patoolib/programs/xdms.py b/patoolib/programs/xdms.py index c1935f3..d76048d 100644 --- a/patoolib/programs/xdms.py +++ b/patoolib/programs/xdms.py @@ -17,26 +17,36 @@ from .. import util -def extract_dms (archive, compression, cmd, verbosity, interactive, outdir): +def extract_dms (archive, compression, cmd, verbosity, interactive, outdir, password=None): """Extract a DMS archive.""" check_archive_ext(archive) cmdlist = [cmd, '-d', outdir] if verbosity > 1: cmdlist.append('-v') + if password: + cmdlist.extend(['-p', password]) cmdlist.extend(['u', archive]) return cmdlist -def list_dms (archive, compression, cmd, verbosity, interactive): +def list_dms (archive, compression, cmd, verbosity, interactive, password=None): """List a DMS archive.""" check_archive_ext(archive) - return [cmd, 'v', archive] + cmdlist = [cmd, 'v'] + if password: + cmdlist.extend(['-p', password]) + cmdlist.append(archive) + return cmdlist -def test_dms (archive, compression, cmd, verbosity, interactive): +def test_dms (archive, compression, cmd, verbosity, interactive, password=None): """Test a DMS archive.""" check_archive_ext(archive) - return [cmd, 't', archive] + cmdlist = [cmd, 't'] + if password: + cmdlist.extend(['-p', password]) + cmdlist.append(archive) + return cmdlist def check_archive_ext (archive): diff --git a/tests/archives/__init__.py b/tests/archives/__init__.py index 5e03f6e..cd33439 100644 --- a/tests/archives/__init__.py +++ b/tests/archives/__init__.py @@ -49,6 +49,10 @@ class ArchiveTest (unittest.TestCase): # set program to use for archive handling in subclass program = None + # set password for test with password + password = None + # default archive basename to check + filename = 't' def archive_commands (self, filename, **kwargs): """Run archive commands list, test, extract and create. @@ -75,7 +79,7 @@ class ArchiveTest (unittest.TestCase): try: olddir = patoolib.util.chdir(tmpdir) try: - output = patoolib.extract_archive(archive, program=self.program, verbosity=verbosity, interactive=False) + output = patoolib.extract_archive(archive, program=self.program, verbosity=verbosity, interactive=False, password=self.password) if check: self.check_extracted_archive(archive, output, check) finally: @@ -117,13 +121,13 @@ class ArchiveTest (unittest.TestCase): """Test archive listing.""" archive = os.path.join(datadir, filename) for verbosity in (-1, 0, 1, 2): - patoolib.list_archive(archive, program=self.program, verbosity=verbosity, interactive=False) + patoolib.list_archive(archive, program=self.program, verbosity=verbosity, interactive=False, password=self.password) def archive_test (self, filename): """Test archive testing.""" archive = os.path.join(datadir, filename) for verbosity in (-1, 0, 1, 2): - patoolib.test_archive(archive, program=self.program, verbosity=verbosity, interactive=False) + patoolib.test_archive(archive, program=self.program, verbosity=verbosity, interactive=False, password=self.password) def archive_create (self, archive, srcfiles=None, check=Content.Recursive): """Test archive creation.""" @@ -156,7 +160,7 @@ class ArchiveTest (unittest.TestCase): try: archive = os.path.join(tmpdir, archive) self.assertTrue(os.path.isabs(archive), "archive path is not absolute: %r" % archive) - patoolib.create_archive(archive, srcfiles, verbosity=verbosity, interactive=False, program=program) + patoolib.create_archive(archive, srcfiles, verbosity=verbosity, interactive=False, program=program, password=self.password) self.assertTrue(os.path.isfile(archive)) self.check_created_archive_with_test(archive) self.check_created_archive_with_diff(archive, srcfiles) @@ -184,7 +188,7 @@ class ArchiveTest (unittest.TestCase): program = '7z' elif self.program == 'shar': return - command(archive, program=program) + command(archive, program=program, password=self.password) def check_created_archive_with_diff(self, archive, srcfiles): """Extract created archive again and compare the contents.""" @@ -208,7 +212,7 @@ class ArchiveTest (unittest.TestCase): try: olddir = patoolib.util.chdir(tmpdir) try: - output = patoolib.extract_archive(archive, program=program, interactive=False) + output = patoolib.extract_archive(archive, program=program, interactive=False, password=self.password) if len(srcfiles) == 1: source = os.path.join(datadir, srcfiles[0]) patoolib.util.run_checked([diff, "-urN", source, output]) diff --git a/tests/archives/test_7z.py b/tests/archives/test_7z.py index 318549a..f2a91f5 100644 --- a/tests/archives/test_7z.py +++ b/tests/archives/test_7z.py @@ -116,6 +116,47 @@ class Test7z (ArchiveTest): @needs_codec(program, 'rar') def test_7z_rar_file (self): # only succeeds with the rar module for 7z installed - self.archive_list('t.rar.foo') - self.archive_extract('t.rar.foo') - self.archive_test('t.rar.foo') + self.archive_list(self.filename + '.rar.foo') + self.archive_extract(self.filename + '.rar.foo') + self.archive_test(self.filename + '.rar.foo') + + +class Test7zPassword(ArchiveTest): + + program = '7z' + password = 'thereisnotry' + + @needs_program(program) + def test_7z (self): + self.archive_commands('p .7z') + self.archive_commands('p.zip') + self.archive_commands('p.cbz') + self.archive_list('p.arj') + self.archive_extract('p.arj') + self.archive_test('p.arj') + + @needs_codec(program, 'rar') + def test_7z_rar (self): + # only succeeds with the rar module for 7z installed + self.archive_list('p.rar') + self.archive_extract('p.rar') + self.archive_test('p.rar') + + @needs_program('file') + @needs_program(program) + def test_7z_file (self): + self.archive_commands('p.7z.foo', skip_create=True) + self.archive_commands('p.zip.foo', skip_create=True) + self.archive_commands('p.cbz.foo', skip_create=True) + self.archive_list('p.arj.foo') + self.archive_extract('p.arj.foo') + self.archive_test('p.arj.foo') + + @needs_program('file') + @needs_codec(program, 'rar') + def test_7z_rar_file (self): + # only succeeds with the rar module for 7z installed + self.archive_list('p.rar.foo') + self.archive_extract('p.rar.foo') + self.archive_test('p.rar.foo') + diff --git a/tests/archives/test_arc.py b/tests/archives/test_arc.py index a4ff847..3091b39 100644 --- a/tests/archives/test_arc.py +++ b/tests/archives/test_arc.py @@ -22,10 +22,15 @@ class TestArc(ArchiveTest): @needs_program(program) def test_arc(self): - self.archive_commands('t.arc', check=Content.Multifile) + self.archive_commands(self.filename + '.arc', check=Content.Multifile) @needs_program('file') @needs_program(program) def test_arc_file(self): - self.archive_commands('t.arc.foo', check=Content.Multifile, skip_create=True) + self.archive_commands(self.filename + '.arc.foo', check=Content.Multifile, skip_create=True) + +class TestArcPassword(TestArc): + + password = 'thereisnotry' + filename = 'p' diff --git a/tests/archives/test_arj.py b/tests/archives/test_arj.py index 9d60661..cddc315 100644 --- a/tests/archives/test_arj.py +++ b/tests/archives/test_arj.py @@ -22,10 +22,15 @@ class TestArj (ArchiveTest): @needs_program(program) def test_arj(self): - self.archive_commands('t.arj') + self.archive_commands(self.filename + '.arj') @needs_program('file') @needs_program(program) def test_arj_file(self): - self.archive_commands('t.arj.foo', skip_create=True) + self.archive_commands(self.filename + '.arj.foo', skip_create=True) + +class TestArjPassword(TestArj): + + password = 'thereisnotry' + filename = 'p' diff --git a/tests/archives/test_pyzipfile.py b/tests/archives/test_pyzipfile.py index 2be701b..3e87bc4 100644 --- a/tests/archives/test_pyzipfile.py +++ b/tests/archives/test_pyzipfile.py @@ -21,11 +21,15 @@ class TestPyzipfile (ArchiveTest): program = 'py_zipfile' def test_py_zipfile(self): - self.archive_commands('t.zip') - self.archive_commands('t.cbz') + self.archive_commands(self.filename + '.zip') + self.archive_commands(self.filename + '.cbz') @needs_program('file') def test_py_zipfile_file(self): - self.archive_commands('t.zip.foo', skip_create=True) - self.archive_commands('t.cbz.foo', skip_create=True) + self.archive_commands(self.filename + '.zip.foo', skip_create=True) + self.archive_commands(self.filename + '.cbz.foo', skip_create=True) +class TestPyzipPasswordfile (TestPyzipfile): + + filename = 'p' + password = 'thereisnotry' diff --git a/tests/archives/test_rar.py b/tests/archives/test_rar.py index e7c41c6..820f275 100644 --- a/tests/archives/test_rar.py +++ b/tests/archives/test_rar.py @@ -22,12 +22,17 @@ class TestRar (ArchiveTest): @needs_program(program) def test_rar(self): - self.archive_commands('t.rar') - self.archive_commands('t.cbr') + self.archive_commands(self.filename + '.rar') + self.archive_commands(self.filename + '.cbr') @needs_program('file') @needs_program(program) def test_rar_file(self): - self.archive_commands('t.rar.foo', skip_create=True) - self.archive_commands('t.cbr.foo', skip_create=True) + self.archive_commands(self.filename + '.rar.foo', skip_create=True) + self.archive_commands(self.filename + '.cbr.foo', skip_create=True) + +class TestRarPassword (TestRar): + + filename = 'p' + password = 'thereisnotry' diff --git a/tests/archives/test_unace.py b/tests/archives/test_unace.py index 3691d8d..3b45953 100644 --- a/tests/archives/test_unace.py +++ b/tests/archives/test_unace.py @@ -22,19 +22,26 @@ class TestUnace (ArchiveTest): @needs_program(program) def test_unace(self): - self.archive_list('t.ace') - self.archive_test('t.ace') - self.archive_extract('t.ace') - self.archive_list('t.cba') - self.archive_test('t.cba') - self.archive_extract('t.cba') + self.archive_list(self.filename + '.ace') + self.archive_test(self.filename + '.ace') + self.archive_extract(self.filename + '.ace') + self.archive_list(self.filename + '.cba') + self.archive_test(self.filename + '.cba') + self.archive_extract(self.filename + '.cba') @needs_program('file') @needs_program(program) def test_unace_file(self): - self.archive_list('t.ace.foo') - self.archive_test('t.ace.foo') - self.archive_extract('t.ace.foo') - self.archive_list('t.cba.foo') - self.archive_test('t.cba.foo') - self.archive_extract('t.cba.foo') + self.archive_list(self.filename + '.ace.foo') + self.archive_test(self.filename + '.ace.foo') + self.archive_extract(self.filename + '.ace.foo') + self.archive_list(self.filename + '.cba.foo') + self.archive_test(self.filename + '.cba.foo') + self.archive_extract(self.filename + '.cba.foo') + + +# TODO: add p.ace, p.ace.foo, p.cba, p.cba.foo with password to repository +# class TestUnacePassword (TestUnace): +# +# filename = 'p' +# password = 'thereisnotry' diff --git a/tests/archives/test_unzip.py b/tests/archives/test_unzip.py index a25885a..91b046f 100644 --- a/tests/archives/test_unzip.py +++ b/tests/archives/test_unzip.py @@ -56,3 +56,28 @@ class TestUnzip (ArchiveTest): self.archive_extract('t.apk.foo', check=None) self.archive_list('t.apk.foo') self.archive_test('t.apk.foo') + + +class TestUnzipPassword (ArchiveTest): + + program = 'unzip' + password = 'thereisnotry' + + @needs_program(program) + def test_unzip (self): + self.archive_extract('p.zip', check=None) + self.archive_list('p.zip') + self.archive_test('p.zip') + self.archive_extract('p.cbz', check=None) + self.archive_list('p.cbz') + self.archive_test('p.cbz') + + @needs_program('file') + @needs_program(program) + def test_unzip_file (self): + self.archive_extract('p.zip.foo', check=None) + self.archive_list('p.zip.foo') + self.archive_test('p.zip.foo') + self.archive_extract('p.cbz.foo', check=None) + self.archive_list('p.cbz.foo') + self.archive_test('p.cbz.foo') diff --git a/tests/data/p .7z b/tests/data/p .7z new file mode 100644 index 0000000000000000000000000000000000000000..ff9f05c46c02bb5442d350430ca867e7be9f97ef GIT binary patch literal 186 zcmXr7+Ou9=hJhuY@$#W61_)4q()FPqr-?4jw>)syGkizSx+7fY?-(#JG#az7<3IOl z6A$}_!?(W2yLL?vZqhum^3H~h)h2b-LO;)R?zy6^V4kyuxq6w%j{DJpo>Qc`ex)}( zc)0Z3^(8;D7OCw@>s<1Pe`$c~vPCs)Ui+UrbENIRaH6^V9P_@yEw{~8wLa1fdK#z(MBf# literal 0 HcmV?d00001 diff --git a/tests/data/p.7z.foo b/tests/data/p.7z.foo new file mode 100644 index 0000000000000000000000000000000000000000..ff9f05c46c02bb5442d350430ca867e7be9f97ef GIT binary patch literal 186 zcmXr7+Ou9=hJhuY@$#W61_)4q()FPqr-?4jw>)syGkizSx+7fY?-(#JG#az7<3IOl z6A$}_!?(W2yLL?vZqhum^3H~h)h2b-LO;)R?zy6^V4kyuxq6w%j{DJpo>Qc`ex)}( zc)0Z3^(8;D7OCw@>s<1Pe`$c~vPCs)Ui+UrbENIRaH6^V9P_@yEw{~8wLa1fdK#z(MBf# literal 0 HcmV?d00001 diff --git a/tests/data/p.arc b/tests/data/p.arc new file mode 100644 index 0000000000000000000000000000000000000000..390e0767d2a655c34d0a87a5cd82e5d35ace4dab GIT binary patch literal 64 vcmb1QD$y&cC}Ch=5D<{_aApEB!kmPrO&0~R5~`$_N{k@#NYWzf;L;2LgKP`Q literal 0 HcmV?d00001 diff --git a/tests/data/p.arc.foo b/tests/data/p.arc.foo new file mode 100644 index 0000000000000000000000000000000000000000..390e0767d2a655c34d0a87a5cd82e5d35ace4dab GIT binary patch literal 64 vcmb1QD$y&cC}Ch=5D<{_aApEB!kmPrO&0~R5~`$_N{k@#NYWzf;L;2LgKP`Q literal 0 HcmV?d00001 diff --git a/tests/data/p.arj b/tests/data/p.arj new file mode 100644 index 0000000000000000000000000000000000000000..7d5b342aa7f78cdd237c4068a7223d646af03e3a GIT binary patch literal 129 zcmYdzrOBYg&B!Fkz{K$M$NYE@W_3IjvJD{}@tpcY0(hNn>` zb>5snB}_ovu|dU%iD7{tM7Qv?eg1o(hLz}-=#^BIFfg=KSDP|0MEYmMX9}fU4oG;# GzyJUbjUEvI literal 0 HcmV?d00001 diff --git a/tests/data/p.arj.foo b/tests/data/p.arj.foo new file mode 100644 index 0000000000000000000000000000000000000000..7d5b342aa7f78cdd237c4068a7223d646af03e3a GIT binary patch literal 129 zcmYdzrOBYg&B!Fkz{K$M$NYE@W_3IjvJD{}@tpcY0(hNn>` zb>5snB}_ovu|dU%iD7{tM7Qv?eg1o(hLz}-=#^BIFfg=KSDP|0MEYmMX9}fU4oG;# GzyJUbjUEvI literal 0 HcmV?d00001 diff --git a/tests/data/p.cbz b/tests/data/p.cbz new file mode 100644 index 0000000000000000000000000000000000000000..57ea283d9d77baa757622968aa07b126fd0295e9 GIT binary patch literal 278 zcmWIWW@Zs#W&i>kw_qC(4FgO-Mu~m^Se_BcmIcapY)~=c1F}JK>|ps4y^@NOzVaql zzNreysc+4=PdNm5GcwsT<1$nQs0{=J8eTYp=n{P{1_cmG{{^C9W@2{;%uI!b1&sh0I>4Ki4X6X?BPNEm KKsp%2VE_Pd$1*nn literal 0 HcmV?d00001 diff --git a/tests/data/p.cbz.foo b/tests/data/p.cbz.foo new file mode 100644 index 0000000000000000000000000000000000000000..57ea283d9d77baa757622968aa07b126fd0295e9 GIT binary patch literal 278 zcmWIWW@Zs#W&i>kw_qC(4FgO-Mu~m^Se_BcmIcapY)~=c1F}JK>|ps4y^@NOzVaql zzNreysc+4=PdNm5GcwsT<1$nQs0{=J8eTYp=n{P{1_cmG{{^C9W@2{;%uI!b1&sh0I>4Ki4X6X?BPNEm KKsp%2VE_Pd$1*nn literal 0 HcmV?d00001 diff --git a/tests/data/p.rar b/tests/data/p.rar new file mode 100644 index 0000000000000000000000000000000000000000..05b663a19dc78ace710a13825dc0318afaa9dbe1 GIT binary patch literal 158 zcmWGaEK-zWXJq*Nu<127BP%-t8zW;wLj%K%u&4e0Ow5K87}%N^7Bn+iNz{4Q2iSQw zurjij=$Gh~RFoJnGBEQi*auHZHo9!dot5OjYno{E#@3oUi`3(uHn~SDGjGsj6TT2q zl-A?$%kgT?X{B2E2b)^Oe0yH;kw_qC(4FgO-Mu~m^Se_BcmIcapY)~=c1F}JK>|ps4y^@NO^UNH} zGdI+IE{^d|PDu^$W@NHw#$~7qP#XvcG`w&G(Ixs^3<@9y10#b31A~-vtop`Nj14L` zQa5hA#@KMGG#Nz0%*5^xn3)O<3mO%GCY9)eorPjB<3=m6!B7Jc2D7pObpUkw_qC(4FgO-Mu~m^Se_BcmIcapY)~=c1F}JK>|ps4y^@NO^UNH} zGdI+IE{^d|PDu^$W@NHw#$~7qP#XvcG`w&G(Ixs^3<@9y10#b31A~-vtop`Nj14L` zQa5hA#@KMGG#Nz0%*5^xn3)O<3mO%GCY9)eorPjB<3=m6!B7Jc2D7pObpU Date: Wed, 4 Nov 2020 13:08:37 +0300 Subject: [PATCH 2/5] Added examples of using password settings --- doc/README.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/README.txt b/doc/README.txt index 0a0ce09..8aa3a9a 100644 --- a/doc/README.txt +++ b/doc/README.txt @@ -30,6 +30,9 @@ Examples # Extract several archives with different formats patool extract archive.zip otherarchive.rar +# Extract archive with password +patool extract --password somepassword archive.rar + # Test archive integrity patool test --verbose dist.tar.gz @@ -39,6 +42,9 @@ patool list package.deb # Create a new archive patool create --verbose /path/to/myfiles.zip file1.txt dir/ +# Create a new archive with password +patool create --verbose --password somepassword /path/to/myfiles.zip file1.txt dir/ + # Show differences between two archives patool diff release1.0.tar.gz release2.0.zip From 237b025afc46ca0a8106009e8703e1e07f260a7c Mon Sep 17 00:00:00 2001 From: Vladimir Oprya Date: Sat, 14 Nov 2020 12:31:09 +0300 Subject: [PATCH 3/5] Changed password support check from try...catch to check 'password' in inspect.signature(archive_cmdlist_func).parameters --- patoolib/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/patoolib/__init__.py b/patoolib/__init__.py index e88e9ea..1c2e423 100644 --- a/patoolib/__init__.py +++ b/patoolib/__init__.py @@ -14,6 +14,8 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . from __future__ import print_function + +import inspect import sys if not hasattr(sys, "version_info") or sys.version_info < (2, 7, 0, "final", 0): raise SystemExit("This program requires Python 2.7 or later.") @@ -633,11 +635,9 @@ def get_archive_cmdlist_func (program, command, format): if 'password' not in kwargs: return archive_cmdlist_func(*args, **kwargs) else: - try: + if 'password' in inspect.signature(archive_cmdlist_func).parameters: return archive_cmdlist_func(*args, **kwargs) - except TypeError as msg: - if "unexpected keyword argument 'password'" in str(msg): - raise util.PatoolError('There is no support for password in %s' % program) + raise util.PatoolError('There is no support for password in %s' % program) return check_for_password_before_cmdlist_func_call except AttributeError as msg: raise util.PatoolError(msg) From de35c30d0b1e12e40574fd4a9c79f6c88b896cc6 Mon Sep 17 00:00:00 2001 From: Vladimir Oprya Date: Sat, 21 Nov 2020 12:01:30 +0300 Subject: [PATCH 4/5] Adding helper _maybe_add_password where it's possible, to centralize the logic of work with password. --- patoolib/programs/arj.py | 17 +++++++++-------- patoolib/programs/p7zip.py | 31 +++++++++++++------------------ patoolib/programs/unalz.py | 11 +++++++---- patoolib/programs/unzip.py | 13 +++++++------ patoolib/programs/xdms.py | 14 ++++++++------ 5 files changed, 44 insertions(+), 42 deletions(-) diff --git a/patoolib/programs/arj.py b/patoolib/programs/arj.py index d1f5e33..9fb751f 100644 --- a/patoolib/programs/arj.py +++ b/patoolib/programs/arj.py @@ -22,11 +22,15 @@ def _get_password_switch(password): raise PatoolError("Password for ARJ can't contain spaces.") return '-g%s' % password +def _maybe_add_password(cmdlist, password): + if password: + cmdlist.append(_get_password_switch(password)) + + def extract_arj (archive, compression, cmd, verbosity, interactive, outdir, password=None): """Extract an ARJ archive.""" cmdlist = [cmd, 'x', '-r'] - if password: - cmdlist.append(_get_password_switch(password)) + _maybe_add_password(cmdlist, password) if not interactive: cmdlist.append('-y') cmdlist.extend([archive, outdir]) @@ -36,8 +40,7 @@ def extract_arj (archive, compression, cmd, verbosity, interactive, outdir, pass def list_arj (archive, compression, cmd, verbosity, interactive, password=None): """List an ARJ archive.""" cmdlist = [cmd] - if password: - cmdlist.append(_get_password_switch(password)) + _maybe_add_password(cmdlist, password) if verbosity > 1: cmdlist.append('v') else: @@ -51,8 +54,7 @@ def list_arj (archive, compression, cmd, verbosity, interactive, password=None): def test_arj (archive, compression, cmd, verbosity, interactive, password=None): """Test an ARJ archive.""" cmdlist = [cmd, 't', '-r'] - if password: - cmdlist.append(_get_password_switch(password)) + _maybe_add_password(cmdlist, password) if not interactive: cmdlist.append('-y') cmdlist.append(archive) @@ -62,8 +64,7 @@ def test_arj (archive, compression, cmd, verbosity, interactive, password=None): def create_arj (archive, compression, cmd, verbosity, interactive, filenames, password=None): """Create an ARJ archive.""" cmdlist = [cmd, 'a', '-r'] - if password: - cmdlist.append(_get_password_switch(password)) + _maybe_add_password(cmdlist, password) if not interactive: cmdlist.append('-y') cmdlist.append(archive) diff --git a/patoolib/programs/p7zip.py b/patoolib/programs/p7zip.py index 45e8483..ee1865a 100644 --- a/patoolib/programs/p7zip.py +++ b/patoolib/programs/p7zip.py @@ -15,13 +15,16 @@ # along with this program. If not, see . """Archive commands for the 7z program.""" +def _maybe_add_password(cmdlist, password): + if password: + cmdlist.append('-p%s' % password) + def extract_7z(archive, compression, cmd, verbosity, interactive, outdir, password=None): """Extract a 7z archive.""" cmdlist = [cmd, 'x'] if not interactive: cmdlist.append('-y') - if password: - cmdlist.append('-p%s' % password) + _maybe_add_password(cmdlist, password) cmdlist.extend(['-o%s' % outdir, '--', archive]) return cmdlist @@ -32,8 +35,7 @@ def extract_7z_singlefile(archive, compression, cmd, verbosity, interactive, out cmdlist = [cmd, 'e'] if not interactive: cmdlist.append('-y') - if password: - cmdlist.append('-p%s' % password) + _maybe_add_password(cmdlist, password) cmdlist.extend(['-o%s' % outdir, '--', archive]) return cmdlist @@ -60,8 +62,7 @@ def list_7z (archive, compression, cmd, verbosity, interactive, password=None): cmdlist = [cmd, 'l'] if not interactive: cmdlist.append('-y') - if password: - cmdlist.append('-p%s' % password) + _maybe_add_password(cmdlist, password) cmdlist.extend(['--', archive]) return cmdlist @@ -87,8 +88,7 @@ def test_7z (archive, compression, cmd, verbosity, interactive, password=None): cmdlist = [cmd, 't'] if not interactive: cmdlist.append('-y') - if password: - cmdlist.append('-p%s' % password) + _maybe_add_password(cmdlist, password) cmdlist.extend(['--', archive]) return cmdlist @@ -114,8 +114,7 @@ def create_7z(archive, compression, cmd, verbosity, interactive, filenames, pass cmdlist = [cmd, 'a'] if not interactive: cmdlist.append('-y') - if password: - cmdlist.append('-p%s' % password) + _maybe_add_password(cmdlist, password) cmdlist.extend(['-t7z', '-mx=9', '--', archive]) cmdlist.extend(filenames) return cmdlist @@ -126,8 +125,7 @@ def create_zip(archive, compression, cmd, verbosity, interactive, filenames, pas cmdlist = [cmd, 'a'] if not interactive: cmdlist.append('-y') - if password: - cmdlist.append('-p%s' % password) + _maybe_add_password(cmdlist, password) cmdlist.extend(['-tzip', '-mx=9', '--', archive]) cmdlist.extend(filenames) return cmdlist @@ -138,8 +136,7 @@ def create_xz(archive, compression, cmd, verbosity, interactive, filenames, pass cmdlist = [cmd, 'a'] if not interactive: cmdlist.append('-y') - if password: - cmdlist.append('-p%s' % password) + _maybe_add_password(cmdlist, password) cmdlist.extend(['-txz', '-mx=9', '--', archive]) cmdlist.extend(filenames) return cmdlist @@ -150,8 +147,7 @@ def create_gzip(archive, compression, cmd, verbosity, interactive, filenames, pa cmdlist = [cmd, 'a'] if not interactive: cmdlist.append('-y') - if password: - cmdlist.append('-p%s' % password) + _maybe_add_password(cmdlist, password) cmdlist.extend(['-tgzip', '-mx=9', '--', archive]) cmdlist.extend(filenames) return cmdlist @@ -162,8 +158,7 @@ def create_bzip2(archive, compression, cmd, verbosity, interactive, filenames, p cmdlist = [cmd, 'a'] if not interactive: cmdlist.append('-y') - if password: - cmdlist.append('-p%s' % password) + _maybe_add_password(cmdlist, password) cmdlist.extend(['-tbzip2', '-mx=9', '--', archive]) cmdlist.extend(filenames) return cmdlist diff --git a/patoolib/programs/unalz.py b/patoolib/programs/unalz.py index 9e2f69c..4bb64d2 100644 --- a/patoolib/programs/unalz.py +++ b/patoolib/programs/unalz.py @@ -15,11 +15,15 @@ # along with this program. If not, see . """Archive commands for the unalz program.""" +def _maybe_add_password(cmdlist, password): + if password: + cmdlist.extend(['-pwd', password]) + + def extract_alzip (archive, compression, cmd, verbosity, interactive, outdir, password=None): """Extract a ALZIP archive.""" cmdlist = [cmd, '-d', outdir] - if password: - cmdlist.extend(['-pwd', password]) + _maybe_add_password(cmdlist, password) cmdlist.append(archive) return cmdlist @@ -27,8 +31,7 @@ def extract_alzip (archive, compression, cmd, verbosity, interactive, outdir, pa def list_alzip (archive, compression, cmd, verbosity, interactive, password=None): """List a ALZIP archive.""" cmdlist = [cmd, '-l'] - if password: - cmdlist.extend(['-pwd', password]) + _maybe_add_password(cmdlist, password) cmdlist.append(archive) return cmdlist diff --git a/patoolib/programs/unzip.py b/patoolib/programs/unzip.py index 2b875b9..b87e497 100644 --- a/patoolib/programs/unzip.py +++ b/patoolib/programs/unzip.py @@ -15,13 +15,16 @@ # along with this program. If not, see . """Archive commands for the unzip program.""" +def _maybe_add_password(cmdlist, password): + if password: + cmdlist.extend(['-P', password]) + def extract_zip (archive, compression, cmd, verbosity, interactive, outdir, password=None): """Extract a ZIP archive.""" cmdlist = [cmd] if verbosity > 1: cmdlist.append('-v') - if password: - cmdlist.extend(['-P', password]) + _maybe_add_password(cmdlist, password) cmdlist.extend(['--', archive, '-d', outdir]) return cmdlist @@ -30,8 +33,7 @@ def list_zip (archive, compression, cmd, verbosity, interactive, password=None): cmdlist = [cmd, '-l'] if verbosity > 1: cmdlist.append('-v') - if password: - cmdlist.extend(['-P', password]) + _maybe_add_password(cmdlist, password) cmdlist.extend(['--', archive]) return cmdlist @@ -40,7 +42,6 @@ def test_zip (archive, compression, cmd, verbosity, interactive, password=None): cmdlist = [cmd, '-t'] if verbosity > 1: cmdlist.append('-v') - if password: - cmdlist.extend(['-P', password]) + _maybe_add_password(cmdlist, password) cmdlist.extend(['--', archive]) return cmdlist diff --git a/patoolib/programs/xdms.py b/patoolib/programs/xdms.py index d76048d..a05fe8f 100644 --- a/patoolib/programs/xdms.py +++ b/patoolib/programs/xdms.py @@ -17,14 +17,18 @@ from .. import util +def _maybe_add_password(cmdlist, password): + if password: + cmdlist.extend(['-p', password]) + + def extract_dms (archive, compression, cmd, verbosity, interactive, outdir, password=None): """Extract a DMS archive.""" check_archive_ext(archive) cmdlist = [cmd, '-d', outdir] if verbosity > 1: cmdlist.append('-v') - if password: - cmdlist.extend(['-p', password]) + _maybe_add_password(cmdlist, password) cmdlist.extend(['u', archive]) return cmdlist @@ -33,8 +37,7 @@ def list_dms (archive, compression, cmd, verbosity, interactive, password=None): """List a DMS archive.""" check_archive_ext(archive) cmdlist = [cmd, 'v'] - if password: - cmdlist.extend(['-p', password]) + _maybe_add_password(cmdlist, password) cmdlist.append(archive) return cmdlist @@ -43,8 +46,7 @@ def test_dms (archive, compression, cmd, verbosity, interactive, password=None): """Test a DMS archive.""" check_archive_ext(archive) cmdlist = [cmd, 't'] - if password: - cmdlist.extend(['-p', password]) + _maybe_add_password(cmdlist, password) cmdlist.append(archive) return cmdlist From d9cd295d0709ddd240d80d3aa8d7a9e1c53426a0 Mon Sep 17 00:00:00 2001 From: Vladimir Oprya Date: Sat, 21 Nov 2020 12:01:30 +0300 Subject: [PATCH 5/5] Adding helper _maybe_add_password where it's possible, to centralize the logic of work with password. --- patoolib/programs/arc.py | 5 +++++ patoolib/programs/arj.py | 17 +++++++++-------- patoolib/programs/p7zip.py | 31 +++++++++++++------------------ patoolib/programs/unalz.py | 11 +++++++---- patoolib/programs/unzip.py | 13 +++++++------ patoolib/programs/xdms.py | 14 ++++++++------ 6 files changed, 49 insertions(+), 42 deletions(-) diff --git a/patoolib/programs/arc.py b/patoolib/programs/arc.py index c89dba9..8eadaf2 100644 --- a/patoolib/programs/arc.py +++ b/patoolib/programs/arc.py @@ -17,6 +17,7 @@ import os from ..util import PatoolError + def _add_password_to_options(options, password): """Check password and add it to ARC options.""" if password is None: @@ -26,6 +27,7 @@ def _add_password_to_options(options, password): options += 'g%s' % password return options + def extract_arc (archive, compression, cmd, verbosity, interactive, outdir, password=None): """Extract a ARC archive.""" # Since extracted files will be placed in the current directory, @@ -34,6 +36,7 @@ def extract_arc (archive, compression, cmd, verbosity, interactive, outdir, pass cmdlist = [cmd, options, os.path.abspath(archive)] return (cmdlist, {'cwd': outdir}) + def list_arc (archive, compression, cmd, verbosity, interactive, password=None): """List a ARC archive.""" cmdlist = [cmd] @@ -44,10 +47,12 @@ def list_arc (archive, compression, cmd, verbosity, interactive, password=None): cmdlist.append(archive) return cmdlist + def test_arc (archive, compression, cmd, verbosity, interactive, password=None): """Test a ARC archive.""" return [cmd, _add_password_to_options('t', password), archive] + def create_arc (archive, compression, cmd, verbosity, interactive, filenames, password=None): """Create a ARC archive.""" cmdlist = [cmd, _add_password_to_options('a', password), archive] diff --git a/patoolib/programs/arj.py b/patoolib/programs/arj.py index d1f5e33..9fb751f 100644 --- a/patoolib/programs/arj.py +++ b/patoolib/programs/arj.py @@ -22,11 +22,15 @@ def _get_password_switch(password): raise PatoolError("Password for ARJ can't contain spaces.") return '-g%s' % password +def _maybe_add_password(cmdlist, password): + if password: + cmdlist.append(_get_password_switch(password)) + + def extract_arj (archive, compression, cmd, verbosity, interactive, outdir, password=None): """Extract an ARJ archive.""" cmdlist = [cmd, 'x', '-r'] - if password: - cmdlist.append(_get_password_switch(password)) + _maybe_add_password(cmdlist, password) if not interactive: cmdlist.append('-y') cmdlist.extend([archive, outdir]) @@ -36,8 +40,7 @@ def extract_arj (archive, compression, cmd, verbosity, interactive, outdir, pass def list_arj (archive, compression, cmd, verbosity, interactive, password=None): """List an ARJ archive.""" cmdlist = [cmd] - if password: - cmdlist.append(_get_password_switch(password)) + _maybe_add_password(cmdlist, password) if verbosity > 1: cmdlist.append('v') else: @@ -51,8 +54,7 @@ def list_arj (archive, compression, cmd, verbosity, interactive, password=None): def test_arj (archive, compression, cmd, verbosity, interactive, password=None): """Test an ARJ archive.""" cmdlist = [cmd, 't', '-r'] - if password: - cmdlist.append(_get_password_switch(password)) + _maybe_add_password(cmdlist, password) if not interactive: cmdlist.append('-y') cmdlist.append(archive) @@ -62,8 +64,7 @@ def test_arj (archive, compression, cmd, verbosity, interactive, password=None): def create_arj (archive, compression, cmd, verbosity, interactive, filenames, password=None): """Create an ARJ archive.""" cmdlist = [cmd, 'a', '-r'] - if password: - cmdlist.append(_get_password_switch(password)) + _maybe_add_password(cmdlist, password) if not interactive: cmdlist.append('-y') cmdlist.append(archive) diff --git a/patoolib/programs/p7zip.py b/patoolib/programs/p7zip.py index 45e8483..ee1865a 100644 --- a/patoolib/programs/p7zip.py +++ b/patoolib/programs/p7zip.py @@ -15,13 +15,16 @@ # along with this program. If not, see . """Archive commands for the 7z program.""" +def _maybe_add_password(cmdlist, password): + if password: + cmdlist.append('-p%s' % password) + def extract_7z(archive, compression, cmd, verbosity, interactive, outdir, password=None): """Extract a 7z archive.""" cmdlist = [cmd, 'x'] if not interactive: cmdlist.append('-y') - if password: - cmdlist.append('-p%s' % password) + _maybe_add_password(cmdlist, password) cmdlist.extend(['-o%s' % outdir, '--', archive]) return cmdlist @@ -32,8 +35,7 @@ def extract_7z_singlefile(archive, compression, cmd, verbosity, interactive, out cmdlist = [cmd, 'e'] if not interactive: cmdlist.append('-y') - if password: - cmdlist.append('-p%s' % password) + _maybe_add_password(cmdlist, password) cmdlist.extend(['-o%s' % outdir, '--', archive]) return cmdlist @@ -60,8 +62,7 @@ def list_7z (archive, compression, cmd, verbosity, interactive, password=None): cmdlist = [cmd, 'l'] if not interactive: cmdlist.append('-y') - if password: - cmdlist.append('-p%s' % password) + _maybe_add_password(cmdlist, password) cmdlist.extend(['--', archive]) return cmdlist @@ -87,8 +88,7 @@ def test_7z (archive, compression, cmd, verbosity, interactive, password=None): cmdlist = [cmd, 't'] if not interactive: cmdlist.append('-y') - if password: - cmdlist.append('-p%s' % password) + _maybe_add_password(cmdlist, password) cmdlist.extend(['--', archive]) return cmdlist @@ -114,8 +114,7 @@ def create_7z(archive, compression, cmd, verbosity, interactive, filenames, pass cmdlist = [cmd, 'a'] if not interactive: cmdlist.append('-y') - if password: - cmdlist.append('-p%s' % password) + _maybe_add_password(cmdlist, password) cmdlist.extend(['-t7z', '-mx=9', '--', archive]) cmdlist.extend(filenames) return cmdlist @@ -126,8 +125,7 @@ def create_zip(archive, compression, cmd, verbosity, interactive, filenames, pas cmdlist = [cmd, 'a'] if not interactive: cmdlist.append('-y') - if password: - cmdlist.append('-p%s' % password) + _maybe_add_password(cmdlist, password) cmdlist.extend(['-tzip', '-mx=9', '--', archive]) cmdlist.extend(filenames) return cmdlist @@ -138,8 +136,7 @@ def create_xz(archive, compression, cmd, verbosity, interactive, filenames, pass cmdlist = [cmd, 'a'] if not interactive: cmdlist.append('-y') - if password: - cmdlist.append('-p%s' % password) + _maybe_add_password(cmdlist, password) cmdlist.extend(['-txz', '-mx=9', '--', archive]) cmdlist.extend(filenames) return cmdlist @@ -150,8 +147,7 @@ def create_gzip(archive, compression, cmd, verbosity, interactive, filenames, pa cmdlist = [cmd, 'a'] if not interactive: cmdlist.append('-y') - if password: - cmdlist.append('-p%s' % password) + _maybe_add_password(cmdlist, password) cmdlist.extend(['-tgzip', '-mx=9', '--', archive]) cmdlist.extend(filenames) return cmdlist @@ -162,8 +158,7 @@ def create_bzip2(archive, compression, cmd, verbosity, interactive, filenames, p cmdlist = [cmd, 'a'] if not interactive: cmdlist.append('-y') - if password: - cmdlist.append('-p%s' % password) + _maybe_add_password(cmdlist, password) cmdlist.extend(['-tbzip2', '-mx=9', '--', archive]) cmdlist.extend(filenames) return cmdlist diff --git a/patoolib/programs/unalz.py b/patoolib/programs/unalz.py index 9e2f69c..4bb64d2 100644 --- a/patoolib/programs/unalz.py +++ b/patoolib/programs/unalz.py @@ -15,11 +15,15 @@ # along with this program. If not, see . """Archive commands for the unalz program.""" +def _maybe_add_password(cmdlist, password): + if password: + cmdlist.extend(['-pwd', password]) + + def extract_alzip (archive, compression, cmd, verbosity, interactive, outdir, password=None): """Extract a ALZIP archive.""" cmdlist = [cmd, '-d', outdir] - if password: - cmdlist.extend(['-pwd', password]) + _maybe_add_password(cmdlist, password) cmdlist.append(archive) return cmdlist @@ -27,8 +31,7 @@ def extract_alzip (archive, compression, cmd, verbosity, interactive, outdir, pa def list_alzip (archive, compression, cmd, verbosity, interactive, password=None): """List a ALZIP archive.""" cmdlist = [cmd, '-l'] - if password: - cmdlist.extend(['-pwd', password]) + _maybe_add_password(cmdlist, password) cmdlist.append(archive) return cmdlist diff --git a/patoolib/programs/unzip.py b/patoolib/programs/unzip.py index 2b875b9..b87e497 100644 --- a/patoolib/programs/unzip.py +++ b/patoolib/programs/unzip.py @@ -15,13 +15,16 @@ # along with this program. If not, see . """Archive commands for the unzip program.""" +def _maybe_add_password(cmdlist, password): + if password: + cmdlist.extend(['-P', password]) + def extract_zip (archive, compression, cmd, verbosity, interactive, outdir, password=None): """Extract a ZIP archive.""" cmdlist = [cmd] if verbosity > 1: cmdlist.append('-v') - if password: - cmdlist.extend(['-P', password]) + _maybe_add_password(cmdlist, password) cmdlist.extend(['--', archive, '-d', outdir]) return cmdlist @@ -30,8 +33,7 @@ def list_zip (archive, compression, cmd, verbosity, interactive, password=None): cmdlist = [cmd, '-l'] if verbosity > 1: cmdlist.append('-v') - if password: - cmdlist.extend(['-P', password]) + _maybe_add_password(cmdlist, password) cmdlist.extend(['--', archive]) return cmdlist @@ -40,7 +42,6 @@ def test_zip (archive, compression, cmd, verbosity, interactive, password=None): cmdlist = [cmd, '-t'] if verbosity > 1: cmdlist.append('-v') - if password: - cmdlist.extend(['-P', password]) + _maybe_add_password(cmdlist, password) cmdlist.extend(['--', archive]) return cmdlist diff --git a/patoolib/programs/xdms.py b/patoolib/programs/xdms.py index d76048d..a05fe8f 100644 --- a/patoolib/programs/xdms.py +++ b/patoolib/programs/xdms.py @@ -17,14 +17,18 @@ from .. import util +def _maybe_add_password(cmdlist, password): + if password: + cmdlist.extend(['-p', password]) + + def extract_dms (archive, compression, cmd, verbosity, interactive, outdir, password=None): """Extract a DMS archive.""" check_archive_ext(archive) cmdlist = [cmd, '-d', outdir] if verbosity > 1: cmdlist.append('-v') - if password: - cmdlist.extend(['-p', password]) + _maybe_add_password(cmdlist, password) cmdlist.extend(['u', archive]) return cmdlist @@ -33,8 +37,7 @@ def list_dms (archive, compression, cmd, verbosity, interactive, password=None): """List a DMS archive.""" check_archive_ext(archive) cmdlist = [cmd, 'v'] - if password: - cmdlist.extend(['-p', password]) + _maybe_add_password(cmdlist, password) cmdlist.append(archive) return cmdlist @@ -43,8 +46,7 @@ def test_dms (archive, compression, cmd, verbosity, interactive, password=None): """Test a DMS archive.""" check_archive_ext(archive) cmdlist = [cmd, 't'] - if password: - cmdlist.extend(['-p', password]) + _maybe_add_password(cmdlist, password) cmdlist.append(archive) return cmdlist