diff --git a/extract.py b/extract.py index d6447a2..d6bd610 100755 --- a/extract.py +++ b/extract.py @@ -1,40 +1,52 @@ -#!/bin/python +#!/usr/bin/env python + +""" +Archive extract script with sub-directory creation +""" + +# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 + import os import re import sys -import getopt +import argparse import subprocess -import re -import logging from subprocess import check_output from subprocess import call +__author__ = 'lanxu ' + def is_available(command): - status, result = subprocess.getstatusoutput(command) + """Check if executable is available""" + status, return_value = subprocess.getstatusoutput(command) if status < 127: return True return False + def is_exe(fpath): + """Check if file is executable""" return os.path.isfile(fpath) and os.access(fpath, os.X_OK) def run_command(command): + """Run provided command and provide return value""" try: - return_value = call(command) + return_value = call(command) except (RuntimeError, TypeError, NameError, OSError) as error: print(error) raise return return_value def has_multiple_files(file): + """Check if archive has multiple top level files""" file = re.escape(file) check_7z_command = "7z l -slt " + file + " | grep -c 'Path = [^/]*$'" - check_tar_command = "tar --exclude=\"*/*\" -tf " + file + " | wc -l" # returns top level list of files + check_tar_command = "tar --exclude=\"*/*\" -tf " + file + " | wc -l" check_command = None - m = re.search("\.tar\.", file) - if m != None: + match = re.search(r"\.tar\.", file) + if match != None: check_command = check_tar_command else: check_command = check_7z_command @@ -46,67 +58,86 @@ def has_multiple_files(file): number_of_files = int(return_command.decode("utf-8")) - if number_of_files > 1: - if check_command is check_7z_command and number_of_files > 2: - return True - else: - return False + if check_command is check_tar_command and number_of_files > 1: + return True + if check_command is check_7z_command and number_of_files >= 2: return True return False -def main(argv): - extractTools = [ - { "extension": "\.tar\.gz$", "command": "tar", "params": "-xf", "oparams": "-C" }, - { "extension": "\.tar\.xz$", "command": "tar", "params": "-xf", "oparams": "-C" }, - { "extension": "\.zip$", "command": "unzip", "params": "", "oparams": "-d" }, - { "extension": "\.rar$", "command": "unrar", "params": "x", "oparams": "" }, - ] +def extract(filename, loglevel): + """ Main extract function for a single file """ + extract_tools = [ + { "extension": r"\.tar\.gz$", "command": "tar", "params": "-xf", "oparams": "-C", "dparams": "" }, + { "extension": r"\.tar\.xz$", "command": "tar", "params": "-xf", "oparams": "-C", "dparams": "" }, + { "extension": r"\.zip$", "command": "unzip", "params": "", "oparams": "-d", "dparams": "-qq -o" }, + { "extension": r"\.rar$", "command": "unrar", "params": "x", "oparams": "", "dparams": "-inul -y -o" }, + ] - if os.path.isfile(argv[0]) == False: - print("No such file") - sys.exit(2) + if loglevel == 'verbose': + print("Processing file " + filename) - print("Processing file " + argv[0]) - - for tool in extractTools: - m = re.search(tool["extension"], argv[0]) - if m != None: + for tool in extract_tools: + match = re.search(tool["extension"], filename) + if match is not None: if is_available(tool["command"]): command = [tool["command"]] - - if tool["params"] is not "": + + if tool["params"] != "": command.append(tool["params"]) - command.append(argv[0]) + if tool["dparams"] != "" and loglevel != 'verbose': + command.extend(tool["dparams"].split()) + + command.append(filename) output_path = "." - if has_multiple_files(argv[0]): - base = os.path.basename(argv[0]) + if has_multiple_files(filename): + base = os.path.basename(filename) basefile = os.path.splitext(base)[0] - output_path = os.path.dirname(os.path.abspath(argv[0])) + output_path = os.path.dirname(os.path.abspath(filename)) output_path = os.path.join(output_path, basefile) - print("Extracting to " + output_path) + if loglevel == 'verbose': + print("Extracting to " + output_path + "/") if not os.path.exists(output_path): os.makedirs(output_path) - - if tool["oparams"] is not "": + + if tool["oparams"] != "": command.append(tool['oparams']) command.append(output_path) - try: - - val = run_command(command) - if val > 0: - sys.exit(2) - except: - print('Something went horribly wrong') + val = run_command(command) + if val > 0: sys.exit(2) + else: print("Command " + tool["command"] + " not found") sys.exit(2) + + +def main(): + """ Main function with argument parser """ + loglevel = 'quiet' + + parser = argparse.ArgumentParser(description='Extract archives') + parser.add_argument('input', nargs='+', help='input files') + parser.add_argument('--verbose', dest='verbose', action='store_true', help='set verbose mode on', required=False, default=False) + args = parser.parse_args() + + # Set verbosity if needed + if args.verbose: + loglevel = 'verbose' + + for filename in args.input: + if os.path.isfile(filename) is False: + print("No such file") + sys.exit(2) + else: + extract(filename, loglevel) + if __name__ == "__main__": - main(sys.argv[1:]) + # main(sys.argv[1:]) + main()