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

Improve and standardize empty data check for all parsers

This commit is contained in:
Kelly Brazil
2020-06-14 17:17:40 -07:00
parent 2af61730f0
commit cc0f0971d7
56 changed files with 449 additions and 412 deletions

View File

@ -1,5 +1,8 @@
jc changelog
20200612 v1.11.6
- Improve and standardize empty data check for all parsers
20200612 v1.11.5
- Update airport_s parser to fix error on parsing empty data
- Update arp parser to fix error on parsing empty data

View File

@ -21,7 +21,7 @@ import jc.appdirs as appdirs
class info():
version = '1.11.5'
version = '1.11.6'
description = 'jc cli output JSON conversion tool'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'

View File

@ -55,7 +55,7 @@ import jc.utils
class info():
version = '1.0'
version = '1.1'
description = 'airport -I command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -131,9 +131,11 @@ def parse(data, raw=False, quiet=False):
raw_output = {}
for line in filter(None, data.splitlines()):
linedata = line.split(':', maxsplit=1)
raw_output[linedata[0].strip().lower().replace(' ', '_').replace('.', '_')] = linedata[1].strip()
if jc.utils.has_data(data):
for line in filter(None, data.splitlines()):
linedata = line.split(':', maxsplit=1)
raw_output[linedata[0].strip().lower().replace(' ', '_').replace('.', '_')] = linedata[1].strip()
if raw:
return raw_output

View File

@ -88,7 +88,7 @@ import jc.parsers.universal
class info():
version = '1.1'
version = '1.2'
description = 'airport -s command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -173,7 +173,7 @@ def parse(data, raw=False, quiet=False):
raw_output = []
cleandata = list(filter(None, data.splitlines()))
if cleandata:
if jc.utils.has_data(data):
# fix headers
cleandata[0] = cleandata[0].lower()
cleandata[0] = cleandata[0].replace('-', '_')

View File

@ -99,7 +99,7 @@ import jc.parsers.universal
class info():
version = '1.5'
version = '1.6'
description = 'arp command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -174,7 +174,7 @@ def parse(data, raw=False, quiet=False):
raw_output = []
cleandata = list(filter(None, data.splitlines()))
if cleandata:
if jc.utils.has_data(data):
# remove final Entries row if -v was used
if cleandata[-1].startswith('Entries:'):

View File

@ -79,7 +79,7 @@ import jc.utils
class info():
version = '1.1'
version = '1.2'
description = 'blkid command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -176,7 +176,8 @@ def parse(data, raw=False, quiet=False):
raw_output = []
if list(filter(None, data.splitlines())):
if jc.utils.has_data(data):
# if the first field is a device, use normal parsing:
if data.split(maxsplit=1)[0][-1] == ':':
linedata = data.splitlines()

View File

@ -132,7 +132,7 @@ import jc.parsers.universal
class info():
version = '1.3'
version = '1.4'
description = 'crontab command and file parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -225,7 +225,8 @@ def parse(data, raw=False, quiet=False):
# Clear any blank lines
cleandata = list(filter(None, cleandata))
if cleandata:
if jc.utils.has_data(data):
# Clear any commented lines
for i, line in reversed(list(enumerate(cleandata))):
if line.strip().startswith('#'):

View File

@ -133,7 +133,7 @@ import jc.parsers.universal
class info():
version = '1.2'
version = '1.3'
description = 'crontab file parser with user support'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -226,7 +226,8 @@ def parse(data, raw=False, quiet=False):
# Clear any blank lines
cleandata = list(filter(None, cleandata))
if cleandata:
if jc.utils.has_data(data):
# Clear any commented lines
for i, line in reversed(list(enumerate(cleandata))):
if line.strip().startswith('#'):

View File

@ -63,7 +63,7 @@ import csv
class info():
version = '1.0'
version = '1.1'
description = 'CSV file parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -123,7 +123,8 @@ def parse(data, raw=False, quiet=False):
# Clear any blank lines
cleandata = list(filter(None, cleandata))
if cleandata:
if jc.utils.has_data(data):
dialect = None
try:
dialect = csv.Sniffer().sniff(data[:1024])

View File

@ -73,7 +73,7 @@ import jc.parsers.universal
class info():
version = '1.4'
version = '1.5'
description = 'df command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -186,7 +186,8 @@ def parse(data, raw=False, quiet=False):
cleandata = data.splitlines()
raw_output = []
if list(filter(None, cleandata)):
if jc.utils.has_data(data):
# fix headers
cleandata[0] = cleandata[0].lower()
cleandata[0] = cleandata[0].replace('-', '_')

View File

@ -324,7 +324,7 @@ import jc.utils
class info():
version = '1.2'
version = '1.3'
description = 'dig command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -574,100 +574,103 @@ def parse(data, raw=False, quiet=False):
axfr = False
output_entry = {}
for line in cleandata:
if line.startswith('; <<>> ') and ' axfr ' in line.lower():
question = False
authority = False
answer = False
axfr = True
axfr_list = []
continue
if jc.utils.has_data(data):
for line in cleandata:
if ';' not in line and axfr:
axfr_list.append(parse_axfr(line))
output_entry.update({'axfr': axfr_list})
continue
if line.startswith('; <<>> ') and ' axfr ' in line.lower():
question = False
authority = False
answer = False
axfr = True
axfr_list = []
continue
if line.startswith(';; ->>HEADER<<-'):
output_entry = {}
output_entry.update(parse_header(line))
continue
if ';' not in line and axfr:
axfr_list.append(parse_axfr(line))
output_entry.update({'axfr': axfr_list})
continue
if line.startswith(';; flags:'):
output_entry.update(parse_flags_line(line))
continue
if line.startswith(';; ->>HEADER<<-'):
output_entry = {}
output_entry.update(parse_header(line))
continue
if line.startswith(';; QUESTION SECTION:'):
question = True
authority = False
answer = False
axfr = False
continue
if line.startswith(';; flags:'):
output_entry.update(parse_flags_line(line))
continue
if question:
output_entry['question'] = parse_question(line)
question = False
authority = False
answer = False
axfr = False
continue
if line.startswith(';; QUESTION SECTION:'):
question = True
authority = False
answer = False
axfr = False
continue
if line.startswith(';; AUTHORITY SECTION:'):
question = False
authority = True
answer = False
axfr = False
authority_list = []
continue
if question:
output_entry['question'] = parse_question(line)
question = False
authority = False
answer = False
axfr = False
continue
if ';' not in line and authority:
authority_list.append(parse_authority(line))
output_entry.update({'authority': authority_list})
continue
if line.startswith(';; AUTHORITY SECTION:'):
question = False
authority = True
answer = False
axfr = False
authority_list = []
continue
if line.startswith(';; ANSWER SECTION:'):
question = False
authority = False
answer = True
axfr = False
answer_list = []
continue
if ';' not in line and authority:
authority_list.append(parse_authority(line))
output_entry.update({'authority': authority_list})
continue
if ';' not in line and answer:
answer_list.append(parse_answer(line))
output_entry.update({'answer': answer_list})
continue
if line.startswith(';; ANSWER SECTION:'):
question = False
authority = False
answer = True
axfr = False
answer_list = []
continue
# footer consists of 4 lines
# footer line 1
if line.startswith(';; Query time:'):
output_entry.update({'query_time': line.split(':')[1].lstrip()})
continue
if ';' not in line and answer:
answer_list.append(parse_answer(line))
output_entry.update({'answer': answer_list})
continue
# footer line 2
if line.startswith(';; SERVER:'):
output_entry.update({'server': line.split(':')[1].lstrip()})
continue
# footer consists of 4 lines
# footer line 1
if line.startswith(';; Query time:'):
output_entry.update({'query_time': line.split(':')[1].lstrip()})
continue
# footer line 3
if line.startswith(';; WHEN:'):
output_entry.update({'when': line.split(':', maxsplit=1)[1].lstrip()})
continue
# footer line 2
if line.startswith(';; SERVER:'):
output_entry.update({'server': line.split(':')[1].lstrip()})
continue
# footer line 4 (last line)
if line.startswith(';; MSG SIZE rcvd:'):
output_entry.update({'rcvd': line.split(':')[1].lstrip()})
# footer line 3
if line.startswith(';; WHEN:'):
output_entry.update({'when': line.split(':', maxsplit=1)[1].lstrip()})
continue
if output_entry:
raw_output.append(output_entry)
elif line.startswith(';; XFR size:'):
output_entry.update({'size': line.split(':')[1].lstrip()})
# footer line 4 (last line)
if line.startswith(';; MSG SIZE rcvd:'):
output_entry.update({'rcvd': line.split(':')[1].lstrip()})
if output_entry:
raw_output.append(output_entry)
if output_entry:
raw_output.append(output_entry)
elif line.startswith(';; XFR size:'):
output_entry.update({'size': line.split(':')[1].lstrip()})
if output_entry:
raw_output.append(output_entry)
raw_output = list(filter(None, raw_output))
raw_output = list(filter(None, raw_output))
if raw:
return raw_output
else:

View File

@ -102,7 +102,7 @@ import jc.utils
class info():
version = '1.0'
version = '1.1'
description = 'dmidecode command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -190,148 +190,150 @@ def parse(data, raw=False, quiet=False):
raw_output = []
data = data.splitlines()
if jc.utils.has_data(data):
# remove header rows
for row in data.copy():
if row:
data.pop(0)
else:
break
data = data.splitlines()
# main parsing loop
for line in data:
# new item
if not line:
item_header = True
item_values = False
value_list = False
# remove header rows
for row in data.copy():
if row:
data.pop(0)
else:
break
# main parsing loop
for line in data:
# new item
if not line:
item_header = True
item_values = False
value_list = False
if item:
if values:
item['values'][attribute] = values
if key_data:
item['values'][f'{key}_data'] = key_data
raw_output.append(item)
item = {}
header = None
key = None
val = None
attribute = None
values = []
key_data = []
continue
# header
if line.startswith('Handle ') and line.endswith('bytes'):
# Handle 0x0000, DMI type 0, 24 bytes
header = line.replace(',', ' ').split()
item = {
'handle': header[1],
'type': header[4],
'bytes': header[5]
}
continue
# description
if item_header:
item_header = False
item_values = True
value_list = False
item['description'] = line
item['values'] = {}
continue
# new item if multiple descriptions in handle
if not item_header and not line.startswith('\t'):
item_header = False
item_values = True
value_list = False
if item:
if values:
item['values'][attribute] = values
if key_data:
item['values'][f'{key}_data'] = key_data
raw_output.append(item)
item = {
'handle': header[1],
'type': header[4],
'bytes': header[5],
'description': line,
'values': {}
}
key = None
val = None
attribute = None
values = []
key_data = []
continue
# keys and values
if item_values \
and len(line.split(':', maxsplit=1)) == 2 \
and line.startswith('\t') \
and not line.startswith('\t\t') \
and not line.strip().endswith(':'):
item_header = False
item_values = True
value_list = False
if item:
if values:
item['values'][attribute] = values
values = []
if key_data:
item['values'][f'{key}_data'] = key_data
raw_output.append(item)
key_data = []
item = {}
header = None
key = None
val = None
attribute = None
values = []
key_data = []
continue
key = line.split(':', maxsplit=1)[0].strip().lower().replace(' ', '_')
val = line.split(':', maxsplit=1)[1].strip()
item['values'].update({key: val})
continue
# header
if line.startswith('Handle ') and line.endswith('bytes'):
# multi-line key
if item_values \
and line.startswith('\t') \
and not line.startswith('\t\t') \
and line.strip().endswith(':'):
item_header = False
item_values = True
value_list = True
# Handle 0x0000, DMI type 0, 24 bytes
header = line.replace(',', ' ').split()
item = {
'handle': header[1],
'type': header[4],
'bytes': header[5]
}
continue
# description
if item_header:
item_header = False
item_values = True
value_list = False
item['description'] = line
item['values'] = {}
continue
# new item if multiple descriptions in handle
if not item_header and not line.startswith('\t'):
item_header = False
item_values = True
value_list = False
if item:
if values:
item['values'][attribute] = values
values = []
if key_data:
item['values'][f'{key}_data'] = key_data
raw_output.append(item)
key_data = []
item = {
'handle': header[1],
'type': header[4],
'bytes': header[5],
'description': line,
'values': {}
}
key = None
val = None
attribute = None
values = []
key_data = []
continue
# keys and values
if item_values \
and len(line.split(':', maxsplit=1)) == 2 \
and line.startswith('\t') \
and not line.startswith('\t\t') \
and not line.strip().endswith(':'):
item_header = False
item_values = True
value_list = False
if values:
item['values'][attribute] = values
attribute = line[:-1].strip().lower().replace(' ', '_')
values = []
if key_data:
item['values'][f'{key}_data'] = key_data
key_data = []
continue
key = line.split(':', maxsplit=1)[0].strip().lower().replace(' ', '_')
val = line.split(':', maxsplit=1)[1].strip()
item['values'].update({key: val})
continue
# multi-line values
if value_list \
and line.startswith('\t\t'):
values.append(line.strip())
continue
# multi-line key
if item_values \
and line.startswith('\t') \
and not line.startswith('\t\t') \
and line.strip().endswith(':'):
item_header = False
item_values = True
value_list = True
# data for hybrid multi-line objects
if item_values \
and not value_list \
and line.startswith('\t\t'):
if f'{key}_data' not in item['values']:
item['values'][f'{key}_data'] = []
key_data.append(line.strip())
continue
if values:
item['values'][attribute] = values
values = []
if key_data:
item['values'][f'{key}_data'] = key_data
key_data = []
attribute = line[:-1].strip().lower().replace(' ', '_')
values = []
continue
# multi-line values
if value_list \
and line.startswith('\t\t'):
values.append(line.strip())
continue
# data for hybrid multi-line objects
if item_values \
and not value_list \
and line.startswith('\t\t'):
if f'{key}_data' not in item['values']:
item['values'][f'{key}_data'] = []
key_data.append(line.strip())
continue
if item:
raw_output.append(item)
if item:
raw_output.append(item)
if raw:
return raw_output

View File

@ -73,7 +73,7 @@ import jc.parsers.universal
class info():
version = '1.1'
version = '1.2'
description = 'du command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -137,12 +137,12 @@ def parse(data, raw=False, quiet=False):
jc.utils.compatibility(__name__, info.compatible)
raw_output = []
cleandata = data.splitlines()
# Clear any blank lines
cleandata = list(filter(None, cleandata))
cleandata = list(filter(None, data.splitlines()))
if jc.utils.has_data(data):
if cleandata:
cleandata.insert(0, 'size name')
raw_output = jc.parsers.universal.simple_table_parse(cleandata)

View File

@ -52,7 +52,7 @@ import jc.utils
class info():
version = '1.1'
version = '1.2'
description = 'env command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -116,12 +116,10 @@ def parse(data, raw=False, quiet=False):
raw_output = {}
linedata = data.splitlines()
# Clear any blank lines
cleandata = list(filter(None, linedata))
cleandata = list(filter(None, data.splitlines()))
if cleandata:
if jc.utils.has_data(data):
for entry in cleandata:
parsed_line = entry.split('=', maxsplit=1)

View File

@ -48,7 +48,7 @@ import jc.parsers.universal
class info():
version = '1.1'
version = '1.2'
description = 'file command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -104,23 +104,26 @@ def parse(data, raw=False, quiet=False):
raw_output = []
warned = False
for line in filter(None, data.splitlines()):
linedata = line.rsplit(': ', maxsplit=1)
try:
filename = linedata[0].strip()
filetype = linedata[1].strip()
if jc.utils.has_data(data):
raw_output.append(
{
'filename': filename,
'type': filetype
}
)
except IndexError:
if not warned:
jc.utils.warning_message('Filenames with newline characters detected. Some filenames may be truncated.')
warned = True
for line in filter(None, data.splitlines()):
linedata = line.rsplit(': ', maxsplit=1)
try:
filename = linedata[0].strip()
filetype = linedata[1].strip()
raw_output.append(
{
'filename': filename,
'type': filetype
}
)
except IndexError:
if not warned:
jc.utils.warning_message('Filenames with newline characters detected. Some filenames may be truncated.')
warned = True
if raw:
return raw_output

View File

@ -78,9 +78,11 @@ def parse(data, raw=False, quiet=False):
raw_output = []
for line in filter(None, data.splitlines()):
# parse the content
pass
if jc.utils.has_data(data):
for line in filter(None, data.splitlines()):
# parse the content
pass
if raw:
return raw_output

View File

@ -53,7 +53,7 @@ import jc.parsers.universal
class info():
version = '1.1'
version = '1.2'
description = 'free command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -124,7 +124,8 @@ def parse(data, raw=False, quiet=False):
cleandata = data.splitlines()
raw_output = []
if cleandata:
if jc.utils.has_data(data):
cleandata[0] = cleandata[0].lower()
cleandata[0] = cleandata[0].replace('buff/cache', 'buff_cache')
cleandata[0] = 'type ' + cleandata[0]

View File

@ -70,7 +70,7 @@ import jc.utils
class info():
version = '1.2'
version = '1.3'
description = 'fstab file parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -141,7 +141,8 @@ def parse(data, raw=False, quiet=False):
# Clear any blank lines
cleandata = list(filter(None, cleandata))
if cleandata:
if jc.utils.has_data(data):
for line in cleandata:
output_line = {}
# ignore commented lines

View File

@ -94,7 +94,7 @@ import jc.utils
class info():
version = '1.0'
version = '1.1'
description = '/etc/group file parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -169,7 +169,8 @@ def parse(data, raw=False, quiet=False):
# Clear any blank lines
cleandata = list(filter(None, cleandata))
if cleandata:
if jc.utils.has_data(data):
for entry in cleandata:
if entry.startswith('#'):
continue

View File

@ -60,7 +60,7 @@ import jc.utils
class info():
version = '1.0'
version = '1.1'
description = '/etc/gshadow file parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -131,7 +131,8 @@ def parse(data, raw=False, quiet=False):
# Clear any blank lines
cleandata = list(filter(None, cleandata))
if cleandata:
if jc.utils.has_data(data):
for entry in cleandata:
if entry.startswith('#'):
continue

View File

@ -44,7 +44,7 @@ import jc.utils
class info():
version = '1.2'
version = '1.3'
description = 'history command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -108,17 +108,19 @@ def parse(data, raw=False, quiet=False):
raw_output = {}
# split lines and clear out any non-ascii chars
linedata = data.encode('ascii', errors='ignore').decode().splitlines()
if jc.utils.has_data(data):
# Skip any blank lines
for entry in filter(None, linedata):
try:
parsed_line = entry.split(maxsplit=1)
raw_output[parsed_line[0]] = parsed_line[1]
except IndexError:
# need to catch indexerror in case there is weird input from prior commands
pass
# split lines and clear out any non-ascii chars
linedata = data.encode('ascii', errors='ignore').decode().splitlines()
# Skip any blank lines
for entry in filter(None, linedata):
try:
parsed_line = entry.split(maxsplit=1)
raw_output[parsed_line[0]] = parsed_line[1]
except IndexError:
# need to catch indexerror in case there is weird input from prior commands
pass
if raw:
return raw_output

View File

@ -61,7 +61,7 @@ import jc.utils
class info():
version = '1.1'
version = '1.2'
description = '/etc/hosts file parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -117,12 +117,12 @@ def parse(data, raw=False, quiet=False):
jc.utils.compatibility(__name__, info.compatible)
raw_output = []
cleandata = data.splitlines()
# Clear any blank lines
cleandata = list(filter(None, cleandata))
cleandata = list(filter(None, data.splitlines()))
if jc.utils.has_data(data):
if cleandata:
for line in cleandata:
output_line = {}
# ignore commented lines

View File

@ -70,7 +70,7 @@ import jc.utils
class info():
version = '1.0'
version = '1.1'
description = 'id command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -166,12 +166,12 @@ def parse(data, raw=False, quiet=False):
jc.utils.compatibility(__name__, info.compatible)
raw_output = {}
cleandata = data.split()
# Clear any blank lines
cleandata = list(filter(None, cleandata))
cleandata = list(filter(None, data.split()))
if jc.utils.has_data(data):
if cleandata:
for section in cleandata:
if section.startswith('uid'):
uid_parsed = section.replace('(', '=').replace(')', '=')

View File

@ -147,7 +147,7 @@ import jc.utils
class info():
version = '1.7'
version = '1.8'
description = 'ifconfig command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -475,14 +475,16 @@ def parse(data, raw=False, quiet=False):
raw_output = []
parsed = IfconfigParser(console_output=data)
interfaces = parsed.get_interfaces()
if jc.utils.has_data(data):
# convert ifconfigparser output to a dictionary
for iface in interfaces:
d = interfaces[iface]._asdict()
dct = dict(d)
raw_output.append(dct)
parsed = IfconfigParser(console_output=data)
interfaces = parsed.get_interfaces()
# convert ifconfigparser output to a dictionary
for iface in interfaces:
d = interfaces[iface]._asdict()
dct = dict(d)
raw_output.append(dct)
if raw:
return raw_output

View File

@ -47,7 +47,7 @@ import configparser
class info():
version = '1.0'
version = '1.1'
description = 'INI file parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -101,7 +101,8 @@ def parse(data, raw=False, quiet=False):
raw_output = {}
if data:
if jc.utils.has_data(data):
ini = configparser.ConfigParser()
ini.read_string(data)
raw_output = {s: dict(ini.items(s)) for s in ini.sections()}

View File

@ -134,7 +134,7 @@ import jc.utils
class info():
version = '1.2'
version = '1.3'
description = 'iptables command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -245,34 +245,36 @@ def parse(data, raw=False, quiet=False):
cleandata = data.splitlines()
for line in cleandata:
if jc.utils.has_data(data):
if line.startswith('Chain'):
raw_output.append(chain)
chain = {}
headers = []
for line in cleandata:
parsed_line = line.split()
if line.startswith('Chain'):
raw_output.append(chain)
chain = {}
headers = []
chain['chain'] = parsed_line[1]
chain['rules'] = []
parsed_line = line.split()
continue
chain['chain'] = parsed_line[1]
chain['rules'] = []
elif line.startswith('target') or line.find('pkts') == 1 or line.startswith('num'):
headers = []
headers = [h for h in ' '.join(line.lower().strip().split()).split() if h]
headers.append("options")
continue
continue
elif line.startswith('target') or line.find('pkts') == 1 or line.startswith('num'):
headers = []
headers = [h for h in ' '.join(line.lower().strip().split()).split() if h]
headers.append("options")
else:
rule = line.split(maxsplit=len(headers) - 1)
temp_rule = dict(zip(headers, rule))
if temp_rule:
chain['rules'].append(temp_rule)
continue
raw_output = list(filter(None, raw_output))
else:
rule = line.split(maxsplit=len(headers) - 1)
temp_rule = dict(zip(headers, rule))
if temp_rule:
chain['rules'].append(temp_rule)
raw_output = list(filter(None, raw_output))
if raw:
return raw_output

View File

@ -77,7 +77,7 @@ import jc.utils
class info():
version = '1.1'
version = '1.2'
description = 'jobs command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -144,12 +144,10 @@ def parse(data, raw=False, quiet=False):
raw_output = []
linedata = data.splitlines()
# Clear any blank lines
cleandata = list(filter(None, linedata))
cleandata = list(filter(None, data.splitlines()))
if cleandata:
if jc.utils.has_data(data):
for entry in cleandata:
output_line = {}

View File

@ -72,7 +72,7 @@ import jc.utils
class info():
version = '1.2'
version = '1.3'
description = 'last and lastb command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -149,12 +149,12 @@ def parse(data, raw=False, quiet=False):
jc.utils.compatibility(__name__, info.compatible)
raw_output = []
cleandata = data.splitlines()
# Clear any blank lines
cleandata = list(filter(None, cleandata))
cleandata = list(filter(None, data.splitlines()))
if jc.utils.has_data(data):
if cleandata:
for entry in cleandata:
output_line = {}

View File

@ -149,7 +149,7 @@ import jc.utils
class info():
version = '1.5'
version = '1.6'
description = 'ls command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -226,7 +226,8 @@ def parse(data, raw=False, quiet=False):
linedata = data.splitlines()
if linedata:
if jc.utils.has_data(data):
# Delete first line if it starts with 'total 1234'
if re.match(r'total [0-9]+', linedata[0]):
linedata.pop(0)

View File

@ -216,7 +216,7 @@ import jc.parsers.universal
class info():
version = '1.4'
version = '1.5'
description = 'lsblk command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -327,12 +327,12 @@ def parse(data, raw=False, quiet=False):
if not quiet:
jc.utils.compatibility(__name__, info.compatible)
linedata = data.splitlines()
# Clear any blank lines
cleandata = list(filter(None, linedata))
cleandata = list(filter(None, data.splitlines()))
raw_output = []
if cleandata:
if jc.utils.has_data(data):
cleandata = data.splitlines()
cleandata[0] = cleandata[0].lower()

View File

@ -107,7 +107,7 @@ import jc.parsers.universal
class info():
version = '1.2'
version = '1.3'
description = 'lsmod command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -177,7 +177,8 @@ def parse(data, raw=False, quiet=False):
cleandata = data.splitlines()
raw_output = []
if list(filter(None, cleandata)):
if jc.utils.has_data(data):
cleandata[0] = cleandata[0].lower()
raw_output = jc.parsers.universal.simple_table_parse(cleandata)

View File

@ -97,7 +97,7 @@ import jc.parsers.universal
class info():
version = '1.1'
version = '1.2'
description = 'lsof command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -169,12 +169,11 @@ def parse(data, raw=False, quiet=False):
raw_output = []
linedata = data.splitlines()
# Clear any blank lines
cleandata = list(filter(None, linedata))
cleandata = list(filter(None, data.splitlines()))
if jc.utils.has_data(data):
if cleandata:
cleandata[0] = cleandata[0].lower()
cleandata[0] = cleandata[0].replace('/', '_')

View File

@ -56,7 +56,7 @@ import jc.utils
class info():
version = '1.4'
version = '1.5'
description = 'mount command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -158,13 +158,12 @@ def parse(data, raw=False, quiet=False):
if not quiet:
jc.utils.compatibility(__name__, info.compatible)
linedata = data.splitlines()
# Clear any blank lines
cleandata = list(filter(None, linedata))
cleandata = list(filter(None, data.splitlines()))
raw_output = []
if cleandata:
if jc.utils.has_data(data):
# check for OSX output
if ' type ' not in cleandata[0]:
raw_output = osx_parse(cleandata)

View File

@ -247,7 +247,7 @@ Examples:
class info():
version = '1.7'
version = '1.8'
description = 'netstat command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -431,11 +431,11 @@ def parse(data, raw=False, quiet=False):
if not quiet:
jc.utils.compatibility(__name__, info.compatible)
cleandata = data.splitlines()
cleandata = list(filter(None, cleandata))
cleandata = list(filter(None, data.splitlines()))
raw_output = []
if cleandata:
if jc.utils.has_data(data):
# check for FreeBSD/OSX vs Linux
# is this from FreeBSD/OSX?
if cleandata[0] == 'Active Internet connections' \

View File

@ -183,7 +183,7 @@ import jc.parsers.universal
class info():
version = '1.2'
version = '1.3'
description = 'ntpq -p command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -271,7 +271,8 @@ def parse(data, raw=False, quiet=False):
cleandata = data.splitlines()
raw_output = []
if list(filter(None, cleandata)):
if jc.utils.has_data(data):
cleandata[0] = 's ' + cleandata[0]
cleandata[0] = cleandata[0].lower()

View File

@ -78,7 +78,7 @@ import jc.utils
class info():
version = '1.0'
version = '1.1'
description = '/etc/passwd file parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -146,12 +146,12 @@ def parse(data, raw=False, quiet=False):
jc.utils.compatibility(__name__, info.compatible)
raw_output = []
cleandata = data.splitlines()
# Clear any blank lines
cleandata = list(filter(None, cleandata))
cleandata = list(filter(None, data.splitlines()))
if jc.utils.has_data(data):
if cleandata:
for entry in cleandata:
if entry.startswith('#'):
continue

View File

@ -32,7 +32,7 @@ import jc.parsers.universal
class info():
version = '1.2'
version = '1.3'
description = 'pip list command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -88,12 +88,11 @@ def parse(data, raw=False, quiet=False):
raw_output = []
linedata = data.splitlines()
# Clear any blank lines
cleandata = list(filter(None, linedata))
cleandata = list(filter(None, data.splitlines()))
if jc.utils.has_data(data):
if cleandata:
# detect legacy output type
if ' (' in cleandata[0]:
for row in cleandata:

View File

@ -42,7 +42,7 @@ import jc.utils
class info():
version = '1.0'
version = '1.1'
description = 'pip show command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -107,12 +107,11 @@ def parse(data, raw=False, quiet=False):
raw_output = []
package = {}
linedata = data.splitlines()
# Clear any blank lines
cleandata = list(filter(None, linedata))
cleandata = list(filter(None, data.splitlines()))
if jc.utils.has_data(data):
if cleandata:
for row in cleandata:
if row.startswith('---'):
raw_output.append(package)

View File

@ -177,7 +177,7 @@ import jc.parsers.universal
class info():
version = '1.2'
version = '1.3'
description = 'ps command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -284,9 +284,9 @@ def parse(data, raw=False, quiet=False):
cleandata = data.splitlines()
raw_output = []
if list(filter(None, cleandata)):
cleandata[0] = cleandata[0].lower()
if jc.utils.has_data(data):
cleandata[0] = cleandata[0].lower()
raw_output = jc.parsers.universal.simple_table_parse(cleandata)
if raw:

View File

@ -84,7 +84,7 @@ import jc.parsers.universal
class info():
version = '1.2'
version = '1.3'
description = 'route command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -184,9 +184,9 @@ def parse(data, raw=False, quiet=False):
cleandata = data.splitlines()[1:]
raw_output = []
if list(filter(None, cleandata)):
cleandata[0] = cleandata[0].lower()
if jc.utils.has_data(data):
cleandata[0] = cleandata[0].lower()
raw_output = jc.parsers.universal.simple_table_parse(cleandata)
if raw:

View File

@ -84,7 +84,7 @@ import jc.utils
class info():
version = '1.0'
version = '1.1'
description = '/etc/shadow file parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -153,12 +153,12 @@ def parse(data, raw=False, quiet=False):
jc.utils.compatibility(__name__, info.compatible)
raw_output = []
cleandata = data.splitlines()
# Clear any blank lines
cleandata = list(filter(None, cleandata))
cleandata = list(filter(None, data.splitlines()))
if jc.utils.has_data(data):
if cleandata:
for entry in cleandata:
if entry.startswith('#'):
continue

View File

@ -251,7 +251,7 @@ import jc.utils
class info():
version = '1.1'
version = '1.2'
description = 'ss command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -342,12 +342,12 @@ def parse(data, raw=False, quiet=False):
contains_colon = ['nl', 'p_raw', 'raw', 'udp', 'tcp', 'v_str', 'icmp6']
raw_output = []
cleandata = data.splitlines()
# Clear any blank lines
cleandata = list(filter(None, cleandata))
cleandata = list(filter(None, data.splitlines()))
if jc.utils.has_data(data):
if cleandata:
header_text = cleandata[0].lower()
header_text = header_text.replace('netidstate', 'netid state')
header_text = header_text.replace('local address:port', 'local_address local_port')

View File

@ -105,7 +105,7 @@ import jc.utils
class info():
version = '1.4'
version = '1.5'
description = 'stat command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -197,12 +197,11 @@ def parse(data, raw=False, quiet=False):
jc.utils.compatibility(__name__, info.compatible)
raw_output = []
cleandata = data.splitlines()
# Clear any blank lines
cleandata = list(filter(None, cleandata))
cleandata = list(filter(None, data.splitlines()))
if cleandata:
if jc.utils.has_data(data):
# linux output
if cleandata[0].startswith(' File: '):

View File

@ -40,7 +40,7 @@ import jc.utils
class info():
version = '1.2'
version = '1.3'
description = 'systemctl command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -96,12 +96,12 @@ def parse(data, raw=False, quiet=False):
if not quiet:
jc.utils.compatibility(__name__, info.compatible)
linedata = data.splitlines()
# Clear any blank lines
linedata = list(filter(None, linedata))
linedata = list(filter(None, data.splitlines()))
raw_output = []
if linedata:
if jc.utils.has_data(data):
# clean up non-ascii characters, if any
cleandata = []
for entry in linedata:

View File

@ -59,7 +59,7 @@ import jc.utils
class info():
version = '1.2'
version = '1.3'
description = 'systemctl list-jobs command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -122,12 +122,12 @@ def parse(data, raw=False, quiet=False):
if not quiet:
jc.utils.compatibility(__name__, info.compatible)
linedata = data.splitlines()
# Clear any blank lines
linedata = list(filter(None, linedata))
linedata = list(filter(None, data.splitlines()))
raw_output = []
if linedata:
if jc.utils.has_data(data):
cleandata = []
# clean up non-ascii characters, if any

View File

@ -34,7 +34,7 @@ import jc.utils
class info():
version = '1.2'
version = '1.3'
description = 'systemctl list-sockets command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -88,12 +88,12 @@ def parse(data, raw=False, quiet=False):
if not quiet:
jc.utils.compatibility(__name__, info.compatible)
linedata = data.splitlines()
# Clear any blank lines
linedata = list(filter(None, linedata))
linedata = list(filter(None, data.splitlines()))
raw_output = []
if linedata:
if jc.utils.has_data(data):
cleandata = []
# clean up non-ascii characters, if any
for entry in linedata:

View File

@ -31,7 +31,7 @@ import jc.utils
class info():
version = '1.2'
version = '1.3'
description = 'systemctl list-unit-files command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -84,12 +84,12 @@ def parse(data, raw=False, quiet=False):
if not quiet:
jc.utils.compatibility(__name__, info.compatible)
linedata = data.splitlines()
# Clear any blank lines
linedata = list(filter(None, linedata))
linedata = list(filter(None, data.splitlines()))
raw_output = []
if linedata:
if jc.utils.has_data(data):
cleandata = []
# clean up non-ascii characters, if any
for entry in linedata:

View File

@ -38,7 +38,7 @@ import jc.utils
class info():
version = '1.0'
version = '1.1'
description = 'timedatectl status command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -109,12 +109,14 @@ def parse(data, raw=False, quiet=False):
raw_output = {}
for line in filter(None, data.splitlines()):
linedata = line.split(':', maxsplit=1)
raw_output[linedata[0].strip().lower().replace(' ', '_')] = linedata[1].strip()
if jc.utils.has_data(data):
if linedata[0].strip() == 'DST active':
break
for line in filter(None, data.splitlines()):
linedata = line.split(':', maxsplit=1)
raw_output[linedata[0].strip().lower().replace(' ', '_')] = linedata[1].strip()
if linedata[0].strip() == 'DST active':
break
if raw:
return raw_output

View File

@ -30,7 +30,7 @@ import jc.utils
class info():
version = '1.2'
version = '1.3'
description = 'uname -a command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -88,9 +88,9 @@ def parse(data, raw=False, quiet=False):
jc.utils.compatibility(__name__, info.compatible)
raw_output = {}
split_line = data.split()
if len(split_line) > 1:
if jc.utils.has_data(data):
# check for OSX output
if data.startswith('Darwin'):
parsed_line = data.split()

View File

@ -34,7 +34,7 @@ import jc.utils
class info():
version = '1.1'
version = '1.2'
description = 'uptime command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -109,7 +109,8 @@ def parse(data, raw=False, quiet=False):
raw_output = {}
cleandata = data.splitlines()
if list(filter(None, cleandata)):
if jc.utils.has_data(data):
parsed_line = cleandata[0].split()
# allow space for odd times

View File

@ -83,7 +83,7 @@ import jc.utils
class info():
version = '1.2'
version = '1.3'
description = 'w command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -151,7 +151,8 @@ def parse(data, raw=False, quiet=False):
cleandata = data.splitlines()[1:]
raw_output = []
if list(filter(None, cleandata)):
if jc.utils.has_data(data):
header_text = cleandata[0].lower()
# fixup for 'from' column that can be blank
from_col = header_text.find('from')

View File

@ -103,7 +103,7 @@ import jc.utils
class info():
version = '1.0'
version = '1.1'
description = 'who command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -174,12 +174,12 @@ def parse(data, raw=False, quiet=False):
jc.utils.compatibility(__name__, info.compatible)
raw_output = []
cleandata = data.splitlines()
# Clear any blank lines
cleandata = list(filter(None, cleandata))
cleandata = list(filter(None, data.splitlines()))
if jc.utils.has_data(data):
if cleandata:
for line in cleandata:
output_line = {}
linedata = line.split()

View File

@ -59,7 +59,7 @@ import xmltodict
class info():
version = '1.1'
version = '1.2'
description = 'XML file parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -113,7 +113,8 @@ def parse(data, raw=False, quiet=False):
raw_output = []
if list(filter(None, data.splitlines())):
if jc.utils.has_data(data):
raw_output = xmltodict.parse(data)
if raw:

View File

@ -71,7 +71,7 @@ from ruamel.yaml import YAML
class info():
version = '1.0'
version = '1.1'
description = 'YAML file parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@ -126,10 +126,13 @@ def parse(data, raw=False, quiet=False):
jc.utils.compatibility(__name__, info.compatible)
raw_output = []
yaml = YAML(typ='safe')
for document in yaml.load_all(data):
raw_output.append(document)
if jc.utils.has_data(data):
yaml = YAML(typ='safe')
for document in yaml.load_all(data):
raw_output.append(document)
if raw:
return raw_output

View File

@ -67,3 +67,7 @@ def compatibility(mod_name, compatible):
mod = mod_name.split('.')[-1]
compat_list = ', '.join(compatible)
warning_message(f'{mod} parser not compatible with your OS ({sys.platform}).\n Compatible platforms: {compat_list}')
def has_data(data):
return True if data and not data.isspace() else False

View File

@ -5,7 +5,7 @@ with open('README.md', 'r') as f:
setuptools.setup(
name='jc',
version='1.11.5',
version='1.11.6',
author='Kelly Brazil',
author_email='kellyjonbrazil@gmail.com',
description='Converts the output of popular command-line tools and file-types to JSON.',