1
0
mirror of https://github.com/kellyjonbrazil/jc.git synced 2025-06-17 00:07:37 +02:00

proof of concept for magic syntax (e.g. jc ls -al)

This commit is contained in:
Kelly Brazil
2020-02-11 12:16:23 -08:00
parent 028e136161
commit fe27dcdb8f
2 changed files with 319 additions and 45 deletions

134
jc/cli.py
View File

@ -3,6 +3,7 @@
JC cli module
"""
import sys
import os
import importlib
import textwrap
import signal
@ -11,7 +12,7 @@ import jc.utils
class info():
version = '1.7.2'
version = '1.8.0'
description = 'jc cli output JSON conversion tool'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -19,48 +20,51 @@ class info():
__version__ = info.version
parsers = [
'arp',
'crontab',
'crontab-u',
'df',
'dig',
'du',
'env',
'free',
'fstab',
'history',
'hosts',
'id',
'ifconfig',
'ini',
'iptables',
'jobs',
'ls',
'lsblk',
'lsmod',
'lsof',
'mount',
'netstat',
'pip-list',
'pip-show',
'ps',
'route',
'ss',
'stat',
'systemctl',
'systemctl-lj',
'systemctl-ls',
'systemctl-luf',
'uname',
'uptime',
'w',
'xml',
'yaml'
]
# map of parser real-name -> matching command name for magic syntax
# use lists as the value, then when reversing, loop through the list to create the new dict
parsers = {
'arp': 'arp',
'crontab': 'crontab',
'crontab-u': None,
'df': 'df',
'dig': 'dig',
'du': 'du',
'env': 'env',
'free': 'free',
'fstab': None, # might need this command for linux
'history': 'history',
'hosts': None,
'id': 'id',
'ifconfig': 'ifconfig',
'ini': None,
'iptables': 'iptables',
'jobs': 'jobs',
'ls': 'ls',
'lsblk': 'lsblk',
'lsmod': 'lsmod',
'lsof': 'lsof',
'mount': 'mount',
'netstat': 'netstat',
'pip-list': 'pip3 list',
'pip-show': 'pip3 show',
'ps': 'ps',
'route': 'route',
'ss': 'ss',
'stat': 'stat',
'systemctl': 'systemctl',
'systemctl-lj': 'systemctl list-jobs',
'systemctl-ls': 'systemctl list-sockets',
'systemctl-luf': 'systemctl list-unit-files',
'uname': 'uname -a',
'uptime': 'uptime',
'w': 'w',
'xml': None,
'yaml': None
}
def ctrlc(signum, frame):
"""exit with error on SIGINT"""
sys.exit(1)
@ -87,7 +91,7 @@ def parser_module(parser):
def parsers_text(indent=0, pad=0):
ptext = ''
for parser in parsers:
for parser in parsers.keys():
parser_arg = parser_argument(parser)
parser_mod = parser_module(parser)
@ -105,7 +109,7 @@ def parsers_text(indent=0, pad=0):
def about_jc():
parser_list = []
for parser in parsers:
for parser in parsers.keys():
parser_mod = parser_module(parser)
if hasattr(parser_mod, 'info'):
@ -161,9 +165,49 @@ def json_out(data, pretty=False):
print(json.dumps(data))
def magic():
"""Parse with magic syntax: jc ls -al"""
if len(sys.argv) > 1 and not sys.argv[1].startswith('-'):
# reverse the parser dictionary keys and values
commands = {v: k for k, v in parsers.items() if v is not None}
args_given = sys.argv[1:]
options = []
found_parser = None
# first create a list of options from the commands dict based on the arguments passed
for comm, pars in commands.items():
if args_given[0] == comm.split()[0]:
options.append([comm, pars])
if len(options) > 1:
for comm2, pars2 in options:
if args_given[1] == comm2.split()[1]:
found_parser = pars2
else:
try:
found_parser = options[0][1]
except Exception:
found_parser = None
# run the command through the parser
run_command = ' '.join(sys.argv[1:])
whole_command = [run_command, '|', 'jc', parser_argument(found_parser), '-p']
if found_parser is not None:
os.system(' '.join(whole_command))
exit()
else:
args_given_pretty = ' '.join(args_given)
helptext(f'parser not found for "{args_given_pretty}"')
sys.exit(1)
def main():
signal.signal(signal.SIGINT, ctrlc)
# try magic syntax first
magic()
debug = False
pretty = False
quiet = False
@ -198,7 +242,7 @@ def main():
for arg in sys.argv:
parser_name = parser_shortname(arg)
if parser_name in parsers:
if parser_name in parsers.keys():
# load parser module just in time so we don't need to load all modules
parser = parser_module(arg)
result = parser.parse(data, raw=raw, quiet=quiet)
@ -208,14 +252,14 @@ def main():
for arg in sys.argv:
parser_name = parser_shortname(arg)
if parser_name in parsers:
if parser_name in parsers.keys():
# load parser module just in time so we don't need to load all modules
parser = parser_module(arg)
try:
result = parser.parse(data, raw=raw, quiet=quiet)
found = True
break
except:
except Exception:
jc.utils.error_message(f'{parser_name} parser could not parse the input data. Did you use the correct parser?\n For details use the -d option.')
sys.exit(1)