1
0
mirror of https://github.com/kellyjonbrazil/jc.git synced 2025-07-13 01:20:24 +02:00

add finger parser

This commit is contained in:
Kelly Brazil
2021-04-05 17:09:22 -07:00
parent 6fe175344f
commit fd1ca82d86
5 changed files with 263 additions and 0 deletions

View File

@ -143,6 +143,7 @@ The JSON output can be compact (default) or pretty formatted with the `-p` optio
- `--du` enables the `du` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/du))
- `--env` enables the `env` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/env))
- `--file` enables the `file` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/file))
- `--finger` enables the `finger` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/finger))
- `--free` enables the `free` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/free))
- `--fstab` enables the `/etc/fstab` file parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/fstab))
- `--group` enables the `/etc/group` file parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/group))

102
docs/parsers/finger.md Normal file
View File

@ -0,0 +1,102 @@
# jc.parsers.finger
jc - JSON CLI output utility `finger` command output parser
<<Short finger description and caveats>>
Usage (cli):
$ finger | jc --finger
or
$ jc finger
Usage (module):
import jc.parsers.finger
result = jc.parsers.finger.parse(finger_command_output)
Compatibility:
'linux', 'darwin', 'cygwin', 'aix', 'freebsd'
Examples:
$ finger | jc --finger -p
[
{
"login": "jdoe",
"name": "John Doe",
"tty": "*tty1",
"idle": "13d",
"login_time": "Mar 22 21:14"
},
{
"login": "jdoe",
"name": "John Doe",
"tty": "pts/0",
"idle": null,
"login_time": "Apr 5 15:33",
"details": "(192.168.1.22)"
}
]
## info
```python
info()
```
## process
```python
process(proc_data)
```
Final processing to conform to the schema.
Parameters:
proc_data: (List of Dictionaries) raw structured data to process
Returns:
List of Dictionaries. Structured data with the following schema:
[
{
"login": "kbrazil",
"name": "Kelly Brazil",
"tty": "*tty1",
"idle": "13d",
"login_time": "Mar 22 21:14"
},
{
"login": "kbrazil",
"name": "Kelly Brazil",
"tty": "pts/0",
"idle": null,
"login_time": "Apr 5 15:33",
"details": "(192.168.1.221)"
}
]
## parse
```python
parse(data, raw=False, quiet=False)
```
Main text parsing function
Parameters:
data: (string) text data to parse
raw: (boolean) output preprocessed JSON if True
quiet: (boolean) suppress warning messages if True
Returns:
List of Dictionaries. Raw or processed structured data.

View File

@ -57,6 +57,7 @@ parsers = [
'du',
'env',
'file',
'finger',
'free',
'fstab',
'group',

154
jc/parsers/finger.py Normal file
View File

@ -0,0 +1,154 @@
"""jc - JSON CLI output utility `finger` command output parser
<<Short finger description and caveats>>
Usage (cli):
$ finger | jc --finger
or
$ jc finger
Usage (module):
import jc.parsers.finger
result = jc.parsers.finger.parse(finger_command_output)
Compatibility:
'linux', 'darwin', 'cygwin', 'aix', 'freebsd'
Examples:
$ finger | jc --finger -p
[
{
"login": "jdoe",
"name": "John Doe",
"tty": "*tty1",
"idle": "13d",
"login_time": "Mar 22 21:14"
},
{
"login": "jdoe",
"name": "John Doe",
"tty": "pts/0",
"idle": null,
"login_time": "Apr 5 15:33",
"details": "(192.168.1.22)"
}
]
"""
import re
import jc.utils
import jc.parsers.universal
class info():
version = '1.0'
description = '`finger` command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
# details = 'enter any other details here'
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
compatible = ['linux', 'darwin', 'cygwin', 'aix', 'freebsd']
magic_commands = ['finger']
__version__ = info.version
def process(proc_data):
"""
Final processing to conform to the schema.
Parameters:
proc_data: (List of Dictionaries) raw structured data to process
Returns:
List of Dictionaries. Structured data with the following schema:
[
{
"login": "kbrazil",
"name": "Kelly Brazil",
"tty": "*tty1",
"idle": "13d",
"login_time": "Mar 22 21:14"
},
{
"login": "kbrazil",
"name": "Kelly Brazil",
"tty": "pts/0",
"idle": null,
"login_time": "Apr 5 15:33",
"details": "(192.168.1.221)"
}
]
"""
# rebuild output for added semantic information
return proc_data
def parse(data, raw=False, quiet=False):
"""
Main text parsing function
Parameters:
data: (string) text data to parse
raw: (boolean) output preprocessed JSON if True
quiet: (boolean) suppress warning messages if True
Returns:
List of Dictionaries. Raw or processed structured data.
"""
if not quiet:
jc.utils.compatibility(__name__, info.compatible)
raw_output = []
if jc.utils.has_data(data):
# Finger output is an abomination that is nearly unparsable. But there is a way:
# First find the location of the last character of 'Idle' in the table and cut
# all lines at that spot. Data before that spot can use the unviversal.sparse_table_parse function.
# All data after that spot can be run through regex to find the login datetime and possibly
# other fields.
data_lines = list(filter(None, data.splitlines()))
sep_col = data_lines[0].find('Idle') + 4
first_half = []
second_half = []
for line in data_lines:
first_half.append(line[:sep_col])
second_half.append(line[sep_col:])
first_half[0] = first_half[0].lower()
# parse the first half
raw_output = jc.parsers.universal.sparse_table_parse(first_half)
# use regex to get login datetime and 'other' data
pattern = re.compile(r'([A-Z][a-z]{2}\s+\d{1,2}\s+\d\d:\d\d)(\s+\S+)?')
# remove header row from list
second_half.pop(0)
for index, line in enumerate(second_half):
dt = re.search(pattern, line)
if dt.group(1):
raw_output[index]['login_time'] = dt.group(1).strip()
if dt.group(2):
raw_output[index]['details'] = dt.group(2).strip()
if raw:
return raw_output
else:
return process(raw_output)

View File

@ -107,6 +107,11 @@ CSV file parser
\fB--file\fP
`file` command parser
.TP
.B
\fB--finger\fP
`finger` command parser
.TP
.B
\fB--free\fP