1
0
mirror of https://github.com/kellyjonbrazil/jc.git synced 2025-08-06 22:32:54 +02:00

Merge pull request #53 from kellyjonbrazil/dev

Dev v1.10.1
This commit is contained in:
Kelly Brazil
2020-04-04 17:28:21 -07:00
committed by GitHub
22 changed files with 67 additions and 104 deletions

View File

@ -1,5 +1,8 @@
jc changelog jc changelog
20200402 v1.10.1
- Code cleanup
20200402 v1.10.0 20200402 v1.10.0
- Add color output by default when not piping data to another program - Add color output by default when not piping data to another program
- Add -m option for monochrome output - Add -m option for monochrome output

View File

@ -18,7 +18,7 @@ import jc.utils
class info(): class info():
version = '1.10.0' version = '1.10.1'
description = 'jc cli output JSON conversion tool' description = 'jc cli output JSON conversion tool'
author = 'Kelly Brazil' author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com' author_email = 'kellyjonbrazil@gmail.com'

View File

@ -91,7 +91,7 @@ import jc.parsers.universal
class info(): class info():
version = '1.2' version = '1.3'
description = 'arp command parser' description = 'arp command parser'
author = 'Kelly Brazil' author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com' author_email = 'kellyjonbrazil@gmail.com'
@ -156,7 +156,7 @@ def parse(data, raw=False, quiet=False):
cleandata = data.splitlines() cleandata = data.splitlines()
# remove final Entries row if -v was used # remove final Entries row if -v was used
if cleandata[-1].find('Entries:') == 0: if cleandata[-1].startswith('Entries:'):
cleandata.pop(-1) cleandata.pop(-1)
# detect if osx style was used # detect if osx style was used
@ -179,7 +179,7 @@ def parse(data, raw=False, quiet=False):
return process(raw_output) return process(raw_output)
# detect if linux style was used # detect if linux style was used
elif cleandata[0].find('Address') == 0: elif cleandata[0].startswith('Address'):
# fix header row to change Flags Mask to flags_mask # fix header row to change Flags Mask to flags_mask
cleandata[0] = cleandata[0].replace('Flags Mask', 'flags_mask') cleandata[0] = cleandata[0].replace('Flags Mask', 'flags_mask')

View File

@ -132,7 +132,7 @@ import jc.parsers.universal
class info(): class info():
version = '1.1' version = '1.2'
description = 'crontab command and file parser' description = 'crontab command and file parser'
author = 'Kelly Brazil' author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com' author_email = 'kellyjonbrazil@gmail.com'
@ -227,13 +227,13 @@ def parse(data, raw=False, quiet=False):
# Clear any commented lines # Clear any commented lines
for i, line in reversed(list(enumerate(cleandata))): for i, line in reversed(list(enumerate(cleandata))):
if line.strip().find('#') == 0: if line.strip().startswith('#'):
cleandata.pop(i) cleandata.pop(i)
# Pop any variable assignment lines # Pop any variable assignment lines
cron_var = [] cron_var = []
for i, line in reversed(list(enumerate(cleandata))): for i, line in reversed(list(enumerate(cleandata))):
if line.find('=') != -1: if '=' in line:
var_line = cleandata.pop(i) var_line = cleandata.pop(i)
var_name = var_line.split('=', maxsplit=1)[0].strip() var_name = var_line.split('=', maxsplit=1)[0].strip()
var_value = var_line.split('=', maxsplit=1)[1].strip() var_value = var_line.split('=', maxsplit=1)[1].strip()

View File

@ -133,7 +133,7 @@ import jc.parsers.universal
class info(): class info():
version = '1.0' version = '1.1'
description = 'crontab file parser with user support' description = 'crontab file parser with user support'
author = 'Kelly Brazil' author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com' author_email = 'kellyjonbrazil@gmail.com'
@ -228,13 +228,13 @@ def parse(data, raw=False, quiet=False):
# Clear any commented lines # Clear any commented lines
for i, line in reversed(list(enumerate(cleandata))): for i, line in reversed(list(enumerate(cleandata))):
if line.strip().find('#') == 0: if line.strip().startswith('#'):
cleandata.pop(i) cleandata.pop(i)
# Pop any variable assignment lines # Pop any variable assignment lines
cron_var = [] cron_var = []
for i, line in reversed(list(enumerate(cleandata))): for i, line in reversed(list(enumerate(cleandata))):
if line.find('=') != -1: if '=' in line:
var_line = cleandata.pop(i) var_line = cleandata.pop(i)
var_name = var_line.split('=', maxsplit=1)[0].strip() var_name = var_line.split('=', maxsplit=1)[0].strip()
var_value = var_line.split('=', maxsplit=1)[1].strip() var_value = var_line.split('=', maxsplit=1)[1].strip()

View File

@ -73,7 +73,7 @@ import jc.parsers.universal
class info(): class info():
version = '1.1' version = '1.2'
description = 'df command parser' description = 'df command parser'
author = 'Kelly Brazil' author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com' author_email = 'kellyjonbrazil@gmail.com'
@ -135,7 +135,7 @@ def process(proc_data):
# change any entry for key with '_blocks' in the name to int # change any entry for key with '_blocks' in the name to int
for k in entry: for k in entry:
if str(k).find('_blocks') != -1: if '_blocks' in str(k):
try: try:
blocks_int = int(entry[k]) blocks_int = int(entry[k])
entry[k] = blocks_int entry[k] = blocks_int

View File

@ -324,7 +324,7 @@ import jc.utils
class info(): class info():
version = '1.1' version = '1.2'
description = 'dig command parser' description = 'dig command parser'
author = 'Kelly Brazil' author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com' author_email = 'kellyjonbrazil@gmail.com'
@ -525,11 +525,12 @@ def parse_answer(answer):
'ttl': answer_ttl, 'ttl': answer_ttl,
'data': answer_data} 'data': answer_data}
def parse_axfr(axfr): def parse_axfr(axfr):
#; <<>> DiG 9.11.14-3-Debian <<>> @81.4.108.41 axfr zonetransfer.me +nocookie # ; <<>> DiG 9.11.14-3-Debian <<>> @81.4.108.41 axfr zonetransfer.me +nocookie
#; (1 server found) # ; (1 server found)
#;; global options: +cmd # ;; global options: +cmd
#zonetransfer.me. 7200 IN A 5.196.105.14 # zonetransfer.me. 7200 IN A 5.196.105.14
axfr = axfr.split(maxsplit=4) axfr = axfr.split(maxsplit=4)
axfr_name = axfr[0] axfr_name = axfr[0]
axfr_ttl = axfr[1] axfr_ttl = axfr[1]
@ -575,7 +576,7 @@ def parse(data, raw=False, quiet=False):
output_entry = {} output_entry = {}
for line in cleandata: for line in cleandata:
if line.startswith('; <<>> ') and line.lower().find(' axfr ') != -1: if line.startswith('; <<>> ') and ' axfr ' in line.lower():
question = False question = False
authority = False authority = False
answer = False answer = False
@ -583,7 +584,7 @@ def parse(data, raw=False, quiet=False):
axfr_list = [] axfr_list = []
continue continue
if line.find(';') == -1 and axfr: if ';' not in line and axfr:
axfr_list.append(parse_axfr(line)) axfr_list.append(parse_axfr(line))
output_entry.update({'axfr': axfr_list}) output_entry.update({'axfr': axfr_list})
continue continue
@ -620,7 +621,7 @@ def parse(data, raw=False, quiet=False):
authority_list = [] authority_list = []
continue continue
if line.find(';') == -1 and authority: if ';' not in line and authority:
authority_list.append(parse_authority(line)) authority_list.append(parse_authority(line))
output_entry.update({'authority': authority_list}) output_entry.update({'authority': authority_list})
continue continue
@ -633,7 +634,7 @@ def parse(data, raw=False, quiet=False):
answer_list = [] answer_list = []
continue continue
if line.find(';') == -1 and answer: if ';' not in line and answer:
answer_list.append(parse_answer(line)) answer_list.append(parse_answer(line))
output_entry.update({'answer': answer_list}) output_entry.update({'answer': answer_list})
continue continue

View File

@ -70,7 +70,7 @@ import jc.utils
class info(): class info():
version = '1.0' version = '1.1'
description = 'fstab file parser' description = 'fstab file parser'
author = 'Kelly Brazil' author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com' author_email = 'kellyjonbrazil@gmail.com'
@ -145,7 +145,7 @@ def parse(data, raw=False, quiet=False):
for line in cleandata: for line in cleandata:
output_line = {} output_line = {}
# ignore commented lines # ignore commented lines
if line.strip().find('#') == 0: if line.strip().startswith('#'):
continue continue
line_list = line.split(maxsplit=6) line_list = line.split(maxsplit=6)

View File

@ -61,7 +61,7 @@ import jc.utils
class info(): class info():
version = '1.0' version = '1.1'
description = '/etc/hosts file parser' description = '/etc/hosts file parser'
author = 'Kelly Brazil' author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com' author_email = 'kellyjonbrazil@gmail.com'
@ -126,7 +126,7 @@ def parse(data, raw=False, quiet=False):
for line in cleandata: for line in cleandata:
output_line = {} output_line = {}
# ignore commented lines # ignore commented lines
if line.strip().find('#') == 0: if line.strip().startswith('#'):
continue continue
line_list = line.split(maxsplit=1) line_list = line.split(maxsplit=1)
@ -136,7 +136,7 @@ def parse(data, raw=False, quiet=False):
comment_found = False comment_found = False
for i, item in enumerate(hosts_list): for i, item in enumerate(hosts_list):
if item.find('#') != -1: if '#' in item:
comment_found = True comment_found = True
comment_item = i comment_item = i
break break

View File

@ -146,7 +146,7 @@ from ifconfigparser import IfconfigParser
class info(): class info():
version = '1.5' version = '1.6'
description = 'ifconfig command parser' description = 'ifconfig command parser'
author = 'Kelly Brazil' author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com' author_email = 'kellyjonbrazil@gmail.com'
@ -220,7 +220,7 @@ def process(proc_data):
# convert OSX-style subnet mask to dotted quad # convert OSX-style subnet mask to dotted quad
if 'ipv4_mask' in entry: if 'ipv4_mask' in entry:
try: try:
if entry['ipv4_mask'].find('0x') == 0: if entry['ipv4_mask'].startswith('0x'):
new_mask = entry['ipv4_mask'] new_mask = entry['ipv4_mask']
new_mask = new_mask.lstrip('0x') new_mask = new_mask.lstrip('0x')
new_mask = '.'.join(str(int(i, 16)) for i in [new_mask[i:i + 2] for i in range(0, len(new_mask), 2)]) new_mask = '.'.join(str(int(i, 16)) for i in [new_mask[i:i + 2] for i in range(0, len(new_mask), 2)])

View File

@ -134,7 +134,7 @@ import jc.utils
class info(): class info():
version = '1.1' version = '1.2'
description = 'iptables command parser' description = 'iptables command parser'
author = 'Kelly Brazil' author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com' author_email = 'kellyjonbrazil@gmail.com'
@ -247,7 +247,7 @@ def parse(data, raw=False, quiet=False):
for line in cleandata: for line in cleandata:
if line.find('Chain') == 0: if line.startswith('Chain'):
raw_output.append(chain) raw_output.append(chain)
chain = {} chain = {}
headers = [] headers = []
@ -259,7 +259,7 @@ def parse(data, raw=False, quiet=False):
continue continue
elif line.find('target') == 0 or line.find('pkts') == 1 or line.find('num') == 0: elif line.startswith('target') or line.find('pkts') == 1 or line.startswith('num'):
headers = [] headers = []
headers = [h for h in ' '.join(line.lower().strip().split()).split() if h] headers = [h for h in ' '.join(line.lower().strip().split()).split() if h]
headers.append("options") headers.append("options")

View File

@ -77,7 +77,7 @@ import jc.utils
class info(): class info():
version = '1.0' version = '1.1'
description = 'jobs command parser' description = 'jobs command parser'
author = 'Kelly Brazil' author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com' author_email = 'kellyjonbrazil@gmail.com'
@ -176,11 +176,11 @@ def parse(data, raw=False, quiet=False):
parsed_line.insert(0, job_number) parsed_line.insert(0, job_number)
# check for + or - in first field # check for + or - in first field
if parsed_line[0].find('+') != -1: if '+' in parsed_line[0]:
job_history = 'current' job_history = 'current'
parsed_line[0] = parsed_line[0].rstrip('+') parsed_line[0] = parsed_line[0].rstrip('+')
if parsed_line[0].find('-') != -1: if '-' in parsed_line[0]:
job_history = 'previous' job_history = 'previous'
parsed_line[0] = parsed_line[0].rstrip('-') parsed_line[0] = parsed_line[0].rstrip('-')

View File

@ -97,7 +97,7 @@ import jc.parsers.universal
class info(): class info():
version = '1.0' version = '1.1'
description = 'lsof command parser' description = 'lsof command parser'
author = 'Kelly Brazil' author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com' author_email = 'kellyjonbrazil@gmail.com'
@ -180,47 +180,6 @@ def parse(data, raw=False, quiet=False):
raw_output = jc.parsers.universal.sparse_table_parse(cleandata) raw_output = jc.parsers.universal.sparse_table_parse(cleandata)
'''
# find column value of last character of each header
header_text = cleandata.pop(0).lower()
# clean up 'size/off' header
# even though forward slash in a key is valid json, it can make things difficult
header_row = header_text.replace('/', '_')
headers = header_row.split()
header_spec = []
for i, h in enumerate(headers):
# header tuple is (index, header_name, col)
header_spec.append((i, h, header_row.find(h) + len(h)))
# parse lines
for entry in cleandata:
output_line = {}
# normalize data by inserting Null for missing data
temp_line = entry.split(maxsplit=len(headers) - 1)
for spec in header_spec:
index = spec[0]
header_name = spec[1]
col = spec[2] - 1 # subtract one since column starts at 0 instead of 1
if header_name == 'command' or header_name == 'name':
continue
if entry[col] in string.whitespace:
temp_line.insert(index, None)
name = ' '.join(temp_line[9:])
fixed_line = temp_line[0:9]
fixed_line.append(name)
output_line = dict(zip(headers, fixed_line))
raw_output.append(output_line)
'''
if raw: if raw:
return raw_output return raw_output
else: else:

View File

@ -56,7 +56,7 @@ import jc.utils
class info(): class info():
version = '1.1' version = '1.2'
description = 'mount command parser' description = 'mount command parser'
author = 'Kelly Brazil' author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com' author_email = 'kellyjonbrazil@gmail.com'
@ -165,7 +165,7 @@ def parse(data, raw=False, quiet=False):
if cleandata: if cleandata:
# check for OSX output # check for OSX output
if cleandata[0].find(' type ') == -1: if ' type ' not in cleandata[0]:
raw_output = osx_parse(cleandata) raw_output = osx_parse(cleandata)
else: else:

View File

@ -313,7 +313,7 @@ import jc.utils
class info(): class info():
version = '1.2' version = '1.3'
description = 'netstat command parser' description = 'netstat command parser'
author = 'Kelly Brazil' author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com' author_email = 'kellyjonbrazil@gmail.com'
@ -498,14 +498,14 @@ def parse_post(raw_data):
if 'proto' in entry and 'kind' in entry: if 'proto' in entry and 'kind' in entry:
if entry['kind'] == 'network': if entry['kind'] == 'network':
if entry['proto'].find('tcp') != -1: if 'tcp' in entry['proto']:
entry['transport_protocol'] = 'tcp' entry['transport_protocol'] = 'tcp'
elif entry['proto'].find('udp') != -1: elif 'udp' in entry['proto']:
entry['transport_protocol'] = 'udp' entry['transport_protocol'] = 'udp'
else: else:
entry['transport_protocol'] = None entry['transport_protocol'] = None
if entry['proto'].find('6') != -1: if '6' in entry['proto']:
entry['network_protocol'] = 'ipv6' entry['network_protocol'] = 'ipv6'
else: else:
entry['network_protocol'] = 'ipv4' entry['network_protocol'] = 'ipv4'
@ -542,19 +542,19 @@ def parse(data, raw=False, quiet=False):
for line in cleandata: for line in cleandata:
if line.find('Active Internet') == 0: if line.startswith('Active Internet'):
network_list = [] network_list = []
network = True network = True
socket = False socket = False
continue continue
if line.find('Active UNIX') == 0: if line.startswith('Active UNIX'):
socket_list = [] socket_list = []
network = False network = False
socket = True socket = True
continue continue
if line.find('Proto') == 0: if line.startswith('Proto'):
header_text = normalize_headers(line) header_text = normalize_headers(line)
headers = header_text.split() headers = header_text.split()
continue continue

View File

@ -32,7 +32,7 @@ import jc.parsers.universal
class info(): class info():
version = '1.0' version = '1.1'
description = 'pip list command parser' description = 'pip list command parser'
author = 'Kelly Brazil' author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com' author_email = 'kellyjonbrazil@gmail.com'
@ -94,7 +94,7 @@ def parse(data, raw=False, quiet=False):
cleandata = list(filter(None, linedata)) cleandata = list(filter(None, linedata))
# detect legacy output type # detect legacy output type
if cleandata[0].find(' (') != -1: if ' (' in cleandata[0]:
for row in cleandata: for row in cleandata:
raw_output.append({'package': row.split(' (')[0], raw_output.append({'package': row.split(' (')[0],
'version': row.split(' (')[1].rstrip(')')}) 'version': row.split(' (')[1].rstrip(')')})
@ -103,7 +103,7 @@ def parse(data, raw=False, quiet=False):
else: else:
# clear separator line # clear separator line
for i, line in reversed(list(enumerate(cleandata))): for i, line in reversed(list(enumerate(cleandata))):
if line.find('---') != -1: if '---' in line:
cleandata.pop(i) cleandata.pop(i)
cleandata[0] = cleandata[0].lower() cleandata[0] = cleandata[0].lower()

View File

@ -104,7 +104,7 @@ import jc.utils
class info(): class info():
version = '1.0' version = '1.1'
description = 'stat command parser' description = 'stat command parser'
author = 'Kelly Brazil' author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com' author_email = 'kellyjonbrazil@gmail.com'
@ -208,7 +208,7 @@ def parse(data, raw=False, quiet=False):
output_line['file'] = line_list[1] output_line['file'] = line_list[1]
# populate link_to field if -> found # populate link_to field if -> found
if output_line['file'].find(' -> ') != -1: if ' -> ' in output_line['file']:
filename = output_line['file'].split(' -> ')[0].strip('\u2018').rstrip('\u2019') filename = output_line['file'].split(' -> ')[0].strip('\u2018').rstrip('\u2019')
link = output_line['file'].split(' -> ')[1].strip('\u2018').rstrip('\u2019') link = output_line['file'].split(' -> ')[1].strip('\u2018').rstrip('\u2019')
output_line['file'] = filename output_line['file'] = filename
@ -229,7 +229,7 @@ def parse(data, raw=False, quiet=False):
continue continue
# line #3 # line #3
if line.find('Device:') == 0: if line.startswith('Device:'):
line_list = line.split() line_list = line.split()
output_line['device'] = line_list[1] output_line['device'] = line_list[1]
output_line['inode'] = line_list[3] output_line['inode'] = line_list[3]
@ -237,7 +237,7 @@ def parse(data, raw=False, quiet=False):
continue continue
# line #4 # line #4
if line.find('Access: (') == 0: if line.startswith('Access: ('):
line = line.replace('(', ' ').replace(')', ' ').replace('/', ' ') line = line.replace('(', ' ').replace(')', ' ').replace('/', ' ')
line_list = line.split() line_list = line.split()
output_line['access'] = line_list[1] output_line['access'] = line_list[1]
@ -249,19 +249,19 @@ def parse(data, raw=False, quiet=False):
continue continue
# line #5 # line #5
if line.find('Access: 2') == 0: if line.startswith('Access: 2'):
line_list = line.split(maxsplit=1) line_list = line.split(maxsplit=1)
output_line['access_time'] = line_list[1] output_line['access_time'] = line_list[1]
continue continue
# line #6 # line #6
if line.find('Modify:') == 0: if line.startswith('Modify:'):
line_list = line.split(maxsplit=1) line_list = line.split(maxsplit=1)
output_line['modify_time'] = line_list[1] output_line['modify_time'] = line_list[1]
continue continue
# line #7 # line #7
if line.find('Change:') == 0: if line.startswith('Change:'):
line_list = line.split(maxsplit=1) line_list = line.split(maxsplit=1)
output_line['change_time'] = line_list[1] output_line['change_time'] = line_list[1]
continue continue

View File

@ -40,7 +40,7 @@ import jc.utils
class info(): class info():
version = '1.0' version = '1.1'
description = 'systemctl command parser' description = 'systemctl command parser'
author = 'Kelly Brazil' author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com' author_email = 'kellyjonbrazil@gmail.com'
@ -110,7 +110,7 @@ def parse(data, raw=False, quiet=False):
raw_output = [] raw_output = []
for entry in cleandata[1:]: for entry in cleandata[1:]:
if entry.find('LOAD = ') != -1: if 'LOAD = ' in entry:
break break
else: else:

View File

@ -59,7 +59,7 @@ import jc.utils
class info(): class info():
version = '1.0' version = '1.1'
description = 'systemctl list-jobs command parser' description = 'systemctl list-jobs command parser'
author = 'Kelly Brazil' author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com' author_email = 'kellyjonbrazil@gmail.com'
@ -137,7 +137,7 @@ def parse(data, raw=False, quiet=False):
raw_output = [] raw_output = []
for entry in cleandata[1:]: for entry in cleandata[1:]:
if entry.find('No jobs running.') != -1 or entry.find('jobs listed.') != -1: if 'No jobs running.' in entry or 'jobs listed.' in entry:
break break
else: else:

View File

@ -34,7 +34,7 @@ import jc.utils
class info(): class info():
version = '1.0' version = '1.1'
description = 'systemctl list-sockets command parser' description = 'systemctl list-sockets command parser'
author = 'Kelly Brazil' author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com' author_email = 'kellyjonbrazil@gmail.com'
@ -102,7 +102,7 @@ def parse(data, raw=False, quiet=False):
raw_output = [] raw_output = []
for entry in cleandata[1:]: for entry in cleandata[1:]:
if entry.find('sockets listed.') != -1: if 'sockets listed.' in entry:
break break
else: else:

View File

@ -31,7 +31,7 @@ import jc.utils
class info(): class info():
version = '1.0' version = '1.1'
description = 'systemctl list-unit-files command parser' description = 'systemctl list-unit-files command parser'
author = 'Kelly Brazil' author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com' author_email = 'kellyjonbrazil@gmail.com'
@ -99,7 +99,7 @@ def parse(data, raw=False, quiet=False):
raw_output = [] raw_output = []
for entry in cleandata[1:]: for entry in cleandata[1:]:
if entry.find('unit files listed.') != -1: if 'unit files listed.' in entry:
break break
else: else:

View File

@ -5,7 +5,7 @@ with open('README.md', 'r') as f:
setuptools.setup( setuptools.setup(
name='jc', name='jc',
version='1.10.0', version='1.10.1',
author='Kelly Brazil', author='Kelly Brazil',
author_email='kellyjonbrazil@gmail.com', author_email='kellyjonbrazil@gmail.com',
description='This tool serializes the output of popular command line tools and filetypes to structured JSON output.', description='This tool serializes the output of popular command line tools and filetypes to structured JSON output.',