1
0
mirror of https://github.com/kellyjonbrazil/jc.git synced 2026-04-03 17:44:07 +02:00

Compare commits

...

30 Commits

Author SHA1 Message Date
Kelly Brazil
d0d7254c6a add docstring 2020-06-14 17:23:10 -07:00
Kelly Brazil
cc0f0971d7 Improve and standardize empty data check for all parsers 2020-06-14 17:17:40 -07:00
Kelly Brazil
2af61730f0 Merge pull request #68 from kellyjonbrazil/dev
Dev v1.11.5
2020-06-12 12:34:34 -07:00
Kelly Brazil
83f41b83dc version bump 2020-06-12 12:30:19 -07:00
Kelly Brazil
1fb84fce88 fix for no data 2020-06-12 12:25:07 -07:00
Kelly Brazil
a8837e1244 remove --upgrade from pip install 2020-06-12 07:57:40 -07:00
Kelly Brazil
04d2eec558 fix for no data 2020-06-11 17:59:06 -07:00
Kelly Brazil
1b57ec92f0 fix for no data 2020-06-11 17:52:03 -07:00
Kelly Brazil
4d88595404 enhance empty data check 2020-06-11 17:16:11 -07:00
Kelly Brazil
52b1272a3a enhance empty data check 2020-06-11 17:13:45 -07:00
Kelly Brazil
d2ccad6a83 fix for no data 2020-06-11 17:09:51 -07:00
Kelly Brazil
cad6dde4ac fix for no data 2020-06-10 17:54:06 -07:00
Kelly Brazil
06811c3539 add test for no data 2020-06-10 17:41:54 -07:00
Kelly Brazil
0cb23c2b21 add fix for no data 2020-06-10 17:40:18 -07:00
Kelly Brazil
ac4688dca2 add test for no data 2020-06-10 17:35:40 -07:00
Kelly Brazil
326c3b4670 add test for no data 2020-06-10 17:34:22 -07:00
Kelly Brazil
9b29d0c268 add test for no data 2020-06-10 17:32:39 -07:00
Kelly Brazil
e0013c3871 add test for no data 2020-06-10 17:31:14 -07:00
Kelly Brazil
a75744075b add no data test 2020-06-10 17:29:41 -07:00
Kelly Brazil
525aec1a02 fix for no data 2020-06-10 17:27:46 -07:00
Kelly Brazil
0bf9a7a072 add test for no data 2020-06-10 17:22:59 -07:00
Kelly Brazil
d8f2f4c95b fix for no data 2020-06-10 17:20:09 -07:00
Kelly Brazil
35d733b44f fix for no data 2020-06-10 17:10:53 -07:00
Kelly Brazil
9179b4175c add nodata tests 2020-06-10 16:40:11 -07:00
Kelly Brazil
bb07d78c78 add nodata fix 2020-06-10 16:39:49 -07:00
Kelly Brazil
07b179cd7f Merge pull request #67 from kellyjonbrazil/Dev
Dev v1.11.4
2020-06-10 06:07:42 -07:00
Kelly Brazil
054422d837 add test for empty directory 2020-06-10 06:04:50 -07:00
Kelly Brazil
3e052d1810 version bump 2020-06-10 05:53:20 -07:00
Kelly Brazil
c8e72805cf fix error on empty directory 2020-06-10 05:51:12 -07:00
Kelly Brazil
12a80e7db0 add fedora package info 2020-06-09 15:13:53 -07:00
111 changed files with 1144 additions and 703 deletions

View File

@@ -70,21 +70,29 @@ Release notes can be found [here](https://blog.kellybrazil.com/category/jc-news/
For more information on the motivations for this project, please see my [blog post](https://blog.kellybrazil.com/2019/11/26/bringing-the-unix-philosophy-to-the-21st-century/).
## Installation
There are several ways to get `jc`. You can install via `pip`; other OS package repositories like `zypper`, `nix-env`, `brew`, or `portsnap`; via DEB/RPM packages; or by downloading the correct binary for your architecture and running it anywhere on your filesystem.
There are several ways to get `jc`. You can install via `pip`; other OS package repositories like `dnf`, `zypper`, `nix-env`, `brew`, or `portsnap`; via DEB/RPM packages; or by downloading the correct binary for your architecture and running it anywhere on your filesystem.
### Pip (macOS, linux, unix, Windows)
```
$ pip3 install --upgrade jc
$ pip3 install jc
```
### OS Package Repositories
#### Dnf (Fedora linux)
```
# dnf install jc
```
or
```
# dnf --enablerepo=updates-testing install jc
```
#### Zypper (openSUSE linux)
```
# zypper install jc
```
#### nix-env (NixOS linux)
#### Nix-env (NixOS linux)
```
$ nix-env -iA nixpkgs.jc
```

View File

@@ -1,5 +1,36 @@
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
- Update blkid parser to fix error on parsing empty data
- Update crontab parser to fix error on parsing empty data
- Update crontab_u parser to fix error on parsing empty data
- Update df parser to fix error on parsing empty data
- Update free parser to fix error on parsing empty data
- Update lsblk parser to fix error on parsing empty data
- Update lsmod parser to fix error on parsing empty data
- Update mount parser to fix error on parsing empty data
- Update netstat parser to fix error on parsing empty data
- Update ntpq parser to fix error on parsing empty data
- Update ps parser to fix error on parsing empty data
- Update route parser to fix error on parsing empty data
- Update systemctl parser to fix error on parsing empty data
- Update systemctl_lj parser to fix error on parsing empty data
- Update systemctl_ls parser to fix error on parsing empty data
- Update systemctl_luf parser to fix error on parsing empty data
- Update uptime parser to fix error on parsing empty data
- Update w parser to fix error on parsing empty data
- Update xml parser to fix error on parsing empty data
- Add tests to all parsers for no data condition
- Update ss parser to fix integer fields
20200610 v1.11.4
- Update ls parser to fix error on parsing an empty directory
20200609 v1.11.3
- Add local parser plugin feature (contributed by Dean Serenevy)

View File

@@ -48,3 +48,18 @@ Returns:
no return, just prints output to STDERR
## has_data
```python
has_data(data)
```
Checks if the input contains data. If there are any non-whitespace characters then return True, else return False
Parameters:
data: (string) input to check whether it contains data
Returns:
Boolean True if input string (data) contains non-whitespace characters, otherwise False

View File

@@ -21,7 +21,7 @@ import jc.appdirs as appdirs
class info():
version = '1.11.3'
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.0'
version = '1.2'
description = 'airport -s command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -170,15 +170,17 @@ def parse(data, raw=False, quiet=False):
if not quiet:
jc.utils.compatibility(__name__, info.compatible)
cleandata = data.splitlines()
raw_output = []
cleandata = list(filter(None, data.splitlines()))
# fix headers
cleandata[0] = cleandata[0].lower()
cleandata[0] = cleandata[0].replace('-', '_')
cleandata[0] = cleandata[0].replace('security (auth/unicast/group)', 'security')
if jc.utils.has_data(data):
# fix headers
cleandata[0] = cleandata[0].lower()
cleandata[0] = cleandata[0].replace('-', '_')
cleandata[0] = cleandata[0].replace('security (auth/unicast/group)', 'security')
# parse the data
raw_output = jc.parsers.universal.sparse_table_parse(cleandata)
# parse the data
raw_output = jc.parsers.universal.sparse_table_parse(cleandata)
if raw:
return raw_output

View File

@@ -99,7 +99,7 @@ import jc.parsers.universal
class info():
version = '1.4'
version = '1.6'
description = 'arp command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -171,69 +171,65 @@ def parse(data, raw=False, quiet=False):
if not quiet:
jc.utils.compatibility(__name__, info.compatible)
cleandata = data.splitlines()
raw_output = []
cleandata = list(filter(None, data.splitlines()))
# remove final Entries row if -v was used
if cleandata[-1].startswith('Entries:'):
cleandata.pop(-1)
if jc.utils.has_data(data):
# detect if freebsd/osx style was used
if cleandata[0][-1] == ']':
raw_output = []
for line in cleandata:
splitline = line.split()
output_line = {
'name': splitline[0],
'address': splitline[1].lstrip('(').rstrip(')'),
'hwtype': splitline[-1].lstrip('[').rstrip(']'),
'hwaddress': splitline[3],
'iface': splitline[5]
}
# remove final Entries row if -v was used
if cleandata[-1].startswith('Entries:'):
cleandata.pop(-1)
if 'permanent' in splitline:
output_line['permanent'] = True
# detect if freebsd/osx style was used
if cleandata[0][-1] == ']':
for line in cleandata:
splitline = line.split()
output_line = {
'name': splitline[0],
'address': splitline[1].lstrip('(').rstrip(')'),
'hwtype': splitline[-1].lstrip('[').rstrip(']'),
'hwaddress': splitline[3],
'iface': splitline[5]
}
if 'permanent' in splitline:
output_line['permanent'] = True
else:
output_line['permanent'] = False
if 'expires' in splitline:
output_line['expires'] = splitline[-3]
raw_output.append(output_line)
if raw:
return raw_output
else:
output_line['permanent'] = False
return process(raw_output)
if 'expires' in splitline:
output_line['expires'] = splitline[-3]
# detect if linux style was used
elif cleandata[0].startswith('Address'):
raw_output.append(output_line)
# fix header row to change Flags Mask to flags_mask
cleandata[0] = cleandata[0].replace('Flags Mask', 'flags_mask')
cleandata[0] = cleandata[0].lower()
if raw:
return raw_output
raw_output = jc.parsers.universal.simple_table_parse(cleandata)
# otherwise, try bsd style
else:
return process(raw_output)
for line in cleandata:
line = line.split()
output_line = {
'name': line[0],
'address': line[1].lstrip('(').rstrip(')'),
'hwtype': line[4].lstrip('[').rstrip(']'),
'hwaddress': line[3],
'iface': line[6],
}
raw_output.append(output_line)
# detect if linux style was used
elif cleandata[0].startswith('Address'):
# fix header row to change Flags Mask to flags_mask
cleandata[0] = cleandata[0].replace('Flags Mask', 'flags_mask')
cleandata[0] = cleandata[0].lower()
raw_output = jc.parsers.universal.simple_table_parse(cleandata)
if raw:
return raw_output
else:
return process(raw_output)
# otherwise, try bsd style
if raw:
return raw_output
else:
raw_output = []
for line in cleandata:
line = line.split()
output_line = {
'name': line[0],
'address': line[1].lstrip('(').rstrip(')'),
'hwtype': line[4].lstrip('[').rstrip(']'),
'hwaddress': line[3],
'iface': line[6],
}
raw_output.append(output_line)
if raw:
return raw_output
else:
return process(raw_output)
return process(raw_output)

View File

@@ -79,7 +79,7 @@ import jc.utils
class info():
version = '1.0'
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 data:
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.2'
version = '1.4'
description = 'crontab command and file parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -225,44 +225,46 @@ def parse(data, raw=False, quiet=False):
# Clear any blank lines
cleandata = list(filter(None, cleandata))
# Clear any commented lines
for i, line in reversed(list(enumerate(cleandata))):
if line.strip().startswith('#'):
cleandata.pop(i)
if jc.utils.has_data(data):
# Pop any variable assignment lines
cron_var = []
for i, line in reversed(list(enumerate(cleandata))):
if '=' in line:
var_line = cleandata.pop(i)
var_name = var_line.split('=', maxsplit=1)[0].strip()
var_value = var_line.split('=', maxsplit=1)[1].strip()
cron_var.append({'name': var_name,
'value': var_value})
# Clear any commented lines
for i, line in reversed(list(enumerate(cleandata))):
if line.strip().startswith('#'):
cleandata.pop(i)
raw_output['variables'] = cron_var
# Pop any variable assignment lines
cron_var = []
for i, line in reversed(list(enumerate(cleandata))):
if '=' in line:
var_line = cleandata.pop(i)
var_name = var_line.split('=', maxsplit=1)[0].strip()
var_value = var_line.split('=', maxsplit=1)[1].strip()
cron_var.append({'name': var_name,
'value': var_value})
# Pop any shortcut lines
shortcut_list = []
for i, line in reversed(list(enumerate(cleandata))):
if line.strip().startswith('@'):
shortcut_line = cleandata.pop(i)
occurrence = shortcut_line.split(maxsplit=1)[0].strip().lstrip('@')
cmd = shortcut_line.split(maxsplit=1)[1].strip()
shortcut_list.append({'occurrence': occurrence,
'command': cmd})
raw_output['variables'] = cron_var
# Add header row for parsing
cleandata[:0] = ['minute hour day_of_month month day_of_week command']
# Pop any shortcut lines
shortcut_list = []
for i, line in reversed(list(enumerate(cleandata))):
if line.strip().startswith('@'):
shortcut_line = cleandata.pop(i)
occurrence = shortcut_line.split(maxsplit=1)[0].strip().lstrip('@')
cmd = shortcut_line.split(maxsplit=1)[1].strip()
shortcut_list.append({'occurrence': occurrence,
'command': cmd})
if len(cleandata) > 1:
cron_list = jc.parsers.universal.simple_table_parse(cleandata)
# Add header row for parsing
cleandata[:0] = ['minute hour day_of_month month day_of_week command']
raw_output['schedule'] = cron_list
if len(cleandata) > 1:
cron_list = jc.parsers.universal.simple_table_parse(cleandata)
# Add shortcut entries back in
for item in shortcut_list:
raw_output['schedule'].append(item)
raw_output['schedule'] = cron_list
# Add shortcut entries back in
for item in shortcut_list:
raw_output['schedule'].append(item)
if raw:
return raw_output

View File

@@ -133,7 +133,7 @@ import jc.parsers.universal
class info():
version = '1.1'
version = '1.3'
description = 'crontab file parser with user support'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -226,46 +226,48 @@ def parse(data, raw=False, quiet=False):
# Clear any blank lines
cleandata = list(filter(None, cleandata))
# Clear any commented lines
for i, line in reversed(list(enumerate(cleandata))):
if line.strip().startswith('#'):
cleandata.pop(i)
if jc.utils.has_data(data):
# Pop any variable assignment lines
cron_var = []
for i, line in reversed(list(enumerate(cleandata))):
if '=' in line:
var_line = cleandata.pop(i)
var_name = var_line.split('=', maxsplit=1)[0].strip()
var_value = var_line.split('=', maxsplit=1)[1].strip()
cron_var.append({'name': var_name,
'value': var_value})
# Clear any commented lines
for i, line in reversed(list(enumerate(cleandata))):
if line.strip().startswith('#'):
cleandata.pop(i)
raw_output['variables'] = cron_var
# Pop any variable assignment lines
cron_var = []
for i, line in reversed(list(enumerate(cleandata))):
if '=' in line:
var_line = cleandata.pop(i)
var_name = var_line.split('=', maxsplit=1)[0].strip()
var_value = var_line.split('=', maxsplit=1)[1].strip()
cron_var.append({'name': var_name,
'value': var_value})
# Pop any shortcut lines
shortcut_list = []
for i, line in reversed(list(enumerate(cleandata))):
if line.strip().startswith('@'):
shortcut_line = cleandata.pop(i)
occurrence = shortcut_line.split(maxsplit=1)[0].strip().lstrip('@')
usr = shortcut_line.split(maxsplit=2)[1].strip()
cmd = shortcut_line.split(maxsplit=2)[2].strip()
shortcut_list.append({'occurrence': occurrence,
'user': usr,
'command': cmd})
raw_output['variables'] = cron_var
# Add header row for parsing
cleandata[:0] = ['minute hour day_of_month month day_of_week user command']
# Pop any shortcut lines
shortcut_list = []
for i, line in reversed(list(enumerate(cleandata))):
if line.strip().startswith('@'):
shortcut_line = cleandata.pop(i)
occurrence = shortcut_line.split(maxsplit=1)[0].strip().lstrip('@')
usr = shortcut_line.split(maxsplit=2)[1].strip()
cmd = shortcut_line.split(maxsplit=2)[2].strip()
shortcut_list.append({'occurrence': occurrence,
'user': usr,
'command': cmd})
if len(cleandata) > 1:
cron_list = jc.parsers.universal.simple_table_parse(cleandata)
# Add header row for parsing
cleandata[:0] = ['minute hour day_of_month month day_of_week user command']
raw_output['schedule'] = cron_list
if len(cleandata) > 1:
cron_list = jc.parsers.universal.simple_table_parse(cleandata)
# Add shortcut entries back in
for item in shortcut_list:
raw_output['schedule'].append(item)
raw_output['schedule'] = cron_list
# Add shortcut entries back in
for item in shortcut_list:
raw_output['schedule'].append(item)
if raw:
return raw_output

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.3'
version = '1.5'
description = 'df command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -184,14 +184,17 @@ def parse(data, raw=False, quiet=False):
jc.utils.compatibility(__name__, info.compatible)
cleandata = data.splitlines()
raw_output = []
# fix headers
cleandata[0] = cleandata[0].lower()
cleandata[0] = cleandata[0].replace('-', '_')
cleandata[0] = cleandata[0].replace('mounted on', 'mounted_on')
if jc.utils.has_data(data):
# parse the data
raw_output = jc.parsers.universal.sparse_table_parse(cleandata)
# fix headers
cleandata[0] = cleandata[0].lower()
cleandata[0] = cleandata[0].replace('-', '_')
cleandata[0] = cleandata[0].replace('mounted on', 'mounted_on')
# parse the data
raw_output = jc.parsers.universal.sparse_table_parse(cleandata)
if raw:
return raw_output

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.0'
version = '1.2'
description = 'free command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -122,14 +122,18 @@ def parse(data, raw=False, quiet=False):
jc.utils.compatibility(__name__, info.compatible)
cleandata = data.splitlines()
cleandata[0] = cleandata[0].lower()
cleandata[0] = cleandata[0].replace('buff/cache', 'buff_cache')
cleandata[0] = 'type ' + cleandata[0]
raw_output = []
raw_output = jc.parsers.universal.simple_table_parse(cleandata)
if jc.utils.has_data(data):
for entry in raw_output:
entry['type'] = entry['type'].rstrip(':')
cleandata[0] = cleandata[0].lower()
cleandata[0] = cleandata[0].replace('buff/cache', 'buff_cache')
cleandata[0] = 'type ' + cleandata[0]
raw_output = jc.parsers.universal.simple_table_parse(cleandata)
for entry in raw_output:
entry['type'] = entry['type'].rstrip(':')
if raw:
return raw_output

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.4'
version = '1.6'
description = 'ls command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -226,20 +226,20 @@ def parse(data, raw=False, quiet=False):
linedata = data.splitlines()
# Delete first line if it starts with 'total 1234'
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)
# Look for parent line if glob or -R is used
if not re.match(r'[-dclpsbDCMnP?]([-r][-w][-xsS]){2}([-r][-w][-xtT])[+]?', linedata[0]) \
and linedata[0].endswith(':'):
parent = linedata.pop(0)[:-1]
# Pop following total line if it exists
if re.match(r'total [0-9]+', linedata[0]):
linedata.pop(0)
# Look for parent line if glob or -R is used
if not re.match(r'[-dclpsbDCMnP?]([-r][-w][-xsS]){2}([-r][-w][-xtT])[+]?', linedata[0]) \
and linedata[0].endswith(':'):
parent = linedata.pop(0)[:-1]
# Pop following total line if it exists
if re.match(r'total [0-9]+', linedata[0]):
linedata.pop(0)
if linedata:
# Check if -l was used to parse extra data
if re.match(r'[-dclpsbDCMnP?]([-r][-w][-xsS]){2}([-r][-w][-xtT])[+]?', linedata[0]):
for entry in linedata:

View File

@@ -216,7 +216,7 @@ import jc.parsers.universal
class info():
version = '1.3'
version = '1.5'
description = 'lsblk command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -327,20 +327,23 @@ 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 = data.splitlines()
cleandata = list(filter(None, data.splitlines()))
raw_output = []
cleandata[0] = cleandata[0].lower()
cleandata[0] = cleandata[0].replace(':', '_')
cleandata[0] = cleandata[0].replace('-', '_')
if jc.utils.has_data(data):
raw_output = jc.parsers.universal.sparse_table_parse(cleandata)
cleandata = data.splitlines()
# clean up non-ascii characters, if any
for entry in raw_output:
entry['name'] = entry['name'].encode('ascii', errors='ignore').decode()
cleandata[0] = cleandata[0].lower()
cleandata[0] = cleandata[0].replace(':', '_')
cleandata[0] = cleandata[0].replace('-', '_')
raw_output = jc.parsers.universal.sparse_table_parse(cleandata)
# clean up non-ascii characters, if any
for entry in raw_output:
entry['name'] = entry['name'].encode('ascii', errors='ignore').decode()
if raw:
return raw_output

View File

@@ -107,7 +107,7 @@ import jc.parsers.universal
class info():
version = '1.1'
version = '1.3'
description = 'lsmod command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -175,13 +175,17 @@ def parse(data, raw=False, quiet=False):
jc.utils.compatibility(__name__, info.compatible)
cleandata = data.splitlines()
cleandata[0] = cleandata[0].lower()
raw_output = []
raw_output = jc.parsers.universal.simple_table_parse(cleandata)
if jc.utils.has_data(data):
for mod in raw_output:
if 'by' in mod:
mod['by'] = mod['by'].split(',')
cleandata[0] = cleandata[0].lower()
raw_output = jc.parsers.universal.simple_table_parse(cleandata)
for mod in raw_output:
if 'by' in mod:
mod['by'] = mod['by'].split(',')
if raw:
return raw_output

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.3'
version = '1.5'
description = 'mount command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -158,12 +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 jc.utils.has_data(data):
if cleandata:
# 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.6'
version = '1.8'
description = 'netstat command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -431,29 +431,30 @@ 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 = []
# check for FreeBSD/OSX vs Linux
# is this from FreeBSD/OSX?
if cleandata[0] == 'Active Internet connections' \
or cleandata[0] == 'Active Internet connections (including servers)' \
or cleandata[0] == 'Active Multipath Internet connections' \
or cleandata[0] == 'Active LOCAL (UNIX) domain sockets' \
or cleandata[0] == 'Registered kernel control modules' \
or cleandata[0] == 'Active kernel event sockets' \
or cleandata[0] == 'Active kernel control sockets' \
or cleandata[0] == 'Routing tables' \
or cleandata[0].startswith('Name '):
if jc.utils.has_data(data):
import jc.parsers.netstat_freebsd_osx
raw_output = jc.parsers.netstat_freebsd_osx.parse(cleandata)
# check for FreeBSD/OSX vs Linux
# is this from FreeBSD/OSX?
if cleandata[0] == 'Active Internet connections' \
or cleandata[0] == 'Active Internet connections (including servers)' \
or cleandata[0] == 'Active Multipath Internet connections' \
or cleandata[0] == 'Active LOCAL (UNIX) domain sockets' \
or cleandata[0] == 'Registered kernel control modules' \
or cleandata[0] == 'Active kernel event sockets' \
or cleandata[0] == 'Active kernel control sockets' \
or cleandata[0] == 'Routing tables' \
or cleandata[0].startswith('Name '):
# use linux parser
else:
import jc.parsers.netstat_linux
raw_output = jc.parsers.netstat_linux.parse(cleandata)
import jc.parsers.netstat_freebsd_osx
raw_output = jc.parsers.netstat_freebsd_osx.parse(cleandata)
# use linux parser
else:
import jc.parsers.netstat_linux
raw_output = jc.parsers.netstat_linux.parse(cleandata)
if raw:
return raw_output

View File

@@ -183,7 +183,7 @@ import jc.parsers.universal
class info():
version = '1.1'
version = '1.3'
description = 'ntpq -p command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -268,28 +268,30 @@ def parse(data, raw=False, quiet=False):
if not quiet:
jc.utils.compatibility(__name__, info.compatible)
cleandata = data.splitlines()
raw_output = []
cleandata = data.splitlines()
cleandata[0] = 's ' + cleandata[0]
cleandata[0] = cleandata[0].lower()
if jc.utils.has_data(data):
# delete header delimiter
del cleandata[1]
cleandata[0] = 's ' + cleandata[0]
cleandata[0] = cleandata[0].lower()
# separate first character with a space for easier parsing
for i, line in list(enumerate(cleandata[1:])):
if line[0] == ' ':
# fixup for no-state
cleandata[i + 1] = '~ ' + line[1:]
else:
# fixup - realign columns since we added the 's' column
cleandata[i + 1] = line[:1] + ' ' + line[1:]
# delete header delimiter
del cleandata[1]
# fixup for occaisional ip/hostname fields with a space
cleandata[i + 1] = cleandata[i + 1].replace(' (', '_(')
# separate first character with a space for easier parsing
for i, line in list(enumerate(cleandata[1:])):
if line[0] == ' ':
# fixup for no-state
cleandata[i + 1] = '~ ' + line[1:]
else:
# fixup - realign columns since we added the 's' column
cleandata[i + 1] = line[:1] + ' ' + line[1:]
raw_output = jc.parsers.universal.simple_table_parse(cleandata)
# fixup for occaisional ip/hostname fields with a space
cleandata[i + 1] = cleandata[i + 1].replace(' (', '_(')
raw_output = jc.parsers.universal.simple_table_parse(cleandata)
if raw:
return raw_output

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.1'
version = '1.3'
description = 'pip list command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -88,28 +88,28 @@ 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()))
# detect legacy output type
if ' (' in cleandata[0]:
for row in cleandata:
raw_output.append({'package': row.split(' (')[0],
'version': row.split(' (')[1].rstrip(')')})
if jc.utils.has_data(data):
# otherwise normal table output
else:
# clear separator line
for i, line in reversed(list(enumerate(cleandata))):
if '---' in line:
cleandata.pop(i)
# detect legacy output type
if ' (' in cleandata[0]:
for row in cleandata:
raw_output.append({'package': row.split(' (')[0],
'version': row.split(' (')[1].rstrip(')')})
cleandata[0] = cleandata[0].lower()
# otherwise normal table output
else:
# clear separator line
for i, line in reversed(list(enumerate(cleandata))):
if '---' in line:
cleandata.pop(i)
if cleandata:
raw_output = jc.parsers.universal.simple_table_parse(cleandata)
cleandata[0] = cleandata[0].lower()
if cleandata:
raw_output = jc.parsers.universal.simple_table_parse(cleandata)
if raw:
return raw_output

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.1'
version = '1.3'
description = 'ps command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -282,9 +282,12 @@ def parse(data, raw=False, quiet=False):
jc.utils.compatibility(__name__, info.compatible)
cleandata = data.splitlines()
cleandata[0] = cleandata[0].lower()
raw_output = []
raw_output = jc.parsers.universal.simple_table_parse(cleandata)
if jc.utils.has_data(data):
cleandata[0] = cleandata[0].lower()
raw_output = jc.parsers.universal.simple_table_parse(cleandata)
if raw:
return raw_output

View File

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

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.0'
version = '1.2'
description = 'ss command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -308,17 +308,17 @@ def process(proc_data):
except (ValueError):
entry[key] = None
if 'local_port' in entry:
if 'local_port' in entry:
try:
entry['local_port_num'] = int(entry['local_port'])
except (ValueError):
pass
if 'peer_port' in entry:
try:
entry['peer_port_num'] = int(entry['peer_port'])
except (ValueError):
pass
if 'peer_port' in entry:
try:
entry['peer_port_num'] = int(entry['peer_port'])
except (ValueError):
pass
return proc_data
@@ -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.1'
version = '1.3'
description = 'systemctl command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -96,27 +96,30 @@ 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))
# clean up non-ascii characters, if any
cleandata = []
for entry in linedata:
cleandata.append(entry.encode('ascii', errors='ignore').decode())
header_text = cleandata[0]
header_list = header_text.lower().split()
linedata = list(filter(None, data.splitlines()))
raw_output = []
for entry in cleandata[1:]:
if 'LOAD = ' in entry:
break
if jc.utils.has_data(data):
else:
entry_list = entry.rstrip().split(maxsplit=4)
output_line = dict(zip(header_list, entry_list))
raw_output.append(output_line)
# clean up non-ascii characters, if any
cleandata = []
for entry in linedata:
cleandata.append(entry.encode('ascii', errors='ignore').decode())
header_text = cleandata[0]
header_list = header_text.lower().split()
raw_output = []
for entry in cleandata[1:]:
if 'LOAD = ' in entry:
break
else:
entry_list = entry.rstrip().split(maxsplit=4)
output_line = dict(zip(header_list, entry_list))
raw_output.append(output_line)
if raw:
return raw_output

View File

@@ -59,7 +59,7 @@ import jc.utils
class info():
version = '1.1'
version = '1.3'
description = 'systemctl list-jobs command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -122,28 +122,32 @@ 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))
# clean up non-ascii characters, if any
cleandata = []
for entry in linedata:
cleandata.append(entry.encode('ascii', errors='ignore').decode())
header_text = cleandata[0]
header_text = header_text.lower()
header_list = header_text.split()
linedata = list(filter(None, data.splitlines()))
raw_output = []
for entry in cleandata[1:]:
if 'No jobs running.' in entry or 'jobs listed.' in entry:
break
if jc.utils.has_data(data):
else:
entry_list = entry.split(maxsplit=4)
output_line = dict(zip(header_list, entry_list))
raw_output.append(output_line)
cleandata = []
# clean up non-ascii characters, if any
for entry in linedata:
cleandata.append(entry.encode('ascii', errors='ignore').decode())
header_text = cleandata[0]
header_text = header_text.lower()
header_list = header_text.split()
raw_output = []
for entry in cleandata[1:]:
if 'No jobs running.' in entry or 'jobs listed.' in entry:
break
else:
entry_list = entry.split(maxsplit=4)
output_line = dict(zip(header_list, entry_list))
raw_output.append(output_line)
if raw:
return raw_output

View File

@@ -34,7 +34,7 @@ import jc.utils
class info():
version = '1.1'
version = '1.3'
description = 'systemctl list-sockets command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -88,27 +88,30 @@ 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))
# clean up non-ascii characters, if any
cleandata = []
for entry in linedata:
cleandata.append(entry.encode('ascii', errors='ignore').decode())
header_text = cleandata[0].lower()
header_list = header_text.split()
linedata = list(filter(None, data.splitlines()))
raw_output = []
for entry in cleandata[1:]:
if 'sockets listed.' in entry:
break
if jc.utils.has_data(data):
else:
entry_list = entry.rsplit(maxsplit=2)
output_line = dict(zip(header_list, entry_list))
raw_output.append(output_line)
cleandata = []
# clean up non-ascii characters, if any
for entry in linedata:
cleandata.append(entry.encode('ascii', errors='ignore').decode())
header_text = cleandata[0].lower()
header_list = header_text.split()
raw_output = []
for entry in cleandata[1:]:
if 'sockets listed.' in entry:
break
else:
entry_list = entry.rsplit(maxsplit=2)
output_line = dict(zip(header_list, entry_list))
raw_output.append(output_line)
if raw:
return raw_output

View File

@@ -31,7 +31,7 @@ import jc.utils
class info():
version = '1.1'
version = '1.3'
description = 'systemctl list-unit-files command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -84,28 +84,31 @@ 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))
# clean up non-ascii characters, if any
cleandata = []
for entry in linedata:
cleandata.append(entry.encode('ascii', errors='ignore').decode())
header_text = cleandata[0]
header_text = header_text.lower().replace('unit file', 'unit_file')
header_list = header_text.split()
linedata = list(filter(None, data.splitlines()))
raw_output = []
for entry in cleandata[1:]:
if 'unit files listed.' in entry:
break
if jc.utils.has_data(data):
else:
entry_list = entry.split(maxsplit=4)
output_line = dict(zip(header_list, entry_list))
raw_output.append(output_line)
cleandata = []
# clean up non-ascii characters, if any
for entry in linedata:
cleandata.append(entry.encode('ascii', errors='ignore').decode())
header_text = cleandata[0]
header_text = header_text.lower().replace('unit file', 'unit_file')
header_list = header_text.split()
raw_output = []
for entry in cleandata[1:]:
if 'unit files listed.' in entry:
break
else:
entry_list = entry.split(maxsplit=4)
output_line = dict(zip(header_list, entry_list))
raw_output.append(output_line)
if raw:
return raw_output

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.0'
version = '1.2'
description = 'uptime command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -107,10 +107,10 @@ def parse(data, raw=False, quiet=False):
jc.utils.compatibility(__name__, info.compatible)
raw_output = {}
cleandata = data.splitlines()
if 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.1'
version = '1.3'
description = 'w command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -149,36 +149,40 @@ def parse(data, raw=False, quiet=False):
jc.utils.compatibility(__name__, info.compatible)
cleandata = data.splitlines()[1:]
header_text = cleandata[0].lower()
# fixup for 'from' column that can be blank
from_col = header_text.find('from')
# clean up 'login@' header
# even though @ in a key is valid json, it can make things difficult
header_text = header_text.replace('login@', 'login_at')
headers = [h for h in ' '.join(header_text.strip().split()).split() if h]
# parse lines
raw_output = []
if cleandata:
for entry in cleandata[1:]:
output_line = {}
# normalize data by inserting Null for missing data
temp_line = entry.split(maxsplit=len(headers) - 1)
if jc.utils.has_data(data):
# fix from column, always at column 2
if 'from' in headers:
if entry[from_col] in string.whitespace:
temp_line.insert(2, '-')
header_text = cleandata[0].lower()
# fixup for 'from' column that can be blank
from_col = header_text.find('from')
# clean up 'login@' header
# even though @ in a key is valid json, it can make things difficult
header_text = header_text.replace('login@', 'login_at')
headers = [h for h in ' '.join(header_text.strip().split()).split() if h]
output_line = dict(zip(headers, temp_line))
raw_output.append(output_line)
# parse lines
raw_output = []
if cleandata:
for entry in cleandata[1:]:
output_line = {}
# strip whitespace from beginning and end of all string values
for row in raw_output:
for item in row:
if isinstance(row[item], str):
row[item] = row[item].strip()
# normalize data by inserting Null for missing data
temp_line = entry.split(maxsplit=len(headers) - 1)
# fix from column, always at column 2
if 'from' in headers:
if entry[from_col] in string.whitespace:
temp_line.insert(2, '-')
output_line = dict(zip(headers, temp_line))
raw_output.append(output_line)
# strip whitespace from beginning and end of all string values
for row in raw_output:
for item in row:
if isinstance(row[item], str):
row[item] = row[item].strip()
if raw:
return raw_output

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.0'
version = '1.2'
description = 'XML file parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -111,7 +111,10 @@ def parse(data, raw=False, quiet=False):
if not quiet:
jc.utils.compatibility(__name__, info.compatible)
if data:
raw_output = []
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,18 @@ 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):
"""
Checks if the input contains data. If there are any non-whitespace characters then return True, else return False
Parameters:
data: (string) input to check whether it contains data
Returns:
Boolean True if input string (data) contains non-whitespace characters, otherwise False
"""
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.3',
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.',

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -17,6 +17,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/airport-I.json'), 'r', encoding='utf-8') as f:
self.osx_10_14_6_airport_I_json = json.loads(f.read())
def test_airport_I_nodata(self):
"""
Test 'airport -I' with no data
"""
self.assertEqual(jc.parsers.airport.parse('', quiet=True), {})
def test_airport_I_osx_10_14_6(self):
"""
Test 'airport -I' on OSX 10.14.6

View File

@@ -17,6 +17,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/airport-s.json'), 'r', encoding='utf-8') as f:
self.osx_10_14_6_airport_s_json = json.loads(f.read())
def test_airport_s_nodata(self):
"""
Test 'airport -s' with no data
"""
self.assertEqual(jc.parsers.airport_s.parse('', quiet=True), [])
def test_airport_s_osx_10_14_6(self):
"""
Test 'airport -s' on OSX 10.14.6

View File

@@ -71,6 +71,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/freebsd12/arp-a.json'), 'r', encoding='utf-8') as f:
self.freebsd12_arp_a_json = json.loads(f.read())
def test_arp_nodata(self):
"""
Test 'arp' with no data
"""
self.assertEqual(jc.parsers.arp.parse('', quiet=True), [])
def test_arp_centos_7_7(self):
"""
Test 'arp' on Centos 7.7

View File

@@ -71,6 +71,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/blkid-ip-udev-multi.json'), 'r', encoding='utf-8') as f:
self.ubuntu_18_4_blkid_ip_udev_multi_json = json.loads(f.read())
def test_blkid_nodata(self):
"""
Test 'blkid' with no data
"""
self.assertEqual(jc.parsers.blkid.parse('', quiet=True), [])
def test_blkid_centos_7_7(self):
"""
Test 'blkid' on Centos 7.7

View File

@@ -17,6 +17,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/crontab.json'), 'r', encoding='utf-8') as f:
self.centos_7_7_crontab_json = json.loads(f.read())
def test_crontab_nodata(self):
"""
Test 'crontab' with no data
"""
self.assertEqual(jc.parsers.crontab.parse('', quiet=True), {})
def test_crontab_centos_7_7(self):
"""
Test 'crontab' on Centos 7.7

View File

@@ -23,6 +23,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/crontab-u.json'), 'r', encoding='utf-8') as f:
self.centos_7_7_crontab_u_json = json.loads(f.read())
def test_crontab_u_nodata(self):
"""
Test 'crontab' with no data (has a user field)
"""
self.assertEqual(jc.parsers.crontab_u.parse('', quiet=True), {})
def test_crontab_u_ubuntu_18_4(self):
"""
Test 'crontab' on Ubuntu 18.4 (has a user field)

View File

@@ -65,6 +65,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/csv-insurance.json'), 'r', encoding='utf-8') as f:
self.generic_csv_insurance_json = json.loads(f.read())
def test_csv_nodata(self):
"""
Test with no data
"""
self.assertEqual(jc.parsers.csv.parse('', quiet=True), [])
def test_csv_biostats(self):
"""
Test 'biostats.csv' file

View File

@@ -59,6 +59,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/df-h.json'), 'r', encoding='utf-8') as f:
self.osx_10_14_6_df_h_json = json.loads(f.read())
def test_df_nodata(self):
"""
Test plain 'df' with no data
"""
self.assertEqual(jc.parsers.df.parse('', quiet=True), [])
def test_df_centos_7_7(self):
"""
Test plain 'df' on Centos 7.7

View File

@@ -101,6 +101,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/dig-axfr.json'), 'r', encoding='utf-8') as f:
self.osx_10_14_6_dig_axfr_json = json.loads(f.read())
def test_dig_nodata(self):
"""
Test 'dig' with no data
"""
self.assertEqual(jc.parsers.dig.parse('', quiet=True), [])
def test_dig_centos_7_7(self):
"""
Test 'dig' on Centos 7.7

View File

@@ -29,6 +29,11 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/fedora32/dmidecode.json'), 'r', encoding='utf-8') as f:
self.fedora32_dmidecode_json = json.loads(f.read())
def test_dmidecode_nodata(self):
"""
Test 'dmidecode' with no data
"""
self.assertEqual(jc.parsers.dmidecode.parse('', quiet=True), [])
def test_dmidecode_centos_7_7(self):
"""

View File

@@ -35,6 +35,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/du.json'), 'r', encoding='utf-8') as f:
self.osx_10_14_6_du_json = json.loads(f.read())
def test_du_nodata(self):
"""
Test 'du' with no data
"""
self.assertEqual(jc.parsers.du.parse('', quiet=True), [])
def test_du_centos_7_7(self):
"""
Test 'du' on Centos 7.7

View File

@@ -23,6 +23,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/env.json'), 'r', encoding='utf-8') as f:
self.ubuntu_18_4_env_json = json.loads(f.read())
def test_env_nodata(self):
"""
Test 'env' with no data
"""
self.assertEqual(jc.parsers.env.parse('', quiet=True), [])
def test_env_centos_7_7(self):
"""
Test 'env' on Centos 7.7

View File

@@ -35,6 +35,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/file2.json'), 'r', encoding='utf-8') as f:
self.osx_10_14_6_file2_json = json.loads(f.read())
def test_file_nodata(self):
"""
Test 'file' with no data
"""
self.assertEqual(jc.parsers.file.parse('', quiet=True), [])
def test_file_centos_7_7(self):
"""
Test 'file *' on Centos 7.7

View File

@@ -35,6 +35,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/free-h.json'), 'r', encoding='utf-8') as f:
self.ubuntu_18_4_free_h_json = json.loads(f.read())
def test_free_nodata(self):
"""
Test 'free' with no data
"""
self.assertEqual(jc.parsers.free.parse('', quiet=True), [])
def test_free_centos_7_7(self):
"""
Test 'free' on Centos 7.7

View File

@@ -23,6 +23,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/fstab.json'), 'r', encoding='utf-8') as f:
self.ubuntu_18_4_fstab_json = json.loads(f.read())
def test_fstab_nodata(self):
"""
Test 'cat /etc/fstab' with no data
"""
self.assertEqual(jc.parsers.fstab.parse('', quiet=True), [])
def test_fstab_centos_7_7(self):
"""
Test 'cat /etc/fstab' on Centos 7.7

View File

@@ -29,6 +29,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/group.json'), 'r', encoding='utf-8') as f:
self.osx_10_14_6_group_json = json.loads(f.read())
def test_group_nodata(self):
"""
Test 'cat /etc/group' with no data
"""
self.assertEqual(jc.parsers.group.parse('', quiet=True), [])
def test_group_centos_7_7(self):
"""
Test 'cat /etc/group' on Centos 7.7

View File

@@ -23,6 +23,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/gshadow.json'), 'r', encoding='utf-8') as f:
self.ubuntu_18_4_gshadow_json = json.loads(f.read())
def test_gshadow_nodata(self):
"""
Test 'cat /etc/gshadow' with no data
"""
self.assertEqual(jc.parsers.gshadow.parse('', quiet=True), [])
def test_gshadow_centos_7_7(self):
"""
Test 'cat /etc/gshadow' on Centos 7.7

View File

@@ -23,6 +23,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/history.json'), 'r', encoding='utf-8') as f:
self.ubuntu_18_4_history_json = json.loads(f.read())
def test_history_nodata(self):
"""
Test 'history' with no data
"""
self.assertEqual(jc.parsers.history.parse('', quiet=True), [])
def test_history_centos_7_7(self):
"""
Test 'history' on Centos 7.7

View File

@@ -23,6 +23,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/hosts.json'), 'r', encoding='utf-8') as f:
self.ubuntu_18_4_hosts_json = json.loads(f.read())
def test_hosts_nodata(self):
"""
Test 'cat /etc/hosts' with no data
"""
self.assertEqual(jc.parsers.hosts.parse('', quiet=True), [])
def test_hosts_centos_7_7(self):
"""
Test 'cat /etc/hosts' on Centos 7.7

View File

@@ -23,6 +23,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/id.json'), 'r', encoding='utf-8') as f:
self.osx_10_14_6_id_json = json.loads(f.read())
def test_id_nodata(self):
"""
Test 'id' with no data
"""
self.assertEqual(jc.parsers.id.parse('', quiet=True), {})
def test_id_centos_7_7(self):
"""
Test 'id' on Centos 7.7

View File

@@ -47,6 +47,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/ifconfig2.json'), 'r', encoding='utf-8') as f:
self.osx_10_14_6_ifconfig2_json = json.loads(f.read())
def test_ifconfig_nodata(self):
"""
Test 'ifconfig' with no data
"""
self.assertEqual(jc.parsers.ifconfig.parse('', quiet=True), [])
def test_ifconfig_centos_7_7(self):
"""
Test 'ifconfig' on Centos 7.7

View File

@@ -23,6 +23,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/ini-iptelserver.json'), 'r', encoding='utf-8') as f:
self.generic_ini_iptelserver_json = json.loads(f.read())
def test_ini_nodata(self):
"""
Test the test ini file with no data
"""
self.assertEqual(jc.parsers.ini.parse('', quiet=True), {})
def test_ini_test(self):
"""
Test the test ini file

View File

@@ -83,6 +83,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/iptables-raw.json'), 'r', encoding='utf-8') as f:
self.ubuntu_18_4_iptables_raw_json = json.loads(f.read())
def test_iptables_nodata(self):
"""
Test 'sudo iptables' with no data
"""
self.assertEqual(jc.parsers.iptables.parse('', quiet=True), [])
def test_iptables_filter_centos_7_7(self):
"""
Test 'sudo iptables -L -t filter' on Centos 7.7

View File

@@ -23,6 +23,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/jobs.json'), 'r', encoding='utf-8') as f:
self.ubuntu_18_4_jobs_json = json.loads(f.read())
def test_jobs_nodata(self):
"""
Test 'jobs' with no data
"""
self.assertEqual(jc.parsers.jobs.parse('', quiet=True), [])
def test_jobs_centos_7_7(self):
"""
Test 'jobs' on Centos 7.7

View File

@@ -65,6 +65,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/freebsd12/last.json'), 'r', encoding='utf-8') as f:
self.freebsd12_last_json = json.loads(f.read())
def test_last_nodata(self):
"""
Test plain 'last' with no data
"""
self.assertEqual(jc.parsers.last.parse('', quiet=True), [])
def test_last_centos_7_7(self):
"""
Test plain 'last' on Centos 7.7

View File

@@ -215,6 +215,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/ls-lR-empty-folder.json'), 'r', encoding='utf-8') as f:
self.osx_10_14_6_ls_lR_empty_folder_json = json.loads(f.read())
def test_ls_empty_dir(self):
"""
Test plain 'ls' on an empty directory
"""
self.assertEqual(jc.parsers.ls.parse('', quiet=True), [])
def test_ls_centos_7_7(self):
"""
Test plain 'ls /' on Centos 7.7

View File

@@ -35,6 +35,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/lsblk-allcols.json'), 'r', encoding='utf-8') as f:
self.ubuntu_18_4_lsblk_allcols_json = json.loads(f.read())
def test_lsblk_nodata(self):
"""
Test 'lsblk' with no data
"""
self.assertEqual(jc.parsers.lsblk.parse('', quiet=True), [])
def test_lsblk_centos_7_7(self):
"""
Test 'lsblk' on Centos 7.7

View File

@@ -23,6 +23,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/lsmod.json'), 'r', encoding='utf-8') as f:
self.ubuntu_18_4_lsmod_json = json.loads(f.read())
def test_lsmod_nodata(self):
"""
Test 'lsmod' with no data
"""
self.assertEqual(jc.parsers.lsmod.parse('', quiet=True), [])
def test_lsmod_centos_7_7(self):
"""
Test 'lsmod' on Centos 7.7

View File

@@ -35,6 +35,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/lsof-sudo.json'), 'r', encoding='utf-8') as f:
self.ubuntu_18_4_lsof_sudo_json = json.loads(f.read())
def test_lsof_nodata(self):
"""
Test 'lsof' with no data
"""
self.assertEqual(jc.parsers.lsof.parse('', quiet=True), [])
def test_lsof_centos_7_7(self):
"""
Test 'lsof' on Centos 7.7

View File

@@ -35,6 +35,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/mount2.json'), 'r', encoding='utf-8') as f:
self.osx_10_14_6_mount2_json = json.loads(f.read())
def test_mount_nodata(self):
"""
Test 'mount' with no data
"""
self.assertEqual(jc.parsers.mount.parse('', quiet=True), [])
def test_mount_centos_7_7(self):
"""
Test 'mount' on Centos 7.7

View File

@@ -227,6 +227,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/freebsd12/netstat-ib.json'), 'r', encoding='utf-8') as f:
self.freebsd12_netstat_ib_json = json.loads(f.read())
def test_netstat_nodata(self):
"""
Test 'netstat' with no data
"""
self.assertEqual(jc.parsers.netstat.parse('', quiet=True), [])
def test_netstat_centos_7_7(self):
"""
Test 'netstat' on Centos 7.7

View File

@@ -47,6 +47,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/freebsd12/ntpq-p.json'), 'r', encoding='utf-8') as f:
self.freebsd12_ntpq_p_json = json.loads(f.read())
def test_ntpq_p_nodata(self):
"""
Test 'ntpq -p' with no data
"""
self.assertEqual(jc.parsers.ntpq.parse('', quiet=True), [])
def test_ntpq_p_centos_7_7(self):
"""
Test 'ntpq -p' on Centos 7.7

View File

@@ -29,6 +29,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/passwd.json'), 'r', encoding='utf-8') as f:
self.osx_10_14_6_passwd_json = json.loads(f.read())
def test_passwd_nodata(self):
"""
Test 'cat /etc/passwd' with no data
"""
self.assertEqual(jc.parsers.passwd.parse('', quiet=True), [])
def test_passwd_centos_7_7(self):
"""
Test 'cat /etc/passwd' on Centos 7.7

View File

@@ -41,6 +41,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/pip-list.json'), 'r', encoding='utf-8') as f:
self.osx_10_14_6_pip_list_json = json.loads(f.read())
def test_pip_list_nodata(self):
"""
Test 'pip_list' with no data
"""
self.assertEqual(jc.parsers.pip_list.parse('', quiet=True), [])
def test_pip_list_centos_7_7(self):
"""
Test 'pip_list' on Centos 7.7

View File

@@ -35,6 +35,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/pip-show.json'), 'r', encoding='utf-8') as f:
self.osx_10_14_6_pip_show_json = json.loads(f.read())
def test_pip_show_nodata(self):
"""
Test 'pip show' with no data
"""
self.assertEqual(jc.parsers.pip_show.parse('', quiet=True), [])
def test_pip_show_centos_7_7(self):
"""
Test 'pip show' on Centos 7.7

View File

@@ -59,6 +59,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/ps-axu.json'), 'r', encoding='utf-8') as f:
self.osx_10_14_6_ps_axu_json = json.loads(f.read())
def test_ps_nodata(self):
"""
Test 'ps' with no data
"""
self.assertEqual(jc.parsers.ps.parse('', quiet=True), [])
def test_ps_ef_centos_7_7(self):
"""
Test 'ps -ef' on Centos 7.7

View File

@@ -41,6 +41,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/nixos/route-ee.json'), 'r', encoding='utf-8') as f:
self.nixos_route_ee_json = json.loads(f.read())
def test_route_nodata(self):
"""
Test 'route' with no data
"""
self.assertEqual(jc.parsers.route.parse('', quiet=True), [])
def test_route_centos_7_7(self):
"""
Test 'route' on Centos 7.7

View File

@@ -23,6 +23,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/shadow.json'), 'r', encoding='utf-8') as f:
self.ubuntu_18_4_shadow_json = json.loads(f.read())
def test_shadow_nodata(self):
"""
Test 'cat /etc/shadow' with no data
"""
self.assertEqual(jc.parsers.shadow.parse('', quiet=True), [])
def test_shadow_centos_7_7(self):
"""
Test 'cat /etc/shadow' on Centos 7.7

View File

@@ -23,6 +23,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/ss-sudo-a.json'), 'r', encoding='utf-8') as f:
self.ubuntu_18_4_ss_sudo_a_json = json.loads(f.read())
def test_ss_nodata(self):
"""
Test 'ss' with no data
"""
self.assertEqual(jc.parsers.ss.parse('', quiet=True), [])
def test_ss_sudo_a_centos_7_7(self):
"""
Test 'sudo ss -a' on Centos 7.7

View File

@@ -35,6 +35,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/freebsd12/stat.json'), 'r', encoding='utf-8') as f:
self.freebsd12_stat_json = json.loads(f.read())
def test_stat_nodata(self):
"""
Test 'stat' with no data
"""
self.assertEqual(jc.parsers.stat.parse('', quiet=True), [])
def test_stat_centos_7_7(self):
"""
Test 'stat /bin/*' on Centos 7.7

Some files were not shown because too many files have changed in this diff Show More