diff --git a/examples/7zx.py b/examples/7zx.py new file mode 100755 index 00000000..7d651957 --- /dev/null +++ b/examples/7zx.py @@ -0,0 +1,93 @@ +# -*- coding: utf-8 -*- +"""Usage: + 7zx.py [--help | options] ... + +Options: + -h, --help Print this help and exit + -v, --version Print version and exit + -c, --compressed Use compressed (instead of uncompressed) file sizes + -y, --yes Assume yes to all queries (for extraction) + -D=, --debug= + Print various types of debugging information. Choices: + CRITICAL|FATAL + ERROR + WARN(ING) + [default: INFO] + DEBUG + NOTSET + -d, --debug-trace Print lots of debugging information (-D NOTSET) +""" +from __future__ import print_function +from docopt import docopt +import logging as log +import subprocess +import re +from tqdm import tqdm +__author__ = "Casper da Costa-Luis " +__licence__ = "MPLv2.0" +__version__ = "0.0.0" +__license__ = __licence__ + + +RE_SCN = re.compile("([0-9]+)\s+([0-9]+)\s+(.*)$", flags=re.M) + + +def main(): + args = docopt(__doc__, version=__version__) + if args.pop('--debug-trace', False): + args['--debug'] = "NOTSET" + log.basicConfig(level=getattr(log, args['--debug'], log.INFO), + format='%(levelname)s: %(message)s') + log.debug(args) + + # Get compressed sizes + zips = {} + for fn in args['']: + info = subprocess.check_output(["7z", "l", fn]).strip() + finfo = RE_SCN.findall(info) + + # builtin test: last line should be total sizes + log.debug(finfo) + totals = map(int, finfo[-1][:2]) + # log.debug(totals) + for s in range(2): + assert(sum(map(int, (inf[s] for inf in finfo[:-1]))) == totals[s]) + fcomp = dict((n, int(c if args['--compressed'] else u)) + for (u, c, n) in finfo[:-1]) + # log.debug(fcomp) + zips[fn] = fcomp + + # Extract + cmd7zx = ["7z", "x", "-bd"] + if args['--yes']: + cmd7zx += ["-y"] + log.info("Extracting from {:d} file(s)".format(len(zips))) + with tqdm(total=sum(s for fcomp in zips.values() + for (_, s) in fcomp.items()), + unit="B", unit_scale=True) as t: + for fn, fcomp in zips.items(): + ex = subprocess.Popen(cmd7zx + [fn], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + for l_raw in ex.stdout: + l = l_raw.strip() + if l.startswith("Extracting"): + exname = l.lstrip("Extracting").lstrip() + t.update(fcomp.get(exname, 0)) + # elif l: + # if not any(l.startswith(i) for i in + # ("7-Zip ", + # "p7zip Version ", + # "Processing archive: ", + # "Everything is Ok", + # "Folders: ", + # "Files: ", + # "Size: ", + # "Compressed: ")): + # t.write(l) + ex.wait() +main.__doc__ = __doc__ + + +if __name__ == "__main__": + main()