2017-03-25 03:00:57 +02:00
|
|
|
#!/usr/bin/env python
|
|
|
|
|
|
|
|
"""
|
|
|
|
Archive extract script with sub-directory creation
|
|
|
|
"""
|
|
|
|
|
|
|
|
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
|
|
|
|
2017-03-19 19:56:44 +02:00
|
|
|
import os
|
|
|
|
import re
|
|
|
|
import sys
|
2017-03-25 03:00:57 +02:00
|
|
|
import argparse
|
2017-03-19 19:56:44 +02:00
|
|
|
import subprocess
|
|
|
|
from subprocess import check_output
|
|
|
|
from subprocess import call
|
|
|
|
|
2017-03-25 03:00:57 +02:00
|
|
|
__author__ = 'lanxu <jukka.lankinen@gmail.com>'
|
|
|
|
|
2017-03-19 19:56:44 +02:00
|
|
|
def is_available(command):
|
2017-03-25 03:00:57 +02:00
|
|
|
"""Check if executable is available"""
|
|
|
|
status, return_value = subprocess.getstatusoutput(command)
|
2017-03-19 19:56:44 +02:00
|
|
|
if status < 127:
|
|
|
|
return True
|
|
|
|
return False
|
|
|
|
|
2017-03-25 03:00:57 +02:00
|
|
|
|
2017-03-19 19:56:44 +02:00
|
|
|
def is_exe(fpath):
|
2017-03-25 03:00:57 +02:00
|
|
|
"""Check if file is executable"""
|
2017-03-19 19:56:44 +02:00
|
|
|
return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
|
|
|
|
|
|
|
|
def run_command(command):
|
2017-03-25 03:00:57 +02:00
|
|
|
"""Run provided command and provide return value"""
|
2017-03-19 19:56:44 +02:00
|
|
|
try:
|
2017-03-25 03:00:57 +02:00
|
|
|
return_value = call(command)
|
2017-03-19 19:56:44 +02:00
|
|
|
except (RuntimeError, TypeError, NameError, OSError) as error:
|
|
|
|
print(error)
|
|
|
|
raise
|
|
|
|
return return_value
|
|
|
|
|
|
|
|
def has_multiple_files(file):
|
2017-03-25 03:00:57 +02:00
|
|
|
"""Check if archive has multiple top level files"""
|
2017-03-19 19:56:44 +02:00
|
|
|
file = re.escape(file)
|
|
|
|
check_7z_command = "7z l -slt " + file + " | grep -c 'Path = [^/]*$'"
|
2017-03-25 03:00:57 +02:00
|
|
|
check_tar_command = "tar --exclude=\"*/*\" -tf " + file + " | wc -l"
|
2017-03-19 19:56:44 +02:00
|
|
|
|
|
|
|
check_command = None
|
|
|
|
|
2017-03-25 03:00:57 +02:00
|
|
|
match = re.search(r"\.tar\.", file)
|
|
|
|
if match != None:
|
2017-03-19 19:56:44 +02:00
|
|
|
check_command = check_tar_command
|
|
|
|
else:
|
|
|
|
check_command = check_7z_command
|
|
|
|
|
|
|
|
return_command = check_output(check_command, shell=True)
|
|
|
|
if return_command is None:
|
|
|
|
print('Something went horribly wrong')
|
|
|
|
sys.exit(2)
|
|
|
|
|
|
|
|
number_of_files = int(return_command.decode("utf-8"))
|
|
|
|
|
2017-03-25 03:00:57 +02:00
|
|
|
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:
|
2017-03-19 19:56:44 +02:00
|
|
|
return True
|
|
|
|
return False
|
|
|
|
|
2017-03-25 03:00:57 +02:00
|
|
|
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 loglevel == 'verbose':
|
|
|
|
print("Processing file " + filename)
|
|
|
|
|
|
|
|
for tool in extract_tools:
|
|
|
|
match = re.search(tool["extension"], filename)
|
|
|
|
if match is not None:
|
2017-03-19 19:56:44 +02:00
|
|
|
if is_available(tool["command"]):
|
|
|
|
command = [tool["command"]]
|
2017-03-25 03:00:57 +02:00
|
|
|
|
|
|
|
if tool["params"] != "":
|
2017-03-19 19:56:44 +02:00
|
|
|
command.append(tool["params"])
|
|
|
|
|
2017-03-25 03:00:57 +02:00
|
|
|
if tool["dparams"] != "" and loglevel != 'verbose':
|
|
|
|
command.extend(tool["dparams"].split())
|
|
|
|
|
|
|
|
command.append(filename)
|
2017-03-19 19:56:44 +02:00
|
|
|
|
|
|
|
output_path = "."
|
|
|
|
|
2017-03-25 03:00:57 +02:00
|
|
|
if has_multiple_files(filename):
|
|
|
|
base = os.path.basename(filename)
|
2017-03-19 19:56:44 +02:00
|
|
|
basefile = os.path.splitext(base)[0]
|
|
|
|
|
2017-03-25 03:00:57 +02:00
|
|
|
output_path = os.path.dirname(os.path.abspath(filename))
|
2017-03-19 19:56:44 +02:00
|
|
|
output_path = os.path.join(output_path, basefile)
|
2017-03-25 03:00:57 +02:00
|
|
|
if loglevel == 'verbose':
|
|
|
|
print("Extracting to " + output_path + "/")
|
2017-03-19 19:56:44 +02:00
|
|
|
|
|
|
|
if not os.path.exists(output_path):
|
|
|
|
os.makedirs(output_path)
|
2017-03-25 03:00:57 +02:00
|
|
|
|
|
|
|
if tool["oparams"] != "":
|
2017-03-19 20:10:59 +02:00
|
|
|
command.append(tool['oparams'])
|
2017-03-19 19:56:44 +02:00
|
|
|
command.append(output_path)
|
|
|
|
|
2017-03-25 03:00:57 +02:00
|
|
|
val = run_command(command)
|
|
|
|
if val > 0:
|
2017-03-19 19:56:44 +02:00
|
|
|
sys.exit(2)
|
2017-03-25 03:00:57 +02:00
|
|
|
|
2017-03-19 19:56:44 +02:00
|
|
|
else:
|
|
|
|
print("Command " + tool["command"] + " not found")
|
|
|
|
sys.exit(2)
|
|
|
|
|
2017-03-25 03:00:57 +02:00
|
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
2017-03-19 19:56:44 +02:00
|
|
|
if __name__ == "__main__":
|
2017-03-25 03:00:57 +02:00
|
|
|
# main(sys.argv[1:])
|
|
|
|
main()
|