mirror of
https://github.com/kellyjonbrazil/jc.git
synced 2026-04-03 17:44:07 +02:00
Compare commits
318 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2bccd14c5d | ||
|
|
0d4823c9de | ||
|
|
2a14f56b72 | ||
|
|
fe49759598 | ||
|
|
ee737a59eb | ||
|
|
517ab10930 | ||
|
|
604fb574be | ||
|
|
a254ee8d88 | ||
|
|
f784a7a76d | ||
|
|
2e33afbe18 | ||
|
|
103bb174fc | ||
|
|
2a76a64fa1 | ||
|
|
c8fb56c601 | ||
|
|
e835227027 | ||
|
|
88ffcaee56 | ||
|
|
a9ba98847c | ||
|
|
2630049ab7 | ||
|
|
47c7e081f3 | ||
|
|
ef7f755614 | ||
|
|
32bd7ffbf6 | ||
|
|
347097a294 | ||
|
|
356857f5d6 | ||
|
|
ee12c52291 | ||
|
|
0e7ebf4dc1 | ||
|
|
f1e0cec9d6 | ||
|
|
d96a2a8623 | ||
|
|
1b1bc46222 | ||
|
|
d5a8b4eed2 | ||
|
|
5ddd4f0e86 | ||
|
|
8b94c326de | ||
|
|
29b012e66d | ||
|
|
572a3207cd | ||
|
|
2a88f2be6b | ||
|
|
3de6eac1ad | ||
|
|
f44260603e | ||
|
|
1c60f5355e | ||
|
|
40fa78a966 | ||
|
|
71db67ef49 | ||
|
|
1cd723b48f | ||
|
|
82ee4d7b30 | ||
|
|
dfd19f38f3 | ||
|
|
2358c883d0 | ||
|
|
79e4f3a761 | ||
|
|
5be45622cc | ||
|
|
5f4136b943 | ||
|
|
941bfe2724 | ||
|
|
3ed44a26d9 | ||
|
|
b7270517bd | ||
|
|
bf63ac93c6 | ||
|
|
1cb80f15c2 | ||
|
|
b5c22c6e53 | ||
|
|
7951366117 | ||
|
|
c78a4bb655 | ||
|
|
8aceda18b9 | ||
|
|
e0c75a9b6b | ||
|
|
fd283f6cf7 | ||
|
|
b881ad4ec0 | ||
|
|
2fcb32e26f | ||
|
|
13a802225b | ||
|
|
88649a4e8d | ||
|
|
5c6fa5bff6 | ||
|
|
b70025d6d6 | ||
|
|
59b89ecbd4 | ||
|
|
8f7502ff0f | ||
|
|
249d93f15c | ||
|
|
b0cf2e2d78 | ||
|
|
264fcd40ad | ||
|
|
54def8ef49 | ||
|
|
63c271b837 | ||
|
|
741b2d1c1d | ||
|
|
47d4335890 | ||
|
|
81f721f1ab | ||
|
|
c4e1068895 | ||
|
|
a77bb4165a | ||
|
|
3cd2dce496 | ||
|
|
46a8978740 | ||
|
|
3161c48939 | ||
|
|
a89a9187f8 | ||
|
|
d9e0aa5b93 | ||
|
|
d298e101e9 | ||
|
|
cea975d7f1 | ||
|
|
1ed69f9e6a | ||
|
|
ab0e05ec82 | ||
|
|
c16cce4bf0 | ||
|
|
d3489536a1 | ||
|
|
041050ce28 | ||
|
|
7de1a8a5d6 | ||
|
|
d4604743d1 | ||
|
|
0b8fb31298 | ||
|
|
dcdd79e28c | ||
|
|
5291baeb8e | ||
|
|
6867102c66 | ||
|
|
36ed2c7e2e | ||
|
|
4ab0aba9d3 | ||
|
|
e643badaf7 | ||
|
|
d96e96219e | ||
|
|
e42af3353e | ||
|
|
4ec2b16f42 | ||
|
|
0a028456bf | ||
|
|
a1f10928e1 | ||
|
|
eae1d4b89a | ||
|
|
d3c7cec333 | ||
|
|
36fa08d711 | ||
|
|
a9958841e4 | ||
|
|
504ad81a01 | ||
|
|
8bf2f4f4d0 | ||
|
|
805397ea18 | ||
|
|
1b3985c2d7 | ||
|
|
f602043642 | ||
|
|
1a1aa8fda3 | ||
|
|
3249a017ae | ||
|
|
84f0246b2d | ||
|
|
1c795982b0 | ||
|
|
c5164b4108 | ||
|
|
dc3716ecb3 | ||
|
|
c5165ccc21 | ||
|
|
5b2035e0e6 | ||
|
|
5205154aaf | ||
|
|
f500de3af6 | ||
|
|
4b028b5080 | ||
|
|
4cd721be85 | ||
|
|
d58ca402a7 | ||
|
|
5386879040 | ||
|
|
f19a1f23a9 | ||
|
|
5023e5be4c | ||
|
|
5527d22459 | ||
|
|
9d567c2e70 | ||
|
|
39c03a15d5 | ||
|
|
5e6d2562f9 | ||
|
|
7009d5a014 | ||
|
|
42f9ddabb9 | ||
|
|
30efb5afc0 | ||
|
|
786dc76c09 | ||
|
|
fc48874a5d | ||
|
|
67164e7b23 | ||
|
|
3db9774ac6 | ||
|
|
03aef93d9a | ||
|
|
9b7e3de3ed | ||
|
|
291b6b061a | ||
|
|
08496533e2 | ||
|
|
f8dceb5046 | ||
|
|
240ed4047f | ||
|
|
0bf6f7cd7c | ||
|
|
313bd86e3e | ||
|
|
56259d5605 | ||
|
|
8a4885c1fe | ||
|
|
5b06f84917 | ||
|
|
37a1428914 | ||
|
|
bff065daf3 | ||
|
|
c60d899f31 | ||
|
|
fb7c390506 | ||
|
|
22afb69573 | ||
|
|
be51304c9c | ||
|
|
44f83d800f | ||
|
|
bf07973d90 | ||
|
|
11e94b686c | ||
|
|
c68bf674a1 | ||
|
|
dbbc310082 | ||
|
|
e861f4a597 | ||
|
|
049e93707c | ||
|
|
164294ecb7 | ||
|
|
22ef489795 | ||
|
|
8f9d650f6c | ||
|
|
7e134a63bd | ||
|
|
9b5c25cb5b | ||
|
|
894946b207 | ||
|
|
92ad2068db | ||
|
|
59662a1500 | ||
|
|
125b88a2ca | ||
|
|
79fce8c769 | ||
|
|
a4a53f8b3b | ||
|
|
743e1ae90f | ||
|
|
dbcff80907 | ||
|
|
6e10965aed | ||
|
|
0c8c4a9c53 | ||
|
|
7632541a1e | ||
|
|
a213ad9a85 | ||
|
|
15ac5a9004 | ||
|
|
0658668eb0 | ||
|
|
ccef69ac37 | ||
|
|
64676fda2e | ||
|
|
6ea2d776ae | ||
|
|
98ced9616c | ||
|
|
ae19183803 | ||
|
|
8536514baf | ||
|
|
81982a9f79 | ||
|
|
1acbb2f096 | ||
|
|
80fb4d40a5 | ||
|
|
c972dd1aac | ||
|
|
9dde65c25c | ||
|
|
7486b0c7cd | ||
|
|
5c7a520a0b | ||
|
|
193ddf71f8 | ||
|
|
c46fe9816c | ||
|
|
aada5f0794 | ||
|
|
5c7bf363a6 | ||
|
|
00b74be540 | ||
|
|
96cb01f57a | ||
|
|
adf5f403ae | ||
|
|
1c09c95c71 | ||
|
|
64f442d743 | ||
|
|
cd8d43446b | ||
|
|
7361eac1a4 | ||
|
|
9d41f0a938 | ||
|
|
00274c15df | ||
|
|
d0b8a91f94 | ||
|
|
098e8dbef6 | ||
|
|
ec29b8bbc6 | ||
|
|
1d8f83b8c6 | ||
|
|
12c4419c6a | ||
|
|
b134c53f33 | ||
|
|
23ff19fdb5 | ||
|
|
7a43ba631b | ||
|
|
2beb26f3e3 | ||
|
|
4b55f49e99 | ||
|
|
c0239a771c | ||
|
|
bc4738e900 | ||
|
|
1c76caf59b | ||
|
|
0679951d4a | ||
|
|
df7aee9e4b | ||
|
|
a8d97a2521 | ||
|
|
9370b336d8 | ||
|
|
118f98222a | ||
|
|
dc997821f4 | ||
|
|
aef0fdb435 | ||
|
|
21ee3c0e78 | ||
|
|
d6c665f74b | ||
|
|
79305a50d0 | ||
|
|
e758aa41ef | ||
|
|
910cb34b09 | ||
|
|
976fea4eb2 | ||
|
|
81447ec9e6 | ||
|
|
61b8e9f7b5 | ||
|
|
8e86a04448 | ||
|
|
f23715a783 | ||
|
|
fa693a8bb1 | ||
|
|
103168c25b | ||
|
|
ae7ed4eec5 | ||
|
|
caa516db72 | ||
|
|
f05c3d6113 | ||
|
|
5d872b1535 | ||
|
|
1559cd9f5c | ||
|
|
a5a87c7da1 | ||
|
|
0e6cec62c1 | ||
|
|
3bb1d89165 | ||
|
|
f5f5f102fb | ||
|
|
0c82fe7e4d | ||
|
|
13ffe8a84d | ||
|
|
4c6eebaa33 | ||
|
|
f8fbb2dce2 | ||
|
|
dbfe682674 | ||
|
|
2a148d44a1 | ||
|
|
0648d2e9e3 | ||
|
|
ac9128fa0c | ||
|
|
4d7a872670 | ||
|
|
07f716b254 | ||
|
|
b0d6a7307c | ||
|
|
53ad793ff8 | ||
|
|
ea4332d8e4 | ||
|
|
5c5ff9324f | ||
|
|
2ab6352fdb | ||
|
|
56dcbaf40c | ||
|
|
029b5abcac | ||
|
|
32521ac91a | ||
|
|
bf88407902 | ||
|
|
63cf47db63 | ||
|
|
9970866b3b | ||
|
|
d61941b276 | ||
|
|
081fdb8026 | ||
|
|
f64dfbf79d | ||
|
|
5fb73f4ad5 | ||
|
|
1c16d32420 | ||
|
|
e367e0d714 | ||
|
|
4046649e32 | ||
|
|
77fcfe439c | ||
|
|
71d1355419 | ||
|
|
d1b270f336 | ||
|
|
9190a08332 | ||
|
|
3fae50e305 | ||
|
|
3582497ed4 | ||
|
|
19a67daabf | ||
|
|
02a7e5fd8a | ||
|
|
df72b16022 | ||
|
|
61bdc13810 | ||
|
|
1350a34316 | ||
|
|
7cfe68b96a | ||
|
|
7a93a61f54 | ||
|
|
362977e598 | ||
|
|
5cac897beb | ||
|
|
cad94cc6b3 | ||
|
|
fe4e429e85 | ||
|
|
d83b10e2d5 | ||
|
|
bd2a757fcd | ||
|
|
358b69a4cb | ||
|
|
08821a1454 | ||
|
|
90277c1d87 | ||
|
|
a51e702f77 | ||
|
|
466e37128b | ||
|
|
f1ea61388f | ||
|
|
72c11fda3a | ||
|
|
d6645983ef | ||
|
|
01e911ecdb | ||
|
|
12c0b3d889 | ||
|
|
c1075e40b7 | ||
|
|
fabe3f01b7 | ||
|
|
3a2ff61899 | ||
|
|
aeff94d272 | ||
|
|
c94f5d83fa | ||
|
|
b0756fa0f9 | ||
|
|
6c85abd57b | ||
|
|
7659ae94bd | ||
|
|
e306e81e43 | ||
|
|
6d5768b26b | ||
|
|
cee9f8bf32 | ||
|
|
b8e2678c01 | ||
|
|
b0fe96ed03 | ||
|
|
bb65ec380b | ||
|
|
ae6248227b |
4
.github/workflows/pythonapp.yml
vendored
4
.github/workflows/pythonapp.yml
vendored
@@ -14,12 +14,12 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-latest, ubuntu-20.04, windows-latest]
|
||||
python-version: ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11"]
|
||||
python-version: ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: "Set up timezone to America/Los_Angeles"
|
||||
uses: szenius/set-timezone@v1.0
|
||||
uses: szenius/set-timezone@v1.2
|
||||
with:
|
||||
timezoneLinux: "America/Los_Angeles"
|
||||
timezoneMacos: "America/Los_Angeles"
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -6,3 +6,4 @@ build/
|
||||
.github/
|
||||
.vscode/
|
||||
_config.yml
|
||||
.venv
|
||||
|
||||
107
CHANGELOG
107
CHANGELOG
@@ -1,5 +1,112 @@
|
||||
jc changelog
|
||||
|
||||
20231216 v1.24.0
|
||||
- Add `debconf-show` command parser
|
||||
- Add `iftop` command parser
|
||||
- Add `pkg-index-apk` parser for Alpine Linux Package Index files
|
||||
- Add `pkg-index-deb` parser for Debian/Ubuntu Package Index files
|
||||
- Add `proc-cmdline` parser for `/proc/cmdline` file
|
||||
- Add `swapon` command parser
|
||||
- Add `tune2fs` command parser
|
||||
- Remove `iso-datetime` parser deprecated since v1.22.1. (use `datetime-iso` instead)
|
||||
- Update timezone change in Github Actions for node v16 requirement
|
||||
- Add Python 3.12 tests to Github Actions
|
||||
- Refactor `acpi` command parser for code cleanup
|
||||
- Refactor vendored libraries to remove Python 2 support
|
||||
- Fix `iptables` parser for cases where the `target` field is blank in a rule
|
||||
- Fix `vmstat` parsers for some cases where wide output is used
|
||||
- Fix `mount` parser for cases with spaces in the mount point name
|
||||
- Fix `xrandr` parser for infinite loop issues
|
||||
|
||||
20231023 v1.23.6
|
||||
- Fix XML parser for xmltodict library versions < 0.13.0
|
||||
- Fix `who` command parser for cases when the from field contains spaces
|
||||
|
||||
20231021 v1.23.5
|
||||
- Add `host` command parser
|
||||
- Add `nsd-control` command parser
|
||||
- Add `lsb_release` command parser
|
||||
- Add `/etc/os-release` file parser
|
||||
- Enhance `env` command parser to support multi-line values
|
||||
- Enhance `ping` and `ping-s` parsers to add error and corrupted support
|
||||
- Enhance `xml` parser to include comments in the JSON output
|
||||
- Fix `pidstat` command parser when using `-T ALL`
|
||||
- Fix `x509-cert` parser to allow negative serial numbers
|
||||
- Fix `x509-cert` parser for cases when bitstrings are larger than standard
|
||||
- Fix `xrandr` command parser for associated device issues
|
||||
- Fix error when pygments library is not installed
|
||||
|
||||
20230730 v1.23.4
|
||||
- Add `/etc/resolve.conf` file parser
|
||||
- Add `/proc/net/tcp` and `/proc/net/tcp6` file parser
|
||||
- Add `find` command parser
|
||||
- Add `ip route` command parser
|
||||
- Fix `certbot` command parser to be more robust with different line endings
|
||||
|
||||
20230621 v1.23.3
|
||||
- Add `lsattr` command parser
|
||||
- Add `srt` file parser
|
||||
- Add `veracrypt` command parser
|
||||
- Add X509 Certificate Request file parser
|
||||
- Enhance X509 Certificate parser to allow non-compliant email addresses with a warning
|
||||
- Enhance `dig` command parser to support the `+nsid` option
|
||||
- Enhance `last` and `lastb` command parser to support the `-x` option
|
||||
- Enhance `route` command parser to add Windows support
|
||||
- Enhnace `netstat` command parser to add Windows support
|
||||
- Enhance `ss` command parser to support extended options
|
||||
- Enhance the compatibility warning message
|
||||
- Fix `bluetoothctl` command parser for some mouse devices
|
||||
- Fix `ping` command parsers for output with missing hostname
|
||||
- Fix `stat` command parser for older versions that may not contain all fields
|
||||
- Fix deprecated option in `setup.cfg`
|
||||
|
||||
20230429 v1.23.2
|
||||
- Add `bluetoothctl` command parser
|
||||
- Add `certbot` command parser for `certificates` and `show_account` options
|
||||
- Fix `acpi` command parser for "Not charging" battery status lines
|
||||
- Fix `iwconfig` command parser for SSIDs with dashes in the name
|
||||
- Fix `crontab` command parsers for incorrect variable parsing in some cases
|
||||
- Fix `git-log` and `git-log-s` command parsers for incorrect insertion/deletion parsing
|
||||
- Fix `ufw-appinfo` command parser for parsing errors on multiline description fields
|
||||
- Fix pytest warnings
|
||||
|
||||
20230323 v1.23.1
|
||||
- Fix `zpool-status` command parser for lines that start with tab
|
||||
- Fix `timedatectl` command parser when RTC set to local
|
||||
- Fix to ensure `py.typed` file is included in the package wheel
|
||||
- Fix `lsusb` command parser to support CDC MBIM and CDC MBIM Extended fields
|
||||
- Add support for the `timesync-status` for the `timedatectl` command parser
|
||||
- Fix to ignore non-parser-plugins in the parser plugin directory
|
||||
|
||||
20230227 v1.23.0
|
||||
- Add input slicing as a `jc` command-line option
|
||||
- Add `ssh` configuration file parser
|
||||
- Add `ver` Version string parser
|
||||
- Add `zpool iostat` command parser
|
||||
- Add `zpool status` command parser
|
||||
- Fix `acpi` command parser for "will never fully discharge" battery state
|
||||
- Fix `crontab` and `crontab-u` command and file parsers for cases where only
|
||||
shortcut schedule items exist
|
||||
- Fix `ifconfig` command parser for older-style linux output
|
||||
- Fix `xrandr` command parser for proper `is_current` output
|
||||
- Fix `xrandr` command parser for infinite loop with some device configurations
|
||||
- Add `reflection` key to `xrandr` parser schema
|
||||
- Add display model info from EDID to `xrandr` parser
|
||||
- Add `MPX-specific VMA` support for VM Flags in `/proc/<pid>/smaps` parser
|
||||
|
||||
20230111 v1.22.5
|
||||
- Add TOML file parser
|
||||
- Add INI with duplicate key support file parser
|
||||
- Add AIX support for the `arp` command parser
|
||||
- Add AIX support for the `mount` command parser
|
||||
- Fix `lsusb` command parser when extra hub port status information is output
|
||||
- Refactor `lsusb` command parser for more code reuse
|
||||
- Fix INI file parser to include top-level values with no section header
|
||||
- Fix INI file parser to not specially handle the [DEFAULT] section
|
||||
- Fix INI file and Key/Value parsers to only remove one quotation mark from the
|
||||
beginning and end of values.
|
||||
- Update copyright dates
|
||||
|
||||
20221230 v1.22.4
|
||||
- Add `iwconfig` command parser
|
||||
- Add NeXTSTEP format support to the PLIST file parser
|
||||
|
||||
67
EXAMPLES.md
67
EXAMPLES.md
@@ -1636,21 +1636,21 @@ cat example.ini | jc --ini -p
|
||||
```
|
||||
```json
|
||||
{
|
||||
"bitbucket.org": {
|
||||
"ServeraLiveInterval": "45",
|
||||
"DEFAULT": {
|
||||
"ServerAliveInterval": "45",
|
||||
"Compression": "yes",
|
||||
"CompressionLevel": "9",
|
||||
"ForwardX11": "yes",
|
||||
"ForwardX11": "yes"
|
||||
},
|
||||
"bitbucket.org": {
|
||||
"User": "hg"
|
||||
},
|
||||
"topsecret.server.com": {
|
||||
"ServeraLiveInterval": "45",
|
||||
"Compression": "yes",
|
||||
"CompressionLevel": "9",
|
||||
"ForwardX11": "no",
|
||||
"Port": "50022"
|
||||
"Port": "50022",
|
||||
"ForwardX11": "no"
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
### iostat
|
||||
```bash
|
||||
@@ -4551,6 +4551,57 @@ cat entrust.pem | jc --x509-cert -p
|
||||
}
|
||||
]
|
||||
```
|
||||
### X.509 PEM and DER certificate request files
|
||||
```bash
|
||||
cat myserver.csr | jc --x509-csr -p
|
||||
```
|
||||
```json
|
||||
[
|
||||
{
|
||||
"certification_request_info": {
|
||||
"version": "v1",
|
||||
"subject": {
|
||||
"common_name": "myserver.for.example"
|
||||
},
|
||||
"subject_pk_info": {
|
||||
"algorithm": {
|
||||
"algorithm": "ec",
|
||||
"parameters": "secp256r1"
|
||||
},
|
||||
"public_key": "04:40:33:c0:91:8f:e9:46:ea:d0:dc:d0:f9:63:2c:a4:35:1f:0f:54:c8:a9:9b:e3:9e:d4:f3:64:b8:60:cc:7f:39:75:dd:a7:61:31:02:7c:9e:89:c6:db:45:15:f2:5f:b0:65:29:0b:42:d2:6e:c2:ea:a6:23:bd:fc:65:e5:7d:4e"
|
||||
},
|
||||
"attributes": [
|
||||
{
|
||||
"type": "extension_request",
|
||||
"values": [
|
||||
[
|
||||
{
|
||||
"extn_id": "extended_key_usage",
|
||||
"critical": false,
|
||||
"extn_value": [
|
||||
"server_auth"
|
||||
]
|
||||
},
|
||||
{
|
||||
"extn_id": "subject_alt_name",
|
||||
"critical": false,
|
||||
"extn_value": [
|
||||
"myserver.for.example"
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"signature_algorithm": {
|
||||
"algorithm": "sha384_ecdsa",
|
||||
"parameters": null
|
||||
},
|
||||
"signature": "30:45:02:20:77:ac:5b:51:bf:c5:f5:43:02:52:ae:66:8a:fe:95:98:98:98:a9:45:34:31:08:ff:2c:cc:92:d9:1c:70:28:74:02:21:00:97:79:7b:e7:45:18:76:cf:d7:3b:79:34:56:d2:69:b5:73:41:9b:8a:b7:ad:ec:80:23:c1:2f:64:da:e5:28:19"
|
||||
}
|
||||
]
|
||||
```
|
||||
### XML files
|
||||
```bash
|
||||
cat cd_catalog.xml
|
||||
|
||||
409
README.md
409
README.md
@@ -3,13 +3,15 @@
|
||||
|
||||
> Check out the `jc` Python [package documentation](https://github.com/kellyjonbrazil/jc/tree/master/docs) for developers
|
||||
|
||||
> Try the `jc` [web demo](https://jc-web.onrender.com/)
|
||||
> Try the `jc` [web demo](https://jc-web.onrender.com/) and [REST API](https://github.com/kellyjonbrazil/jc-restapi)
|
||||
|
||||
> JC is [now available](https://galaxy.ansible.com/community/general) as an
|
||||
> `jc` is [now available](https://galaxy.ansible.com/community/general) as an
|
||||
Ansible filter plugin in the `community.general` collection. See this
|
||||
[blog post](https://blog.kellybrazil.com/2020/08/30/parsing-command-output-in-ansible-with-jc/)
|
||||
for an example.
|
||||
|
||||
> Looking for something like `jc` but lower-level? Check out [regex2json](https://gitlab.com/tozd/regex2json).
|
||||
|
||||
# JC
|
||||
JSON Convert
|
||||
|
||||
@@ -44,8 +46,8 @@ $ jc dig example.com | jq -r '.[].answer[].data'
|
||||
93.184.216.34
|
||||
```
|
||||
|
||||
`jc` can also be used as a python library. In this case the output will be
|
||||
a python dictionary, a list of dictionaries, or even a
|
||||
`jc` can also be used as a python library. In this case the returned value
|
||||
will be a python dictionary, a list of dictionaries, or even a
|
||||
[lazy iterable of dictionaries](#using-streaming-parsers-as-python-modules)
|
||||
instead of JSON:
|
||||
```python
|
||||
@@ -118,6 +120,7 @@ pip3 install jc
|
||||
| NixOS linux | `nix-env -iA nixpkgs.jc` or `nix-env -iA nixos.jc` |
|
||||
| Guix System linux | `guix install jc` |
|
||||
| Gentoo Linux | `emerge dev-python/jc` |
|
||||
| Photon linux | `tdnf install jc` |
|
||||
| macOS | `brew install jc` |
|
||||
| FreeBSD | `portsnap fetch update && cd /usr/ports/textproc/py-jc && make install clean` |
|
||||
| Ansible filter plugin | `ansible-galaxy collection install community.general` |
|
||||
@@ -133,9 +136,9 @@ on Github.
|
||||
`jc` accepts piped input from `STDIN` and outputs a JSON representation of the
|
||||
previous command's output to `STDOUT`.
|
||||
```bash
|
||||
COMMAND | jc [OPTIONS] PARSER
|
||||
cat FILE | jc [OPTIONS] PARSER
|
||||
echo STRING | jc [OPTIONS] PARSER
|
||||
COMMAND | jc [SLICE] [OPTIONS] PARSER
|
||||
cat FILE | jc [SLICE] [OPTIONS] PARSER
|
||||
echo STRING | jc [SLICE] [OPTIONS] PARSER
|
||||
```
|
||||
|
||||
Alternatively, the "magic" syntax can be used by prepending `jc` to the command
|
||||
@@ -143,8 +146,8 @@ to be converted or in front of the absolute path for Proc files. Options can be
|
||||
passed to `jc` immediately before the command or Proc file path is given.
|
||||
(Note: command aliases and shell builtins are not supported)
|
||||
```bash
|
||||
jc [OPTIONS] COMMAND
|
||||
jc [OPTIONS] /proc/<path-to-procfile>
|
||||
jc [SLICE] [OPTIONS] COMMAND
|
||||
jc [SLICE] [OPTIONS] /proc/<path-to-procfile>
|
||||
```
|
||||
|
||||
The JSON output can be compact (default) or pretty formatted with the `-p`
|
||||
@@ -154,141 +157,165 @@ option.
|
||||
|
||||
| Argument | Command or Filetype | Documentation |
|
||||
|-------------------|---------------------------------------------------------|----------------------------------------------------------------------------|
|
||||
| ` --acpi` | `acpi` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/acpi) |
|
||||
| ` --airport` | `airport -I` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/airport) |
|
||||
| ` --airport-s` | `airport -s` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/airport_s) |
|
||||
| ` --arp` | `arp` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/arp) |
|
||||
| ` --asciitable` | ASCII and Unicode table parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/asciitable) |
|
||||
| ` --asciitable-m` | multi-line ASCII and Unicode table parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/asciitable_m) |
|
||||
| ` --blkid` | `blkid` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/blkid) |
|
||||
| ` --cbt` | `cbt` (Google Bigtable) command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/cbt) |
|
||||
| ` --cef` | CEF string parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/cef) |
|
||||
| ` --cef-s` | CEF string streaming parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/cef_s) |
|
||||
| ` --chage` | `chage --list` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/chage) |
|
||||
| ` --cksum` | `cksum` and `sum` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/cksum) |
|
||||
| ` --clf` | Common and Combined Log Format file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/clf) |
|
||||
| ` --clf-s` | Common and Combined Log Format file streaming parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/clf_s) |
|
||||
| ` --crontab` | `crontab` command and file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/crontab) |
|
||||
| ` --crontab-u` | `crontab` file parser with user support | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/crontab_u) |
|
||||
| ` --csv` | CSV file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/csv) |
|
||||
| ` --csv-s` | CSV file streaming parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/csv_s) |
|
||||
| ` --date` | `date` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/date) |
|
||||
| ` --datetime-iso` | ISO 8601 Datetime string parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/datetime_iso) |
|
||||
| ` --df` | `df` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/df) |
|
||||
| ` --dig` | `dig` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/dig) |
|
||||
| ` --dir` | `dir` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/dir) |
|
||||
| ` --dmidecode` | `dmidecode` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/dmidecode) |
|
||||
| ` --dpkg-l` | `dpkg -l` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/dpkg_l) |
|
||||
| ` --du` | `du` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/du) |
|
||||
| `--acpi` | `acpi` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/acpi) |
|
||||
| `--airport` | `airport -I` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/airport) |
|
||||
| `--airport-s` | `airport -s` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/airport_s) |
|
||||
| `--arp` | `arp` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/arp) |
|
||||
| `--asciitable` | ASCII and Unicode table parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/asciitable) |
|
||||
| `--asciitable-m` | multi-line ASCII and Unicode table parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/asciitable_m) |
|
||||
| `--blkid` | `blkid` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/blkid) |
|
||||
| `--bluetoothctl` | `bluetoothctl` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/bluetoothctl) |
|
||||
| `--cbt` | `cbt` (Google Bigtable) command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/cbt) |
|
||||
| `--cef` | CEF string parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/cef) |
|
||||
| `--cef-s` | CEF string streaming parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/cef_s) |
|
||||
| `--certbot` | `certbot` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/certbot) |
|
||||
| `--chage` | `chage --list` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/chage) |
|
||||
| `--cksum` | `cksum` and `sum` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/cksum) |
|
||||
| `--clf` | Common and Combined Log Format file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/clf) |
|
||||
| `--clf-s` | Common and Combined Log Format file streaming parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/clf_s) |
|
||||
| `--crontab` | `crontab` command and file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/crontab) |
|
||||
| `--crontab-u` | `crontab` file parser with user support | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/crontab_u) |
|
||||
| `--csv` | CSV file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/csv) |
|
||||
| `--csv-s` | CSV file streaming parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/csv_s) |
|
||||
| `--date` | `date` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/date) |
|
||||
| `--datetime-iso` | ISO 8601 Datetime string parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/datetime_iso) |
|
||||
| `--debconf-show` | `debconf-show` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/debconf_show) |
|
||||
| `--df` | `df` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/df) |
|
||||
| `--dig` | `dig` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/dig) |
|
||||
| `--dir` | `dir` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/dir) |
|
||||
| `--dmidecode` | `dmidecode` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/dmidecode) |
|
||||
| `--dpkg-l` | `dpkg -l` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/dpkg_l) |
|
||||
| `--du` | `du` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/du) |
|
||||
| `--email-address` | Email Address string parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/email_address) |
|
||||
| ` --env` | `env` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/env) |
|
||||
| ` --file` | `file` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/file) |
|
||||
| ` --findmnt` | `findmnt` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/findmnt) |
|
||||
| ` --finger` | `finger` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/finger) |
|
||||
| ` --free` | `free` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/free) |
|
||||
| ` --fstab` | `/etc/fstab` file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/fstab) |
|
||||
| ` --git-log` | `git log` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/git_log) |
|
||||
| ` --git-log-s` | `git log` command streaming parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/git_log_s) |
|
||||
| `--env` | `env` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/env) |
|
||||
| `--file` | `file` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/file) |
|
||||
| `--find` | `find` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/find) |
|
||||
| `--findmnt` | `findmnt` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/findmnt) |
|
||||
| `--finger` | `finger` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/finger) |
|
||||
| `--free` | `free` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/free) |
|
||||
| `--fstab` | `/etc/fstab` file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/fstab) |
|
||||
| `--git-log` | `git log` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/git_log) |
|
||||
| `--git-log-s` | `git log` command streaming parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/git_log_s) |
|
||||
| `--git-ls-remote` | `git ls-remote` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/git_ls_remote) |
|
||||
| ` --gpg` | `gpg --with-colons` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/gpg) |
|
||||
| ` --group` | `/etc/group` file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/group) |
|
||||
| ` --gshadow` | `/etc/gshadow` file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/gshadow) |
|
||||
| ` --hash` | `hash` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/hash) |
|
||||
| ` --hashsum` | hashsum command parser (`md5sum`, `shasum`, etc.) | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/hashsum) |
|
||||
| ` --hciconfig` | `hciconfig` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/hciconfig) |
|
||||
| ` --history` | `history` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/history) |
|
||||
| ` --hosts` | `/etc/hosts` file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/hosts) |
|
||||
| ` --id` | `id` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/id) |
|
||||
| ` --ifconfig` | `ifconfig` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/ifconfig) |
|
||||
| ` --ini` | INI file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/ini) |
|
||||
| ` --iostat` | `iostat` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/iostat) |
|
||||
| ` --iostat-s` | `iostat` command streaming parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/iostat_s) |
|
||||
| ` --ip-address` | IPv4 and IPv6 Address string parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/ip_address) |
|
||||
| ` --iptables` | `iptables` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/iptables) |
|
||||
| ` --iw-scan` | `iw dev [device] scan` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/iw_scan) |
|
||||
| ` --iwconfig` | `iwconfig` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/iwconfig) |
|
||||
| ` --jar-manifest` | Java MANIFEST.MF file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/jar_manifest) |
|
||||
| ` --jobs` | `jobs` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/jobs) |
|
||||
| ` --jwt` | JWT string parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/jwt) |
|
||||
| ` --kv` | Key/Value file and string parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/kv) |
|
||||
| ` --last` | `last` and `lastb` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/last) |
|
||||
| ` --ls` | `ls` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/ls) |
|
||||
| ` --ls-s` | `ls` command streaming parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/ls_s) |
|
||||
| ` --lsblk` | `lsblk` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/lsblk) |
|
||||
| ` --lsmod` | `lsmod` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/lsmod) |
|
||||
| ` --lsof` | `lsof` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/lsof) |
|
||||
| ` --lspci` | `lspci -mmv` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/lspci) |
|
||||
| ` --lsusb` | `lsusb` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/lsusb) |
|
||||
| ` --m3u` | M3U and M3U8 file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/m3u) |
|
||||
| ` --mdadm` | `mdadm` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/mdadm) |
|
||||
| ` --mount` | `mount` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/mount) |
|
||||
| ` --mpstat` | `mpstat` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/mpstat) |
|
||||
| ` --mpstat-s` | `mpstat` command streaming parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/mpstat_s) |
|
||||
| ` --netstat` | `netstat` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/netstat) |
|
||||
| ` --nmcli` | `nmcli` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/nmcli) |
|
||||
| ` --ntpq` | `ntpq -p` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/ntpq) |
|
||||
| ` --openvpn` | openvpn-status.log file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/openvpn) |
|
||||
| ` --os-prober` | `os-prober` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/os_prober) |
|
||||
| ` --passwd` | `/etc/passwd` file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/passwd) |
|
||||
| ` --pci-ids` | `pci.ids` file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/pci_ids) |
|
||||
| ` --pgpass` | PostgreSQL password file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/pgpass) |
|
||||
| ` --pidstat` | `pidstat -H` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/pidstat) |
|
||||
| ` --pidstat-s` | `pidstat -H` command streaming parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/pidstat_s) |
|
||||
| ` --ping` | `ping` and `ping6` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/ping) |
|
||||
| ` --ping-s` | `ping` and `ping6` command streaming parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/ping_s) |
|
||||
| ` --pip-list` | `pip list` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/pip_list) |
|
||||
| ` --pip-show` | `pip show` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/pip_show) |
|
||||
| ` --plist` | PLIST file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/plist) |
|
||||
| ` --postconf` | `postconf -M` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/postconf) |
|
||||
| ` --proc` | `/proc/` file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/proc) |
|
||||
| ` --ps` | `ps` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/ps) |
|
||||
| ` --route` | `route` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/route) |
|
||||
| ` --rpm-qi` | `rpm -qi` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/rpm_qi) |
|
||||
| ` --rsync` | `rsync` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/rsync) |
|
||||
| ` --rsync-s` | `rsync` command streaming parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/rsync_s) |
|
||||
| ` --semver` | Semantic Version string parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/semver) |
|
||||
| ` --sfdisk` | `sfdisk` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/sfdisk) |
|
||||
| ` --shadow` | `/etc/shadow` file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/shadow) |
|
||||
| ` --ss` | `ss` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/ss) |
|
||||
| ` --sshd-conf` | sshd config file and `sshd -T` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/sshd_conf) |
|
||||
| ` --stat` | `stat` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/stat) |
|
||||
| ` --stat-s` | `stat` command streaming parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/stat_s) |
|
||||
| ` --sysctl` | `sysctl` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/sysctl) |
|
||||
| ` --syslog` | Syslog RFC 5424 string parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/syslog) |
|
||||
| ` --syslog-s` | Syslog RFC 5424 string streaming parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/syslog_s) |
|
||||
| ` --syslog-bsd` | Syslog RFC 3164 string parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/syslog_bsd) |
|
||||
| ` --syslog-bsd-s` | Syslog RFC 3164 string streaming parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/syslog_bsd_s) |
|
||||
| ` --systemctl` | `systemctl` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/systemctl) |
|
||||
| ` --systemctl-lj` | `systemctl list-jobs` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/systemctl_lj) |
|
||||
| ` --systemctl-ls` | `systemctl list-sockets` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/systemctl_ls) |
|
||||
| `--gpg` | `gpg --with-colons` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/gpg) |
|
||||
| `--group` | `/etc/group` file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/group) |
|
||||
| `--gshadow` | `/etc/gshadow` file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/gshadow) |
|
||||
| `--hash` | `hash` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/hash) |
|
||||
| `--hashsum` | hashsum command parser (`md5sum`, `shasum`, etc.) | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/hashsum) |
|
||||
| `--hciconfig` | `hciconfig` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/hciconfig) |
|
||||
| `--history` | `history` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/history) |
|
||||
| `--host` | `host` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/host) |
|
||||
| `--hosts` | `/etc/hosts` file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/hosts) |
|
||||
| `--id` | `id` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/id) |
|
||||
| `--ifconfig` | `ifconfig` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/ifconfig) |
|
||||
| `--ini` | INI file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/ini) |
|
||||
| `--ini-dup` | INI with duplicate key file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/ini_dup) |
|
||||
| `--iostat` | `iostat` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/iostat) |
|
||||
| `--iostat-s` | `iostat` command streaming parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/iostat_s) |
|
||||
| `--ip-address` | IPv4 and IPv6 Address string parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/ip_address) |
|
||||
| `--iptables` | `iptables` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/iptables) |
|
||||
| `--ip-route` | `ip route` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/ip_route) |
|
||||
| `--iw-scan` | `iw dev [device] scan` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/iw_scan) |
|
||||
| `--iwconfig` | `iwconfig` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/iwconfig) |
|
||||
| `--jar-manifest` | Java MANIFEST.MF file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/jar_manifest) |
|
||||
| `--jobs` | `jobs` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/jobs) |
|
||||
| `--jwt` | JWT string parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/jwt) |
|
||||
| `--kv` | Key/Value file and string parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/kv) |
|
||||
| `--last` | `last` and `lastb` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/last) |
|
||||
| `--ls` | `ls` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/ls) |
|
||||
| `--ls-s` | `ls` command streaming parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/ls_s) |
|
||||
| `--lsattr` | `lsattr` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/lsattr) |
|
||||
| `--lsb-release` | `lsb_release` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/lsb_release) |
|
||||
| `--lsblk` | `lsblk` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/lsblk) |
|
||||
| `--lsmod` | `lsmod` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/lsmod) |
|
||||
| `--lsof` | `lsof` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/lsof) |
|
||||
| `--lspci` | `lspci -mmv` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/lspci) |
|
||||
| `--lsusb` | `lsusb` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/lsusb) |
|
||||
| `--m3u` | M3U and M3U8 file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/m3u) |
|
||||
| `--mdadm` | `mdadm` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/mdadm) |
|
||||
| `--mount` | `mount` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/mount) |
|
||||
| `--mpstat` | `mpstat` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/mpstat) |
|
||||
| `--mpstat-s` | `mpstat` command streaming parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/mpstat_s) |
|
||||
| `--netstat` | `netstat` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/netstat) |
|
||||
| `--nmcli` | `nmcli` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/nmcli) |
|
||||
| `--nsd-control` | `nsd-control` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/nsd_control) |
|
||||
| `--ntpq` | `ntpq -p` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/ntpq) |
|
||||
| `--openvpn` | openvpn-status.log file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/openvpn) |
|
||||
| `--os-prober` | `os-prober` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/os_prober) |
|
||||
| `--os-release` | `/etc/os-release` file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/os_release) |
|
||||
| `--passwd` | `/etc/passwd` file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/passwd) |
|
||||
| `--pci-ids` | `pci.ids` file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/pci_ids) |
|
||||
| `--pgpass` | PostgreSQL password file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/pgpass) |
|
||||
| `--pidstat` | `pidstat -H` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/pidstat) |
|
||||
| `--pidstat-s` | `pidstat -H` command streaming parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/pidstat_s) |
|
||||
| `--ping` | `ping` and `ping6` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/ping) |
|
||||
| `--ping-s` | `ping` and `ping6` command streaming parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/ping_s) |
|
||||
| `--pip-list` | `pip list` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/pip_list) |
|
||||
| `--pip-show` | `pip show` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/pip_show) |
|
||||
| `--pkg-index-apk` | Alpine Linux Package Index file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/pkg_index_apk) |
|
||||
| `--pkg-index-deb` | Debian Package Index file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/pkg_index_deb) |
|
||||
| `--plist` | PLIST file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/plist) |
|
||||
| `--postconf` | `postconf -M` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/postconf) |
|
||||
| `--proc` | `/proc/` file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/proc) |
|
||||
| `--ps` | `ps` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/ps) |
|
||||
| `--resolve-conf` | `/etc/resolve.conf` file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/resolve_conf) |
|
||||
| `--route` | `route` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/route) |
|
||||
| `--rpm-qi` | `rpm -qi` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/rpm_qi) |
|
||||
| `--rsync` | `rsync` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/rsync) |
|
||||
| `--rsync-s` | `rsync` command streaming parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/rsync_s) |
|
||||
| `--semver` | Semantic Version string parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/semver) |
|
||||
| `--sfdisk` | `sfdisk` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/sfdisk) |
|
||||
| `--shadow` | `/etc/shadow` file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/shadow) |
|
||||
| `--srt` | SRT file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/srt) |
|
||||
| `--ss` | `ss` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/ss) |
|
||||
| `--ssh-conf` | `ssh` config file and `ssh -G` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/ssh_conf) |
|
||||
| `--sshd-conf` | `sshd` config file and `sshd -T` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/sshd_conf) |
|
||||
| `--stat` | `stat` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/stat) |
|
||||
| `--stat-s` | `stat` command streaming parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/stat_s) |
|
||||
| `--swapon` | `swapon` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/swapon) |
|
||||
| `--sysctl` | `sysctl` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/sysctl) |
|
||||
| `--syslog` | Syslog RFC 5424 string parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/syslog) |
|
||||
| `--syslog-s` | Syslog RFC 5424 string streaming parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/syslog_s) |
|
||||
| `--syslog-bsd` | Syslog RFC 3164 string parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/syslog_bsd) |
|
||||
| `--syslog-bsd-s` | Syslog RFC 3164 string streaming parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/syslog_bsd_s) |
|
||||
| `--systemctl` | `systemctl` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/systemctl) |
|
||||
| `--systemctl-lj` | `systemctl list-jobs` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/systemctl_lj) |
|
||||
| `--systemctl-ls` | `systemctl list-sockets` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/systemctl_ls) |
|
||||
| `--systemctl-luf` | `systemctl list-unit-files` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/systemctl_luf) |
|
||||
| ` --systeminfo` | `systeminfo` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/systeminfo) |
|
||||
| ` --time` | `/usr/bin/time` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/time) |
|
||||
| ` --timedatectl` | `timedatectl status` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/timedatectl) |
|
||||
| ` --timestamp` | Unix Epoch Timestamp string parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/timestamp) |
|
||||
| ` --top` | `top -b` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/top) |
|
||||
| ` --top-s` | `top -b` command streaming parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/top_s) |
|
||||
| ` --tracepath` | `tracepath` and `tracepath6` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/tracepath) |
|
||||
| ` --traceroute` | `traceroute` and `traceroute6` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/traceroute) |
|
||||
| ` --udevadm` | `udevadm info` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/udevadm) |
|
||||
| ` --ufw` | `ufw status` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/ufw) |
|
||||
| ` --ufw-appinfo` | `ufw app info [application]` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/ufw_appinfo) |
|
||||
| ` --uname` | `uname -a` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/uname) |
|
||||
| `--systeminfo` | `systeminfo` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/systeminfo) |
|
||||
| `--time` | `/usr/bin/time` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/time) |
|
||||
| `--timedatectl` | `timedatectl status` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/timedatectl) |
|
||||
| `--timestamp` | Unix Epoch Timestamp string parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/timestamp) |
|
||||
| `--toml` | TOML file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/toml) |
|
||||
| `--top` | `top -b` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/top) |
|
||||
| `--top-s` | `top -b` command streaming parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/top_s) |
|
||||
| `--tracepath` | `tracepath` and `tracepath6` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/tracepath) |
|
||||
| `--traceroute` | `traceroute` and `traceroute6` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/traceroute) |
|
||||
| `--tune2fs` | `tune2fs -l` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/tune2fs) |
|
||||
| `--udevadm` | `udevadm info` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/udevadm) |
|
||||
| `--ufw` | `ufw status` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/ufw) |
|
||||
| `--ufw-appinfo` | `ufw app info [application]` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/ufw_appinfo) |
|
||||
| `--uname` | `uname -a` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/uname) |
|
||||
| `--update-alt-gs` | `update-alternatives --get-selections` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/update_alt_gs) |
|
||||
| ` --update-alt-q` | `update-alternatives --query` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/update_alt_q) |
|
||||
| ` --upower` | `upower` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/upower) |
|
||||
| ` --uptime` | `uptime` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/uptime) |
|
||||
| ` --url` | URL string parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/url) |
|
||||
| ` --vmstat` | `vmstat` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/vmstat) |
|
||||
| ` --vmstat-s` | `vmstat` command streaming parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/vmstat_s) |
|
||||
| ` --w` | `w` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/w) |
|
||||
| ` --wc` | `wc` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/wc) |
|
||||
| ` --who` | `who` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/who) |
|
||||
| ` --x509-cert` | X.509 PEM and DER certificate file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/x509_cert) |
|
||||
| ` --xml` | XML file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/xml) |
|
||||
| ` --xrandr` | `xrandr` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/xrandr) |
|
||||
| ` --yaml` | YAML file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/yaml) |
|
||||
| ` --zipinfo` | `zipinfo` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/zipinfo) |
|
||||
| `--update-alt-q` | `update-alternatives --query` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/update_alt_q) |
|
||||
| `--upower` | `upower` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/upower) |
|
||||
| `--uptime` | `uptime` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/uptime) |
|
||||
| `--url` | URL string parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/url) |
|
||||
| `--ver` | Version string parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/ver) |
|
||||
| `--veracrypt` | `veracrypt` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/veracrypt) |
|
||||
| `--vmstat` | `vmstat` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/vmstat) |
|
||||
| `--vmstat-s` | `vmstat` command streaming parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/vmstat_s) |
|
||||
| `--w` | `w` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/w) |
|
||||
| `--wc` | `wc` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/wc) |
|
||||
| `--who` | `who` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/who) |
|
||||
| `--x509-cert` | X.509 PEM and DER certificate file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/x509_cert) |
|
||||
| `--x509-csr` | X.509 PEM and DER certificate request file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/x509_csr) |
|
||||
| `--xml` | XML file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/xml) |
|
||||
| `--xrandr` | `xrandr` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/xrandr) |
|
||||
| `--yaml` | YAML file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/yaml) |
|
||||
| `--zipinfo` | `zipinfo` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/zipinfo) |
|
||||
| `--zpool-iostat` | `zpool iostat` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/zpool_iostat) |
|
||||
| `--zpool-status` | `zpool status` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/zpool_status) |
|
||||
|
||||
### Options
|
||||
|
||||
@@ -309,6 +336,54 @@ option.
|
||||
| `-B` | `--bash-comp` | Generate Bash shell completion script ([more info](https://github.com/kellyjonbrazil/jc/wiki/Shell-Completions)) |
|
||||
| `-Z` | `--zsh-comp` | Generate Zsh shell completion script ([more info](https://github.com/kellyjonbrazil/jc/wiki/Shell-Completions)) |
|
||||
|
||||
### Slice
|
||||
Line slicing is supported using the `START:STOP` syntax similar to Python
|
||||
slicing. This allows you to skip lines at the beginning and/or end of the
|
||||
`STDIN` input you would like `jc` to convert.
|
||||
|
||||
`START` and `STOP` can be positive or negative integers or blank and allow
|
||||
you to specify how many lines to skip and how many lines to process.
|
||||
Positive and blank slices are the most memory efficient. Any negative
|
||||
integers in the slice will use more memory.
|
||||
|
||||
For example, to skip the first and last line of the following text, you
|
||||
could express the slice in a couple ways:
|
||||
|
||||
```bash
|
||||
$ cat table.txt
|
||||
### We want to skip this header ###
|
||||
col1 col2
|
||||
foo 1
|
||||
bar 2
|
||||
### We want to skip this footer ###
|
||||
$ cat table.txt | jc 1:-1 --asciitable
|
||||
[{"col1":"foo","col2":"1"},{"col1":"bar","col2":"2"}]
|
||||
$ cat table.txt | jc 1:4 --asciitable
|
||||
[{"col1":"foo","col2":"1"},{"col1":"bar","col2":"2"}]
|
||||
```
|
||||
In this example `1:-1` and `1:4` line slices provide the same output.
|
||||
|
||||
When using positive integers the index location of `STOP` is non-inclusive.
|
||||
Positive slices count from the first line of the input toward the end
|
||||
starting at `0` as the first line. Negative slices count from the last line
|
||||
toward the beginning starting at `-1` as the last line. This is also the way
|
||||
[Python's slicing](https://stackoverflow.com/questions/509211/understanding-slicing)
|
||||
feature works.
|
||||
|
||||
Here is a breakdown of line slice options:
|
||||
|
||||
| Slice Notation | Input Lines Processed |
|
||||
|----------------|--------------------------------------------------------------|
|
||||
| `START:STOP` | lines `START` through `STOP - 1` |
|
||||
| `START:` | lines `START` through the rest of the output |
|
||||
| `:STOP` | lines from the beginning through `STOP - 1` |
|
||||
| `-START:STOP` | `START` lines from the end through `STOP - 1` |
|
||||
| `START:-STOP` | lines `START` through `STOP` lines from the end |
|
||||
| `-START:-STOP` | `START` lines from the end through `STOP` lines from the end |
|
||||
| `-START:` | `START` lines from the end through the rest of the output |
|
||||
| `:-STOP` | lines from the beginning through `STOP` lines from the end |
|
||||
| `:` | all lines |
|
||||
|
||||
### Exit Codes
|
||||
Any fatal errors within `jc` will generate an exit code of `100`, otherwise the
|
||||
exit code will be `0`.
|
||||
@@ -479,20 +554,22 @@ for item in result:
|
||||
print(item["filename"])
|
||||
```
|
||||
|
||||
### Custom Parsers
|
||||
Custom local parser plugins may be placed in a `jc/jcparsers` folder in your
|
||||
local **"App data directory"**:
|
||||
### Parser Plugins
|
||||
Parser plugins may be placed in a `jc/jcparsers` folder in your local
|
||||
**"App data directory"**:
|
||||
|
||||
- Linux/unix: `$HOME/.local/share/jc/jcparsers`
|
||||
- macOS: `$HOME/Library/Application Support/jc/jcparsers`
|
||||
- Windows: `$LOCALAPPDATA\jc\jc\jcparsers`
|
||||
|
||||
Local parser plugins are standard python module files. Use the
|
||||
Parser plugins are standard python module files. Use the
|
||||
[`jc/parsers/foo.py`](https://github.com/kellyjonbrazil/jc/blob/master/jc/parsers/foo.py)
|
||||
or [`jc/parsers/foo_s.py (streaming)`](https://github.com/kellyjonbrazil/jc/blob/master/jc/parsers/foo_s.py)
|
||||
parser as a template and simply place a `.py` file in the `jcparsers` subfolder.
|
||||
Any dependencies can be placed in the `jc` folder above `jcparsers` and can
|
||||
be imported in the parser code.
|
||||
|
||||
Local plugin filenames must be valid python module names and therefore must
|
||||
Parser plugin filenames must be valid python module names and therefore must
|
||||
start with a letter and consist entirely of alphanumerics and underscores.
|
||||
Local plugins may override default parsers.
|
||||
|
||||
@@ -550,7 +627,7 @@ they are run on an unsupported platform. To see all parser information,
|
||||
including compatibility, run `jc -ap`.
|
||||
|
||||
You may still use a parser on an unsupported platform - for example, you may
|
||||
want to parse a file with linux `lsof` output on an macOS or Windows laptop. In
|
||||
want to parse a file with linux `lsof` output on a macOS or Windows laptop. In
|
||||
that case you can suppress the warning message with the `-q` cli option or the
|
||||
`quiet=True` function parameter in `parse()`:
|
||||
|
||||
@@ -756,37 +833,31 @@ ifconfig | jc -p --ifconfig # or: jc -p ifconfig
|
||||
cat example.ini
|
||||
```
|
||||
```
|
||||
[DEFAULT]
|
||||
ServerAliveInterval = 45
|
||||
Compression = yes
|
||||
CompressionLevel = 9
|
||||
ForwardX11 = yes
|
||||
foo = fiz
|
||||
bar = buz
|
||||
|
||||
[bitbucket.org]
|
||||
User = hg
|
||||
[section1]
|
||||
fruit = apple
|
||||
color = blue
|
||||
|
||||
[topsecret.server.com]
|
||||
Port = 50022
|
||||
ForwardX11 = no
|
||||
[section2]
|
||||
fruit = pear
|
||||
color = green
|
||||
```
|
||||
```bash
|
||||
cat example.ini | jc -p --ini
|
||||
```
|
||||
```json
|
||||
{
|
||||
"bitbucket.org": {
|
||||
"ServeraLiveInterval": "45",
|
||||
"Compression": "yes",
|
||||
"CompressionLevel": "9",
|
||||
"ForwardX11": "yes",
|
||||
"User": "hg"
|
||||
"foo": "fiz",
|
||||
"bar": "buz",
|
||||
"section1": {
|
||||
"fruit": "apple",
|
||||
"color": "blue"
|
||||
},
|
||||
"topsecret.server.com": {
|
||||
"ServeraLiveInterval": "45",
|
||||
"Compression": "yes",
|
||||
"CompressionLevel": "9",
|
||||
"ForwardX11": "no",
|
||||
"Port": "50022"
|
||||
"section2": {
|
||||
"fruit": "pear",
|
||||
"color": "green"
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -1242,4 +1313,4 @@ cat istio.yaml | jc -p --yaml
|
||||
]
|
||||
```
|
||||
|
||||
© 2019-2022 Kelly Brazil
|
||||
© 2019-2023 Kelly Brazil
|
||||
@@ -3,8 +3,8 @@ _jc()
|
||||
local cur prev words cword jc_commands jc_parsers jc_options \
|
||||
jc_about_options jc_about_mod_options jc_help_options jc_special_options
|
||||
|
||||
jc_commands=(acpi airport arp blkid cbt chage cksum crontab date df dig dmidecode dpkg du env file findmnt finger free git gpg hciconfig id ifconfig iostat iptables iw iwconfig jobs last lastb ls lsblk lsmod lsof lspci lsusb md5 md5sum mdadm mount mpstat netstat nmcli ntpq os-prober pidstat ping ping6 pip pip3 postconf printenv ps route rpm rsync sfdisk sha1sum sha224sum sha256sum sha384sum sha512sum shasum ss sshd stat sum sysctl systemctl systeminfo timedatectl top tracepath tracepath6 traceroute traceroute6 udevadm ufw uname update-alternatives upower uptime vdir vmstat w wc who xrandr zipinfo)
|
||||
jc_parsers=(--acpi --airport --airport-s --arp --asciitable --asciitable-m --blkid --cbt --cef --cef-s --chage --cksum --clf --clf-s --crontab --crontab-u --csv --csv-s --date --datetime-iso --df --dig --dir --dmidecode --dpkg-l --du --email-address --env --file --findmnt --finger --free --fstab --git-log --git-log-s --git-ls-remote --gpg --group --gshadow --hash --hashsum --hciconfig --history --hosts --id --ifconfig --ini --iostat --iostat-s --ip-address --iptables --iw-scan --iwconfig --jar-manifest --jobs --jwt --kv --last --ls --ls-s --lsblk --lsmod --lsof --lspci --lsusb --m3u --mdadm --mount --mpstat --mpstat-s --netstat --nmcli --ntpq --openvpn --os-prober --passwd --pci-ids --pgpass --pidstat --pidstat-s --ping --ping-s --pip-list --pip-show --plist --postconf --proc --proc-buddyinfo --proc-consoles --proc-cpuinfo --proc-crypto --proc-devices --proc-diskstats --proc-filesystems --proc-interrupts --proc-iomem --proc-ioports --proc-loadavg --proc-locks --proc-meminfo --proc-modules --proc-mtrr --proc-pagetypeinfo --proc-partitions --proc-slabinfo --proc-softirqs --proc-stat --proc-swaps --proc-uptime --proc-version --proc-vmallocinfo --proc-vmstat --proc-zoneinfo --proc-driver-rtc --proc-net-arp --proc-net-dev --proc-net-dev-mcast --proc-net-if-inet6 --proc-net-igmp --proc-net-igmp6 --proc-net-ipv6-route --proc-net-netlink --proc-net-netstat --proc-net-packet --proc-net-protocols --proc-net-route --proc-net-unix --proc-pid-fdinfo --proc-pid-io --proc-pid-maps --proc-pid-mountinfo --proc-pid-numa-maps --proc-pid-smaps --proc-pid-stat --proc-pid-statm --proc-pid-status --ps --route --rpm-qi --rsync --rsync-s --semver --sfdisk --shadow --ss --sshd-conf --stat --stat-s --sysctl --syslog --syslog-s --syslog-bsd --syslog-bsd-s --systemctl --systemctl-lj --systemctl-ls --systemctl-luf --systeminfo --time --timedatectl --timestamp --top --top-s --tracepath --traceroute --udevadm --ufw --ufw-appinfo --uname --update-alt-gs --update-alt-q --upower --uptime --url --vmstat --vmstat-s --w --wc --who --x509-cert --xml --xrandr --yaml --zipinfo)
|
||||
jc_commands=(acpi airport arp blkid bluetoothctl cbt certbot chage cksum crontab date debconf-show df dig dmidecode dpkg du env file findmnt finger free git gpg hciconfig host id ifconfig iostat ip iptables iw iwconfig jobs last lastb ls lsattr lsb_release lsblk lsmod lsof lspci lsusb md5 md5sum mdadm mount mpstat netstat nmcli nsd-control ntpq os-prober pidstat ping ping6 pip pip3 postconf printenv ps route rpm rsync sfdisk sha1sum sha224sum sha256sum sha384sum sha512sum shasum ss ssh sshd stat sum swapon sysctl systemctl systeminfo timedatectl top tracepath tracepath6 traceroute traceroute6 tune2fs udevadm ufw uname update-alternatives upower uptime vdir veracrypt vmstat w wc who xrandr zipinfo zpool)
|
||||
jc_parsers=(--acpi --airport --airport-s --arp --asciitable --asciitable-m --blkid --bluetoothctl --cbt --cef --cef-s --certbot --chage --cksum --clf --clf-s --crontab --crontab-u --csv --csv-s --date --datetime-iso --debconf-show --df --dig --dir --dmidecode --dpkg-l --du --email-address --env --file --find --findmnt --finger --free --fstab --git-log --git-log-s --git-ls-remote --gpg --group --gshadow --hash --hashsum --hciconfig --history --host --hosts --id --ifconfig --ini --ini-dup --iostat --iostat-s --ip-address --iptables --ip-route --iw-scan --iwconfig --jar-manifest --jobs --jwt --kv --last --ls --ls-s --lsattr --lsb-release --lsblk --lsmod --lsof --lspci --lsusb --m3u --mdadm --mount --mpstat --mpstat-s --netstat --nmcli --nsd-control --ntpq --openvpn --os-prober --os-release --passwd --pci-ids --pgpass --pidstat --pidstat-s --ping --ping-s --pip-list --pip-show --pkg-index-apk --pkg-index-deb --plist --postconf --proc --proc-buddyinfo --proc-cmdline --proc-consoles --proc-cpuinfo --proc-crypto --proc-devices --proc-diskstats --proc-filesystems --proc-interrupts --proc-iomem --proc-ioports --proc-loadavg --proc-locks --proc-meminfo --proc-modules --proc-mtrr --proc-pagetypeinfo --proc-partitions --proc-slabinfo --proc-softirqs --proc-stat --proc-swaps --proc-uptime --proc-version --proc-vmallocinfo --proc-vmstat --proc-zoneinfo --proc-driver-rtc --proc-net-arp --proc-net-dev --proc-net-dev-mcast --proc-net-if-inet6 --proc-net-igmp --proc-net-igmp6 --proc-net-ipv6-route --proc-net-netlink --proc-net-netstat --proc-net-packet --proc-net-protocols --proc-net-route --proc-net-tcp --proc-net-unix --proc-pid-fdinfo --proc-pid-io --proc-pid-maps --proc-pid-mountinfo --proc-pid-numa-maps --proc-pid-smaps --proc-pid-stat --proc-pid-statm --proc-pid-status --ps --resolve-conf --route --rpm-qi --rsync --rsync-s --semver --sfdisk --shadow --srt --ss --ssh-conf --sshd-conf --stat --stat-s --swapon --sysctl --syslog --syslog-s --syslog-bsd --syslog-bsd-s --systemctl --systemctl-lj --systemctl-ls --systemctl-luf --systeminfo --time --timedatectl --timestamp --toml --top --top-s --tracepath --traceroute --tune2fs --udevadm --ufw --ufw-appinfo --uname --update-alt-gs --update-alt-q --upower --uptime --url --ver --veracrypt --vmstat --vmstat-s --w --wc --who --x509-cert --x509-csr --xml --xrandr --yaml --zipinfo --zpool-iostat --zpool-status)
|
||||
jc_options=(--force-color -C --debug -d --monochrome -m --meta-out -M --pretty -p --quiet -q --raw -r --unbuffer -u --yaml-out -y)
|
||||
jc_about_options=(--about -a)
|
||||
jc_about_mod_options=(--pretty -p --yaml-out -y --monochrome -m --force-color -C)
|
||||
|
||||
@@ -9,17 +9,20 @@ _jc() {
|
||||
jc_help_options jc_help_options_describe \
|
||||
jc_special_options jc_special_options_describe
|
||||
|
||||
jc_commands=(acpi airport arp blkid cbt chage cksum crontab date df dig dmidecode dpkg du env file findmnt finger free git gpg hciconfig id ifconfig iostat iptables iw iwconfig jobs last lastb ls lsblk lsmod lsof lspci lsusb md5 md5sum mdadm mount mpstat netstat nmcli ntpq os-prober pidstat ping ping6 pip pip3 postconf printenv ps route rpm rsync sfdisk sha1sum sha224sum sha256sum sha384sum sha512sum shasum ss sshd stat sum sysctl systemctl systeminfo timedatectl top tracepath tracepath6 traceroute traceroute6 udevadm ufw uname update-alternatives upower uptime vdir vmstat w wc who xrandr zipinfo)
|
||||
jc_commands=(acpi airport arp blkid bluetoothctl cbt certbot chage cksum crontab date debconf-show df dig dmidecode dpkg du env file findmnt finger free git gpg hciconfig host id ifconfig iostat ip iptables iw iwconfig jobs last lastb ls lsattr lsb_release lsblk lsmod lsof lspci lsusb md5 md5sum mdadm mount mpstat netstat nmcli nsd-control ntpq os-prober pidstat ping ping6 pip pip3 postconf printenv ps route rpm rsync sfdisk sha1sum sha224sum sha256sum sha384sum sha512sum shasum ss ssh sshd stat sum swapon sysctl systemctl systeminfo timedatectl top tracepath tracepath6 traceroute traceroute6 tune2fs udevadm ufw uname update-alternatives upower uptime vdir veracrypt vmstat w wc who xrandr zipinfo zpool)
|
||||
jc_commands_describe=(
|
||||
'acpi:run "acpi" command with magic syntax.'
|
||||
'airport:run "airport" command with magic syntax.'
|
||||
'arp:run "arp" command with magic syntax.'
|
||||
'blkid:run "blkid" command with magic syntax.'
|
||||
'bluetoothctl:run "bluetoothctl" command with magic syntax.'
|
||||
'cbt:run "cbt" command with magic syntax.'
|
||||
'certbot:run "certbot" command with magic syntax.'
|
||||
'chage:run "chage" command with magic syntax.'
|
||||
'cksum:run "cksum" command with magic syntax.'
|
||||
'crontab:run "crontab" command with magic syntax.'
|
||||
'date:run "date" command with magic syntax.'
|
||||
'debconf-show:run "debconf-show" command with magic syntax.'
|
||||
'df:run "df" command with magic syntax.'
|
||||
'dig:run "dig" command with magic syntax.'
|
||||
'dmidecode:run "dmidecode" command with magic syntax.'
|
||||
@@ -33,9 +36,11 @@ _jc() {
|
||||
'git:run "git" command with magic syntax.'
|
||||
'gpg:run "gpg" command with magic syntax.'
|
||||
'hciconfig:run "hciconfig" command with magic syntax.'
|
||||
'host:run "host" command with magic syntax.'
|
||||
'id:run "id" command with magic syntax.'
|
||||
'ifconfig:run "ifconfig" command with magic syntax.'
|
||||
'iostat:run "iostat" command with magic syntax.'
|
||||
'ip:run "ip" command with magic syntax.'
|
||||
'iptables:run "iptables" command with magic syntax.'
|
||||
'iw:run "iw" command with magic syntax.'
|
||||
'iwconfig:run "iwconfig" command with magic syntax.'
|
||||
@@ -43,6 +48,8 @@ _jc() {
|
||||
'last:run "last" command with magic syntax.'
|
||||
'lastb:run "lastb" command with magic syntax.'
|
||||
'ls:run "ls" command with magic syntax.'
|
||||
'lsattr:run "lsattr" command with magic syntax.'
|
||||
'lsb_release:run "lsb_release" command with magic syntax.'
|
||||
'lsblk:run "lsblk" command with magic syntax.'
|
||||
'lsmod:run "lsmod" command with magic syntax.'
|
||||
'lsof:run "lsof" command with magic syntax.'
|
||||
@@ -55,6 +62,7 @@ _jc() {
|
||||
'mpstat:run "mpstat" command with magic syntax.'
|
||||
'netstat:run "netstat" command with magic syntax.'
|
||||
'nmcli:run "nmcli" command with magic syntax.'
|
||||
'nsd-control:run "nsd-control" command with magic syntax.'
|
||||
'ntpq:run "ntpq" command with magic syntax.'
|
||||
'os-prober:run "os-prober" command with magic syntax.'
|
||||
'pidstat:run "pidstat" command with magic syntax.'
|
||||
@@ -76,9 +84,11 @@ _jc() {
|
||||
'sha512sum:run "sha512sum" command with magic syntax.'
|
||||
'shasum:run "shasum" command with magic syntax.'
|
||||
'ss:run "ss" command with magic syntax.'
|
||||
'ssh:run "ssh" command with magic syntax.'
|
||||
'sshd:run "sshd" command with magic syntax.'
|
||||
'stat:run "stat" command with magic syntax.'
|
||||
'sum:run "sum" command with magic syntax.'
|
||||
'swapon:run "swapon" command with magic syntax.'
|
||||
'sysctl:run "sysctl" command with magic syntax.'
|
||||
'systemctl:run "systemctl" command with magic syntax.'
|
||||
'systeminfo:run "systeminfo" command with magic syntax.'
|
||||
@@ -88,6 +98,7 @@ _jc() {
|
||||
'tracepath6:run "tracepath6" command with magic syntax.'
|
||||
'traceroute:run "traceroute" command with magic syntax.'
|
||||
'traceroute6:run "traceroute6" command with magic syntax.'
|
||||
'tune2fs:run "tune2fs" command with magic syntax.'
|
||||
'udevadm:run "udevadm" command with magic syntax.'
|
||||
'ufw:run "ufw" command with magic syntax.'
|
||||
'uname:run "uname" command with magic syntax.'
|
||||
@@ -95,14 +106,16 @@ _jc() {
|
||||
'upower:run "upower" command with magic syntax.'
|
||||
'uptime:run "uptime" command with magic syntax.'
|
||||
'vdir:run "vdir" command with magic syntax.'
|
||||
'veracrypt:run "veracrypt" command with magic syntax.'
|
||||
'vmstat:run "vmstat" command with magic syntax.'
|
||||
'w:run "w" command with magic syntax.'
|
||||
'wc:run "wc" command with magic syntax.'
|
||||
'who:run "who" command with magic syntax.'
|
||||
'xrandr:run "xrandr" command with magic syntax.'
|
||||
'zipinfo:run "zipinfo" command with magic syntax.'
|
||||
'zpool:run "zpool" command with magic syntax.'
|
||||
)
|
||||
jc_parsers=(--acpi --airport --airport-s --arp --asciitable --asciitable-m --blkid --cbt --cef --cef-s --chage --cksum --clf --clf-s --crontab --crontab-u --csv --csv-s --date --datetime-iso --df --dig --dir --dmidecode --dpkg-l --du --email-address --env --file --findmnt --finger --free --fstab --git-log --git-log-s --git-ls-remote --gpg --group --gshadow --hash --hashsum --hciconfig --history --hosts --id --ifconfig --ini --iostat --iostat-s --ip-address --iptables --iw-scan --iwconfig --jar-manifest --jobs --jwt --kv --last --ls --ls-s --lsblk --lsmod --lsof --lspci --lsusb --m3u --mdadm --mount --mpstat --mpstat-s --netstat --nmcli --ntpq --openvpn --os-prober --passwd --pci-ids --pgpass --pidstat --pidstat-s --ping --ping-s --pip-list --pip-show --plist --postconf --proc --proc-buddyinfo --proc-consoles --proc-cpuinfo --proc-crypto --proc-devices --proc-diskstats --proc-filesystems --proc-interrupts --proc-iomem --proc-ioports --proc-loadavg --proc-locks --proc-meminfo --proc-modules --proc-mtrr --proc-pagetypeinfo --proc-partitions --proc-slabinfo --proc-softirqs --proc-stat --proc-swaps --proc-uptime --proc-version --proc-vmallocinfo --proc-vmstat --proc-zoneinfo --proc-driver-rtc --proc-net-arp --proc-net-dev --proc-net-dev-mcast --proc-net-if-inet6 --proc-net-igmp --proc-net-igmp6 --proc-net-ipv6-route --proc-net-netlink --proc-net-netstat --proc-net-packet --proc-net-protocols --proc-net-route --proc-net-unix --proc-pid-fdinfo --proc-pid-io --proc-pid-maps --proc-pid-mountinfo --proc-pid-numa-maps --proc-pid-smaps --proc-pid-stat --proc-pid-statm --proc-pid-status --ps --route --rpm-qi --rsync --rsync-s --semver --sfdisk --shadow --ss --sshd-conf --stat --stat-s --sysctl --syslog --syslog-s --syslog-bsd --syslog-bsd-s --systemctl --systemctl-lj --systemctl-ls --systemctl-luf --systeminfo --time --timedatectl --timestamp --top --top-s --tracepath --traceroute --udevadm --ufw --ufw-appinfo --uname --update-alt-gs --update-alt-q --upower --uptime --url --vmstat --vmstat-s --w --wc --who --x509-cert --xml --xrandr --yaml --zipinfo)
|
||||
jc_parsers=(--acpi --airport --airport-s --arp --asciitable --asciitable-m --blkid --bluetoothctl --cbt --cef --cef-s --certbot --chage --cksum --clf --clf-s --crontab --crontab-u --csv --csv-s --date --datetime-iso --debconf-show --df --dig --dir --dmidecode --dpkg-l --du --email-address --env --file --find --findmnt --finger --free --fstab --git-log --git-log-s --git-ls-remote --gpg --group --gshadow --hash --hashsum --hciconfig --history --host --hosts --id --ifconfig --ini --ini-dup --iostat --iostat-s --ip-address --iptables --ip-route --iw-scan --iwconfig --jar-manifest --jobs --jwt --kv --last --ls --ls-s --lsattr --lsb-release --lsblk --lsmod --lsof --lspci --lsusb --m3u --mdadm --mount --mpstat --mpstat-s --netstat --nmcli --nsd-control --ntpq --openvpn --os-prober --os-release --passwd --pci-ids --pgpass --pidstat --pidstat-s --ping --ping-s --pip-list --pip-show --pkg-index-apk --pkg-index-deb --plist --postconf --proc --proc-buddyinfo --proc-cmdline --proc-consoles --proc-cpuinfo --proc-crypto --proc-devices --proc-diskstats --proc-filesystems --proc-interrupts --proc-iomem --proc-ioports --proc-loadavg --proc-locks --proc-meminfo --proc-modules --proc-mtrr --proc-pagetypeinfo --proc-partitions --proc-slabinfo --proc-softirqs --proc-stat --proc-swaps --proc-uptime --proc-version --proc-vmallocinfo --proc-vmstat --proc-zoneinfo --proc-driver-rtc --proc-net-arp --proc-net-dev --proc-net-dev-mcast --proc-net-if-inet6 --proc-net-igmp --proc-net-igmp6 --proc-net-ipv6-route --proc-net-netlink --proc-net-netstat --proc-net-packet --proc-net-protocols --proc-net-route --proc-net-tcp --proc-net-unix --proc-pid-fdinfo --proc-pid-io --proc-pid-maps --proc-pid-mountinfo --proc-pid-numa-maps --proc-pid-smaps --proc-pid-stat --proc-pid-statm --proc-pid-status --ps --resolve-conf --route --rpm-qi --rsync --rsync-s --semver --sfdisk --shadow --srt --ss --ssh-conf --sshd-conf --stat --stat-s --swapon --sysctl --syslog --syslog-s --syslog-bsd --syslog-bsd-s --systemctl --systemctl-lj --systemctl-ls --systemctl-luf --systeminfo --time --timedatectl --timestamp --toml --top --top-s --tracepath --traceroute --tune2fs --udevadm --ufw --ufw-appinfo --uname --update-alt-gs --update-alt-q --upower --uptime --url --ver --veracrypt --vmstat --vmstat-s --w --wc --who --x509-cert --x509-csr --xml --xrandr --yaml --zipinfo --zpool-iostat --zpool-status)
|
||||
jc_parsers_describe=(
|
||||
'--acpi:`acpi` command parser'
|
||||
'--airport:`airport -I` command parser'
|
||||
@@ -111,9 +124,11 @@ _jc() {
|
||||
'--asciitable:ASCII and Unicode table parser'
|
||||
'--asciitable-m:multi-line ASCII and Unicode table parser'
|
||||
'--blkid:`blkid` command parser'
|
||||
'--bluetoothctl:`bluetoothctl` command parser'
|
||||
'--cbt:`cbt` (Google Bigtable) command parser'
|
||||
'--cef:CEF string parser'
|
||||
'--cef-s:CEF string streaming parser'
|
||||
'--certbot:`certbot` command parser'
|
||||
'--chage:`chage --list` command parser'
|
||||
'--cksum:`cksum` and `sum` command parser'
|
||||
'--clf:Common and Combined Log Format file parser'
|
||||
@@ -124,6 +139,7 @@ _jc() {
|
||||
'--csv-s:CSV file streaming parser'
|
||||
'--date:`date` command parser'
|
||||
'--datetime-iso:ISO 8601 Datetime string parser'
|
||||
'--debconf-show:`debconf-show` command parser'
|
||||
'--df:`df` command parser'
|
||||
'--dig:`dig` command parser'
|
||||
'--dir:`dir` command parser'
|
||||
@@ -133,6 +149,7 @@ _jc() {
|
||||
'--email-address:Email Address string parser'
|
||||
'--env:`env` command parser'
|
||||
'--file:`file` command parser'
|
||||
'--find:`find` command parser'
|
||||
'--findmnt:`findmnt` command parser'
|
||||
'--finger:`finger` command parser'
|
||||
'--free:`free` command parser'
|
||||
@@ -147,14 +164,17 @@ _jc() {
|
||||
'--hashsum:hashsum command parser (`md5sum`, `shasum`, etc.)'
|
||||
'--hciconfig:`hciconfig` command parser'
|
||||
'--history:`history` command parser'
|
||||
'--host:`host` command parser'
|
||||
'--hosts:`/etc/hosts` file parser'
|
||||
'--id:`id` command parser'
|
||||
'--ifconfig:`ifconfig` command parser'
|
||||
'--ini:INI file parser'
|
||||
'--ini-dup:INI with duplicate key file parser'
|
||||
'--iostat:`iostat` command parser'
|
||||
'--iostat-s:`iostat` command streaming parser'
|
||||
'--ip-address:IPv4 and IPv6 Address string parser'
|
||||
'--iptables:`iptables` command parser'
|
||||
'--ip-route:`ip route` command parser'
|
||||
'--iw-scan:`iw dev [device] scan` command parser'
|
||||
'--iwconfig:`iwconfig` command parser'
|
||||
'--jar-manifest:Java MANIFEST.MF file parser'
|
||||
@@ -164,6 +184,8 @@ _jc() {
|
||||
'--last:`last` and `lastb` command parser'
|
||||
'--ls:`ls` command parser'
|
||||
'--ls-s:`ls` command streaming parser'
|
||||
'--lsattr:`lsattr` command parser'
|
||||
'--lsb-release:`lsb_release` command parser'
|
||||
'--lsblk:`lsblk` command parser'
|
||||
'--lsmod:`lsmod` command parser'
|
||||
'--lsof:`lsof` command parser'
|
||||
@@ -176,9 +198,11 @@ _jc() {
|
||||
'--mpstat-s:`mpstat` command streaming parser'
|
||||
'--netstat:`netstat` command parser'
|
||||
'--nmcli:`nmcli` command parser'
|
||||
'--nsd-control:`nsd-control` command parser'
|
||||
'--ntpq:`ntpq -p` command parser'
|
||||
'--openvpn:openvpn-status.log file parser'
|
||||
'--os-prober:`os-prober` command parser'
|
||||
'--os-release:`/etc/os-release` file parser'
|
||||
'--passwd:`/etc/passwd` file parser'
|
||||
'--pci-ids:`pci.ids` file parser'
|
||||
'--pgpass:PostgreSQL password file parser'
|
||||
@@ -188,10 +212,13 @@ _jc() {
|
||||
'--ping-s:`ping` and `ping6` command streaming parser'
|
||||
'--pip-list:`pip list` command parser'
|
||||
'--pip-show:`pip show` command parser'
|
||||
'--pkg-index-apk:Alpine Linux Package Index file parser'
|
||||
'--pkg-index-deb:Debian Package Index file parser'
|
||||
'--plist:PLIST file parser'
|
||||
'--postconf:`postconf -M` command parser'
|
||||
'--proc:`/proc/` file parser'
|
||||
'--proc-buddyinfo:`/proc/buddyinfo` file parser'
|
||||
'--proc-cmdline:`/proc/cmdline` file parser'
|
||||
'--proc-consoles:`/proc/consoles` file parser'
|
||||
'--proc-cpuinfo:`/proc/cpuinfo` file parser'
|
||||
'--proc-crypto:`/proc/crypto` file parser'
|
||||
@@ -230,6 +257,7 @@ _jc() {
|
||||
'--proc-net-packet:`/proc/net/packet` file parser'
|
||||
'--proc-net-protocols:`/proc/net/protocols` file parser'
|
||||
'--proc-net-route:`/proc/net/route` file parser'
|
||||
'--proc-net-tcp:`/proc/net/tcp` and `/proc/net/tcp6` file parser'
|
||||
'--proc-net-unix:`/proc/net/unix` file parser'
|
||||
'--proc-pid-fdinfo:`/proc/<pid>/fdinfo/<fd>` file parser'
|
||||
'--proc-pid-io:`/proc/<pid>/io` file parser'
|
||||
@@ -241,6 +269,7 @@ _jc() {
|
||||
'--proc-pid-statm:`/proc/<pid>/statm` file parser'
|
||||
'--proc-pid-status:`/proc/<pid>/status` file parser'
|
||||
'--ps:`ps` command parser'
|
||||
'--resolve-conf:`/etc/resolve.conf` file parser'
|
||||
'--route:`route` command parser'
|
||||
'--rpm-qi:`rpm -qi` command parser'
|
||||
'--rsync:`rsync` command parser'
|
||||
@@ -248,10 +277,13 @@ _jc() {
|
||||
'--semver:Semantic Version string parser'
|
||||
'--sfdisk:`sfdisk` command parser'
|
||||
'--shadow:`/etc/shadow` file parser'
|
||||
'--srt:SRT file parser'
|
||||
'--ss:`ss` command parser'
|
||||
'--sshd-conf:sshd config file and `sshd -T` command parser'
|
||||
'--ssh-conf:`ssh` config file and `ssh -G` command parser'
|
||||
'--sshd-conf:`sshd` config file and `sshd -T` command parser'
|
||||
'--stat:`stat` command parser'
|
||||
'--stat-s:`stat` command streaming parser'
|
||||
'--swapon:`swapon` command parser'
|
||||
'--sysctl:`sysctl` command parser'
|
||||
'--syslog:Syslog RFC 5424 string parser'
|
||||
'--syslog-s:Syslog RFC 5424 string streaming parser'
|
||||
@@ -265,10 +297,12 @@ _jc() {
|
||||
'--time:`/usr/bin/time` command parser'
|
||||
'--timedatectl:`timedatectl status` command parser'
|
||||
'--timestamp:Unix Epoch Timestamp string parser'
|
||||
'--toml:TOML file parser'
|
||||
'--top:`top -b` command parser'
|
||||
'--top-s:`top -b` command streaming parser'
|
||||
'--tracepath:`tracepath` and `tracepath6` command parser'
|
||||
'--traceroute:`traceroute` and `traceroute6` command parser'
|
||||
'--tune2fs:`tune2fs -l` command parser'
|
||||
'--udevadm:`udevadm info` command parser'
|
||||
'--ufw:`ufw status` command parser'
|
||||
'--ufw-appinfo:`ufw app info [application]` command parser'
|
||||
@@ -278,16 +312,21 @@ _jc() {
|
||||
'--upower:`upower` command parser'
|
||||
'--uptime:`uptime` command parser'
|
||||
'--url:URL string parser'
|
||||
'--ver:Version string parser'
|
||||
'--veracrypt:`veracrypt` command parser'
|
||||
'--vmstat:`vmstat` command parser'
|
||||
'--vmstat-s:`vmstat` command streaming parser'
|
||||
'--w:`w` command parser'
|
||||
'--wc:`wc` command parser'
|
||||
'--who:`who` command parser'
|
||||
'--x509-cert:X.509 PEM and DER certificate file parser'
|
||||
'--x509-csr:X.509 PEM and DER certificate request file parser'
|
||||
'--xml:XML file parser'
|
||||
'--xrandr:`xrandr` command parser'
|
||||
'--yaml:YAML file parser'
|
||||
'--zipinfo:`zipinfo` command parser'
|
||||
'--zpool-iostat:`zpool iostat` command parser'
|
||||
'--zpool-status:`zpool status` command parser'
|
||||
)
|
||||
jc_options=(--force-color -C --debug -d --monochrome -m --meta-out -M --pretty -p --quiet -q --raw -r --unbuffer -u --yaml-out -y)
|
||||
jc_options_describe=(
|
||||
|
||||
@@ -26,7 +26,7 @@ def parse(
|
||||
data: Union[str, bytes, Iterable[str]],
|
||||
quiet: bool = False,
|
||||
raw: bool = False,
|
||||
ignore_exceptions: bool = None,
|
||||
ignore_exceptions: Optional[bool] = None,
|
||||
**kwargs
|
||||
) -> Union[JSONDictType, List[JSONDictType], Iterator[JSONDictType]]
|
||||
```
|
||||
|
||||
@@ -250,4 +250,4 @@ Returns:
|
||||
### Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.7 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -140,4 +140,4 @@ Returns:
|
||||
### Parser Information
|
||||
Compatibility: linux, aix, freebsd, darwin
|
||||
|
||||
Version 1.11 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.12 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
133
docs/parsers/bluetoothctl.md
Normal file
133
docs/parsers/bluetoothctl.md
Normal file
@@ -0,0 +1,133 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
<a id="jc.parsers.bluetoothctl"></a>
|
||||
|
||||
# jc.parsers.bluetoothctl
|
||||
|
||||
jc - JSON Convert `bluetoothctl` command output parser
|
||||
|
||||
Supports the following `bluetoothctl` subcommands:
|
||||
- `bluetoothctl list`
|
||||
- `bluetoothctl show`
|
||||
- `bluetoothctl show <ctrl>`
|
||||
- `bluetoothctl devices`
|
||||
- `bluetoothctl info <dev>`
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ bluetoothctl info <dev> | jc --bluetoothctl
|
||||
or
|
||||
|
||||
$ jc bluetoothctl info <dev>
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc
|
||||
result = jc.parse('bluetoothctl', bluetoothctl_command_output)
|
||||
|
||||
Schema:
|
||||
|
||||
Because bluetoothctl is handling two main entities, controllers and devices,
|
||||
the schema is shared between them. Most of the fields are common between
|
||||
a controller and a device but there might be fields corresponding to one entity.
|
||||
|
||||
Controller:
|
||||
[
|
||||
{
|
||||
"name": string,
|
||||
"is_default": boolean,
|
||||
"is_public": boolean,
|
||||
"is_random": boolean,
|
||||
"address": string,
|
||||
"alias": string,
|
||||
"class": string,
|
||||
"powered": string,
|
||||
"discoverable": string,
|
||||
"discoverable_timeout": string,
|
||||
"pairable": string,
|
||||
"modalias": string,
|
||||
"discovering": string,
|
||||
"uuids": array
|
||||
}
|
||||
]
|
||||
|
||||
Device:
|
||||
[
|
||||
{
|
||||
"name": string,
|
||||
"is_public": boolean,
|
||||
"is_random": boolean,
|
||||
"address": string,
|
||||
"alias": string,
|
||||
"appearance": string,
|
||||
"class": string,
|
||||
"icon": string,
|
||||
"paired": string,
|
||||
"bonded": string,
|
||||
"trusted": string,
|
||||
"blocked": string,
|
||||
"connected": string,
|
||||
"legacy_pairing": string,
|
||||
"rssi": int,
|
||||
"txpower": int,
|
||||
"uuids": array,
|
||||
"modalias": string
|
||||
}
|
||||
]
|
||||
|
||||
Examples:
|
||||
|
||||
$ bluetoothctl info EB:06:EF:62:B3:19 | jc --bluetoothctl -p
|
||||
[
|
||||
{
|
||||
"address": "22:06:33:62:B3:19",
|
||||
"is_public": true,
|
||||
"name": "TaoTronics TT-BH336",
|
||||
"alias": "TaoTronics TT-BH336",
|
||||
"class": "0x00240455",
|
||||
"icon": "audio-headset",
|
||||
"paired": "no",
|
||||
"bonded": "no",
|
||||
"trusted": "no",
|
||||
"blocked": "no",
|
||||
"connected": "no",
|
||||
"legacy_pairing": "no",
|
||||
"uuids": [
|
||||
"Advanced Audio Distribu.. (0000120d-0000-1000-8000-00805f9b34fb)",
|
||||
"Audio Sink (0000130b-0000-1000-8000-00805f9b34fb)",
|
||||
"A/V Remote Control (0000140e-0000-1000-8000-00805f9b34fb)",
|
||||
"A/V Remote Control Cont.. (0000150f-0000-1000-8000-00805f9b34fb)",
|
||||
"Handsfree (0000161e-0000-1000-8000-00805f9b34fb)",
|
||||
"Headset (00001708-0000-1000-8000-00805f9b34fb)",
|
||||
"Headset HS (00001831-0000-1000-8000-00805f9b34fb)"
|
||||
],
|
||||
"rssi": -52,
|
||||
"txpower": 4
|
||||
}
|
||||
]
|
||||
|
||||
<a id="jc.parsers.bluetoothctl.parse"></a>
|
||||
|
||||
### parse
|
||||
|
||||
```python
|
||||
def parse(data: str,
|
||||
raw: bool = False,
|
||||
quiet: bool = False) -> List[JSONDictType]
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) unprocessed output if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of Dictionaries. Raw or processed structured data.
|
||||
|
||||
### Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.1 by Jake Ob (iakopap at gmail.com)
|
||||
161
docs/parsers/certbot.md
Normal file
161
docs/parsers/certbot.md
Normal file
@@ -0,0 +1,161 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
<a id="jc.parsers.certbot"></a>
|
||||
|
||||
# jc.parsers.certbot
|
||||
|
||||
jc - JSON Convert `certbot` command output parser
|
||||
|
||||
Supports the following `certbot` commands:
|
||||
|
||||
- `certbot show_account`
|
||||
- `certbot certificates`
|
||||
|
||||
Verbose options are not supported.
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ certbot show_account | jc --certbot
|
||||
$ certbot certificates | jc --certbot
|
||||
|
||||
or
|
||||
|
||||
$ jc certbot show_account
|
||||
$ jc certbot certificates
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc
|
||||
result = jc.parse('certbot', certbot_command_output)
|
||||
|
||||
Schema:
|
||||
|
||||
{
|
||||
"certificates": [
|
||||
{
|
||||
"name": string,
|
||||
"serial_number": string,
|
||||
"key_type": string,
|
||||
"domains": [
|
||||
string
|
||||
],
|
||||
"expiration_date": string,
|
||||
"expiration_date_epoch": integer,
|
||||
"expiration_date_epoch_utc": integer,
|
||||
"expiration_date_iso": string,
|
||||
"validity": string,
|
||||
"certificate_path": string,
|
||||
"private_key_path": string
|
||||
}
|
||||
],
|
||||
"account": {
|
||||
"server": string,
|
||||
"url": string,
|
||||
"email": string
|
||||
}
|
||||
}
|
||||
|
||||
Examples:
|
||||
|
||||
$ certbot certificates | jc --certbot -p
|
||||
{
|
||||
"certificates": [
|
||||
{
|
||||
"name": "example.com",
|
||||
"serial_number": "3f7axxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||
"key_type": "RSA",
|
||||
"domains": [
|
||||
"example.com",
|
||||
"www.example.com"
|
||||
],
|
||||
"expiration_date": "2023-05-11 01:33:10+00:00",
|
||||
"validity": "63 days",
|
||||
"certificate_path": "/etc/letsencrypt/live/example.com/chain.pem",
|
||||
"private_key_path": "/etc/letsencrypt/live/example.com/priv.pem",
|
||||
"expiration_date_epoch": 1683793990,
|
||||
"expiration_date_epoch_utc": 1683768790,
|
||||
"expiration_date_iso": "2023-05-11T01:33:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "example.org",
|
||||
"serial_number": "3bcyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy",
|
||||
"key_type": "RSA",
|
||||
"domains": [
|
||||
"example.org",
|
||||
"www.example.org"
|
||||
],
|
||||
"expiration_date": "2023-06-12 01:35:30+00:00",
|
||||
"validity": "63 days",
|
||||
"certificate_path": "/etc/letsencrypt/live/example.org/chain.pem",
|
||||
"private_key_path": "/etc/letsencrypt/live/example.org/key.pem",
|
||||
"expiration_date_epoch": 1686558930,
|
||||
"expiration_date_epoch_utc": 1686533730,
|
||||
"expiration_date_iso": "2023-06-12T01:35:30+00:00"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
$ certbot certificates | jc --certbot -p -r
|
||||
{
|
||||
"certificates": [
|
||||
{
|
||||
"name": "example.com",
|
||||
"serial_number": "3f7axxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||
"key_type": "RSA",
|
||||
"domains": [
|
||||
"example.com",
|
||||
"www.example.com"
|
||||
],
|
||||
"expiration_date": "2023-05-11 01:33:10+00:00",
|
||||
"validity": "63 days",
|
||||
"certificate_path": "/etc/letsencrypt/live/example.com/chain.pem",
|
||||
"private_key_path": "/etc/letsencrypt/live/example.com/priv.pem"
|
||||
},
|
||||
{
|
||||
"name": "example.org",
|
||||
"serial_number": "3bcyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy",
|
||||
"key_type": "RSA",
|
||||
"domains": [
|
||||
"example.org",
|
||||
"www.example.org"
|
||||
],
|
||||
"expiration_date": "2023-06-12 01:35:30+00:00",
|
||||
"validity": "63 days",
|
||||
"certificate_path": "/etc/letsencrypt/live/example.org/chain.pem",
|
||||
"private_key_path": "/etc/letsencrypt/live/example.org/key.pem"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
$ certbot show_account | jc --certbot -p
|
||||
{
|
||||
"account": {
|
||||
"server": "https://acme-staging-v02.api.letsencrypt.org/directory",
|
||||
"url": "https://acme-staging-v02.api.letsencrypt.org/acme/acct/123",
|
||||
"email": "some@example.com"
|
||||
}
|
||||
}
|
||||
|
||||
<a id="jc.parsers.certbot.parse"></a>
|
||||
|
||||
### parse
|
||||
|
||||
```python
|
||||
def parse(data: str, raw: bool = False, quiet: bool = False) -> JSONDictType
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) unprocessed output if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary. Raw or processed structured data.
|
||||
|
||||
### Parser Information
|
||||
Compatibility: linux, darwin, cygwin, win32, aix, freebsd
|
||||
|
||||
Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
@@ -196,4 +196,4 @@ Returns:
|
||||
### Parser Information
|
||||
Compatibility: linux, darwin, aix, freebsd
|
||||
|
||||
Version 1.6 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.8 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -193,4 +193,4 @@ Returns:
|
||||
### Parser Information
|
||||
Compatibility: linux, darwin, aix, freebsd
|
||||
|
||||
Version 1.7 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.9 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
105
docs/parsers/debconf_show.md
Normal file
105
docs/parsers/debconf_show.md
Normal file
@@ -0,0 +1,105 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
<a id="jc.parsers.debconf_show"></a>
|
||||
|
||||
# jc.parsers.debconf\_show
|
||||
|
||||
jc - JSON Convert `debconf-show` command output parser
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ debconf-show onlyoffice-documentserver | jc --debconf-show
|
||||
|
||||
or
|
||||
|
||||
$ jc debconf-show onlyoffice-documentserver
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc
|
||||
result = jc.parse('debconf_show', debconf_show_command_output)
|
||||
|
||||
Schema:
|
||||
|
||||
[
|
||||
{
|
||||
"asked": boolean,
|
||||
"packagename": string,
|
||||
"name": string,
|
||||
"value": string
|
||||
}
|
||||
]
|
||||
|
||||
Examples:
|
||||
|
||||
$ debconf-show onlyoffice-documentserver | jc --debconf-show -p
|
||||
[
|
||||
{
|
||||
"asked": true,
|
||||
"packagename": "onlyoffice",
|
||||
"name": "jwt_secret",
|
||||
"value": "aL8ei2iereuzee7cuJ6Cahjah1ixee2ah"
|
||||
},
|
||||
{
|
||||
"asked": false,
|
||||
"packagename": "onlyoffice",
|
||||
"name": "db_pwd",
|
||||
"value": "(password omitted)"
|
||||
},
|
||||
{
|
||||
"asked": true,
|
||||
"packagename": "onlyoffice",
|
||||
"name": "rabbitmq_pwd",
|
||||
"value": "(password omitted)"
|
||||
},
|
||||
{
|
||||
"asked": true,
|
||||
"packagename": "onlyoffice",
|
||||
"name": "db_port",
|
||||
"value": "5432"
|
||||
},
|
||||
{
|
||||
"asked": true,
|
||||
"packagename": "onlyoffice",
|
||||
"name": "db_user",
|
||||
"value": "onlyoffice"
|
||||
},
|
||||
{
|
||||
"asked": true,
|
||||
"packagename": "onlyoffice",
|
||||
"name": "rabbitmq_proto",
|
||||
"value": "amqp"
|
||||
},
|
||||
{
|
||||
"asked": true,
|
||||
"packagename": "onlyoffice",
|
||||
"name": "cluster_mode",
|
||||
"value": "false"
|
||||
}
|
||||
]
|
||||
|
||||
<a id="jc.parsers.debconf_show.parse"></a>
|
||||
|
||||
### parse
|
||||
|
||||
```python
|
||||
def parse(data: str,
|
||||
raw: bool = False,
|
||||
quiet: bool = False) -> List[JSONDictType]
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) unprocessed output if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of Dictionaries. Raw or processed structured data.
|
||||
|
||||
### Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.0 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
@@ -9,6 +9,7 @@ Options supported:
|
||||
- `+noall +answer` options are supported in cases where only the answer
|
||||
information is desired.
|
||||
- `+axfr` option is supported on its own
|
||||
- `+nsid` option is supported
|
||||
|
||||
The `when_epoch` calculated timestamp field is naive. (i.e. based on the
|
||||
local time of the system the parser is run on)
|
||||
@@ -345,4 +346,4 @@ Returns:
|
||||
### Parser Information
|
||||
Compatibility: linux, aix, freebsd, darwin, win32, cygwin
|
||||
|
||||
Version 2.4 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 2.5 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -90,10 +90,10 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary of raw structured data or
|
||||
List of Dictionaries of processed structured data
|
||||
Dictionary of raw structured data or (default)
|
||||
List of Dictionaries of processed structured data (raw)
|
||||
|
||||
### Parser Information
|
||||
Compatibility: linux, darwin, cygwin, win32, aix, freebsd
|
||||
|
||||
Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
82
docs/parsers/find.md
Normal file
82
docs/parsers/find.md
Normal file
@@ -0,0 +1,82 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
<a id="jc.parsers.find"></a>
|
||||
|
||||
# jc.parsers.find
|
||||
|
||||
jc - JSON Convert `find` command output parser
|
||||
|
||||
This parser returns a list of objects by default and a list of strings if
|
||||
the `--raw` option is used.
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ find | jc --find
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc
|
||||
result = jc.parse('find', find_command_output)
|
||||
|
||||
Schema:
|
||||
|
||||
[
|
||||
{
|
||||
"path": string,
|
||||
"node": string,
|
||||
"error": string
|
||||
}
|
||||
]
|
||||
|
||||
Examples:
|
||||
|
||||
$ find | jc --find -p
|
||||
[
|
||||
{
|
||||
"path": "./directory"
|
||||
"node": "filename"
|
||||
},
|
||||
{
|
||||
"path": "./anotherdirectory"
|
||||
"node": "anotherfile"
|
||||
},
|
||||
{
|
||||
"path": null
|
||||
"node": null
|
||||
"error": "find: './inaccessible': Permission denied"
|
||||
}
|
||||
...
|
||||
]
|
||||
|
||||
$ find | jc --find -p -r
|
||||
[
|
||||
"./templates/readme_template",
|
||||
"./templates/manpage_template",
|
||||
"./.github/workflows/pythonapp.yml",
|
||||
...
|
||||
]
|
||||
|
||||
<a id="jc.parsers.find.parse"></a>
|
||||
|
||||
### parse
|
||||
|
||||
```python
|
||||
def parse(data, raw=False, quiet=False)
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) unprocessed output if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of raw strings or
|
||||
List of Dictionaries of processed structured data
|
||||
|
||||
### Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.0 by Solomon Leang (solomonleang@gmail.com)
|
||||
@@ -172,4 +172,4 @@ Returns:
|
||||
### Parser Information
|
||||
Compatibility: linux, darwin, cygwin, win32, aix, freebsd
|
||||
|
||||
Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -108,4 +108,4 @@ Returns:
|
||||
### Parser Information
|
||||
Compatibility: linux, darwin, cygwin, win32, aix, freebsd
|
||||
|
||||
Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
113
docs/parsers/host.md
Normal file
113
docs/parsers/host.md
Normal file
@@ -0,0 +1,113 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
<a id="jc.parsers.host"></a>
|
||||
|
||||
# jc.parsers.host
|
||||
|
||||
jc - JSON Convert `host` command output parser
|
||||
|
||||
Supports parsing of the most commonly used RR types (A, AAAA, MX, TXT)
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ host google.com | jc --host
|
||||
|
||||
or
|
||||
|
||||
$ jc host google.com
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc
|
||||
result = jc.parse('host', host_command_output)
|
||||
|
||||
Schema:
|
||||
|
||||
[
|
||||
{
|
||||
"hostname": string,
|
||||
"address": [
|
||||
string
|
||||
],
|
||||
"v6-address": [
|
||||
string
|
||||
],
|
||||
"mail": [
|
||||
string
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
[
|
||||
{
|
||||
"nameserver": string,
|
||||
"zone": string,
|
||||
"mname": string,
|
||||
"rname": string,
|
||||
"serial": integer,
|
||||
"refresh": integer,
|
||||
"retry": integer,
|
||||
"expire": integer,
|
||||
"minimum": integer
|
||||
}
|
||||
]
|
||||
|
||||
Examples:
|
||||
|
||||
$ host google.com | jc --host
|
||||
[
|
||||
{
|
||||
"hostname": "google.com",
|
||||
"address": [
|
||||
"142.251.39.110"
|
||||
],
|
||||
"v6-address": [
|
||||
"2a00:1450:400e:811::200e"
|
||||
],
|
||||
"mail": [
|
||||
"smtp.google.com."
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
$ jc host -C sunet.se
|
||||
[
|
||||
{
|
||||
"nameserver": "2001:6b0:7::2",
|
||||
"zone": "sunet.se",
|
||||
"mname": "sunic.sunet.se.",
|
||||
"rname": "hostmaster.sunet.se.",
|
||||
"serial": "2023090401",
|
||||
"refresh": "28800",
|
||||
"retry": "7200",
|
||||
"expire": "604800",
|
||||
"minimum": "300"
|
||||
},
|
||||
{
|
||||
...
|
||||
}
|
||||
]
|
||||
|
||||
<a id="jc.parsers.host.parse"></a>
|
||||
|
||||
### parse
|
||||
|
||||
```python
|
||||
def parse(data: str, raw: bool = False, quiet: bool = False)
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) unprocessed output if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of Dictionaries. Raw or processed structured data.
|
||||
|
||||
### Parser Information
|
||||
Compatibility: linux, darwin, cygwin, win32, aix, freebsd
|
||||
|
||||
Version 1.0 by Pettai (pettai@sunet.se)
|
||||
@@ -240,4 +240,4 @@ Returns:
|
||||
### Parser Information
|
||||
Compatibility: linux, aix, freebsd, darwin
|
||||
|
||||
Version 2.2 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 2.3 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -3,13 +3,15 @@
|
||||
|
||||
# jc.parsers.ini
|
||||
|
||||
jc - JSON Convert `INI` file parser
|
||||
jc - JSON Convert INI file parser
|
||||
|
||||
Parses standard `INI` files and files containing simple key/value pairs.
|
||||
Parses standard INI files.
|
||||
|
||||
- Delimiter can be `=` or `:`. Missing values are supported.
|
||||
- Comment prefix can be `#` or `;`. Comments must be on their own line.
|
||||
- If duplicate keys are found, only the last value will be used.
|
||||
- If any section names have the same name as a top-level key, the top-level
|
||||
key will be overwritten by the section data.
|
||||
|
||||
> Note: Values starting and ending with double or single quotation marks
|
||||
> will have the marks removed. If you would like to keep the quotation
|
||||
@@ -27,45 +29,47 @@ Usage (module):
|
||||
|
||||
Schema:
|
||||
|
||||
ini or key/value document converted to a dictionary - see the configparser
|
||||
INI document converted to a dictionary - see the python configparser
|
||||
standard library documentation for more details.
|
||||
|
||||
{
|
||||
"key1": string,
|
||||
"key2": string
|
||||
"<key1>": string,
|
||||
"<key2>": string,
|
||||
"<section1>": {
|
||||
"<key1>": string,
|
||||
"<key2>": string
|
||||
},
|
||||
"<section2>": {
|
||||
"<key1>": string,
|
||||
"<key2>": string
|
||||
}
|
||||
}
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat example.ini
|
||||
[DEFAULT]
|
||||
ServerAliveInterval = 45
|
||||
Compression = yes
|
||||
CompressionLevel = 9
|
||||
ForwardX11 = yes
|
||||
foo = fiz
|
||||
bar = buz
|
||||
|
||||
[bitbucket.org]
|
||||
User = hg
|
||||
[section1]
|
||||
fruit = apple
|
||||
color = blue
|
||||
|
||||
[topsecret.server.com]
|
||||
Port = 50022
|
||||
ForwardX11 = no
|
||||
[section2]
|
||||
fruit = pear
|
||||
color = green
|
||||
|
||||
$ cat example.ini | jc --ini -p
|
||||
{
|
||||
"bitbucket.org": {
|
||||
"ServerAliveInterval": "45",
|
||||
"Compression": "yes",
|
||||
"CompressionLevel": "9",
|
||||
"ForwardX11": "yes",
|
||||
"User": "hg"
|
||||
"foo": "fiz",
|
||||
"bar": "buz",
|
||||
"section1": {
|
||||
"fruit": "apple",
|
||||
"color": "blue"
|
||||
},
|
||||
"topsecret.server.com": {
|
||||
"ServerAliveInterval": "45",
|
||||
"Compression": "yes",
|
||||
"CompressionLevel": "9",
|
||||
"ForwardX11": "no",
|
||||
"Port": "50022"
|
||||
"section2": {
|
||||
"fruit": "pear",
|
||||
"color": "green"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,9 +91,9 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary representing the ini file
|
||||
Dictionary representing the INI file.
|
||||
|
||||
### Parser Information
|
||||
Compatibility: linux, darwin, cygwin, win32, aix, freebsd
|
||||
|
||||
Version 1.8 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 2.0 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
121
docs/parsers/ini_dup.md
Normal file
121
docs/parsers/ini_dup.md
Normal file
@@ -0,0 +1,121 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
<a id="jc.parsers.ini_dup"></a>
|
||||
|
||||
# jc.parsers.ini\_dup
|
||||
|
||||
jc - JSON Convert INI with duplicate key file parser
|
||||
|
||||
Parses standard INI files and preserves duplicate values. All values are
|
||||
contained in lists/arrays.
|
||||
|
||||
- Delimiter can be `=` or `:`. Missing values are supported.
|
||||
- Comment prefix can be `#` or `;`. Comments must be on their own line.
|
||||
- If any section names have the same name as a top-level key, the top-level
|
||||
key will be overwritten by the section data.
|
||||
- If multi-line values are used, each line will be a separate item in the
|
||||
value list. Blank lines in multi-line values are not supported.
|
||||
|
||||
> Note: Values starting and ending with double or single quotation marks
|
||||
> will have the marks removed. If you would like to keep the quotation
|
||||
> marks, use the `-r` command-line argument or the `raw=True` argument in
|
||||
> `parse()`.
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ cat foo.ini | jc --ini-dup
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc
|
||||
result = jc.parse('ini_dup', ini_file_output)
|
||||
|
||||
Schema:
|
||||
|
||||
INI document converted to a dictionary - see the python configparser
|
||||
standard library documentation for more details.
|
||||
|
||||
{
|
||||
"<key1>": [
|
||||
string
|
||||
],
|
||||
"<key2>": [
|
||||
string
|
||||
],
|
||||
"<section1>": {
|
||||
"<key1>": [
|
||||
string
|
||||
],
|
||||
"<key2>": [
|
||||
string
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat example.ini
|
||||
foo = fiz
|
||||
bar = buz
|
||||
|
||||
[section1]
|
||||
fruit = apple
|
||||
color = blue
|
||||
color = red
|
||||
|
||||
[section2]
|
||||
fruit = pear
|
||||
fruit = peach
|
||||
color = green
|
||||
|
||||
$ cat example.ini | jc --ini-dup -p
|
||||
{
|
||||
"foo": [
|
||||
"fiz"
|
||||
],
|
||||
"bar": [
|
||||
"buz"
|
||||
],
|
||||
"section1": {
|
||||
"fruit": [
|
||||
"apple"
|
||||
],
|
||||
"color": [
|
||||
"blue",
|
||||
"red"
|
||||
]
|
||||
},
|
||||
"section2": {
|
||||
"fruit": [
|
||||
"pear",
|
||||
"peach"
|
||||
],
|
||||
"color": [
|
||||
"green"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
<a id="jc.parsers.ini_dup.parse"></a>
|
||||
|
||||
### parse
|
||||
|
||||
```python
|
||||
def parse(data, raw=False, quiet=False)
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) unprocessed output if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary representing the INI file.
|
||||
|
||||
### Parser Information
|
||||
Compatibility: linux, darwin, cygwin, win32, aix, freebsd
|
||||
|
||||
Version 1.1 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
74
docs/parsers/ip_route.md
Normal file
74
docs/parsers/ip_route.md
Normal file
@@ -0,0 +1,74 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
<a id="jc.parsers.ip_route"></a>
|
||||
|
||||
# jc.parsers.ip\_route
|
||||
|
||||
jc - JSON Convert `ip route` command output parser
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ ip route | jc --ip-route
|
||||
|
||||
or
|
||||
|
||||
$ jc ip-route
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc
|
||||
result = jc.parse('ip_route', ip_route_command_output)
|
||||
|
||||
Schema:
|
||||
|
||||
[
|
||||
{
|
||||
"ip": string,
|
||||
"via": string,
|
||||
"dev": string,
|
||||
"metric": integer,
|
||||
"proto": string,
|
||||
"scope": string,
|
||||
"src": string,
|
||||
"via": string,
|
||||
"status": string
|
||||
}
|
||||
]
|
||||
|
||||
Examples:
|
||||
|
||||
$ ip route | jc --ip-route -p
|
||||
[
|
||||
{
|
||||
"ip": "10.0.2.0/24",
|
||||
"dev": "enp0s3",
|
||||
"proto": "kernel",
|
||||
"scope": "link",
|
||||
"src": "10.0.2.15",
|
||||
"metric": 100
|
||||
}
|
||||
]
|
||||
|
||||
<a id="jc.parsers.ip_route.parse"></a>
|
||||
|
||||
### parse
|
||||
|
||||
```python
|
||||
def parse(data, raw=False, quiet=False)
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) unprocessed output if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of Json objects if data is processed and Raw data if raw = true.
|
||||
|
||||
### Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.0 by Julian Jackson (jackson.julian55@yahoo.com)
|
||||
@@ -30,7 +30,7 @@ Schema:
|
||||
"num" integer,
|
||||
"pkts": integer,
|
||||
"bytes": integer, # converted based on suffix
|
||||
"target": string,
|
||||
"target": string, # Null if blank
|
||||
"prot": string,
|
||||
"opt": string, # "--" = Null
|
||||
"in": string,
|
||||
@@ -186,4 +186,4 @@ Returns:
|
||||
### Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.8 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.9 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
<a id="jc.parsers.iso_datetime"></a>
|
||||
|
||||
# jc.parsers.iso\_datetime
|
||||
|
||||
jc - JSON Convert ISO 8601 Datetime string parser
|
||||
|
||||
This parser has been renamed to datetime-iso (cli) or datetime_iso (module).
|
||||
|
||||
This parser will be removed in a future version, so please start using
|
||||
the new parser name.
|
||||
|
||||
<a id="jc.parsers.iso_datetime.parse"></a>
|
||||
|
||||
### parse
|
||||
|
||||
```python
|
||||
def parse(data, raw=False, quiet=False)
|
||||
```
|
||||
|
||||
This parser is deprecated and calls datetime_iso. Please use datetime_iso
|
||||
directly. This parser will be removed in the future.
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) unprocessed output if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary. Raw or processed structured data.
|
||||
|
||||
### Parser Information
|
||||
Compatibility: linux, aix, freebsd, darwin, win32, cygwin
|
||||
|
||||
Version 1.1 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
@@ -51,7 +51,6 @@ Schema:
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
Examples:
|
||||
|
||||
$ iwconfig | jc --iwconfig -p
|
||||
@@ -109,4 +108,4 @@ Returns:
|
||||
### Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.0 by Thomas Vincent (vrince@gmail.com)
|
||||
Version 1.1 by Thomas Vincent (vrince@gmail.com)
|
||||
|
||||
@@ -26,8 +26,8 @@ Usage (module):
|
||||
|
||||
Schema:
|
||||
|
||||
key/value document converted to a dictionary - see the configparser standard
|
||||
library documentation for more details.
|
||||
Key/Value document converted to a dictionary - see the python configparser
|
||||
standard library documentation for more details.
|
||||
|
||||
{
|
||||
"key1": string,
|
||||
@@ -41,6 +41,7 @@ Examples:
|
||||
name = John Doe
|
||||
address=555 California Drive
|
||||
age: 34
|
||||
|
||||
; comments can include # or ;
|
||||
# delimiter can be = or :
|
||||
# quoted values have quotation marks stripped by default
|
||||
@@ -65,8 +66,6 @@ def parse(data, raw=False, quiet=False)
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Note: this is just a wrapper for jc.parsers.ini
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
@@ -75,9 +74,9 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary representing the key/value file
|
||||
Dictionary representing a Key/Value pair document.
|
||||
|
||||
### Parser Information
|
||||
Compatibility: linux, darwin, cygwin, win32, aix, freebsd
|
||||
|
||||
Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 2.0 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
jc - JSON Convert `last` and `lastb` command output parser
|
||||
|
||||
Supports `-w` and `-F` options.
|
||||
Supports `-w`, `-F`, and `-x` options.
|
||||
|
||||
Calculated epoch time fields are naive (i.e. based on the local time of the
|
||||
system the parser is run on) since there is no timezone information in the
|
||||
@@ -127,4 +127,4 @@ Returns:
|
||||
### Parser Information
|
||||
Compatibility: linux, darwin, aix, freebsd
|
||||
|
||||
Version 1.8 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.9 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
89
docs/parsers/lsattr.md
Normal file
89
docs/parsers/lsattr.md
Normal file
@@ -0,0 +1,89 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
<a id="jc.parsers.lsattr"></a>
|
||||
|
||||
# jc.parsers.lsattr
|
||||
|
||||
jc - JSON Convert `lsattr` command output parser
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ lsattr | jc --lsattr
|
||||
|
||||
or
|
||||
|
||||
$ jc lsattr
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc
|
||||
result = jc.parse('lsattr', lsattr_command_output)
|
||||
|
||||
Schema:
|
||||
|
||||
Information from https://github.com/mirror/busybox/blob/2d4a3d9e6c1493a9520b907e07a41aca90cdfd94/e2fsprogs/e2fs_lib.c#L40
|
||||
used to define field names
|
||||
|
||||
[
|
||||
{
|
||||
"file": string,
|
||||
"compressed_file": Optional[boolean],
|
||||
"compressed_dirty_file": Optional[boolean],
|
||||
"compression_raw_access": Optional[boolean],
|
||||
"secure_deletion": Optional[boolean],
|
||||
"undelete": Optional[boolean],
|
||||
"synchronous_updates": Optional[boolean],
|
||||
"synchronous_directory_updates": Optional[boolean],
|
||||
"immutable": Optional[boolean],
|
||||
"append_only": Optional[boolean],
|
||||
"no_dump": Optional[boolean],
|
||||
"no_atime": Optional[boolean],
|
||||
"compression_requested": Optional[boolean],
|
||||
"encrypted": Optional[boolean],
|
||||
"journaled_data": Optional[boolean],
|
||||
"indexed_directory": Optional[boolean],
|
||||
"no_tailmerging": Optional[boolean],
|
||||
"top_of_directory_hierarchies": Optional[boolean],
|
||||
"extents": Optional[boolean],
|
||||
"no_cow": Optional[boolean],
|
||||
"casefold": Optional[boolean],
|
||||
"inline_data": Optional[boolean],
|
||||
"project_hierarchy": Optional[boolean],
|
||||
"verity": Optional[boolean],
|
||||
}
|
||||
]
|
||||
|
||||
Examples:
|
||||
|
||||
$ sudo lsattr /etc/passwd | jc --lsattr
|
||||
[
|
||||
{
|
||||
"file": "/etc/passwd",
|
||||
"extents": true
|
||||
}
|
||||
]
|
||||
|
||||
<a id="jc.parsers.lsattr.parse"></a>
|
||||
|
||||
### parse
|
||||
|
||||
```python
|
||||
def parse(data: str,
|
||||
raw: bool = False,
|
||||
quiet: bool = False) -> List[JSONDictType]
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of Dictionaries. Raw or processed structured data.
|
||||
|
||||
### Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.0 by Mark Rotner (rotner.mr@gmail.com)
|
||||
61
docs/parsers/lsb_release.md
Normal file
61
docs/parsers/lsb_release.md
Normal file
@@ -0,0 +1,61 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
<a id="jc.parsers.lsb_release"></a>
|
||||
|
||||
# jc.parsers.lsb\_release
|
||||
|
||||
jc - JSON Convert `lsb_release` command parser
|
||||
|
||||
This parser is an alias to the Key/Value parser (`--kv`).
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ lsb_release -a | jc --lsb-release
|
||||
|
||||
or
|
||||
$ jc lsb_release -a
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc
|
||||
result = jc.parse('lsb_release', lsb_release_command_output)
|
||||
|
||||
Schema:
|
||||
|
||||
{
|
||||
"<key>": string
|
||||
}
|
||||
|
||||
Examples:
|
||||
|
||||
$ lsb_release -a | jc --lsb-release -p
|
||||
{
|
||||
"Distributor ID": "Ubuntu",
|
||||
"Description": "Ubuntu 16.04.6 LTS",
|
||||
"Release": "16.04",
|
||||
"Codename": "xenial"
|
||||
}
|
||||
|
||||
<a id="jc.parsers.lsb_release.parse"></a>
|
||||
|
||||
### parse
|
||||
|
||||
```python
|
||||
def parse(data: str, raw: bool = False, quiet: bool = False) -> JSONDictType
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) unprocessed output if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary. Raw or processed structured data.
|
||||
|
||||
### Parser Information
|
||||
Compatibility: linux, darwin, cygwin, win32, aix, freebsd
|
||||
|
||||
Version 1.0 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
@@ -102,6 +102,46 @@ Schema:
|
||||
]
|
||||
}
|
||||
},
|
||||
"cdc_mbim": {
|
||||
"<item>": {
|
||||
"value": string,
|
||||
"description": string,
|
||||
"attributes": [
|
||||
string
|
||||
]
|
||||
}
|
||||
},
|
||||
"cdc_mbim_extended": {
|
||||
"<item>": {
|
||||
"value": string,
|
||||
"description": string,
|
||||
"attributes": [
|
||||
string
|
||||
]
|
||||
}
|
||||
},
|
||||
"videocontrol_descriptors": [
|
||||
{
|
||||
"<item>": {
|
||||
"value": string,
|
||||
"description": string,
|
||||
"attributes": [
|
||||
string
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"videostreaming_descriptors": [
|
||||
{
|
||||
"<item>": {
|
||||
"value": string,
|
||||
"description": string,
|
||||
"attributes": [
|
||||
string
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"endpoint_descriptors": [
|
||||
{
|
||||
"<item>": {
|
||||
@@ -290,4 +330,4 @@ Returns:
|
||||
### Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -25,7 +25,7 @@ Schema:
|
||||
"filesystem": string,
|
||||
"mount_point": string,
|
||||
"type": string,
|
||||
"access": [
|
||||
"options": [
|
||||
string
|
||||
]
|
||||
}
|
||||
@@ -39,7 +39,7 @@ Example:
|
||||
"filesystem": "sysfs",
|
||||
"mount_point": "/sys",
|
||||
"type": "sysfs",
|
||||
"access": [
|
||||
"options": [
|
||||
"rw",
|
||||
"nosuid",
|
||||
"nodev",
|
||||
@@ -51,7 +51,7 @@ Example:
|
||||
"filesystem": "proc",
|
||||
"mount_point": "/proc",
|
||||
"type": "proc",
|
||||
"access": [
|
||||
"options": [
|
||||
"rw",
|
||||
"nosuid",
|
||||
"nodev",
|
||||
@@ -63,7 +63,7 @@ Example:
|
||||
"filesystem": "udev",
|
||||
"mount_point": "/dev",
|
||||
"type": "devtmpfs",
|
||||
"access": [
|
||||
"options": [
|
||||
"rw",
|
||||
"nosuid",
|
||||
"relatime",
|
||||
@@ -96,6 +96,6 @@ Returns:
|
||||
List of Dictionaries. Raw or processed structured data.
|
||||
|
||||
### Parser Information
|
||||
Compatibility: linux, darwin, freebsd
|
||||
Compatibility: linux, darwin, freebsd, aix
|
||||
|
||||
Version 1.7 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.9 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -376,6 +376,6 @@ Returns:
|
||||
List of Dictionaries. Raw or processed structured data.
|
||||
|
||||
### Parser Information
|
||||
Compatibility: linux, darwin, freebsd
|
||||
Compatibility: linux, darwin, freebsd, win32
|
||||
|
||||
Version 1.13 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.15 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
90
docs/parsers/nsd_control.md
Normal file
90
docs/parsers/nsd_control.md
Normal file
@@ -0,0 +1,90 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
<a id="jc.parsers.nsd_control"></a>
|
||||
|
||||
# jc.parsers.nsd\_control
|
||||
|
||||
jc - JSON Convert `nsd-control` command output parser
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ nsd-control | jc --nsd-control
|
||||
|
||||
or
|
||||
|
||||
$ jc nsd-control
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc
|
||||
result = jc.parse('nsd_control', nsd_control_command_output)
|
||||
|
||||
Schema:
|
||||
|
||||
[
|
||||
{
|
||||
"version": string,
|
||||
"verbosity": integer,
|
||||
"ratelimit": integer
|
||||
}
|
||||
]
|
||||
|
||||
[
|
||||
{
|
||||
"zone": string
|
||||
"status": {
|
||||
"state": string,
|
||||
"served-serial": string,
|
||||
"commit-serial": string,
|
||||
"wait": string
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
Examples:
|
||||
|
||||
$ nsd-control | jc --nsd-control status
|
||||
[
|
||||
{
|
||||
"version": "4.6.2",
|
||||
"verbosity": "2",
|
||||
"ratelimit": "0"
|
||||
}
|
||||
]
|
||||
|
||||
$ nsd-control | jc --nsd-control zonestatus sunet.se
|
||||
[
|
||||
{
|
||||
"zone": "sunet.se",
|
||||
"status": {
|
||||
"state": "ok",
|
||||
"served-serial": "2023090704 since 2023-09-07T16:34:27",
|
||||
"commit-serial": "2023090704 since 2023-09-07T16:34:27",
|
||||
"wait": "28684 sec between attempts"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
<a id="jc.parsers.nsd_control.parse"></a>
|
||||
|
||||
### parse
|
||||
|
||||
```python
|
||||
def parse(data: str, raw: bool = False, quiet: bool = False)
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) unprocessed output if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of Dictionaries. Raw or processed structured data.
|
||||
|
||||
### Parser Information
|
||||
Compatibility: linux, darwin, cygwin, win32, aix, freebsd
|
||||
|
||||
Version 1.0 by Pettai (pettai@sunet.se)
|
||||
86
docs/parsers/os_release.md
Normal file
86
docs/parsers/os_release.md
Normal file
@@ -0,0 +1,86 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
<a id="jc.parsers.os_release"></a>
|
||||
|
||||
# jc.parsers.os\_release
|
||||
|
||||
jc - JSON Convert `/etc/os-release` file parser
|
||||
|
||||
This parser is an alias to the Key/Value parser (`--kv`).
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ cat /etc/os-release | jc --os-release
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc
|
||||
result = jc.parse('os_release', os_release_output)
|
||||
|
||||
Schema:
|
||||
|
||||
{
|
||||
"<key>": string
|
||||
}
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat /etc/os-release | jc --os-release -p
|
||||
{
|
||||
"NAME": "CentOS Linux",
|
||||
"VERSION": "7 (Core)",
|
||||
"ID": "centos",
|
||||
"ID_LIKE": "rhel fedora",
|
||||
"VERSION_ID": "7",
|
||||
"PRETTY_NAME": "CentOS Linux 7 (Core)",
|
||||
"ANSI_COLOR": "0;31",
|
||||
"CPE_NAME": "cpe:/o:centos:centos:7",
|
||||
"HOME_URL": "https://www.centos.org/",
|
||||
"BUG_REPORT_URL": "https://bugs.centos.org/",
|
||||
"CENTOS_MANTISBT_PROJECT": "CentOS-7",
|
||||
"CENTOS_MANTISBT_PROJECT_VERSION": "7",
|
||||
"REDHAT_SUPPORT_PRODUCT": "centos",
|
||||
"REDHAT_SUPPORT_PRODUCT_VERSION": "7"
|
||||
}
|
||||
|
||||
$ cat /etc/os-release | jc --os-release -p -r
|
||||
{
|
||||
"NAME": "\\"CentOS Linux\\"",
|
||||
"VERSION": "\\"7 (Core)\\"",
|
||||
"ID": "\\"centos\\"",
|
||||
"ID_LIKE": "\\"rhel fedora\\"",
|
||||
"VERSION_ID": "\\"7\\"",
|
||||
"PRETTY_NAME": "\\"CentOS Linux 7 (Core)\\"",
|
||||
"ANSI_COLOR": "\\"0;31\\"",
|
||||
"CPE_NAME": "\\"cpe:/o:centos:centos:7\\"",
|
||||
"HOME_URL": "\\"https://www.centos.org/\\"",
|
||||
"BUG_REPORT_URL": "\\"https://bugs.centos.org/\\"",
|
||||
"CENTOS_MANTISBT_PROJECT": "\\"CentOS-7\\"",
|
||||
"CENTOS_MANTISBT_PROJECT_VERSION": "\\"7\\"",
|
||||
"REDHAT_SUPPORT_PRODUCT": "\\"centos\\"",
|
||||
"REDHAT_SUPPORT_PRODUCT_VERSION": "\\"7\\""
|
||||
}
|
||||
|
||||
<a id="jc.parsers.os_release.parse"></a>
|
||||
|
||||
### parse
|
||||
|
||||
```python
|
||||
def parse(data: str, raw: bool = False, quiet: bool = False) -> JSONDictType
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) unprocessed output if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary. Raw or processed structured data.
|
||||
|
||||
### Parser Information
|
||||
Compatibility: linux, darwin, cygwin, win32, aix, freebsd
|
||||
|
||||
Version 1.0 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
@@ -45,6 +45,9 @@ Schema:
|
||||
"kb_ccwr_s": float,
|
||||
"cswch_s": float,
|
||||
"nvcswch_s": float,
|
||||
"usr_ms": integer,
|
||||
"system_ms": integer,
|
||||
"guest_ms": integer,
|
||||
"command": string
|
||||
}
|
||||
]
|
||||
@@ -148,4 +151,4 @@ Returns:
|
||||
### Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.1 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -39,6 +39,7 @@ Schema:
|
||||
"percent_usr": float,
|
||||
"percent_system": float,
|
||||
"percent_guest": float,
|
||||
"percent_wait": float,
|
||||
"percent_cpu": float,
|
||||
"cpu": integer,
|
||||
"minflt_s": float,
|
||||
@@ -53,6 +54,9 @@ Schema:
|
||||
"kb_ccwr_s": float,
|
||||
"cswch_s": float,
|
||||
"nvcswch_s": float,
|
||||
"usr_ms": integer,
|
||||
"system_ms": integer,
|
||||
"guest_ms": integer,
|
||||
"command": string,
|
||||
|
||||
# below object only exists if using -qq or ignore_exceptions=True
|
||||
@@ -107,4 +111,4 @@ Returns:
|
||||
### Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.1 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -35,6 +35,8 @@ Schema:
|
||||
"packets_received": integer,
|
||||
"packet_loss_percent": float,
|
||||
"duplicates": integer,
|
||||
"errors": integer,
|
||||
"corrupted": integer,
|
||||
"round_trip_ms_min": float,
|
||||
"round_trip_ms_avg": float,
|
||||
"round_trip_ms_max": float,
|
||||
@@ -185,4 +187,4 @@ Returns:
|
||||
### Parser Information
|
||||
Compatibility: linux, darwin, freebsd
|
||||
|
||||
Version 1.8 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.10 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -36,7 +36,7 @@ Schema:
|
||||
"source_ip": string,
|
||||
"destination_ip": string,
|
||||
"sent_bytes": integer,
|
||||
"pattern": string, # (null if not set)
|
||||
"pattern": string, # null if not set
|
||||
"destination": string,
|
||||
"timestamp": float,
|
||||
"response_bytes": integer,
|
||||
@@ -49,10 +49,12 @@ Schema:
|
||||
"packets_received": integer,
|
||||
"packet_loss_percent": float,
|
||||
"duplicates": integer,
|
||||
"round_trip_ms_min": float,
|
||||
"round_trip_ms_avg": float,
|
||||
"round_trip_ms_max": float,
|
||||
"round_trip_ms_stddev": float,
|
||||
"errors": integer, # null if not set
|
||||
"corrupted": integer, # null if not set
|
||||
"round_trip_ms_min": float, # null if not set
|
||||
"round_trip_ms_avg": float, # null if not set
|
||||
"round_trip_ms_max": float, # null if not set
|
||||
"round_trip_ms_stddev": float, # null if not set
|
||||
|
||||
# below object only exists if using -qq or ignore_exceptions=True
|
||||
"_jc_meta": {
|
||||
@@ -106,4 +108,4 @@ Returns:
|
||||
### Parser Information
|
||||
Compatibility: linux, darwin, freebsd
|
||||
|
||||
Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
126
docs/parsers/pkg_index_apk.md
Normal file
126
docs/parsers/pkg_index_apk.md
Normal file
@@ -0,0 +1,126 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
<a id="jc.parsers.pkg_index_apk"></a>
|
||||
|
||||
# jc.parsers.pkg\_index\_apk
|
||||
|
||||
jc - JSON Convert Alpine Linux Package Index files
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ cat APKINDEX | jc --pkg-index-apk
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc
|
||||
result = jc.parse('pkg_index_apk', pkg_index_apk_output)
|
||||
|
||||
Schema:
|
||||
|
||||
[
|
||||
{
|
||||
"checksum": string,
|
||||
"package": string,
|
||||
"version": string,
|
||||
"architecture": string,
|
||||
"package_size": integer,
|
||||
"installed_size": integer,
|
||||
"description": string,
|
||||
"url": string,
|
||||
"license": string,
|
||||
"origin": string,
|
||||
"maintainer": {
|
||||
"name": string,
|
||||
"email": string,
|
||||
},
|
||||
"build_time": integer,
|
||||
"commit": string,
|
||||
"provider_priority": string,
|
||||
"dependencies": [
|
||||
string
|
||||
],
|
||||
"provides": [
|
||||
string
|
||||
],
|
||||
"install_if": [
|
||||
string
|
||||
],
|
||||
}
|
||||
]
|
||||
|
||||
Example:
|
||||
|
||||
$ cat APKINDEX | jc --pkg-index-apk
|
||||
[
|
||||
{
|
||||
"checksum": "Q1znBl9k+RKgY6gl5Eg3iz73KZbLY=",
|
||||
"package": "yasm",
|
||||
"version": "1.3.0-r4",
|
||||
"architecture": "x86_64",
|
||||
"package_size": 772109,
|
||||
"installed_size": 1753088,
|
||||
"description": "A rewrite of NASM to allow for multiple synta...",
|
||||
"url": "http://www.tortall.net/projects/yasm/",
|
||||
"license": "BSD-2-Clause",
|
||||
"origin": "yasm",
|
||||
"maintainer": {
|
||||
"name": "Natanael Copa",
|
||||
"email": "ncopa@alpinelinux.org"
|
||||
},
|
||||
"build_time": 1681228881,
|
||||
"commit": "84a227baf001b6e0208e3352b294e4d7a40e93de",
|
||||
"dependencies": [
|
||||
"so:libc.musl-x86_64.so.1"
|
||||
],
|
||||
"provides": [
|
||||
"cmd:vsyasm=1.3.0-r4",
|
||||
"cmd:yasm=1.3.0-r4",
|
||||
"cmd:ytasm=1.3.0-r4"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
$ cat APKINDEX | jc --pkg-index-apk --raw
|
||||
[
|
||||
{
|
||||
"C": "Q1znBl9k+RKgY6gl5Eg3iz73KZbLY=",
|
||||
"P": "yasm",
|
||||
"V": "1.3.0-r4",
|
||||
"A": "x86_64",
|
||||
"S": "772109",
|
||||
"I": "1753088",
|
||||
"T": "A rewrite of NASM to allow for multiple syntax supported...",
|
||||
"U": "http://www.tortall.net/projects/yasm/",
|
||||
"L": "BSD-2-Clause",
|
||||
"o": "yasm",
|
||||
"m": "Natanael Copa <ncopa@alpinelinux.org>",
|
||||
"t": "1681228881",
|
||||
"c": "84a227baf001b6e0208e3352b294e4d7a40e93de",
|
||||
"D": "so:libc.musl-x86_64.so.1",
|
||||
"p": "cmd:vsyasm=1.3.0-r4 cmd:yasm=1.3.0-r4 cmd:ytasm=1.3.0-r4"
|
||||
},
|
||||
]
|
||||
|
||||
<a id="jc.parsers.pkg_index_apk.parse"></a>
|
||||
|
||||
### parse
|
||||
|
||||
```python
|
||||
def parse(data: str, raw: bool = False, quiet: bool = False) -> List[Dict]
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) unprocessed output if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of Dictionaries. Raw or processed structured data.
|
||||
|
||||
### Parser Information
|
||||
Compatibility: linux, darwin, cygwin, win32, aix, freebsd
|
||||
|
||||
Version 1.0 by Roey Darwish Dror (roey.ghost@gmail.com)
|
||||
138
docs/parsers/pkg_index_deb.md
Normal file
138
docs/parsers/pkg_index_deb.md
Normal file
@@ -0,0 +1,138 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
<a id="jc.parsers.pkg_index_deb"></a>
|
||||
|
||||
# jc.parsers.pkg\_index\_deb
|
||||
|
||||
jc - JSON Convert Debian Package Index file parser
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ cat Packages | jc --pkg-index-deb
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc
|
||||
result = jc.parse('pkg_index_deb', pkg_index_deb_output)
|
||||
|
||||
Schema:
|
||||
|
||||
[
|
||||
{
|
||||
"package": string,
|
||||
"version": string,
|
||||
"architecture": string,
|
||||
"section": string,
|
||||
"priority": string,
|
||||
"installed_size": integer,
|
||||
"maintainer": string,
|
||||
"description": string,
|
||||
"homepage": string,
|
||||
"depends": string,
|
||||
"conflicts": string,
|
||||
"replaces": string,
|
||||
"vcs_git": string,
|
||||
"sha256": string,
|
||||
"size": integer,
|
||||
"vcs_git": string,
|
||||
"filename": string
|
||||
}
|
||||
]
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat Packages | jc --pkg-index-deb
|
||||
[
|
||||
{
|
||||
"package": "aspnetcore-runtime-2.1",
|
||||
"version": "2.1.22-1",
|
||||
"architecture": "amd64",
|
||||
"section": "devel",
|
||||
"priority": "standard",
|
||||
"installed_size": 71081,
|
||||
"maintainer": "Microsoft <nugetaspnet@microsoft.com>",
|
||||
"description": "Microsoft ASP.NET Core 2.1.22 Shared Framework",
|
||||
"homepage": "https://www.asp.net/",
|
||||
"depends": "libc6 (>= 2.14), dotnet-runtime-2.1 (>= 2.1.22)",
|
||||
"sha256": "48d4e78a7ceff34105411172f4c3e91a0359b3929d84d26a493...",
|
||||
"size": 21937036,
|
||||
"filename": "pool/main/a/aspnetcore-runtime-2.1/aspnetcore-run..."
|
||||
},
|
||||
{
|
||||
"package": "azure-functions-core-tools-4",
|
||||
"version": "4.0.4590-1",
|
||||
"architecture": "amd64",
|
||||
"section": "devel",
|
||||
"priority": "optional",
|
||||
"maintainer": "Ahmed ElSayed <ahmels@microsoft.com>",
|
||||
"description": "Azure Function Core Tools v4",
|
||||
"homepage": "https://docs.microsoft.com/en-us/azure/azure-func...",
|
||||
"conflicts": "azure-functions-core-tools-2, azure-functions-co...",
|
||||
"replaces": "azure-functions-core-tools-2, azure-functions-cor...",
|
||||
"vcs_git": "https://github.com/Azure/azure-functions-core-tool...",
|
||||
"sha256": "a2a4f99d6d98ba0a46832570285552f2a93bab06cebbda2afc7...",
|
||||
"size": 124417844,
|
||||
"filename": "pool/main/a/azure-functions-core-tools-4/azure-fu..."
|
||||
}
|
||||
]
|
||||
|
||||
$ cat Packages | jc --pkg-index-deb -r
|
||||
[
|
||||
{
|
||||
"package": "aspnetcore-runtime-2.1",
|
||||
"version": "2.1.22-1",
|
||||
"architecture": "amd64",
|
||||
"section": "devel",
|
||||
"priority": "standard",
|
||||
"installed_size": "71081",
|
||||
"maintainer": "Microsoft <nugetaspnet@microsoft.com>",
|
||||
"description": "Microsoft ASP.NET Core 2.1.22 Shared Framework",
|
||||
"homepage": "https://www.asp.net/",
|
||||
"depends": "libc6 (>= 2.14), dotnet-runtime-2.1 (>= 2.1.22)",
|
||||
"sha256": "48d4e78a7ceff34105411172f4c3e91a0359b3929d84d26a493...",
|
||||
"size": "21937036",
|
||||
"filename": "pool/main/a/aspnetcore-runtime-2.1/aspnetcore-run..."
|
||||
},
|
||||
{
|
||||
"package": "azure-functions-core-tools-4",
|
||||
"version": "4.0.4590-1",
|
||||
"architecture": "amd64",
|
||||
"section": "devel",
|
||||
"priority": "optional",
|
||||
"maintainer": "Ahmed ElSayed <ahmels@microsoft.com>",
|
||||
"description": "Azure Function Core Tools v4",
|
||||
"homepage": "https://docs.microsoft.com/en-us/azure/azure-func...",
|
||||
"conflicts": "azure-functions-core-tools-2, azure-functions-co...",
|
||||
"replaces": "azure-functions-core-tools-2, azure-functions-cor...",
|
||||
"vcs_git": "https://github.com/Azure/azure-functions-core-tool...",
|
||||
"sha256": "a2a4f99d6d98ba0a46832570285552f2a93bab06cebbda2afc7...",
|
||||
"size": "124417844",
|
||||
"filename": "pool/main/a/azure-functions-core-tools-4/azure-fu..."
|
||||
}
|
||||
]
|
||||
|
||||
<a id="jc.parsers.pkg_index_deb.parse"></a>
|
||||
|
||||
### parse
|
||||
|
||||
```python
|
||||
def parse(data: str,
|
||||
raw: bool = False,
|
||||
quiet: bool = False) -> List[JSONDictType]
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) unprocessed output if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of Dictionaries. Raw or processed structured data.
|
||||
|
||||
### Parser Information
|
||||
Compatibility: linux, darwin, cygwin, win32, aix, freebsd
|
||||
|
||||
Version 1.0 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
@@ -139,4 +139,4 @@ Returns:
|
||||
### Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.1 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
92
docs/parsers/proc_cmdline.md
Normal file
92
docs/parsers/proc_cmdline.md
Normal file
@@ -0,0 +1,92 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
<a id="jc.parsers.proc_cmdline"></a>
|
||||
|
||||
# jc.parsers.proc\_cmdline
|
||||
|
||||
jc - JSON Convert `/proc/cmdline` file parser
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ cat /proc/cmdline | jc --proc
|
||||
|
||||
or
|
||||
|
||||
$ jc /proc/cmdline
|
||||
|
||||
or
|
||||
|
||||
$ cat /proc/cmdline | jc --proc-cmdline
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc
|
||||
result = jc.parse('proc_cmdline', proc_cmdline_file)
|
||||
|
||||
Schema:
|
||||
|
||||
{
|
||||
"<key>": string,
|
||||
"_options": [
|
||||
string
|
||||
]
|
||||
}
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat /proc/cmdline | jc --proc -p
|
||||
{
|
||||
"BOOT_IMAGE": "clonezilla/live/vmlinuz",
|
||||
"consoleblank": "0",
|
||||
"keyboard-options": "grp:ctrl_shift_toggle,lctrl_shift_toggle",
|
||||
"ethdevice-timeout": "130",
|
||||
"toram": "filesystem.squashfs",
|
||||
"boot": "live",
|
||||
"edd": "on",
|
||||
"ocs_daemonon": "ssh lighttpd",
|
||||
"ocs_live_run": "sudo screen /usr/sbin/ocs-sr -g auto -e1 auto -e2 -batch -r -j2 -k -scr -p true restoreparts win7-64 sda1",
|
||||
"ocs_live_extra_param": "",
|
||||
"keyboard-layouts": "us,ru",
|
||||
"ocs_live_batch": "no",
|
||||
"locales": "ru_RU.UTF-8",
|
||||
"vga": "788",
|
||||
"net.ifnames": "0",
|
||||
"union": "overlay",
|
||||
"fetch": "http://10.1.1.1/tftpboot/clonezilla/live/filesystem.squashfs",
|
||||
"ocs_postrun99": "sudo reboot",
|
||||
"initrd": "clonezilla/live/initrd.img",
|
||||
"_options": [
|
||||
"config",
|
||||
"noswap",
|
||||
"nolocales",
|
||||
"nomodeset",
|
||||
"noprompt",
|
||||
"nosplash",
|
||||
"nodmraid",
|
||||
"components"
|
||||
]
|
||||
}
|
||||
|
||||
<a id="jc.parsers.proc_cmdline.parse"></a>
|
||||
|
||||
### parse
|
||||
|
||||
```python
|
||||
def parse(data: str, raw: bool = False, quiet: bool = False) -> JSONDictType
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) unprocessed output if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary. Raw or processed structured data.
|
||||
|
||||
### Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.0 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
186
docs/parsers/proc_net_tcp.md
Normal file
186
docs/parsers/proc_net_tcp.md
Normal file
@@ -0,0 +1,186 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
<a id="jc.parsers.proc_net_tcp"></a>
|
||||
|
||||
# jc.parsers.proc\_net\_tcp
|
||||
|
||||
jc - JSON Convert `/proc/net/tcp` and `proc/net/tcp6` file parser
|
||||
|
||||
IPv4 and IPv6 addresses are converted to standard notation unless the raw
|
||||
(--raw) option is used.
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ cat /proc/net/tcp | jc --proc
|
||||
|
||||
or
|
||||
|
||||
$ jc /proc/net/tcp
|
||||
|
||||
or
|
||||
|
||||
$ cat /proc/net/tcp | jc --proc-net-tcp
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc
|
||||
result = jc.parse('proc', proc_net_tcp_file)
|
||||
|
||||
or
|
||||
|
||||
import jc
|
||||
result = jc.parse('proc_net_tcp', proc_net_tcp_file)
|
||||
|
||||
Schema:
|
||||
|
||||
Field names and types gathered from the following:
|
||||
|
||||
https://www.kernel.org/doc/Documentation/networking/proc_net_tcp.txt
|
||||
|
||||
https://github.com/torvalds/linux/blob/master/net/ipv4/tcp_ipv4.c
|
||||
|
||||
https://github.com/torvalds/linux/blob/master/net/ipv6/tcp_ipv6.c
|
||||
|
||||
[
|
||||
{
|
||||
"entry": integer,
|
||||
"local_address": string,
|
||||
"local_port": integer,
|
||||
"remote_address": string,
|
||||
"remote_port": integer,
|
||||
"state": string,
|
||||
"tx_queue": string,
|
||||
"rx_queue": string,
|
||||
"timer_active": integer,
|
||||
"jiffies_until_timer_expires": string,
|
||||
"unrecovered_rto_timeouts": string,
|
||||
"uid": integer,
|
||||
"unanswered_0_window_probes": integer,
|
||||
"inode": integer,
|
||||
"sock_ref_count": integer,
|
||||
"sock_mem_loc": string,
|
||||
"retransmit_timeout": integer,
|
||||
"soft_clock_tick": integer,
|
||||
"ack_quick_pingpong": integer,
|
||||
"sending_congestion_window": integer,
|
||||
"slow_start_size_threshold": integer
|
||||
}
|
||||
]
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat /proc/net/tcp | jc --proc -p
|
||||
[
|
||||
{
|
||||
"entry": "0",
|
||||
"local_address": "10.0.0.28",
|
||||
"local_port": 42082,
|
||||
"remote_address": "64.12.0.108",
|
||||
"remote_port": 80,
|
||||
"state": "04",
|
||||
"tx_queue": "00000001",
|
||||
"rx_queue": "00000000",
|
||||
"timer_active": 1,
|
||||
"jiffies_until_timer_expires": "00000015",
|
||||
"unrecovered_rto_timeouts": "00000000",
|
||||
"uid": 0,
|
||||
"unanswered_0_window_probes": 0,
|
||||
"inode": 0,
|
||||
"sock_ref_count": 3,
|
||||
"sock_mem_loc": "ffff8c7a0de930c0",
|
||||
"retransmit_timeout": 21,
|
||||
"soft_clock_tick": 4,
|
||||
"ack_quick_pingpong": 30,
|
||||
"sending_congestion_window": 10,
|
||||
"slow_start_size_threshold": -1
|
||||
},
|
||||
{
|
||||
"entry": "1",
|
||||
"local_address": "10.0.0.28",
|
||||
"local_port": 38864,
|
||||
"remote_address": "104.244.42.65",
|
||||
"remote_port": 80,
|
||||
"state": "06",
|
||||
"tx_queue": "00000000",
|
||||
"rx_queue": "00000000",
|
||||
"timer_active": 3,
|
||||
"jiffies_until_timer_expires": "000007C5",
|
||||
"unrecovered_rto_timeouts": "00000000",
|
||||
"uid": 0,
|
||||
"unanswered_0_window_probes": 0,
|
||||
"inode": 0,
|
||||
"sock_ref_count": 3,
|
||||
"sock_mem_loc": "ffff8c7a12d31aa0"
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
$ cat /proc/net/tcp | jc --proc -p -r
|
||||
[
|
||||
{
|
||||
"entry": "1",
|
||||
"local_address": "1C00000A",
|
||||
"local_port": "A462",
|
||||
"remote_address": "6C000C40",
|
||||
"remote_port": "0050",
|
||||
"state": "04",
|
||||
"tx_queue": "00000001",
|
||||
"rx_queue": "00000000",
|
||||
"timer_active": "01",
|
||||
"jiffies_until_timer_expires": "00000015",
|
||||
"unrecovered_rto_timeouts": "00000000",
|
||||
"uid": "0",
|
||||
"unanswered_0_window_probes": "0",
|
||||
"inode": "0",
|
||||
"sock_ref_count": "3",
|
||||
"sock_mem_loc": "ffff8c7a0de930c0",
|
||||
"retransmit_timeout": "21",
|
||||
"soft_clock_tick": "4",
|
||||
"ack_quick_pingpong": "30",
|
||||
"sending_congestion_window": "10",
|
||||
"slow_start_size_threshold": "-1"
|
||||
},
|
||||
{
|
||||
"entry": "2",
|
||||
"local_address": "1C00000A",
|
||||
"local_port": "97D0",
|
||||
"remote_address": "412AF468",
|
||||
"remote_port": "0050",
|
||||
"state": "06",
|
||||
"tx_queue": "00000000",
|
||||
"rx_queue": "00000000",
|
||||
"timer_active": "03",
|
||||
"jiffies_until_timer_expires": "000007C5",
|
||||
"unrecovered_rto_timeouts": "00000000",
|
||||
"uid": "0",
|
||||
"unanswered_0_window_probes": "0",
|
||||
"inode": "0",
|
||||
"sock_ref_count": "3",
|
||||
"sock_mem_loc": "ffff8c7a12d31aa0"
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
<a id="jc.parsers.proc_net_tcp.parse"></a>
|
||||
|
||||
### parse
|
||||
|
||||
```python
|
||||
def parse(data: str, raw: bool = False, quiet: bool = False) -> List[Dict]
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) unprocessed output if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of Dictionaries. Raw or processed structured data.
|
||||
|
||||
### Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.0 by Alvin Solomon (alvinms01@gmail.com)
|
||||
@@ -114,7 +114,8 @@ Examples:
|
||||
"mw",
|
||||
"me",
|
||||
"dw",
|
||||
"sd"
|
||||
"sd",
|
||||
"mp"
|
||||
],
|
||||
"VmFlags_pretty": [
|
||||
"readable",
|
||||
|
||||
83
docs/parsers/resolve_conf.md
Normal file
83
docs/parsers/resolve_conf.md
Normal file
@@ -0,0 +1,83 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
<a id="jc.parsers.resolve_conf"></a>
|
||||
|
||||
# jc.parsers.resolve\_conf
|
||||
|
||||
jc - JSON Convert `/etc/resolve.conf` file parser
|
||||
|
||||
This parser may be more forgiving than the system parser. For example, if
|
||||
multiple `search` lists are defined, this parser will append all entries to
|
||||
the `search` field, while the system parser may only use the list from the
|
||||
last defined instance.
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ cat /etc/resolve.conf | jc --resolve-conf
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc
|
||||
result = jc.parse('resolve_conf', resolve_conf_output)
|
||||
|
||||
Schema:
|
||||
|
||||
{
|
||||
"domain": string,
|
||||
"search": [
|
||||
string
|
||||
],
|
||||
"nameservers": [
|
||||
string
|
||||
],
|
||||
"options": [
|
||||
string
|
||||
],
|
||||
"sortlist": [
|
||||
string
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat /etc/resolve.conf | jc --resolve-conf -p
|
||||
{
|
||||
"search": [
|
||||
"eng.myprime.com",
|
||||
"dev.eng.myprime.com",
|
||||
"labs.myprime.com",
|
||||
"qa.myprime.com"
|
||||
],
|
||||
"nameservers": [
|
||||
"10.136.17.15"
|
||||
],
|
||||
"options": [
|
||||
"rotate",
|
||||
"ndots:1"
|
||||
]
|
||||
}
|
||||
|
||||
<a id="jc.parsers.resolve_conf.parse"></a>
|
||||
|
||||
### parse
|
||||
|
||||
```python
|
||||
def parse(data: str, raw: bool = False, quiet: bool = False) -> JSONDictType
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) unprocessed output if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary. Raw or processed structured data.
|
||||
|
||||
### Parser Information
|
||||
Compatibility: linux, darwin, cygwin, win32, aix, freebsd
|
||||
|
||||
Version 1.0 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
@@ -22,6 +22,13 @@ Schema:
|
||||
|
||||
[
|
||||
{
|
||||
"interfaces": [
|
||||
{
|
||||
"id": string,
|
||||
"mac": string,
|
||||
"name": string,
|
||||
}
|
||||
]
|
||||
"destination": string,
|
||||
"gateway": string,
|
||||
"genmask": string,
|
||||
@@ -129,6 +136,6 @@ Returns:
|
||||
List of Dictionaries. Raw or processed structured data.
|
||||
|
||||
### Parser Information
|
||||
Compatibility: linux
|
||||
Compatibility: linux, win32
|
||||
|
||||
Version 1.8 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.9 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -184,4 +184,4 @@ Returns:
|
||||
### Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.6 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.7 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -7,6 +7,8 @@ jc - JSON Convert Semantic Version string parser
|
||||
|
||||
This parser conforms to the specification at https://semver.org/
|
||||
|
||||
See Also: `ver` parser.
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ echo 1.2.3-rc.1+44837 | jc --semver
|
||||
|
||||
136
docs/parsers/srt.md
Normal file
136
docs/parsers/srt.md
Normal file
@@ -0,0 +1,136 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
<a id="jc.parsers.srt"></a>
|
||||
|
||||
# jc.parsers.srt
|
||||
|
||||
jc - JSON Convert `SRT` file parser
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ cat foo.srt | jc --srt
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc
|
||||
result = jc.parse('srt', srt_file_output)
|
||||
|
||||
Schema:
|
||||
|
||||
[
|
||||
{
|
||||
"index": int,
|
||||
"start": {
|
||||
"hours": int,
|
||||
"minutes": int,
|
||||
"seconds": int,
|
||||
"milliseconds": int,
|
||||
"timestamp": string
|
||||
},
|
||||
"end": {
|
||||
"hours": int,
|
||||
"minutes": int,
|
||||
"seconds": int,
|
||||
"milliseconds": int,
|
||||
"timestamp": string
|
||||
},
|
||||
"content": string
|
||||
}
|
||||
]
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat attack_of_the_clones.srt
|
||||
1
|
||||
00:02:16,612 --> 00:02:19,376
|
||||
Senator, we're making
|
||||
our final approach into Coruscant.
|
||||
|
||||
2
|
||||
00:02:19,482 --> 00:02:21,609
|
||||
Very good, Lieutenant.
|
||||
...
|
||||
|
||||
$ cat attack_of_the_clones.srt | jc --srt
|
||||
[
|
||||
{
|
||||
"index": 1,
|
||||
"start": {
|
||||
"hours": 0,
|
||||
"minutes": 2,
|
||||
"seconds": 16,
|
||||
"milliseconds": 612,
|
||||
"timestamp": "00:02:16,612"
|
||||
},
|
||||
"end": {
|
||||
"hours": 0,
|
||||
"minutes": 2,
|
||||
"seconds": 19,
|
||||
"milliseconds": 376,
|
||||
"timestamp": "00:02:19,376"
|
||||
},
|
||||
"content": "Senator, we're making\nour final approach into Coruscant."
|
||||
},
|
||||
{
|
||||
"index": 2,
|
||||
"start": {
|
||||
"hours": 0,
|
||||
"minutes": 2,
|
||||
"seconds": 19,
|
||||
"milliseconds": 482,
|
||||
"timestamp": "00:02:19,482"
|
||||
},
|
||||
"end": {
|
||||
"hours": 0,
|
||||
"minutes": 2,
|
||||
"seconds": 21,
|
||||
"milliseconds": 609,
|
||||
"timestamp": "00:02:21,609"
|
||||
},
|
||||
"content": "Very good, Lieutenant."
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
<a id="jc.parsers.srt.parse_timestamp"></a>
|
||||
|
||||
### parse\_timestamp
|
||||
|
||||
```python
|
||||
def parse_timestamp(timestamp: str) -> Dict
|
||||
```
|
||||
|
||||
timestamp: "hours:minutes:seconds,milliseconds" --->
|
||||
{
|
||||
"hours": "hours",
|
||||
"minutes": "minutes",
|
||||
"seconds": "seconds",
|
||||
"milliseconds": "milliseconds",
|
||||
"timestamp": "hours:minutes:seconds,milliseconds"
|
||||
}
|
||||
|
||||
<a id="jc.parsers.srt.parse"></a>
|
||||
|
||||
### parse
|
||||
|
||||
```python
|
||||
def parse(data: str,
|
||||
raw: bool = False,
|
||||
quiet: bool = False) -> List[JSONDictType]
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) unprocessed output if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary. Raw or processed structured data.
|
||||
|
||||
### Parser Information
|
||||
Compatibility: linux, darwin, cygwin, win32, aix, freebsd
|
||||
|
||||
Version 1.0 by Mark Rotner (rotner.mr@gmail.com)
|
||||
@@ -5,9 +5,6 @@
|
||||
|
||||
jc - JSON Convert `ss` command output parser
|
||||
|
||||
Extended information options like `-e` and `-p` are not supported and may
|
||||
cause parsing irregularities.
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ ss | jc --ss
|
||||
@@ -28,21 +25,29 @@ field names
|
||||
|
||||
[
|
||||
{
|
||||
"netid": string,
|
||||
"state": string,
|
||||
"recv_q": integer,
|
||||
"send_q": integer,
|
||||
"local_address": string,
|
||||
"local_port": string,
|
||||
"local_port_num": integer,
|
||||
"peer_address": string,
|
||||
"peer_port": string,
|
||||
"peer_port_num": integer,
|
||||
"interface": string,
|
||||
"link_layer" string,
|
||||
"channel": string,
|
||||
"path": string,
|
||||
"pid": integer
|
||||
"netid": string,
|
||||
"state": string,
|
||||
"recv_q": integer,
|
||||
"send_q": integer,
|
||||
"local_address": string,
|
||||
"local_port": string,
|
||||
"local_port_num": integer,
|
||||
"peer_address": string,
|
||||
"peer_port": string,
|
||||
"peer_port_num": integer,
|
||||
"interface": string,
|
||||
"link_layer" string,
|
||||
"channel": string,
|
||||
"path": string,
|
||||
"pid": integer,
|
||||
"opts": {
|
||||
"process_id": {
|
||||
"<process_id>": {
|
||||
"user": string,
|
||||
"file_descriptor": string
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -303,4 +308,4 @@ Returns:
|
||||
### Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.6 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.7 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
548
docs/parsers/ssh_conf.md
Normal file
548
docs/parsers/ssh_conf.md
Normal file
@@ -0,0 +1,548 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
<a id="jc.parsers.ssh_conf"></a>
|
||||
|
||||
# jc.parsers.ssh\_conf
|
||||
|
||||
jc - JSON Convert `ssh` configuration file and `ssh -G` command output parser
|
||||
|
||||
This parser will work with `ssh` configuration files or the output of
|
||||
`ssh -G`. Any `Match` blocks in the `ssh` configuration file will be
|
||||
ignored.
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ ssh -G hostname | jc --ssh-conf
|
||||
|
||||
or
|
||||
|
||||
$ jc ssh -G hostname
|
||||
|
||||
or
|
||||
|
||||
$ cat ~/.ssh/config | jc --ssh-conf
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc
|
||||
result = jc.parse('ssh_conf', ssh_conf_output)
|
||||
|
||||
Schema:
|
||||
|
||||
[
|
||||
{
|
||||
"host": string,
|
||||
"host_list": [
|
||||
string
|
||||
],
|
||||
"addkeystoagent": string,
|
||||
"addressfamily": string,
|
||||
"batchmode": string,
|
||||
"bindaddress": string,
|
||||
"bindinterface": string,
|
||||
"canonicaldomains": [
|
||||
string
|
||||
],
|
||||
"canonicalizefallbacklocal": string,
|
||||
"canonicalizehostname": string,
|
||||
"canonicalizemaxdots": integer,
|
||||
"canonicalizepermittedcnames": [
|
||||
string
|
||||
],
|
||||
"casignaturealgorithms": [
|
||||
string
|
||||
],
|
||||
"certificatefile": [
|
||||
string
|
||||
],
|
||||
"checkhostip": string,
|
||||
"ciphers": [
|
||||
string
|
||||
],
|
||||
"clearallforwardings": string,
|
||||
"compression": string,
|
||||
"connectionattempts": integer,
|
||||
"connecttimeout": integer,
|
||||
"controlmaster": string,
|
||||
"controlpath": string,
|
||||
"controlpersist": string,
|
||||
"dynamicforward": string,
|
||||
"enableescapecommandline": string,
|
||||
"enablesshkeysign": string,
|
||||
"escapechar": string,
|
||||
"exitonforwardfailure": string,
|
||||
"fingerprinthash": string,
|
||||
"forkafterauthentication": string,
|
||||
"forwardagent": string,
|
||||
"forwardx11": string,
|
||||
"forwardx11timeout": integer,
|
||||
"forwardx11trusted": string,
|
||||
"gatewayports": string,
|
||||
"globalknownhostsfile": [
|
||||
string
|
||||
],
|
||||
"gssapiauthentication": string,
|
||||
"gssapidelegatecredentials": string,
|
||||
"hashknownhosts": string,
|
||||
"hostbasedacceptedalgorithms": [
|
||||
string
|
||||
],
|
||||
"hostbasedauthentication": string,
|
||||
"hostkeyalgorithms": [
|
||||
string
|
||||
],
|
||||
"hostkeyalias": string,
|
||||
"hostname": string,
|
||||
"identitiesonly": string,
|
||||
"identityagent": string,
|
||||
"identityfile": [
|
||||
string
|
||||
],
|
||||
"ignoreunknown": string,
|
||||
"include": [
|
||||
string
|
||||
],
|
||||
"ipqos": [
|
||||
string
|
||||
],
|
||||
"kbdinteractiveauthentication": string,
|
||||
"kbdinteractivedevices": [
|
||||
string
|
||||
],
|
||||
"kexalgorithms": [
|
||||
string
|
||||
],
|
||||
"kexalgorithms_strategy": string,
|
||||
"knownhostscommand": string,
|
||||
"localcommand": string,
|
||||
"localforward": [
|
||||
string
|
||||
],
|
||||
"loglevel": string,
|
||||
"logverbose": [
|
||||
string
|
||||
],
|
||||
"macs": [
|
||||
string
|
||||
],
|
||||
"macs_strategy": string,
|
||||
"nohostauthenticationforlocalhost": string,
|
||||
"numberofpasswordprompts": integer,
|
||||
"passwordauthentication": string,
|
||||
"permitlocalcommand": string,
|
||||
"permitremoteopen": [
|
||||
string
|
||||
],
|
||||
"pkcs11provider": string,
|
||||
"port": integer,
|
||||
"preferredauthentications": [
|
||||
string
|
||||
],
|
||||
"protocol": integer,
|
||||
"proxycommand": string,
|
||||
"proxyjump": [
|
||||
string
|
||||
],
|
||||
"proxyusefdpass": string,
|
||||
"pubkeyacceptedalgorithms": [
|
||||
string
|
||||
],
|
||||
"pubkeyacceptedalgorithms_strategy": string,
|
||||
"pubkeyauthentication": string,
|
||||
"rekeylimit": string,
|
||||
"remotecommand": string,
|
||||
"remoteforward": string,
|
||||
"requesttty": string,
|
||||
"requiredrsasize": integer,
|
||||
"revokedhostkeys": string,
|
||||
"securitykeyprovider": string,
|
||||
"sendenv": [
|
||||
string
|
||||
],
|
||||
"serveralivecountmax": integer,
|
||||
"serveraliveinterval": integer,
|
||||
"sessiontype": string,
|
||||
"setenv": [
|
||||
string
|
||||
],
|
||||
"stdinnull": string,
|
||||
"streamlocalbindmask": string,
|
||||
"streamlocalbindunlink": string,
|
||||
"stricthostkeychecking": string,
|
||||
"syslogfacility": string,
|
||||
"tcpkeepalive": string,
|
||||
"tunnel": string,
|
||||
"tunneldevice": string,
|
||||
"updatehostkeys": string,
|
||||
"user": string,
|
||||
"userknownhostsfile": [
|
||||
string
|
||||
],
|
||||
"verifyhostkeydns": string,
|
||||
"visualhostkey": string,
|
||||
"xauthlocation": string
|
||||
}
|
||||
]
|
||||
|
||||
Examples:
|
||||
|
||||
$ ssh -G - | jc --ssh-conf -p
|
||||
[
|
||||
{
|
||||
"user": "foo",
|
||||
"hostname": "-",
|
||||
"port": 22,
|
||||
"addressfamily": "any",
|
||||
"batchmode": "no",
|
||||
"canonicalizefallbacklocal": "yes",
|
||||
"canonicalizehostname": "false",
|
||||
"checkhostip": "no",
|
||||
"compression": "no",
|
||||
"controlmaster": "false",
|
||||
"enablesshkeysign": "no",
|
||||
"clearallforwardings": "no",
|
||||
"exitonforwardfailure": "no",
|
||||
"fingerprinthash": "SHA256",
|
||||
"forwardx11": "no",
|
||||
"forwardx11trusted": "no",
|
||||
"gatewayports": "no",
|
||||
"gssapiauthentication": "no",
|
||||
"gssapidelegatecredentials": "no",
|
||||
"hashknownhosts": "no",
|
||||
"hostbasedauthentication": "no",
|
||||
"identitiesonly": "no",
|
||||
"kbdinteractiveauthentication": "yes",
|
||||
"nohostauthenticationforlocalhost": "no",
|
||||
"passwordauthentication": "yes",
|
||||
"permitlocalcommand": "no",
|
||||
"proxyusefdpass": "no",
|
||||
"pubkeyauthentication": "true",
|
||||
"requesttty": "auto",
|
||||
"sessiontype": "default",
|
||||
"stdinnull": "no",
|
||||
"forkafterauthentication": "no",
|
||||
"streamlocalbindunlink": "no",
|
||||
"stricthostkeychecking": "ask",
|
||||
"tcpkeepalive": "yes",
|
||||
"tunnel": "false",
|
||||
"verifyhostkeydns": "false",
|
||||
"visualhostkey": "no",
|
||||
"updatehostkeys": "true",
|
||||
"applemultipath": "no",
|
||||
"canonicalizemaxdots": 1,
|
||||
"connectionattempts": 1,
|
||||
"forwardx11timeout": 1200,
|
||||
"numberofpasswordprompts": 3,
|
||||
"serveralivecountmax": 3,
|
||||
"serveraliveinterval": 0,
|
||||
"ciphers": [
|
||||
"chacha20-poly1305@openssh.com",
|
||||
"aes128-ctr",
|
||||
"aes192-ctr",
|
||||
"aes256-ctr",
|
||||
"aes128-gcm@openssh.com",
|
||||
"aes256-gcm@openssh.com"
|
||||
],
|
||||
"hostkeyalgorithms": [
|
||||
"ssh-ed25519-cert-v01@openssh.com",
|
||||
"ecdsa-sha2-nistp256-cert-v01@openssh.com",
|
||||
"ecdsa-sha2-nistp384-cert-v01@openssh.com",
|
||||
"ecdsa-sha2-nistp521-cert-v01@openssh.com",
|
||||
"rsa-sha2-512-cert-v01@openssh.com",
|
||||
"rsa-sha2-256-cert-v01@openssh.com",
|
||||
"ssh-ed25519",
|
||||
"ecdsa-sha2-nistp256",
|
||||
"ecdsa-sha2-nistp384",
|
||||
"ecdsa-sha2-nistp521",
|
||||
"rsa-sha2-512",
|
||||
"rsa-sha2-256"
|
||||
],
|
||||
"hostbasedacceptedalgorithms": [
|
||||
"ssh-ed25519-cert-v01@openssh.com",
|
||||
"ecdsa-sha2-nistp256-cert-v01@openssh.com",
|
||||
"ecdsa-sha2-nistp384-cert-v01@openssh.com",
|
||||
"ecdsa-sha2-nistp521-cert-v01@openssh.com",
|
||||
"rsa-sha2-512-cert-v01@openssh.com",
|
||||
"rsa-sha2-256-cert-v01@openssh.com",
|
||||
"ssh-ed25519",
|
||||
"ecdsa-sha2-nistp256",
|
||||
"ecdsa-sha2-nistp384",
|
||||
"ecdsa-sha2-nistp521",
|
||||
"rsa-sha2-512",
|
||||
"rsa-sha2-256"
|
||||
],
|
||||
"kexalgorithms": [
|
||||
"sntrup761x25519-sha512@openssh.com",
|
||||
"curve25519-sha256",
|
||||
"curve25519-sha256@libssh.org",
|
||||
"ecdh-sha2-nistp256",
|
||||
"ecdh-sha2-nistp384",
|
||||
"ecdh-sha2-nistp521",
|
||||
"diffie-hellman-group-exchange-sha256",
|
||||
"diffie-hellman-group16-sha512",
|
||||
"diffie-hellman-group18-sha512",
|
||||
"diffie-hellman-group14-sha256"
|
||||
],
|
||||
"casignaturealgorithms": [
|
||||
"ssh-ed25519",
|
||||
"ecdsa-sha2-nistp256",
|
||||
"ecdsa-sha2-nistp384",
|
||||
"ecdsa-sha2-nistp521",
|
||||
"rsa-sha2-512",
|
||||
"rsa-sha2-256"
|
||||
],
|
||||
"loglevel": "INFO",
|
||||
"macs": [
|
||||
"umac-64-etm@openssh.com",
|
||||
"umac-128-etm@openssh.com",
|
||||
"hmac-sha2-256-etm@openssh.com",
|
||||
"hmac-sha2-512-etm@openssh.com",
|
||||
"hmac-sha1-etm@openssh.com",
|
||||
"umac-64@openssh.com",
|
||||
"umac-128@openssh.com",
|
||||
"hmac-sha2-256",
|
||||
"hmac-sha2-512",
|
||||
"hmac-sha1"
|
||||
],
|
||||
"securitykeyprovider": "$SSH_SK_PROVIDER",
|
||||
"pubkeyacceptedalgorithms": [
|
||||
"ssh-ed25519-cert-v01@openssh.com",
|
||||
"ecdsa-sha2-nistp256-cert-v01@openssh.com",
|
||||
"ecdsa-sha2-nistp384-cert-v01@openssh.com",
|
||||
"ecdsa-sha2-nistp521-cert-v01@openssh.com",
|
||||
"rsa-sha2-512-cert-v01@openssh.com",
|
||||
"rsa-sha2-256-cert-v01@openssh.com",
|
||||
"ssh-ed25519",
|
||||
"ecdsa-sha2-nistp256",
|
||||
"ecdsa-sha2-nistp384",
|
||||
"ecdsa-sha2-nistp521",
|
||||
"rsa-sha2-512",
|
||||
"rsa-sha2-256"
|
||||
],
|
||||
"xauthlocation": "/usr/X11R6/bin/xauth",
|
||||
"identityfile": [
|
||||
"~/.ssh/id_rsa",
|
||||
"~/.ssh/id_ecdsa",
|
||||
"~/.ssh/id_ecdsa_sk",
|
||||
"~/.ssh/id_ed25519",
|
||||
"~/.ssh/id_ed25519_sk",
|
||||
"~/.ssh/id_xmss",
|
||||
"~/.ssh/id_dsa"
|
||||
],
|
||||
"canonicaldomains": [
|
||||
"none"
|
||||
],
|
||||
"globalknownhostsfile": [
|
||||
"/etc/ssh/ssh_known_hosts",
|
||||
"/etc/ssh/ssh_known_hosts2"
|
||||
],
|
||||
"userknownhostsfile": [
|
||||
"/Users/foo/.ssh/known_hosts",
|
||||
"/Users/foo/.ssh/known_hosts2"
|
||||
],
|
||||
"sendenv": [
|
||||
"LANG",
|
||||
"LC_*"
|
||||
],
|
||||
"logverbose": [
|
||||
"none"
|
||||
],
|
||||
"permitremoteopen": [
|
||||
"any"
|
||||
],
|
||||
"addkeystoagent": "false",
|
||||
"forwardagent": "no",
|
||||
"connecttimeout": null,
|
||||
"tunneldevice": "any:any",
|
||||
"canonicalizepermittedcnames": [
|
||||
"none"
|
||||
],
|
||||
"controlpersist": "no",
|
||||
"escapechar": "~",
|
||||
"ipqos": [
|
||||
"af21",
|
||||
"cs1"
|
||||
],
|
||||
"rekeylimit": "0 0",
|
||||
"streamlocalbindmask": "0177",
|
||||
"syslogfacility": "USER"
|
||||
}
|
||||
]
|
||||
|
||||
$ cat ~/.ssh/config | jc --ssh-conf -p
|
||||
[
|
||||
{
|
||||
"host": "server1",
|
||||
"host_list": [
|
||||
"server1"
|
||||
],
|
||||
"hostname": "server1.cyberciti.biz",
|
||||
"user": "nixcraft",
|
||||
"port": 4242,
|
||||
"identityfile": [
|
||||
"/nfs/shared/users/nixcraft/keys/server1/id_rsa"
|
||||
]
|
||||
},
|
||||
{
|
||||
"host": "nas01",
|
||||
"host_list": [
|
||||
"nas01"
|
||||
],
|
||||
"hostname": "192.168.1.100",
|
||||
"user": "root",
|
||||
"identityfile": [
|
||||
"~/.ssh/nas01.key"
|
||||
]
|
||||
},
|
||||
{
|
||||
"host": "aws.apache",
|
||||
"host_list": [
|
||||
"aws.apache"
|
||||
],
|
||||
"hostname": "1.2.3.4",
|
||||
"user": "wwwdata",
|
||||
"identityfile": [
|
||||
"~/.ssh/aws.apache.key"
|
||||
]
|
||||
},
|
||||
{
|
||||
"host": "uk.gw.lan uk.lan",
|
||||
"host_list": [
|
||||
"uk.gw.lan",
|
||||
"uk.lan"
|
||||
],
|
||||
"hostname": "192.168.0.251",
|
||||
"user": "nixcraft",
|
||||
"proxycommand": "ssh nixcraft@gateway.uk.cyberciti.biz nc %h %p 2> /dev/null"
|
||||
},
|
||||
{
|
||||
"host": "proxyus",
|
||||
"host_list": [
|
||||
"proxyus"
|
||||
],
|
||||
"hostname": "vps1.cyberciti.biz",
|
||||
"user": "breakfree",
|
||||
"identityfile": [
|
||||
"~/.ssh/vps1.cyberciti.biz.key"
|
||||
],
|
||||
"localforward": [
|
||||
"3128 127.0.0.1:3128"
|
||||
]
|
||||
},
|
||||
{
|
||||
"host": "*",
|
||||
"host_list": [
|
||||
"*"
|
||||
],
|
||||
"forwardagent": "no",
|
||||
"forwardx11": "no",
|
||||
"forwardx11trusted": "yes",
|
||||
"user": "nixcraft",
|
||||
"port": 22,
|
||||
"protocol": 2,
|
||||
"serveraliveinterval": 60,
|
||||
"serveralivecountmax": 30
|
||||
}
|
||||
]
|
||||
|
||||
$ cat ~/.ssh/config | jc --ssh-conf -p -r
|
||||
[
|
||||
{
|
||||
"host": "server1",
|
||||
"host_list": [
|
||||
"server1"
|
||||
],
|
||||
"hostname": "server1.cyberciti.biz",
|
||||
"user": "nixcraft",
|
||||
"port": "4242",
|
||||
"identityfile": [
|
||||
"/nfs/shared/users/nixcraft/keys/server1/id_rsa"
|
||||
]
|
||||
},
|
||||
{
|
||||
"host": "nas01",
|
||||
"host_list": [
|
||||
"nas01"
|
||||
],
|
||||
"hostname": "192.168.1.100",
|
||||
"user": "root",
|
||||
"identityfile": [
|
||||
"~/.ssh/nas01.key"
|
||||
]
|
||||
},
|
||||
{
|
||||
"host": "aws.apache",
|
||||
"host_list": [
|
||||
"aws.apache"
|
||||
],
|
||||
"hostname": "1.2.3.4",
|
||||
"user": "wwwdata",
|
||||
"identityfile": [
|
||||
"~/.ssh/aws.apache.key"
|
||||
]
|
||||
},
|
||||
{
|
||||
"host": "uk.gw.lan uk.lan",
|
||||
"host_list": [
|
||||
"uk.gw.lan",
|
||||
"uk.lan"
|
||||
],
|
||||
"hostname": "192.168.0.251",
|
||||
"user": "nixcraft",
|
||||
"proxycommand": "ssh nixcraft@gateway.uk.cyberciti.biz nc %h %p 2> /dev/null"
|
||||
},
|
||||
{
|
||||
"host": "proxyus",
|
||||
"host_list": [
|
||||
"proxyus"
|
||||
],
|
||||
"hostname": "vps1.cyberciti.biz",
|
||||
"user": "breakfree",
|
||||
"identityfile": [
|
||||
"~/.ssh/vps1.cyberciti.biz.key"
|
||||
],
|
||||
"localforward": [
|
||||
"3128 127.0.0.1:3128"
|
||||
]
|
||||
},
|
||||
{
|
||||
"host": "*",
|
||||
"host_list": [
|
||||
"*"
|
||||
],
|
||||
"forwardagent": "no",
|
||||
"forwardx11": "no",
|
||||
"forwardx11trusted": "yes",
|
||||
"user": "nixcraft",
|
||||
"port": "22",
|
||||
"protocol": "2",
|
||||
"serveraliveinterval": "60",
|
||||
"serveralivecountmax": "30"
|
||||
}
|
||||
]
|
||||
|
||||
<a id="jc.parsers.ssh_conf.parse"></a>
|
||||
|
||||
### parse
|
||||
|
||||
```python
|
||||
def parse(data: str,
|
||||
raw: bool = False,
|
||||
quiet: bool = False) -> List[JSONDictType]
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) unprocessed output if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of Dictionaries. Raw or processed structured data.
|
||||
|
||||
### Parser Information
|
||||
Compatibility: linux, darwin, freebsd
|
||||
|
||||
Version 1.0 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
# jc.parsers.sshd\_conf
|
||||
|
||||
jc - JSON Convert sshd configuration file and `sshd -T` command output parser
|
||||
jc - JSON Convert `sshd` configuration file and `sshd -T` command output parser
|
||||
|
||||
This parser will work with `sshd` configuration files or the output of
|
||||
`sshd -T`. Any `Match` blocks in the `sshd` configuration file will be
|
||||
@@ -504,4 +504,4 @@ Returns:
|
||||
### Parser Information
|
||||
Compatibility: linux, darwin, freebsd
|
||||
|
||||
Version 1.0 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.1 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -193,4 +193,4 @@ Returns:
|
||||
### Parser Information
|
||||
Compatibility: linux, darwin, freebsd
|
||||
|
||||
Version 1.12 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.13 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
69
docs/parsers/swapon.md
Normal file
69
docs/parsers/swapon.md
Normal file
@@ -0,0 +1,69 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
<a id="jc.parsers.swapon"></a>
|
||||
|
||||
# jc.parsers.swapon
|
||||
|
||||
jc - JSON Convert `swapon` command output parser
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ swapon | jc --swapon
|
||||
|
||||
or
|
||||
|
||||
$ jc swapon
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc
|
||||
result = jc.parse('swapon', swapon_command_output)
|
||||
|
||||
Schema:
|
||||
|
||||
[
|
||||
{
|
||||
"name": string,
|
||||
"type": string,
|
||||
"size": integer,
|
||||
"used": integer,
|
||||
"priority": integer
|
||||
}
|
||||
]
|
||||
|
||||
Example:
|
||||
|
||||
$ swapon | jc --swapon
|
||||
[
|
||||
{
|
||||
"name": "/swapfile",
|
||||
"type": "file",
|
||||
"size": 1073741824,
|
||||
"used": 0,
|
||||
"priority": -2
|
||||
}
|
||||
]
|
||||
|
||||
<a id="jc.parsers.swapon.parse"></a>
|
||||
|
||||
### parse
|
||||
|
||||
```python
|
||||
def parse(data: str, raw: bool = False, quiet: bool = False) -> List[_Entry]
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) unprocessed output if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary. Raw or processed structured data.
|
||||
|
||||
### Parser Information
|
||||
Compatibility: linux, freebsd
|
||||
|
||||
Version 1.0 by Roey Darwish Dror (roey.ghost@gmail.com)
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
jc - JSON Convert `timedatectl` command output parser
|
||||
|
||||
Also supports the `timesync-status` option.
|
||||
|
||||
The `epoch_utc` calculated timestamp field is timezone-aware and is only
|
||||
available if the `universal_time` field is available.
|
||||
|
||||
@@ -34,7 +36,24 @@ Schema:
|
||||
"system_clock_synchronized": boolean,
|
||||
"systemd-timesyncd.service_active": boolean,
|
||||
"rtc_in_local_tz": boolean,
|
||||
"dst_active": boolean
|
||||
"dst_active": boolean,
|
||||
"server": string,
|
||||
"poll_interval": string,
|
||||
"leap": string,
|
||||
"version": integer,
|
||||
"stratum": integer,
|
||||
"reference": string,
|
||||
"precision": string,
|
||||
"root_distance": string,
|
||||
"offset": float,
|
||||
"offset_unit": string,
|
||||
"delay": float,
|
||||
"delay_unit": string,
|
||||
"jitter": float,
|
||||
"jitter_unit": string,
|
||||
"packet_count": integer,
|
||||
"frequency": float,
|
||||
"frequency_unit": string
|
||||
}
|
||||
|
||||
Examples:
|
||||
@@ -87,4 +106,4 @@ Returns:
|
||||
### Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.7 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.8 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
81
docs/parsers/toml.md
Normal file
81
docs/parsers/toml.md
Normal file
@@ -0,0 +1,81 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
<a id="jc.parsers.toml"></a>
|
||||
|
||||
# jc.parsers.toml
|
||||
|
||||
jc - JSON Convert TOML file parser
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ cat file.toml | jc --toml
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc
|
||||
result = jc.parse('toml', toml_file_output)
|
||||
|
||||
Schema:
|
||||
|
||||
TOML Document converted to a Dictionary.
|
||||
See https://toml.io/en/ for details.
|
||||
|
||||
{
|
||||
"key1": string/int/float/boolean/null/array/object,
|
||||
"key2": string/int/float/boolean/null/array/object
|
||||
}
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat file.toml
|
||||
title = "TOML Example"
|
||||
|
||||
[owner]
|
||||
name = "Tom Preston-Werner"
|
||||
dob = 1979-05-27T07:32:00-08:00
|
||||
|
||||
[database]
|
||||
enabled = true
|
||||
ports = [ 8000, 8001, 8002 ]
|
||||
|
||||
$ cat file.toml | jc --toml -p
|
||||
{
|
||||
"title": "TOML Example",
|
||||
"owner": {
|
||||
"name": "Tom Preston-Werner",
|
||||
"dob": 296667120,
|
||||
"dob_iso": "1979-05-27T07:32:00-08:00"
|
||||
},
|
||||
"database": {
|
||||
"enabled": true,
|
||||
"ports": [
|
||||
8000,
|
||||
8001,
|
||||
8002
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
<a id="jc.parsers.toml.parse"></a>
|
||||
|
||||
### parse
|
||||
|
||||
```python
|
||||
def parse(data: str, raw: bool = False, quiet: bool = False) -> JSONDictType
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) unprocessed output if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary. Raw or processed structured data.
|
||||
|
||||
### Parser Information
|
||||
Compatibility: linux, darwin, cygwin, win32, aix, freebsd
|
||||
|
||||
Version 1.0 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
235
docs/parsers/tune2fs.md
Normal file
235
docs/parsers/tune2fs.md
Normal file
@@ -0,0 +1,235 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
<a id="jc.parsers.tune2fs"></a>
|
||||
|
||||
# jc.parsers.tune2fs
|
||||
|
||||
jc - JSON Convert `tune2fs -l` command output parser
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ tune2fs -l /dev/xvda4 | jc --tune2fs
|
||||
|
||||
or
|
||||
|
||||
$ jc tune2fs -l /dev/xvda4
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc
|
||||
result = jc.parse('tune2fs', tune2fs_command_output)
|
||||
|
||||
Schema:
|
||||
|
||||
{
|
||||
"version": string,
|
||||
"filesystem_volume_name": string,
|
||||
"last_mounted_on": string,
|
||||
"filesystem_uuid": string,
|
||||
"filesystem_magic_number": string,
|
||||
"filesystem_revision_number": string,
|
||||
"filesystem_features": [
|
||||
string
|
||||
],
|
||||
"filesystem_flags": string,
|
||||
"default_mount_options": string,
|
||||
"filesystem_state": string,
|
||||
"errors_behavior": string,
|
||||
"filesystem_os_type": string,
|
||||
"inode_count": integer,
|
||||
"block_count": integer,
|
||||
"reserved_block_count": integer,
|
||||
"overhead_clusters": integer,
|
||||
"free_blocks": integer,
|
||||
"free_inodes": integer,
|
||||
"first_block": integer,
|
||||
"block_size": integer,
|
||||
"fragment_size": integer,
|
||||
"group_descriptor_size": integer,
|
||||
"reserved_gdt_blocks": integer,
|
||||
"blocks_per_group": integer,
|
||||
"fragments_per_group": integer,
|
||||
"inodes_per_group": integer,
|
||||
"inode_blocks_per_group": integer,
|
||||
"flex_block_group_size": integer,
|
||||
"filesystem_created": string,
|
||||
"filesystem_created_epoch": integer,
|
||||
"filesystem_created_epoch_utc": integer,
|
||||
"last_mount_time": string,
|
||||
"last_mount_time_epoch": integer,
|
||||
"last_mount_time_epoch_utc": integer,
|
||||
"last_write_time": string,
|
||||
"last_write_time_epoch": integer,
|
||||
"last_write_time_epoch_utc": integer,
|
||||
"mount_count": integer,
|
||||
"maximum_mount_count": integer,
|
||||
"last_checked": string,
|
||||
"last_checked_epoch": integer,
|
||||
"last_checked_epoch_utc": integer,
|
||||
"check_interval": string,
|
||||
"lifetime_writes": string,
|
||||
"reserved_blocks_uid": string,
|
||||
"reserved_blocks_gid": string,
|
||||
"first_inode": integer,
|
||||
"inode_size": integer,
|
||||
"required_extra_isize": integer,
|
||||
"desired_extra_isize": integer,
|
||||
"journal_inode": integer,
|
||||
"default_directory_hash": string,
|
||||
"directory_hash_seed": string,
|
||||
"journal_backup": string,
|
||||
"checksum_type": string,
|
||||
"checksum": string
|
||||
}
|
||||
|
||||
Examples:
|
||||
|
||||
$ tune2fs | jc --tune2fs -p
|
||||
{
|
||||
"version": "1.46.2 (28-Feb-2021)",
|
||||
"filesystem_volume_name": "<none>",
|
||||
"last_mounted_on": "/home",
|
||||
"filesystem_uuid": "5fb78e1a-b214-44e2-a309-8e35116d8dd6",
|
||||
"filesystem_magic_number": "0xEF53",
|
||||
"filesystem_revision_number": "1 (dynamic)",
|
||||
"filesystem_features": [
|
||||
"has_journal",
|
||||
"ext_attr",
|
||||
"resize_inode",
|
||||
"dir_index",
|
||||
"filetype",
|
||||
"needs_recovery",
|
||||
"extent",
|
||||
"64bit",
|
||||
"flex_bg",
|
||||
"sparse_super",
|
||||
"large_file",
|
||||
"huge_file",
|
||||
"dir_nlink",
|
||||
"extra_isize",
|
||||
"metadata_csum"
|
||||
],
|
||||
"filesystem_flags": "signed_directory_hash",
|
||||
"default_mount_options": "user_xattr acl",
|
||||
"filesystem_state": "clean",
|
||||
"errors_behavior": "Continue",
|
||||
"filesystem_os_type": "Linux",
|
||||
"inode_count": 3932160,
|
||||
"block_count": 15728640,
|
||||
"reserved_block_count": 786432,
|
||||
"free_blocks": 15198453,
|
||||
"free_inodes": 3864620,
|
||||
"first_block": 0,
|
||||
"block_size": 4096,
|
||||
"fragment_size": 4096,
|
||||
"group_descriptor_size": 64,
|
||||
"reserved_gdt_blocks": 1024,
|
||||
"blocks_per_group": 32768,
|
||||
"fragments_per_group": 32768,
|
||||
"inodes_per_group": 8192,
|
||||
"inode_blocks_per_group": 512,
|
||||
"flex_block_group_size": 16,
|
||||
"filesystem_created": "Mon Apr 6 15:10:37 2020",
|
||||
"last_mount_time": "Mon Sep 19 15:16:20 2022",
|
||||
"last_write_time": "Mon Sep 19 15:16:20 2022",
|
||||
"mount_count": 14,
|
||||
"maximum_mount_count": -1,
|
||||
"last_checked": "Fri Apr 8 15:24:22 2022",
|
||||
"check_interval": "0 (<none>)",
|
||||
"lifetime_writes": "203 GB",
|
||||
"reserved_blocks_uid": "0 (user root)",
|
||||
"reserved_blocks_gid": "0 (group root)",
|
||||
"first_inode": 11,
|
||||
"inode_size": 256,
|
||||
"required_extra_isize": 32,
|
||||
"desired_extra_isize": 32,
|
||||
"journal_inode": 8,
|
||||
"default_directory_hash": "half_md4",
|
||||
"directory_hash_seed": "67d5358d-723d-4ce3-b3c0-30ddb433ad9e",
|
||||
"journal_backup": "inode blocks",
|
||||
"checksum_type": "crc32c",
|
||||
"checksum": "0x7809afff",
|
||||
"filesystem_created_epoch": 1586211037,
|
||||
"filesystem_created_epoch_utc": null,
|
||||
"last_mount_time_epoch": 1663625780,
|
||||
"last_mount_time_epoch_utc": null,
|
||||
"last_write_time_epoch": 1663625780,
|
||||
"last_write_time_epoch_utc": null,
|
||||
"last_checked_epoch": 1649456662,
|
||||
"last_checked_epoch_utc": null
|
||||
}
|
||||
|
||||
$ tune2fs | jc --tune2fs -p -r
|
||||
{
|
||||
"version": "1.46.2 (28-Feb-2021)",
|
||||
"filesystem_volume_name": "<none>",
|
||||
"last_mounted_on": "/home",
|
||||
"filesystem_uuid": "5fb78e1a-b214-44e2-a309-8e35116d8dd6",
|
||||
"filesystem_magic_number": "0xEF53",
|
||||
"filesystem_revision_number": "1 (dynamic)",
|
||||
"filesystem_features": "has_journal ext_attr resize_inode dir_index filetype needs_recovery extent 64bit flex_bg sparse_super large_file huge_file dir_nlink extra_isize metadata_csum",
|
||||
"filesystem_flags": "signed_directory_hash",
|
||||
"default_mount_options": "user_xattr acl",
|
||||
"filesystem_state": "clean",
|
||||
"errors_behavior": "Continue",
|
||||
"filesystem_os_type": "Linux",
|
||||
"inode_count": "3932160",
|
||||
"block_count": "15728640",
|
||||
"reserved_block_count": "786432",
|
||||
"free_blocks": "15198453",
|
||||
"free_inodes": "3864620",
|
||||
"first_block": "0",
|
||||
"block_size": "4096",
|
||||
"fragment_size": "4096",
|
||||
"group_descriptor_size": "64",
|
||||
"reserved_gdt_blocks": "1024",
|
||||
"blocks_per_group": "32768",
|
||||
"fragments_per_group": "32768",
|
||||
"inodes_per_group": "8192",
|
||||
"inode_blocks_per_group": "512",
|
||||
"flex_block_group_size": "16",
|
||||
"filesystem_created": "Mon Apr 6 15:10:37 2020",
|
||||
"last_mount_time": "Mon Sep 19 15:16:20 2022",
|
||||
"last_write_time": "Mon Sep 19 15:16:20 2022",
|
||||
"mount_count": "14",
|
||||
"maximum_mount_count": "-1",
|
||||
"last_checked": "Fri Apr 8 15:24:22 2022",
|
||||
"check_interval": "0 (<none>)",
|
||||
"lifetime_writes": "203 GB",
|
||||
"reserved_blocks_uid": "0 (user root)",
|
||||
"reserved_blocks_gid": "0 (group root)",
|
||||
"first_inode": "11",
|
||||
"inode_size": "256",
|
||||
"required_extra_isize": "32",
|
||||
"desired_extra_isize": "32",
|
||||
"journal_inode": "8",
|
||||
"default_directory_hash": "half_md4",
|
||||
"directory_hash_seed": "67d5358d-723d-4ce3-b3c0-30ddb433ad9e",
|
||||
"journal_backup": "inode blocks",
|
||||
"checksum_type": "crc32c",
|
||||
"checksum": "0x7809afff"
|
||||
}
|
||||
|
||||
<a id="jc.parsers.tune2fs.parse"></a>
|
||||
|
||||
### parse
|
||||
|
||||
```python
|
||||
def parse(data: str, raw: bool = False, quiet: bool = False) -> JSONDictType
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) unprocessed output if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary. Raw or processed structured data.
|
||||
|
||||
### Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.0 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
@@ -161,4 +161,4 @@ Returns:
|
||||
### Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -42,8 +42,7 @@ Parameters:
|
||||
underscore '_'. You should also ensure headers are
|
||||
lowercase by using .lower().
|
||||
|
||||
Also, ensure there are no blank lines (list items)
|
||||
in the data.
|
||||
Also, ensure there are no blank rows in the data.
|
||||
|
||||
Returns:
|
||||
|
||||
|
||||
112
docs/parsers/ver.md
Normal file
112
docs/parsers/ver.md
Normal file
@@ -0,0 +1,112 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
<a id="jc.parsers.ver"></a>
|
||||
|
||||
# jc.parsers.ver
|
||||
|
||||
jc - JSON Convert Version string output parser
|
||||
|
||||
Best-effort attempt to parse various styles of version numbers. This parser
|
||||
is based off of the version parser included in the CPython distutils
|
||||
library.
|
||||
|
||||
If the version string conforms to some de facto-standard versioning rules
|
||||
followed by many developers a `strict` key will be present in the output
|
||||
with a value of `true` along with the named parsed components.
|
||||
|
||||
All other version strings will have a `strict` value of `false` and a
|
||||
`components` key will contain a list of detected parts of the version
|
||||
string.
|
||||
|
||||
See Also: `semver` parser.
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ echo 1.2a1 | jc --ver
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc
|
||||
result = jc.parse('ver', version_string_output)
|
||||
|
||||
Schema:
|
||||
|
||||
{
|
||||
"major": integer,
|
||||
"minor": integer,
|
||||
"patch": integer,
|
||||
"prerelease": string,
|
||||
"prerelease_num": integer,
|
||||
"components": [
|
||||
integer/string
|
||||
],
|
||||
"strict": boolean
|
||||
}
|
||||
|
||||
Examples:
|
||||
|
||||
$ echo 1.2a1 | jc --ver -p
|
||||
{
|
||||
"major": 1,
|
||||
"minor": 2,
|
||||
"patch": 0,
|
||||
"prerelease": "a",
|
||||
"prerelease_num": 1,
|
||||
"strict": true
|
||||
}
|
||||
|
||||
$ echo 1.2a1 | jc --ver -p -r
|
||||
{
|
||||
"major": "1",
|
||||
"minor": "2",
|
||||
"patch": "0",
|
||||
"prerelease": "a",
|
||||
"prerelease_num": "1",
|
||||
"strict": true
|
||||
}
|
||||
|
||||
$ echo 1.2beta3 | jc --ver -p
|
||||
{
|
||||
"components": [
|
||||
1,
|
||||
2,
|
||||
"beta",
|
||||
3
|
||||
],
|
||||
"strict": false
|
||||
}
|
||||
|
||||
$ echo 1.2beta3 | jc --ver -p -r
|
||||
{
|
||||
"components": [
|
||||
"1",
|
||||
"2",
|
||||
"beta",
|
||||
"3"
|
||||
],
|
||||
"strict": false
|
||||
}
|
||||
|
||||
<a id="jc.parsers.ver.parse"></a>
|
||||
|
||||
### parse
|
||||
|
||||
```python
|
||||
def parse(data: str, raw: bool = False, quiet: bool = False) -> JSONDictType
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) unprocessed output if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of Dictionaries. Raw or processed structured data.
|
||||
|
||||
### Parser Information
|
||||
Compatibility: linux, darwin, cygwin, win32, aix, freebsd
|
||||
|
||||
Version 1.0 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
108
docs/parsers/veracrypt.md
Normal file
108
docs/parsers/veracrypt.md
Normal file
@@ -0,0 +1,108 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
<a id="jc.parsers.veracrypt"></a>
|
||||
|
||||
# jc.parsers.veracrypt
|
||||
|
||||
jc - JSON Convert `veracrypt` command output parser
|
||||
|
||||
Supports the following `veracrypt` subcommands:
|
||||
- `veracrypt --text --list`
|
||||
- `veracrypt --text --list --verbose`
|
||||
- `veracrypt --text --volume-properties <volume>`
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ veracrypt --text --list | jc --veracrypt
|
||||
or
|
||||
|
||||
$ jc veracrypt --text --list
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc
|
||||
result = jc.parse('veracrypt', veracrypt_command_output)
|
||||
|
||||
Schema:
|
||||
|
||||
Volume:
|
||||
[
|
||||
{
|
||||
"slot": integer,
|
||||
"path": string,
|
||||
"device": string,
|
||||
"mountpoint": string,
|
||||
"size": string,
|
||||
"type": string,
|
||||
"readonly": string,
|
||||
"hidden_protected": string,
|
||||
"encryption_algo": string,
|
||||
"pk_size": string,
|
||||
"sk_size": string,
|
||||
"block_size": string,
|
||||
"mode": string,
|
||||
"prf": string,
|
||||
"format_version": integer,
|
||||
"backup_header": string
|
||||
}
|
||||
]
|
||||
|
||||
Examples:
|
||||
|
||||
$ veracrypt --text --list | jc --veracrypt -p
|
||||
[
|
||||
{
|
||||
"slot": 1,
|
||||
"path": "/dev/sdb1",
|
||||
"device": "/dev/mapper/veracrypt1",
|
||||
"mountpoint": "/home/bob/mount/encrypt/sdb1"
|
||||
}
|
||||
]
|
||||
|
||||
$ veracrypt --text --list --verbose | jc --veracrypt -p
|
||||
[
|
||||
{
|
||||
"slot": 1,
|
||||
"path": "/dev/sdb1",
|
||||
"device": "/dev/mapper/veracrypt1",
|
||||
"mountpoint": "/home/bob/mount/encrypt/sdb1",
|
||||
"size": "522 MiB",
|
||||
"type": "Normal",
|
||||
"readonly": "No",
|
||||
"hidden_protected": "No",
|
||||
"encryption_algo": "AES",
|
||||
"pk_size": "256 bits",
|
||||
"sk_size": "256 bits",
|
||||
"block_size": "128 bits",
|
||||
"mode": "XTS",
|
||||
"prf": "HMAC-SHA-512",
|
||||
"format_version": 2,
|
||||
"backup_header": "Yes"
|
||||
}
|
||||
]
|
||||
|
||||
<a id="jc.parsers.veracrypt.parse"></a>
|
||||
|
||||
### parse
|
||||
|
||||
```python
|
||||
def parse(data: str,
|
||||
raw: bool = False,
|
||||
quiet: bool = False) -> List[JSONDictType]
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) unprocessed output if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of Dictionaries. Raw or processed structured data.
|
||||
|
||||
### Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.0 by Jake Ob (iakopap at gmail.com)
|
||||
@@ -149,4 +149,4 @@ Returns:
|
||||
### Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -123,4 +123,4 @@ Returns:
|
||||
### Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -158,4 +158,4 @@ Returns:
|
||||
### Parser Information
|
||||
Compatibility: linux, darwin, cygwin, aix, freebsd
|
||||
|
||||
Version 1.7 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.8 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -433,4 +433,4 @@ Returns:
|
||||
### Parser Information
|
||||
Compatibility: linux, darwin, cygwin, win32, aix, freebsd
|
||||
|
||||
Version 1.1 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
282
docs/parsers/x509_csr.md
Normal file
282
docs/parsers/x509_csr.md
Normal file
@@ -0,0 +1,282 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
<a id="jc.parsers.x509_csr"></a>
|
||||
|
||||
# jc.parsers.x509\_csr
|
||||
|
||||
jc - JSON Convert X.509 Certificate Request format file parser
|
||||
|
||||
This parser will convert DER and PEM encoded X.509 certificate request files.
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ cat certificateRequest.pem | jc --x509-csr
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc
|
||||
result = jc.parse('x509_csr', x509_csr_file_output)
|
||||
|
||||
Schema:
|
||||
|
||||
[
|
||||
{
|
||||
"certification_request_info": {
|
||||
"version": string,
|
||||
"serial_number": string, # [0]
|
||||
"serial_number_str": string,
|
||||
"signature": {
|
||||
"algorithm": string,
|
||||
"parameters": string/null,
|
||||
},
|
||||
"issuer": {
|
||||
"country_name": string,
|
||||
"state_or_province_name" string,
|
||||
"locality_name": string,
|
||||
"organization_name": array/string,
|
||||
"organizational_unit_name": array/string,
|
||||
"common_name": string,
|
||||
"email_address": string,
|
||||
"serial_number": string, # [0]
|
||||
"serial_number_str": string
|
||||
},
|
||||
"validity": {
|
||||
"not_before": integer, # [1]
|
||||
"not_after": integer, # [1]
|
||||
"not_before_iso": string,
|
||||
"not_after_iso": string
|
||||
},
|
||||
"subject": {
|
||||
"country_name": string,
|
||||
"state_or_province_name": string,
|
||||
"locality_name": string,
|
||||
"organization_name": array/string,
|
||||
"organizational_unit_name": array/string,
|
||||
"common_name": string,
|
||||
"email_address": string,
|
||||
"serial_number": string, # [0]
|
||||
"serial_number_str": string
|
||||
},
|
||||
"subject_public_key_info": {
|
||||
"algorithm": {
|
||||
"algorithm": string,
|
||||
"parameters": string/null,
|
||||
},
|
||||
"public_key": {
|
||||
"modulus": string, # [0]
|
||||
"public_exponent": integer
|
||||
}
|
||||
},
|
||||
"issuer_unique_id": string/null,
|
||||
"subject_unique_id": string/null,
|
||||
"extensions": [
|
||||
{
|
||||
"extn_id": string,
|
||||
"critical": boolean,
|
||||
"extn_value": array/object/string/integer # [2]
|
||||
}
|
||||
]
|
||||
},
|
||||
"signature_algorithm": {
|
||||
"algorithm": string,
|
||||
"parameters": string/null
|
||||
},
|
||||
"signature_value": string # [0]
|
||||
}
|
||||
]
|
||||
|
||||
[0] in colon-delimited hex notation
|
||||
[1] time-zone-aware (UTC) epoch timestamp
|
||||
[2] See below for well-known Extension schemas:
|
||||
|
||||
Basic Constraints:
|
||||
{
|
||||
"extn_id": "basic_constraints",
|
||||
"critical": boolean,
|
||||
"extn_value": {
|
||||
"ca": boolean,
|
||||
"path_len_constraint": string/null
|
||||
}
|
||||
}
|
||||
|
||||
Key Usage:
|
||||
{
|
||||
"extn_id": "key_usage",
|
||||
"critical": boolean,
|
||||
"extn_value": [
|
||||
string
|
||||
]
|
||||
}
|
||||
|
||||
Key Identifier:
|
||||
{
|
||||
"extn_id": "key_identifier",
|
||||
"critical": boolean,
|
||||
"extn_value": string # [0]
|
||||
}
|
||||
|
||||
Authority Key Identifier:
|
||||
{
|
||||
"extn_id": "authority_key_identifier",
|
||||
"critical": boolean,
|
||||
"extn_value": {
|
||||
"key_identifier": string, # [0]
|
||||
"authority_cert_issuer": string/null,
|
||||
"authority_cert_serial_number": string/null
|
||||
}
|
||||
}
|
||||
|
||||
Subject Alternative Name:
|
||||
{
|
||||
"extn_id": "subject_alt_name",
|
||||
"critical": boolean,
|
||||
"extn_value": [
|
||||
string
|
||||
]
|
||||
}
|
||||
|
||||
Certificate Policies:
|
||||
{
|
||||
"extn_id": "certificate_policies",
|
||||
"critical": boolean,
|
||||
"extn_value": [
|
||||
{
|
||||
"policy_identifier": string,
|
||||
"policy_qualifiers": [ array or null
|
||||
{
|
||||
"policy_qualifier_id": string,
|
||||
"qualifier": string
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Signed Certificate Timestamp List:
|
||||
{
|
||||
"extn_id": "signed_certificate_timestamp_list",
|
||||
"critical": boolean,
|
||||
"extn_value": string # [0]
|
||||
}
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat server.csr| jc --x509-csr -p
|
||||
[
|
||||
{
|
||||
"certification_request_info": {
|
||||
"version": "v1",
|
||||
"subject": {
|
||||
"common_name": "myserver.for.example"
|
||||
},
|
||||
"subject_pk_info": {
|
||||
"algorithm": {
|
||||
"algorithm": "ec",
|
||||
"parameters": "secp256r1"
|
||||
},
|
||||
"public_key": "04:40:33:c0:91:8f:e9:46:ea:d0:dc:d0:f9:63:2..."
|
||||
},
|
||||
"attributes": [
|
||||
{
|
||||
"type": "extension_request",
|
||||
"values": [
|
||||
[
|
||||
{
|
||||
"extn_id": "extended_key_usage",
|
||||
"critical": false,
|
||||
"extn_value": [
|
||||
"server_auth"
|
||||
]
|
||||
},
|
||||
{
|
||||
"extn_id": "subject_alt_name",
|
||||
"critical": false,
|
||||
"extn_value": [
|
||||
"myserver.for.example"
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"signature_algorithm": {
|
||||
"algorithm": "sha384_ecdsa",
|
||||
"parameters": null
|
||||
},
|
||||
"signature": "30:45:02:20:77:ac:5b:51:bf:c5:f5:43:02:52:ae:66:..."
|
||||
}
|
||||
]
|
||||
|
||||
$ openssl req -in server.csr | jc --x509-csr -p
|
||||
[
|
||||
{
|
||||
"certification_request_info": {
|
||||
"version": "v1",
|
||||
"subject": {
|
||||
"common_name": "myserver.for.example"
|
||||
},
|
||||
"subject_pk_info": {
|
||||
"algorithm": {
|
||||
"algorithm": "ec",
|
||||
"parameters": "secp256r1"
|
||||
},
|
||||
"public_key": "04:40:33:c0:91:8f:e9:46:ea:d0:dc:d0:f9:63:2..."
|
||||
},
|
||||
"attributes": [
|
||||
{
|
||||
"type": "extension_request",
|
||||
"values": [
|
||||
[
|
||||
{
|
||||
"extn_id": "extended_key_usage",
|
||||
"critical": false,
|
||||
"extn_value": [
|
||||
"server_auth"
|
||||
]
|
||||
},
|
||||
{
|
||||
"extn_id": "subject_alt_name",
|
||||
"critical": false,
|
||||
"extn_value": [
|
||||
"myserver.for.example"
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"signature_algorithm": {
|
||||
"algorithm": "sha384_ecdsa",
|
||||
"parameters": null
|
||||
},
|
||||
"signature": "30:45:02:20:77:ac:5b:51:bf:c5:f5:43:02:52:ae:66:..."
|
||||
}
|
||||
]
|
||||
|
||||
<a id="jc.parsers.x509_csr.parse"></a>
|
||||
|
||||
### parse
|
||||
|
||||
```python
|
||||
def parse(data: Union[str, bytes],
|
||||
raw: bool = False,
|
||||
quiet: bool = False) -> List[Dict]
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string or bytes) text or binary data to parse
|
||||
raw: (boolean) unprocessed output if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of Dictionaries. Raw or processed structured data.
|
||||
|
||||
### Parser Information
|
||||
Compatibility: linux, darwin, cygwin, win32, aix, freebsd
|
||||
|
||||
Version 1.0 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
@@ -98,4 +98,4 @@ Returns:
|
||||
### Parser Information
|
||||
Compatibility: linux, darwin, cygwin, win32, aix, freebsd
|
||||
|
||||
Version 1.7 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.9 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -8,6 +8,7 @@ jc - JSON Convert `xrandr` command output parser
|
||||
Usage (cli):
|
||||
|
||||
$ xrandr | jc --xrandr
|
||||
$ xrandr --properties | jc --xrandr
|
||||
|
||||
or
|
||||
|
||||
@@ -30,50 +31,38 @@ Schema:
|
||||
"current_height": integer,
|
||||
"maximum_width": integer,
|
||||
"maximum_height": integer,
|
||||
"associated_device": {
|
||||
"associated_modes": [
|
||||
{
|
||||
"resolution_width": integer,
|
||||
"resolution_height": integer,
|
||||
"is_high_resolution": boolean,
|
||||
"frequencies": [
|
||||
{
|
||||
"frequency": float,
|
||||
"is_current": boolean,
|
||||
"is_preferred": boolean
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"devices": [
|
||||
{
|
||||
"modes": [
|
||||
{
|
||||
"resolution_width": integer,
|
||||
"resolution_height": integer,
|
||||
"is_high_resolution": boolean,
|
||||
"frequencies": [
|
||||
{
|
||||
"frequency": float,
|
||||
"is_current": boolean,
|
||||
"is_preferred": boolean
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"is_connected": boolean,
|
||||
"is_primary": boolean,
|
||||
"device_name": string,
|
||||
"model_name": string,
|
||||
"product_id" string,
|
||||
"serial_number": string,
|
||||
"resolution_width": integer,
|
||||
"resolution_height": integer,
|
||||
"offset_width": integer,
|
||||
"offset_height": integer,
|
||||
"dimension_width": integer,
|
||||
"dimension_height": integer,
|
||||
"rotation": string
|
||||
}
|
||||
],
|
||||
"unassociated_devices": [
|
||||
{
|
||||
"associated_modes": [
|
||||
{
|
||||
"resolution_width": integer,
|
||||
"resolution_height": integer,
|
||||
"is_high_resolution": boolean,
|
||||
"frequencies": [
|
||||
{
|
||||
"frequency": float,
|
||||
"is_current": boolean,
|
||||
"is_preferred": boolean
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
"rotation": string,
|
||||
"reflection": string
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -91,52 +80,118 @@ Examples:
|
||||
"current_height": 1080,
|
||||
"maximum_width": 32767,
|
||||
"maximum_height": 32767,
|
||||
"associated_device": {
|
||||
"associated_modes": [
|
||||
{
|
||||
"resolution_width": 1920,
|
||||
"resolution_height": 1080,
|
||||
"is_high_resolution": false,
|
||||
"frequencies": [
|
||||
{
|
||||
"frequency": 60.03,
|
||||
"is_current": true,
|
||||
"is_preferred": true
|
||||
},
|
||||
{
|
||||
"frequency": 59.93,
|
||||
"is_current": false,
|
||||
"is_preferred": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"resolution_width": 1680,
|
||||
"resolution_height": 1050,
|
||||
"is_high_resolution": false,
|
||||
"frequencies": [
|
||||
{
|
||||
"frequency": 59.88,
|
||||
"is_current": false,
|
||||
"is_preferred": false
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"is_connected": true,
|
||||
"is_primary": true,
|
||||
"device_name": "eDP1",
|
||||
"resolution_width": 1920,
|
||||
"resolution_height": 1080,
|
||||
"offset_width": 0,
|
||||
"offset_height": 0,
|
||||
"dimension_width": 310,
|
||||
"dimension_height": 170,
|
||||
"rotation": "normal"
|
||||
}
|
||||
"devices": [
|
||||
{
|
||||
"modes": [
|
||||
{
|
||||
"resolution_width": 1920,
|
||||
"resolution_height": 1080,
|
||||
"is_high_resolution": false,
|
||||
"frequencies": [
|
||||
{
|
||||
"frequency": 60.03,
|
||||
"is_current": true,
|
||||
"is_preferred": true
|
||||
},
|
||||
{
|
||||
"frequency": 59.93,
|
||||
"is_current": false,
|
||||
"is_preferred": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"resolution_width": 1680,
|
||||
"resolution_height": 1050,
|
||||
"is_high_resolution": false,
|
||||
"frequencies": [
|
||||
{
|
||||
"frequency": 59.88,
|
||||
"is_current": false,
|
||||
"is_preferred": false
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"is_connected": true,
|
||||
"is_primary": true,
|
||||
"device_name": "eDP1",
|
||||
"resolution_width": 1920,
|
||||
"resolution_height": 1080,
|
||||
"offset_width": 0,
|
||||
"offset_height": 0,
|
||||
"dimension_width": 310,
|
||||
"dimension_height": 170,
|
||||
"rotation": "normal",
|
||||
"reflection": "normal"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"unassociated_devices": []
|
||||
]
|
||||
}
|
||||
|
||||
$ xrandr --properties | jc --xrandr -p
|
||||
{
|
||||
"screens": [
|
||||
{
|
||||
"screen_number": 0,
|
||||
"minimum_width": 8,
|
||||
"minimum_height": 8,
|
||||
"current_width": 1920,
|
||||
"current_height": 1080,
|
||||
"maximum_width": 32767,
|
||||
"maximum_height": 32767,
|
||||
"devices": [
|
||||
{
|
||||
"modes": [
|
||||
{
|
||||
"resolution_width": 1920,
|
||||
"resolution_height": 1080,
|
||||
"is_high_resolution": false,
|
||||
"frequencies": [
|
||||
{
|
||||
"frequency": 60.03,
|
||||
"is_current": true,
|
||||
"is_preferred": true
|
||||
},
|
||||
{
|
||||
"frequency": 59.93,
|
||||
"is_current": false,
|
||||
"is_preferred": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"resolution_width": 1680,
|
||||
"resolution_height": 1050,
|
||||
"is_high_resolution": false,
|
||||
"frequencies": [
|
||||
{
|
||||
"frequency": 59.88,
|
||||
"is_current": false,
|
||||
"is_preferred": false
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"is_connected": true,
|
||||
"is_primary": true,
|
||||
"device_name": "eDP1",
|
||||
"model_name": "ASUS VW193S",
|
||||
"product_id": "54297",
|
||||
"serial_number": "78L8021107",
|
||||
"resolution_width": 1920,
|
||||
"resolution_height": 1080,
|
||||
"offset_width": 0,
|
||||
"offset_height": 0,
|
||||
"dimension_width": 310,
|
||||
"dimension_height": 170,
|
||||
"rotation": "normal",
|
||||
"reflection": "normal"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
<a id="jc.parsers.xrandr.parse"></a>
|
||||
@@ -162,4 +217,4 @@ Returns:
|
||||
### Parser Information
|
||||
Compatibility: linux, darwin, cygwin, aix, freebsd
|
||||
|
||||
Version 1.1 by Kevin Lyter (lyter_git at sent.com)
|
||||
Version 1.4 by Kevin Lyter (code (at) lyterk.com)
|
||||
|
||||
@@ -18,8 +18,8 @@ Usage (module):
|
||||
|
||||
Schema:
|
||||
|
||||
YAML Document converted to a Dictionary
|
||||
See https://pypi.org/project/ruamel.yaml for details
|
||||
YAML Document converted to a Dictionary.
|
||||
See https://pypi.org/project/ruamel.yaml for details.
|
||||
|
||||
[
|
||||
{
|
||||
@@ -30,7 +30,7 @@ Schema:
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat istio-mtls-permissive.yaml
|
||||
$ cat file.yaml
|
||||
apiVersion: "authentication.istio.io/v1alpha1"
|
||||
kind: "Policy"
|
||||
metadata:
|
||||
@@ -51,7 +51,7 @@ Examples:
|
||||
tls:
|
||||
mode: ISTIO_MUTUAL
|
||||
|
||||
$ cat istio-mtls-permissive.yaml | jc --yaml -p
|
||||
$ cat file.yaml | jc --yaml -p
|
||||
[
|
||||
{
|
||||
"apiVersion": "authentication.istio.io/v1alpha1",
|
||||
|
||||
@@ -99,4 +99,4 @@ Returns:
|
||||
### Parser Information
|
||||
Compatibility: linux, darwin
|
||||
|
||||
Version 1.1 by Matt J (https://github.com/listuser)
|
||||
Version 1.2 by Matt J (https://github.com/listuser)
|
||||
|
||||
125
docs/parsers/zpool_iostat.md
Normal file
125
docs/parsers/zpool_iostat.md
Normal file
@@ -0,0 +1,125 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
<a id="jc.parsers.zpool_iostat"></a>
|
||||
|
||||
# jc.parsers.zpool\_iostat
|
||||
|
||||
jc - JSON Convert `zpool iostat` command output parser
|
||||
|
||||
Supports with or without the `-v` flag.
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ zpool iostat | jc --zpool-iostat
|
||||
|
||||
or
|
||||
|
||||
$ jc zpool iostat
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc
|
||||
result = jc.parse('zpool_iostat', zpool_iostat_command_output)
|
||||
|
||||
Schema:
|
||||
|
||||
[
|
||||
{
|
||||
"pool": string,
|
||||
"parent": string,
|
||||
"cap_alloc": float,
|
||||
"cap_alloc_unit": string,
|
||||
"cap_free": float,
|
||||
"cap_free_unit": string,
|
||||
"ops_read": integer,
|
||||
"ops_write": integer,
|
||||
"bw_read": float,
|
||||
"bw_read_unit": string,
|
||||
"bw_write": float,
|
||||
"bw_write_unit": string
|
||||
}
|
||||
]
|
||||
|
||||
Examples:
|
||||
|
||||
$ zpool iostat -v | jc --zpool-iostat -p
|
||||
[
|
||||
{
|
||||
"pool": "zhgstera6",
|
||||
"cap_alloc": 2.89,
|
||||
"cap_free": 2.2,
|
||||
"ops_read": 0,
|
||||
"ops_write": 2,
|
||||
"bw_read": 349.0,
|
||||
"bw_write": 448.0,
|
||||
"cap_alloc_unit": "T",
|
||||
"cap_free_unit": "T",
|
||||
"bw_read_unit": "K",
|
||||
"bw_write_unit": "K"
|
||||
},
|
||||
{
|
||||
"pool": "726060ALE614-K8JAPRGN:10",
|
||||
"parent": "zhgstera6",
|
||||
"cap_alloc": 2.89,
|
||||
"cap_free": 2.2,
|
||||
"ops_read": 0,
|
||||
"ops_write": 2,
|
||||
"bw_read": 349.0,
|
||||
"bw_write": 448.0,
|
||||
"cap_alloc_unit": "T",
|
||||
"cap_free_unit": "T",
|
||||
"bw_read_unit": "K",
|
||||
"bw_write_unit": "K"
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
$ zpool iostat -v | jc --zpool-iostat -p -r
|
||||
[
|
||||
{
|
||||
"pool": "zhgstera6",
|
||||
"cap_alloc": "2.89T",
|
||||
"cap_free": "2.20T",
|
||||
"ops_read": "0",
|
||||
"ops_write": "2",
|
||||
"bw_read": "349K",
|
||||
"bw_write": "448K"
|
||||
},
|
||||
{
|
||||
"pool": "726060ALE614-K8JAPRGN:10",
|
||||
"parent": "zhgstera6",
|
||||
"cap_alloc": "2.89T",
|
||||
"cap_free": "2.20T",
|
||||
"ops_read": "0",
|
||||
"ops_write": "2",
|
||||
"bw_read": "349K",
|
||||
"bw_write": "448K"
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
<a id="jc.parsers.zpool_iostat.parse"></a>
|
||||
|
||||
### parse
|
||||
|
||||
```python
|
||||
def parse(data: str,
|
||||
raw: bool = False,
|
||||
quiet: bool = False) -> List[JSONDictType]
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) unprocessed output if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of Dictionaries. Raw or processed structured data.
|
||||
|
||||
### Parser Information
|
||||
Compatibility: linux, darwin, freebsd
|
||||
|
||||
Version 1.0 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
163
docs/parsers/zpool_status.md
Normal file
163
docs/parsers/zpool_status.md
Normal file
@@ -0,0 +1,163 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
<a id="jc.parsers.zpool_status"></a>
|
||||
|
||||
# jc.parsers.zpool\_status
|
||||
|
||||
jc - JSON Convert `zpool status` command output parser
|
||||
|
||||
Works with or without the `-v` option.
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ zpool status | jc --zpool-status
|
||||
|
||||
or
|
||||
|
||||
$ jc zpool status
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc
|
||||
result = jc.parse('zpool_status', zpool_status_command_output)
|
||||
|
||||
Schema:
|
||||
|
||||
[
|
||||
{
|
||||
"pool": string,
|
||||
"state": string,
|
||||
"status": string,
|
||||
"action": string,
|
||||
"see": string,
|
||||
"scan": string,
|
||||
"scrub": string,
|
||||
"config": [
|
||||
{
|
||||
"name": string,
|
||||
"state": string,
|
||||
"read": integer,
|
||||
"write": integer,
|
||||
"checksum": integer,
|
||||
"errors": string,
|
||||
}
|
||||
],
|
||||
"errors": string
|
||||
}
|
||||
]
|
||||
|
||||
Examples:
|
||||
|
||||
$ zpool status -v | jc --zpool-status -p
|
||||
[
|
||||
{
|
||||
"pool": "tank",
|
||||
"state": "DEGRADED",
|
||||
"status": "One or more devices could not be opened. Suffic...",
|
||||
"action": "Attach the missing device and online it using 'zpool...",
|
||||
"see": "http://www.sun.com/msg/ZFS-8000-2Q",
|
||||
"scrub": "none requested",
|
||||
"config": [
|
||||
{
|
||||
"name": "tank",
|
||||
"state": "DEGRADED",
|
||||
"read": 0,
|
||||
"write": 0,
|
||||
"checksum": 0
|
||||
},
|
||||
{
|
||||
"name": "mirror-0",
|
||||
"state": "DEGRADED",
|
||||
"read": 0,
|
||||
"write": 0,
|
||||
"checksum": 0
|
||||
},
|
||||
{
|
||||
"name": "c1t0d0",
|
||||
"state": "ONLINE",
|
||||
"read": 0,
|
||||
"write": 0,
|
||||
"checksum": 0
|
||||
},
|
||||
{
|
||||
"name": "c1t1d0",
|
||||
"state": "UNAVAIL",
|
||||
"read": 0,
|
||||
"write": 0,
|
||||
"checksum": 0,
|
||||
"errors": "cannot open"
|
||||
}
|
||||
],
|
||||
"errors": "No known data errors"
|
||||
}
|
||||
]
|
||||
|
||||
$ zpool status -v | jc --zpool-status -p -r
|
||||
[
|
||||
{
|
||||
"pool": "tank",
|
||||
"state": "DEGRADED",
|
||||
"status": "One or more devices could not be opened. Sufficient...",
|
||||
"action": "Attach the missing device and online it using 'zpool...",
|
||||
"see": "http://www.sun.com/msg/ZFS-8000-2Q",
|
||||
"scrub": "none requested",
|
||||
"config": [
|
||||
{
|
||||
"name": "tank",
|
||||
"state": "DEGRADED",
|
||||
"read": "0",
|
||||
"write": "0",
|
||||
"checksum": "0"
|
||||
},
|
||||
{
|
||||
"name": "mirror-0",
|
||||
"state": "DEGRADED",
|
||||
"read": "0",
|
||||
"write": "0",
|
||||
"checksum": "0"
|
||||
},
|
||||
{
|
||||
"name": "c1t0d0",
|
||||
"state": "ONLINE",
|
||||
"read": "0",
|
||||
"write": "0",
|
||||
"checksum": "0"
|
||||
},
|
||||
{
|
||||
"name": "c1t1d0",
|
||||
"state": "UNAVAIL",
|
||||
"read": "0",
|
||||
"write": "0",
|
||||
"checksum": "0",
|
||||
"errors": "cannot open"
|
||||
}
|
||||
],
|
||||
"errors": "No known data errors"
|
||||
}
|
||||
]
|
||||
|
||||
<a id="jc.parsers.zpool_status.parse"></a>
|
||||
|
||||
### parse
|
||||
|
||||
```python
|
||||
def parse(data: str,
|
||||
raw: bool = False,
|
||||
quiet: bool = False) -> List[JSONDictType]
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) unprocessed output if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of Dictionaries. Raw or processed structured data.
|
||||
|
||||
### Parser Information
|
||||
Compatibility: linux, darwin, freebsd
|
||||
|
||||
Version 1.1 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
@@ -9,6 +9,7 @@
|
||||
* [convert\_to\_int](#jc.utils.convert_to_int)
|
||||
* [convert\_to\_float](#jc.utils.convert_to_float)
|
||||
* [convert\_to\_bool](#jc.utils.convert_to_bool)
|
||||
* [convert\_size\_to\_int](#jc.utils.convert_size_to_int)
|
||||
* [input\_type\_check](#jc.utils.input_type_check)
|
||||
* [timestamp](#jc.utils.timestamp)
|
||||
* [\_\_init\_\_](#jc.utils.timestamp.__init__)
|
||||
@@ -178,6 +179,48 @@ Returns:
|
||||
True/False False unless a 'truthy' number or string is found
|
||||
('y', 'yes', 'true', '1', 1, -1, etc.)
|
||||
|
||||
<a id="jc.utils.convert_size_to_int"></a>
|
||||
|
||||
### convert\_size\_to\_int
|
||||
|
||||
```python
|
||||
def convert_size_to_int(size: str, binary: bool = False) -> Optional[int]
|
||||
```
|
||||
|
||||
Parse a human readable data size and return the number of bytes.
|
||||
|
||||
Parameters:
|
||||
|
||||
size: (string) The human readable file size to parse.
|
||||
binary: (boolean) `True` to use binary multiples of bytes
|
||||
(base-2) for ambiguous unit symbols and names,
|
||||
`False` to use decimal multiples of bytes (base-10).
|
||||
Returns:
|
||||
|
||||
integer/None Integer if successful conversion, otherwise None
|
||||
|
||||
This function knows how to parse sizes in bytes, kilobytes, megabytes,
|
||||
gigabytes, terabytes and petabytes. Some examples:
|
||||
|
||||
>>> convert_size_to_int('42')
|
||||
42
|
||||
>>> convert_size_to_int('13b')
|
||||
13
|
||||
>>> convert_size_to_int('5 bytes')
|
||||
5
|
||||
>>> convert_size_to_int('1 KB')
|
||||
1000
|
||||
>>> convert_size_to_int('1 kilobyte')
|
||||
1000
|
||||
>>> convert_size_to_int('1 KiB')
|
||||
1024
|
||||
>>> convert_size_to_int('1 KB', binary=True)
|
||||
1024
|
||||
>>> convert_size_to_int('1.5 GB')
|
||||
1500000000
|
||||
>>> convert_size_to_int('1.5 GB', binary=True)
|
||||
1610612736
|
||||
|
||||
<a id="jc.utils.input_type_check"></a>
|
||||
|
||||
### input\_type\_check
|
||||
|
||||
@@ -124,6 +124,14 @@ Get a list of streaming parser module names to be used in
|
||||
`parse()`, `parser_info()`, and `get_help()`. This list is a subset of
|
||||
`parser_mod_list()`.
|
||||
"""
|
||||
from .lib import (__version__, parse, parser_mod_list, plugin_parser_mod_list,
|
||||
standard_parser_mod_list, streaming_parser_mod_list,
|
||||
parser_info, all_parser_info, get_help)
|
||||
from .lib import (
|
||||
__version__ as __version__,
|
||||
parse as parse,
|
||||
parser_mod_list as parser_mod_list,
|
||||
plugin_parser_mod_list as plugin_parser_mod_list,
|
||||
standard_parser_mod_list as standard_parser_mod_list,
|
||||
streaming_parser_mod_list as streaming_parser_mod_list,
|
||||
parser_info as parser_info,
|
||||
all_parser_info as all_parser_info,
|
||||
get_help as get_help
|
||||
)
|
||||
|
||||
@@ -45,10 +45,6 @@ __version_info__ = tuple(int(segment) for segment in __version__.split("."))
|
||||
import sys
|
||||
import os
|
||||
|
||||
PY3 = sys.version_info[0] == 3
|
||||
|
||||
if PY3:
|
||||
unicode = str
|
||||
|
||||
if sys.platform.startswith('java'):
|
||||
import platform
|
||||
@@ -490,10 +486,7 @@ def _get_win_folder_from_registry(csidl_name):
|
||||
registry for this guarantees us the correct answer for all CSIDL_*
|
||||
names.
|
||||
"""
|
||||
if PY3:
|
||||
import winreg as _winreg
|
||||
else:
|
||||
import _winreg
|
||||
import winreg as _winreg
|
||||
|
||||
shell_folder_name = {
|
||||
"CSIDL_APPDATA": "AppData",
|
||||
|
||||
257
jc/cli.py
257
jc/cli.py
@@ -5,11 +5,13 @@ JC cli module
|
||||
import io
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
from itertools import islice
|
||||
from datetime import datetime, timezone
|
||||
import textwrap
|
||||
import shlex
|
||||
import subprocess
|
||||
from typing import List, Dict, Union, Optional, TextIO
|
||||
from typing import List, Dict, Iterable, Union, Optional, TextIO
|
||||
from types import ModuleType
|
||||
from .lib import (
|
||||
__version__, parser_info, all_parser_info, parsers, _get_parser, _parser_is_streaming,
|
||||
@@ -40,6 +42,10 @@ except Exception:
|
||||
JC_CLEAN_EXIT: int = 0
|
||||
JC_ERROR_EXIT: int = 100
|
||||
MAX_EXIT: int = 255
|
||||
SLICER_PATTERN: str = r'-?[0-9]*\:-?[0-9]*$'
|
||||
SLICER_RE = re.compile(SLICER_PATTERN)
|
||||
NEWLINES_PATTERN: str = r'(\r\n|\r|\n)'
|
||||
NEWLINES_RE = re.compile(NEWLINES_PATTERN)
|
||||
|
||||
|
||||
class info():
|
||||
@@ -48,7 +54,7 @@ class info():
|
||||
author: str = 'Kelly Brazil'
|
||||
author_email: str = 'kellyjonbrazil@gmail.com'
|
||||
website: str = 'https://github.com/kellyjonbrazil/jc'
|
||||
copyright: str = '© 2019-2022 Kelly Brazil'
|
||||
copyright: str = '© 2019-2023 Kelly Brazil'
|
||||
license: str = 'MIT License'
|
||||
|
||||
|
||||
@@ -69,11 +75,11 @@ class JcCli():
|
||||
'help_me', 'pretty', 'quiet', 'ignore_exceptions', 'raw', 'meta_out', 'unbuffer',
|
||||
'version_info', 'yaml_output', 'bash_comp', 'zsh_comp', 'magic_found_parser',
|
||||
'magic_options', 'magic_run_command', 'magic_run_command_str', 'magic_stdout',
|
||||
'magic_stderr', 'magic_returncode'
|
||||
'magic_stderr', 'magic_returncode', 'slice_str', 'slice_start', 'slice_end'
|
||||
)
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.data_in: Optional[Union[str, bytes, TextIO]] = None
|
||||
self.data_in: Optional[Union[str, bytes, TextIO, Iterable[str]]] = None
|
||||
self.data_out: Optional[Union[List[JSONDictType], JSONDictType]] = None
|
||||
self.options: List[str] = []
|
||||
self.args: List[str] = []
|
||||
@@ -89,6 +95,11 @@ class JcCli():
|
||||
self.json_indent: Optional[int] = None
|
||||
self.run_timestamp: Optional[datetime] = None
|
||||
|
||||
# slicer
|
||||
self.slice_str: str = ''
|
||||
self.slice_start: Optional[int] = None
|
||||
self.slice_end: Optional[int] = None
|
||||
|
||||
# cli options
|
||||
self.about: bool = False
|
||||
self.debug: bool = False
|
||||
@@ -134,33 +145,34 @@ class JcCli():
|
||||
JC_COLORS=blue,brightblack,magenta,green
|
||||
JC_COLORS=default,default,default,default
|
||||
"""
|
||||
input_error = False
|
||||
env_colors = os.getenv('JC_COLORS')
|
||||
if PYGMENTS_INSTALLED:
|
||||
input_error = False
|
||||
env_colors = os.getenv('JC_COLORS')
|
||||
|
||||
if env_colors:
|
||||
color_list = env_colors.split(',')
|
||||
else:
|
||||
color_list = ['default', 'default', 'default', 'default']
|
||||
if env_colors:
|
||||
color_list = env_colors.split(',')
|
||||
else:
|
||||
color_list = ['default', 'default', 'default', 'default']
|
||||
|
||||
if len(color_list) != 4:
|
||||
input_error = True
|
||||
|
||||
for color in color_list:
|
||||
if color != 'default' and color not in PYGMENT_COLOR:
|
||||
if len(color_list) != 4:
|
||||
input_error = True
|
||||
|
||||
# if there is an issue with the env variable, just set all colors to default and move on
|
||||
if input_error:
|
||||
utils.warning_message(['Could not parse JC_COLORS environment variable'])
|
||||
color_list = ['default', 'default', 'default', 'default']
|
||||
for color in color_list:
|
||||
if color != 'default' and color not in PYGMENT_COLOR:
|
||||
input_error = True
|
||||
|
||||
# Try the color set in the JC_COLORS env variable first. If it is set to default, then fall back to default colors
|
||||
self.custom_colors = {
|
||||
Name.Tag: f'bold {PYGMENT_COLOR[color_list[0]]}' if color_list[0] != 'default' else f"bold {PYGMENT_COLOR['blue']}", # key names
|
||||
Keyword: PYGMENT_COLOR[color_list[1]] if color_list[1] != 'default' else PYGMENT_COLOR['brightblack'], # true, false, null
|
||||
Number: PYGMENT_COLOR[color_list[2]] if color_list[2] != 'default' else PYGMENT_COLOR['magenta'], # numbers
|
||||
String: PYGMENT_COLOR[color_list[3]] if color_list[3] != 'default' else PYGMENT_COLOR['green'] # strings
|
||||
}
|
||||
# if there is an issue with the env variable, just set all colors to default and move on
|
||||
if input_error:
|
||||
utils.warning_message(['Could not parse JC_COLORS environment variable'])
|
||||
color_list = ['default', 'default', 'default', 'default']
|
||||
|
||||
# Try the color set in the JC_COLORS env variable first. If it is set to default, then fall back to default colors
|
||||
self.custom_colors = {
|
||||
Name.Tag: f'bold {PYGMENT_COLOR[color_list[0]]}' if color_list[0] != 'default' else f"bold {PYGMENT_COLOR['blue']}", # key names
|
||||
Keyword: PYGMENT_COLOR[color_list[1]] if color_list[1] != 'default' else PYGMENT_COLOR['brightblack'], # true, false, null
|
||||
Number: PYGMENT_COLOR[color_list[2]] if color_list[2] != 'default' else PYGMENT_COLOR['magenta'], # numbers
|
||||
String: PYGMENT_COLOR[color_list[3]] if color_list[3] != 'default' else PYGMENT_COLOR['green'] # strings
|
||||
}
|
||||
|
||||
def set_mono(self) -> None:
|
||||
"""
|
||||
@@ -204,14 +216,14 @@ class JcCli():
|
||||
category_text: str = ''
|
||||
padding_char: str = ' '
|
||||
all_parsers = all_parser_info(show_hidden=True, show_deprecated=False)
|
||||
generic = [{'arg': x['argument'], 'desc': x['description']} for x in all_parsers if 'generic' in x['tags']]
|
||||
standard = [{'arg': x['argument'], 'desc': x['description']} for x in all_parsers if 'standard' in x['tags']]
|
||||
command = [{'arg': x['argument'], 'desc': x['description']} for x in all_parsers if 'command' in x['tags']]
|
||||
generic = [{'arg': x['argument'], 'desc': x['description']} for x in all_parsers if 'generic' in x.get('tags', [])]
|
||||
standard = [{'arg': x['argument'], 'desc': x['description']} for x in all_parsers if 'standard' in x.get('tags', [])]
|
||||
command = [{'arg': x['argument'], 'desc': x['description']} for x in all_parsers if 'command' in x.get('tags', [])]
|
||||
file_str_bin = [
|
||||
{'arg': x['argument'], 'desc': x['description']} for x in all_parsers
|
||||
if 'file' in x['tags'] or
|
||||
'string' in x['tags'] or
|
||||
'binary' in x['tags']
|
||||
if 'file' in x.get('tags', []) or
|
||||
'string' in x.get('tags', []) or
|
||||
'binary' in x.get('tags', [])
|
||||
]
|
||||
streaming = [{'arg': x['argument'], 'desc': x['description']} for x in all_parsers if x.get('streaming')]
|
||||
categories: Dict = {
|
||||
@@ -432,6 +444,17 @@ class JcCli():
|
||||
self.magic_options = []
|
||||
return
|
||||
|
||||
# slicer found
|
||||
if ':' in arg:
|
||||
if SLICER_RE.match(arg):
|
||||
self.slice_str = arg
|
||||
args_given.pop(0)
|
||||
continue
|
||||
else:
|
||||
utils.warning_message(['Invalid slice syntax.'])
|
||||
args_given.pop(0)
|
||||
continue
|
||||
|
||||
# option found - populate option list
|
||||
if arg.startswith('-'):
|
||||
self.magic_options.extend(args_given.pop(0)[1:])
|
||||
@@ -574,59 +597,6 @@ class JcCli():
|
||||
utils.error_message(['Missing piped data. Use "jc -h" for help.'])
|
||||
self.exit_error()
|
||||
|
||||
def streaming_parse_and_print(self) -> None:
|
||||
"""only supports UTF-8 string data for now"""
|
||||
self.data_in = sys.stdin
|
||||
if self.parser_module:
|
||||
result = self.parser_module.parse(
|
||||
self.data_in,
|
||||
raw=self.raw,
|
||||
quiet=self.quiet,
|
||||
ignore_exceptions=self.ignore_exceptions
|
||||
)
|
||||
|
||||
for line in result:
|
||||
self.data_out = line
|
||||
if self.meta_out:
|
||||
self.run_timestamp = datetime.now(timezone.utc)
|
||||
self.add_metadata_to_output()
|
||||
|
||||
self.safe_print_out()
|
||||
|
||||
def standard_parse_and_print(self) -> None:
|
||||
"""supports binary and UTF-8 string data"""
|
||||
self.data_in = self.magic_stdout or sys.stdin.buffer.read()
|
||||
|
||||
# convert to UTF-8, if possible. Otherwise, leave as bytes
|
||||
try:
|
||||
if isinstance(self.data_in, bytes):
|
||||
self.data_in = self.data_in.decode('utf-8')
|
||||
except UnicodeDecodeError:
|
||||
pass
|
||||
|
||||
if self.parser_module:
|
||||
self.data_out = self.parser_module.parse(
|
||||
self.data_in,
|
||||
raw=self.raw,
|
||||
quiet=self.quiet
|
||||
)
|
||||
|
||||
if self.meta_out:
|
||||
self.run_timestamp = datetime.now(timezone.utc)
|
||||
self.add_metadata_to_output()
|
||||
|
||||
self.safe_print_out()
|
||||
|
||||
def exit_clean(self) -> None:
|
||||
exit_code: int = self.magic_returncode + JC_CLEAN_EXIT
|
||||
exit_code = min(exit_code, MAX_EXIT)
|
||||
sys.exit(exit_code)
|
||||
|
||||
def exit_error(self) -> None:
|
||||
exit_code: int = self.magic_returncode + JC_ERROR_EXIT
|
||||
exit_code = min(exit_code, MAX_EXIT)
|
||||
sys.exit(exit_code)
|
||||
|
||||
def add_metadata_to_output(self) -> None:
|
||||
"""
|
||||
This function mutates data_out in place. If the _jc_meta field
|
||||
@@ -641,7 +611,9 @@ class JcCli():
|
||||
if self.run_timestamp:
|
||||
meta_obj: JSONDictType = {
|
||||
'parser': self.parser_name,
|
||||
'timestamp': self.run_timestamp.timestamp()
|
||||
'timestamp': self.run_timestamp.timestamp(),
|
||||
'slice_start': self.slice_start,
|
||||
'slice_end': self.slice_end
|
||||
}
|
||||
|
||||
if self.magic_run_command:
|
||||
@@ -669,6 +641,116 @@ class JcCli():
|
||||
utils.error_message(['Parser returned an unsupported object type.'])
|
||||
self.exit_error()
|
||||
|
||||
@staticmethod
|
||||
def lazy_splitlines(text: str) -> Iterable[str]:
|
||||
start = 0
|
||||
for m in NEWLINES_RE.finditer(text):
|
||||
begin, end = m.span()
|
||||
if begin != start:
|
||||
yield text[start:begin]
|
||||
start = end
|
||||
|
||||
if text[start:]:
|
||||
yield text[start:]
|
||||
|
||||
def slicer(self) -> None:
|
||||
"""Slice input data lazily, if possible. Updates self.data_in"""
|
||||
if self.slice_str:
|
||||
slice_start_str, slice_end_str = self.slice_str.split(':', maxsplit=1)
|
||||
if slice_start_str:
|
||||
self.slice_start = int(slice_start_str)
|
||||
if slice_end_str:
|
||||
self.slice_end = int(slice_end_str)
|
||||
|
||||
if not self.slice_start is None or not self.slice_end is None:
|
||||
# standard parsers UTF-8 input
|
||||
if isinstance(self.data_in, str):
|
||||
data_in_iter = self.lazy_splitlines(self.data_in)
|
||||
|
||||
# positive slices
|
||||
if (self.slice_start is None or self.slice_start >= 0) \
|
||||
and (self.slice_end is None or self.slice_end >= 0):
|
||||
|
||||
self.data_in = '\n'.join(islice(data_in_iter, self.slice_start, self.slice_end))
|
||||
|
||||
# negative slices found (non-lazy, uses more memory)
|
||||
else:
|
||||
self.data_in = '\n'.join(list(data_in_iter)[self.slice_start:self.slice_end])
|
||||
|
||||
# standard parsers bytes input
|
||||
elif isinstance(self.data_in, bytes):
|
||||
utils.warning_message(['Cannot slice bytes data.'])
|
||||
|
||||
# streaming parsers UTF-8 input
|
||||
else:
|
||||
# positive slices
|
||||
if (self.slice_start is None or self.slice_start >= 0) \
|
||||
and (self.slice_end is None or self.slice_end >= 0) \
|
||||
and self.data_in:
|
||||
|
||||
self.data_in = islice(self.data_in, self.slice_start, self.slice_end)
|
||||
|
||||
# negative slices found (non-lazy, uses more memory)
|
||||
elif self.data_in:
|
||||
self.data_in = list(self.data_in)[self.slice_start:self.slice_end]
|
||||
|
||||
def streaming_parse_and_print(self) -> None:
|
||||
"""only supports UTF-8 string data for now"""
|
||||
self.data_in = sys.stdin
|
||||
self.slicer()
|
||||
|
||||
if self.parser_module:
|
||||
result = self.parser_module.parse(
|
||||
self.data_in,
|
||||
raw=self.raw,
|
||||
quiet=self.quiet,
|
||||
ignore_exceptions=self.ignore_exceptions
|
||||
)
|
||||
|
||||
for line in result:
|
||||
self.data_out = line
|
||||
if self.meta_out:
|
||||
self.run_timestamp = datetime.now(timezone.utc)
|
||||
self.add_metadata_to_output()
|
||||
|
||||
self.safe_print_out()
|
||||
|
||||
def standard_parse_and_print(self) -> None:
|
||||
"""supports binary and UTF-8 string data"""
|
||||
self.data_in = self.magic_stdout or sys.stdin.buffer.read()
|
||||
|
||||
# convert to UTF-8, if possible. Otherwise, leave as bytes
|
||||
try:
|
||||
if isinstance(self.data_in, bytes):
|
||||
self.data_in = self.data_in.decode('utf-8')
|
||||
except UnicodeDecodeError:
|
||||
pass
|
||||
|
||||
self.slicer()
|
||||
|
||||
if self.parser_module:
|
||||
self.data_out = self.parser_module.parse(
|
||||
self.data_in,
|
||||
raw=self.raw,
|
||||
quiet=self.quiet
|
||||
)
|
||||
|
||||
if self.meta_out:
|
||||
self.run_timestamp = datetime.now(timezone.utc)
|
||||
self.add_metadata_to_output()
|
||||
|
||||
self.safe_print_out()
|
||||
|
||||
def exit_clean(self) -> None:
|
||||
exit_code: int = self.magic_returncode + JC_CLEAN_EXIT
|
||||
exit_code = min(exit_code, MAX_EXIT)
|
||||
sys.exit(exit_code)
|
||||
|
||||
def exit_error(self) -> None:
|
||||
exit_code: int = self.magic_returncode + JC_ERROR_EXIT
|
||||
exit_code = min(exit_code, MAX_EXIT)
|
||||
sys.exit(exit_code)
|
||||
|
||||
def _run(self) -> None:
|
||||
# enable colors for Windows cmd.exe terminal
|
||||
if sys.platform.startswith('win32'):
|
||||
@@ -684,6 +766,9 @@ class JcCli():
|
||||
# find options if magic_parser did not find a command
|
||||
if not self.magic_found_parser:
|
||||
for opt in self.args:
|
||||
if SLICER_RE.match(opt):
|
||||
self.slice_str = opt
|
||||
|
||||
if opt in long_options_map:
|
||||
self.options.extend(long_options_map[opt][0])
|
||||
|
||||
|
||||
@@ -63,17 +63,17 @@ Usage:
|
||||
|
||||
Standard syntax:
|
||||
|
||||
COMMAND | jc [OPTIONS] PARSER
|
||||
COMMAND | jc [SLICE] [OPTIONS] PARSER
|
||||
|
||||
cat FILE | jc [OPTIONS] PARSER
|
||||
cat FILE | jc [SLICE] [OPTIONS] PARSER
|
||||
|
||||
echo STRING | jc [OPTIONS] PARSER
|
||||
echo STRING | jc [SLICE] [OPTIONS] PARSER
|
||||
|
||||
Magic syntax:
|
||||
|
||||
jc [OPTIONS] COMMAND
|
||||
jc [SLICE] [OPTIONS] COMMAND
|
||||
|
||||
jc [OPTIONS] /proc/<path-to-procfile>
|
||||
jc [SLICE] [OPTIONS] /proc/<path-to-procfile>
|
||||
|
||||
Parsers:
|
||||
'''
|
||||
@@ -88,6 +88,9 @@ Examples:
|
||||
$ jc --pretty dig www.google.com
|
||||
$ jc --pretty /proc/meminfo
|
||||
|
||||
Line Slicing:
|
||||
$ cat file.csv | jc :101 --csv # parse first 100 lines
|
||||
|
||||
Parser Documentation:
|
||||
$ jc --help --dig
|
||||
|
||||
|
||||
50
jc/lib.py
50
jc/lib.py
@@ -3,13 +3,13 @@ import sys
|
||||
import os
|
||||
import re
|
||||
import importlib
|
||||
from typing import List, Iterable, Union, Iterator
|
||||
from typing import List, Iterable, Optional, Union, Iterator
|
||||
from types import ModuleType
|
||||
from .jc_types import ParserInfoType, JSONDictType
|
||||
from jc import appdirs
|
||||
|
||||
|
||||
__version__ = '1.22.4'
|
||||
__version__ = '1.24.0'
|
||||
|
||||
parsers: List[str] = [
|
||||
'acpi',
|
||||
@@ -19,9 +19,11 @@ parsers: List[str] = [
|
||||
'asciitable',
|
||||
'asciitable-m',
|
||||
'blkid',
|
||||
'bluetoothctl',
|
||||
'cbt',
|
||||
'cef',
|
||||
'cef-s',
|
||||
'certbot',
|
||||
'chage',
|
||||
'cksum',
|
||||
'clf',
|
||||
@@ -32,6 +34,7 @@ parsers: List[str] = [
|
||||
'csv-s',
|
||||
'date',
|
||||
'datetime-iso',
|
||||
'debconf-show',
|
||||
'df',
|
||||
'dig',
|
||||
'dir',
|
||||
@@ -41,6 +44,7 @@ parsers: List[str] = [
|
||||
'email-address',
|
||||
'env',
|
||||
'file',
|
||||
'find',
|
||||
'findmnt',
|
||||
'finger',
|
||||
'free',
|
||||
@@ -55,15 +59,17 @@ parsers: List[str] = [
|
||||
'hashsum',
|
||||
'hciconfig',
|
||||
'history',
|
||||
'host',
|
||||
'hosts',
|
||||
'id',
|
||||
'ifconfig',
|
||||
'ini',
|
||||
'ini-dup',
|
||||
'iostat',
|
||||
'iostat-s',
|
||||
'ip-address',
|
||||
'iptables',
|
||||
'iso-datetime',
|
||||
'ip-route',
|
||||
'iw-scan',
|
||||
'iwconfig',
|
||||
'jar-manifest',
|
||||
@@ -73,6 +79,8 @@ parsers: List[str] = [
|
||||
'last',
|
||||
'ls',
|
||||
'ls-s',
|
||||
'lsattr',
|
||||
'lsb-release',
|
||||
'lsblk',
|
||||
'lsmod',
|
||||
'lsof',
|
||||
@@ -85,9 +93,11 @@ parsers: List[str] = [
|
||||
'mpstat-s',
|
||||
'netstat',
|
||||
'nmcli',
|
||||
'nsd-control',
|
||||
'ntpq',
|
||||
'openvpn',
|
||||
'os-prober',
|
||||
'os-release',
|
||||
'passwd',
|
||||
'pci-ids',
|
||||
'pgpass',
|
||||
@@ -97,10 +107,13 @@ parsers: List[str] = [
|
||||
'ping-s',
|
||||
'pip-list',
|
||||
'pip-show',
|
||||
'pkg-index-apk',
|
||||
'pkg-index-deb',
|
||||
'plist',
|
||||
'postconf',
|
||||
'proc',
|
||||
'proc-buddyinfo',
|
||||
'proc-cmdline',
|
||||
'proc-consoles',
|
||||
'proc-cpuinfo',
|
||||
'proc-crypto',
|
||||
@@ -139,6 +152,7 @@ parsers: List[str] = [
|
||||
'proc-net-packet',
|
||||
'proc-net-protocols',
|
||||
'proc-net-route',
|
||||
'proc-net-tcp',
|
||||
'proc-net-unix',
|
||||
'proc-pid-fdinfo',
|
||||
'proc-pid-io',
|
||||
@@ -150,6 +164,7 @@ parsers: List[str] = [
|
||||
'proc-pid-statm',
|
||||
'proc-pid-status',
|
||||
'ps',
|
||||
'resolve-conf',
|
||||
'route',
|
||||
'rpm-qi',
|
||||
'rsync',
|
||||
@@ -157,10 +172,13 @@ parsers: List[str] = [
|
||||
'semver',
|
||||
'sfdisk',
|
||||
'shadow',
|
||||
'srt',
|
||||
'ss',
|
||||
'ssh-conf',
|
||||
'sshd-conf',
|
||||
'stat',
|
||||
'stat-s',
|
||||
'swapon',
|
||||
'sysctl',
|
||||
'syslog',
|
||||
'syslog-s',
|
||||
@@ -174,10 +192,12 @@ parsers: List[str] = [
|
||||
'time',
|
||||
'timedatectl',
|
||||
'timestamp',
|
||||
'toml',
|
||||
'top',
|
||||
'top-s',
|
||||
'tracepath',
|
||||
'traceroute',
|
||||
'tune2fs',
|
||||
'udevadm',
|
||||
'ufw',
|
||||
'ufw-appinfo',
|
||||
@@ -187,16 +207,21 @@ parsers: List[str] = [
|
||||
'upower',
|
||||
'uptime',
|
||||
'url',
|
||||
'ver',
|
||||
'veracrypt',
|
||||
'vmstat',
|
||||
'vmstat-s',
|
||||
'w',
|
||||
'wc',
|
||||
'who',
|
||||
'x509-cert',
|
||||
'x509-csr',
|
||||
'xml',
|
||||
'xrandr',
|
||||
'yaml',
|
||||
'zipinfo'
|
||||
'zipinfo',
|
||||
'zpool-iostat',
|
||||
'zpool-status'
|
||||
]
|
||||
|
||||
def _cliname_to_modname(parser_cli_name: str) -> str:
|
||||
@@ -207,6 +232,19 @@ def _modname_to_cliname(parser_mod_name: str) -> str:
|
||||
"""Return module's cli name (underscores converted to dashes)"""
|
||||
return parser_mod_name.replace('_', '-')
|
||||
|
||||
def _is_valid_parser_plugin(name: str, local_parsers_dir: str) -> bool:
|
||||
if re.match(r'\w+\.py$', name) and os.path.isfile(os.path.join(local_parsers_dir, name)):
|
||||
try:
|
||||
parser_mod_name = _cliname_to_modname(name)[0:-3]
|
||||
modpath = 'jcparsers.'
|
||||
plugin = importlib.import_module(f'{modpath}{parser_mod_name}')
|
||||
if hasattr(plugin, 'info') and hasattr(plugin, 'parse'):
|
||||
del plugin
|
||||
return True
|
||||
except Exception:
|
||||
return False
|
||||
return False
|
||||
|
||||
# Create the local_parsers list. This is a list of custom or
|
||||
# override parsers from <user_data_dir>/jc/jcparsers/*.py.
|
||||
# Once this list is created, extend the parsers list with it.
|
||||
@@ -216,7 +254,7 @@ local_parsers_dir = os.path.join(data_dir, 'jcparsers')
|
||||
if os.path.isdir(local_parsers_dir):
|
||||
sys.path.append(data_dir)
|
||||
for name in os.listdir(local_parsers_dir):
|
||||
if re.match(r'\w+\.py$', name) and os.path.isfile(os.path.join(local_parsers_dir, name)):
|
||||
if _is_valid_parser_plugin(name, local_parsers_dir):
|
||||
plugin_name = name[0:-3]
|
||||
local_parsers.append(_modname_to_cliname(plugin_name))
|
||||
if plugin_name not in parsers:
|
||||
@@ -277,7 +315,7 @@ def parse(
|
||||
data: Union[str, bytes, Iterable[str]],
|
||||
quiet: bool = False,
|
||||
raw: bool = False,
|
||||
ignore_exceptions: bool = None,
|
||||
ignore_exceptions: Optional[bool] = None,
|
||||
**kwargs
|
||||
) -> Union[JSONDictType, List[JSONDictType], Iterator[JSONDictType]]:
|
||||
"""
|
||||
|
||||
@@ -227,7 +227,7 @@ import jc.utils
|
||||
|
||||
class info():
|
||||
"""Provides parser metadata (version, author, etc.)"""
|
||||
version = '1.4'
|
||||
version = '1.7'
|
||||
description = '`acpi` command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
@@ -333,14 +333,19 @@ def parse(data, raw=False, quiet=False):
|
||||
if obj_type == 'Battery':
|
||||
output_line['type'] = obj_type
|
||||
output_line['id'] = obj_id
|
||||
if 'Charging' in line or 'Discharging' in line or 'Full' in line:
|
||||
if 'Not charging' in line:
|
||||
output_line['state'] = 'Not charging'
|
||||
output_line['charge_percent'] = line.split()[-1].rstrip('%,')
|
||||
|
||||
if any(word in line for word in ('Charging', 'Discharging', 'Full')):
|
||||
output_line['state'] = line.split()[2][:-1]
|
||||
output_line['charge_percent'] = line.split()[3].rstrip('%,')
|
||||
if 'rate information unavailable' not in line:
|
||||
if 'Charging' in line:
|
||||
output_line['until_charged'] = line.split()[4]
|
||||
if 'Discharging' in line:
|
||||
output_line['charge_remaining'] = line.split()[4]
|
||||
if 'will never fully discharge' in line or 'rate information unavailable' in line:
|
||||
pass
|
||||
elif 'Charging' in line:
|
||||
output_line['until_charged'] = line.split()[4]
|
||||
elif 'Discharging' in line:
|
||||
output_line['charge_remaining'] = line.split()[4]
|
||||
|
||||
if 'design capacity' in line:
|
||||
output_line['design_capacity_mah'] = line.split()[4]
|
||||
@@ -350,10 +355,7 @@ def parse(data, raw=False, quiet=False):
|
||||
if obj_type == 'Adapter':
|
||||
output_line['type'] = obj_type
|
||||
output_line['id'] = obj_id
|
||||
if 'on-line' in line:
|
||||
output_line['on-line'] = True
|
||||
else:
|
||||
output_line['on-line'] = False
|
||||
output_line['on-line'] = 'on-line' in line
|
||||
|
||||
if obj_type == 'Thermal':
|
||||
output_line['type'] = obj_type
|
||||
|
||||
@@ -119,7 +119,7 @@ import jc.parsers.universal
|
||||
|
||||
class info():
|
||||
"""Provides parser metadata (version, author, etc.)"""
|
||||
version = '1.11'
|
||||
version = '1.12'
|
||||
description = '`arp` command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
@@ -222,14 +222,26 @@ def parse(
|
||||
else:
|
||||
for line in cleandata:
|
||||
splitline = line.split()
|
||||
if '<incomplete>' not in splitline:
|
||||
|
||||
# Ignore AIX bucket information
|
||||
if 'bucket:' in splitline[0]:
|
||||
continue
|
||||
elif 'There' in splitline[0] and 'are' in splitline[1]:
|
||||
continue
|
||||
|
||||
# AIX uses (incomplete)
|
||||
elif '<incomplete>' not in splitline and '(incomplete)' not in splitline:
|
||||
output_line = {
|
||||
'name': splitline[0],
|
||||
'address': splitline[1].lstrip('(').rstrip(')'),
|
||||
'hwtype': splitline[4].lstrip('[').rstrip(']'),
|
||||
'hwaddress': splitline[3],
|
||||
'iface': splitline[6],
|
||||
}
|
||||
# Handle permanence and ignore interface in AIX
|
||||
if 'permanent' in splitline:
|
||||
output_line['permanent'] = True
|
||||
elif 'in' not in splitline[6]: # AIX doesn't show interface
|
||||
output_line['iface'] = splitline[6]
|
||||
|
||||
else:
|
||||
output_line = {
|
||||
@@ -237,8 +249,10 @@ def parse(
|
||||
'address': splitline[1].lstrip('(').rstrip(')'),
|
||||
'hwtype': None,
|
||||
'hwaddress': None,
|
||||
'iface': splitline[5],
|
||||
}
|
||||
# AIX doesn't show interface
|
||||
if len(splitline) >= 5:
|
||||
output_line['iface'] = splitline[5]
|
||||
|
||||
raw_output.append(output_line)
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import socket
|
||||
import struct
|
||||
|
||||
from ._errors import unwrap
|
||||
from ._types import byte_cls, bytes_to_list, str_cls, type_name
|
||||
from ._types import type_name
|
||||
|
||||
|
||||
def inet_ntop(address_family, packed_ip):
|
||||
@@ -33,7 +33,7 @@ def inet_ntop(address_family, packed_ip):
|
||||
repr(address_family)
|
||||
))
|
||||
|
||||
if not isinstance(packed_ip, byte_cls):
|
||||
if not isinstance(packed_ip, bytes):
|
||||
raise TypeError(unwrap(
|
||||
'''
|
||||
packed_ip must be a byte string, not %s
|
||||
@@ -52,7 +52,7 @@ def inet_ntop(address_family, packed_ip):
|
||||
))
|
||||
|
||||
if address_family == socket.AF_INET:
|
||||
return '%d.%d.%d.%d' % tuple(bytes_to_list(packed_ip))
|
||||
return '%d.%d.%d.%d' % tuple(list(packed_ip))
|
||||
|
||||
octets = struct.unpack(b'!HHHHHHHH', packed_ip)
|
||||
|
||||
@@ -106,7 +106,7 @@ def inet_pton(address_family, ip_string):
|
||||
repr(address_family)
|
||||
))
|
||||
|
||||
if not isinstance(ip_string, str_cls):
|
||||
if not isinstance(ip_string, str):
|
||||
raise TypeError(unwrap(
|
||||
'''
|
||||
ip_string must be a unicode string, not %s
|
||||
|
||||
@@ -13,25 +13,16 @@ from __future__ import unicode_literals, division, absolute_import, print_functi
|
||||
from encodings import idna # noqa
|
||||
import codecs
|
||||
import re
|
||||
import sys
|
||||
|
||||
from ._errors import unwrap
|
||||
from ._types import byte_cls, str_cls, type_name, bytes_to_list, int_types
|
||||
from ._types import type_name
|
||||
|
||||
if sys.version_info < (3,):
|
||||
from urlparse import urlsplit, urlunsplit
|
||||
from urllib import (
|
||||
quote as urlquote,
|
||||
unquote as unquote_to_bytes,
|
||||
)
|
||||
|
||||
else:
|
||||
from urllib.parse import (
|
||||
quote as urlquote,
|
||||
unquote_to_bytes,
|
||||
urlsplit,
|
||||
urlunsplit,
|
||||
)
|
||||
from urllib.parse import (
|
||||
quote as urlquote,
|
||||
unquote_to_bytes,
|
||||
urlsplit,
|
||||
urlunsplit,
|
||||
)
|
||||
|
||||
|
||||
def iri_to_uri(value, normalize=False):
|
||||
@@ -48,7 +39,7 @@ def iri_to_uri(value, normalize=False):
|
||||
A byte string of the ASCII-encoded URI
|
||||
"""
|
||||
|
||||
if not isinstance(value, str_cls):
|
||||
if not isinstance(value, str):
|
||||
raise TypeError(unwrap(
|
||||
'''
|
||||
value must be a unicode string, not %s
|
||||
@@ -57,19 +48,7 @@ def iri_to_uri(value, normalize=False):
|
||||
))
|
||||
|
||||
scheme = None
|
||||
# Python 2.6 doesn't split properly is the URL doesn't start with http:// or https://
|
||||
if sys.version_info < (2, 7) and not value.startswith('http://') and not value.startswith('https://'):
|
||||
real_prefix = None
|
||||
prefix_match = re.match('^[^:]*://', value)
|
||||
if prefix_match:
|
||||
real_prefix = prefix_match.group(0)
|
||||
value = 'http://' + value[len(real_prefix):]
|
||||
parsed = urlsplit(value)
|
||||
if real_prefix:
|
||||
value = real_prefix + value[7:]
|
||||
scheme = _urlquote(real_prefix[:-3])
|
||||
else:
|
||||
parsed = urlsplit(value)
|
||||
parsed = urlsplit(value)
|
||||
|
||||
if scheme is None:
|
||||
scheme = _urlquote(parsed.scheme)
|
||||
@@ -81,7 +60,7 @@ def iri_to_uri(value, normalize=False):
|
||||
password = _urlquote(parsed.password, safe='!$&\'()*+,;=')
|
||||
port = parsed.port
|
||||
if port is not None:
|
||||
port = str_cls(port).encode('ascii')
|
||||
port = str(port).encode('ascii')
|
||||
|
||||
netloc = b''
|
||||
if username is not None:
|
||||
@@ -112,7 +91,7 @@ def iri_to_uri(value, normalize=False):
|
||||
path = ''
|
||||
|
||||
output = urlunsplit((scheme, netloc, path, query, fragment))
|
||||
if isinstance(output, str_cls):
|
||||
if isinstance(output, str):
|
||||
output = output.encode('latin1')
|
||||
return output
|
||||
|
||||
@@ -128,7 +107,7 @@ def uri_to_iri(value):
|
||||
A unicode string of the IRI
|
||||
"""
|
||||
|
||||
if not isinstance(value, byte_cls):
|
||||
if not isinstance(value, bytes):
|
||||
raise TypeError(unwrap(
|
||||
'''
|
||||
value must be a byte string, not %s
|
||||
@@ -148,7 +127,7 @@ def uri_to_iri(value):
|
||||
if hostname:
|
||||
hostname = hostname.decode('idna')
|
||||
port = parsed.port
|
||||
if port and not isinstance(port, int_types):
|
||||
if port and not isinstance(port, int):
|
||||
port = port.decode('ascii')
|
||||
|
||||
netloc = ''
|
||||
@@ -160,7 +139,7 @@ def uri_to_iri(value):
|
||||
if hostname is not None:
|
||||
netloc += hostname
|
||||
if port is not None:
|
||||
netloc += ':' + str_cls(port)
|
||||
netloc += ':' + str(port)
|
||||
|
||||
path = _urlunquote(parsed.path, remap=['/'], preserve=True)
|
||||
query = _urlunquote(parsed.query, remap=['&', '='], preserve=True)
|
||||
@@ -182,7 +161,7 @@ def _iri_utf8_errors_handler(exc):
|
||||
resume at)
|
||||
"""
|
||||
|
||||
bytes_as_ints = bytes_to_list(exc.object[exc.start:exc.end])
|
||||
bytes_as_ints = list(exc.object[exc.start:exc.end])
|
||||
replacements = ['%%%02x' % num for num in bytes_as_ints]
|
||||
return (''.join(replacements), exc.end)
|
||||
|
||||
@@ -230,7 +209,7 @@ def _urlquote(string, safe=''):
|
||||
string = re.sub('%[0-9a-fA-F]{2}', _extract_escape, string)
|
||||
|
||||
output = urlquote(string.encode('utf-8'), safe=safe.encode('utf-8'))
|
||||
if not isinstance(output, byte_cls):
|
||||
if not isinstance(output, bytes):
|
||||
output = output.encode('ascii')
|
||||
|
||||
# Restore the existing quoted values that we extracted
|
||||
|
||||
@@ -1,135 +0,0 @@
|
||||
# Copyright (c) 2009 Raymond Hettinger
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
# (the "Software"), to deal in the Software without restriction,
|
||||
# including without limitation the rights to use, copy, modify, merge,
|
||||
# publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
# and to permit persons to whom the Software is furnished to do so,
|
||||
# subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
# OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
import sys
|
||||
|
||||
if not sys.version_info < (2, 7):
|
||||
|
||||
from collections import OrderedDict
|
||||
|
||||
else:
|
||||
|
||||
from UserDict import DictMixin
|
||||
|
||||
class OrderedDict(dict, DictMixin):
|
||||
|
||||
def __init__(self, *args, **kwds):
|
||||
if len(args) > 1:
|
||||
raise TypeError('expected at most 1 arguments, got %d' % len(args))
|
||||
try:
|
||||
self.__end
|
||||
except AttributeError:
|
||||
self.clear()
|
||||
self.update(*args, **kwds)
|
||||
|
||||
def clear(self):
|
||||
self.__end = end = []
|
||||
end += [None, end, end] # sentinel node for doubly linked list
|
||||
self.__map = {} # key --> [key, prev, next]
|
||||
dict.clear(self)
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
if key not in self:
|
||||
end = self.__end
|
||||
curr = end[1]
|
||||
curr[2] = end[1] = self.__map[key] = [key, curr, end]
|
||||
dict.__setitem__(self, key, value)
|
||||
|
||||
def __delitem__(self, key):
|
||||
dict.__delitem__(self, key)
|
||||
key, prev, next_ = self.__map.pop(key)
|
||||
prev[2] = next_
|
||||
next_[1] = prev
|
||||
|
||||
def __iter__(self):
|
||||
end = self.__end
|
||||
curr = end[2]
|
||||
while curr is not end:
|
||||
yield curr[0]
|
||||
curr = curr[2]
|
||||
|
||||
def __reversed__(self):
|
||||
end = self.__end
|
||||
curr = end[1]
|
||||
while curr is not end:
|
||||
yield curr[0]
|
||||
curr = curr[1]
|
||||
|
||||
def popitem(self, last=True):
|
||||
if not self:
|
||||
raise KeyError('dictionary is empty')
|
||||
if last:
|
||||
key = reversed(self).next()
|
||||
else:
|
||||
key = iter(self).next()
|
||||
value = self.pop(key)
|
||||
return key, value
|
||||
|
||||
def __reduce__(self):
|
||||
items = [[k, self[k]] for k in self]
|
||||
tmp = self.__map, self.__end
|
||||
del self.__map, self.__end
|
||||
inst_dict = vars(self).copy()
|
||||
self.__map, self.__end = tmp
|
||||
if inst_dict:
|
||||
return (self.__class__, (items,), inst_dict)
|
||||
return self.__class__, (items,)
|
||||
|
||||
def keys(self):
|
||||
return list(self)
|
||||
|
||||
setdefault = DictMixin.setdefault
|
||||
update = DictMixin.update
|
||||
pop = DictMixin.pop
|
||||
values = DictMixin.values
|
||||
items = DictMixin.items
|
||||
iterkeys = DictMixin.iterkeys
|
||||
itervalues = DictMixin.itervalues
|
||||
iteritems = DictMixin.iteritems
|
||||
|
||||
def __repr__(self):
|
||||
if not self:
|
||||
return '%s()' % (self.__class__.__name__,)
|
||||
return '%s(%r)' % (self.__class__.__name__, self.items())
|
||||
|
||||
def copy(self):
|
||||
return self.__class__(self)
|
||||
|
||||
@classmethod
|
||||
def fromkeys(cls, iterable, value=None):
|
||||
d = cls()
|
||||
for key in iterable:
|
||||
d[key] = value
|
||||
return d
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, OrderedDict):
|
||||
if len(self) != len(other):
|
||||
return False
|
||||
for p, q in zip(self.items(), other.items()):
|
||||
if p != q:
|
||||
return False
|
||||
return True
|
||||
return dict.__eq__(self, other)
|
||||
|
||||
def __ne__(self, other):
|
||||
return not self == other
|
||||
|
||||
@@ -2,28 +2,10 @@
|
||||
from __future__ import unicode_literals, division, absolute_import, print_function
|
||||
|
||||
import inspect
|
||||
import sys
|
||||
|
||||
|
||||
if sys.version_info < (3,):
|
||||
str_cls = unicode # noqa
|
||||
byte_cls = str
|
||||
int_types = (int, long) # noqa
|
||||
|
||||
def bytes_to_list(byte_string):
|
||||
return [ord(b) for b in byte_string]
|
||||
|
||||
chr_cls = chr
|
||||
|
||||
else:
|
||||
str_cls = str
|
||||
byte_cls = bytes
|
||||
int_types = int
|
||||
|
||||
bytes_to_list = list
|
||||
|
||||
def chr_cls(num):
|
||||
return bytes([num])
|
||||
def chr_cls(num):
|
||||
return bytes([num])
|
||||
|
||||
|
||||
def type_name(value):
|
||||
|
||||
@@ -48,8 +48,10 @@ Other type classes are defined that help compose the types listed above.
|
||||
|
||||
from __future__ import unicode_literals, division, absolute_import, print_function
|
||||
|
||||
from collections import OrderedDict
|
||||
from datetime import datetime, timedelta
|
||||
from fractions import Fraction
|
||||
from io import BytesIO
|
||||
import binascii
|
||||
import copy
|
||||
import math
|
||||
@@ -58,22 +60,10 @@ import sys
|
||||
|
||||
from . import _teletex_codec
|
||||
from ._errors import unwrap
|
||||
from ._ordereddict import OrderedDict
|
||||
from ._types import type_name, str_cls, byte_cls, int_types, chr_cls
|
||||
from ._types import type_name, chr_cls
|
||||
from .parser import _parse, _dump_header
|
||||
from .util import int_to_bytes, int_from_bytes, timezone, extended_datetime, create_timezone, utc_with_dst
|
||||
|
||||
if sys.version_info <= (3,):
|
||||
from cStringIO import StringIO as BytesIO
|
||||
|
||||
range = xrange # noqa
|
||||
_PY2 = True
|
||||
|
||||
else:
|
||||
from io import BytesIO
|
||||
|
||||
_PY2 = False
|
||||
|
||||
|
||||
_teletex_codec.register()
|
||||
|
||||
@@ -220,7 +210,7 @@ class Asn1Value(object):
|
||||
An instance of the current class
|
||||
"""
|
||||
|
||||
if not isinstance(encoded_data, byte_cls):
|
||||
if not isinstance(encoded_data, bytes):
|
||||
raise TypeError('encoded_data must be a byte string, not %s' % type_name(encoded_data))
|
||||
|
||||
spec = None
|
||||
@@ -291,7 +281,7 @@ class Asn1Value(object):
|
||||
cls = self.__class__
|
||||
# Allow explicit to be specified as a simple 2-element tuple
|
||||
# instead of requiring the user make a nested tuple
|
||||
if cls.explicit is not None and isinstance(cls.explicit[0], int_types):
|
||||
if cls.explicit is not None and isinstance(cls.explicit[0], int):
|
||||
cls.explicit = (cls.explicit, )
|
||||
if hasattr(cls, '_setup'):
|
||||
self._setup()
|
||||
@@ -299,7 +289,7 @@ class Asn1Value(object):
|
||||
|
||||
# Normalize tagging values
|
||||
if explicit is not None:
|
||||
if isinstance(explicit, int_types):
|
||||
if isinstance(explicit, int):
|
||||
if class_ is None:
|
||||
class_ = 'context'
|
||||
explicit = (class_, explicit)
|
||||
@@ -309,7 +299,7 @@ class Asn1Value(object):
|
||||
tag = None
|
||||
|
||||
if implicit is not None:
|
||||
if isinstance(implicit, int_types):
|
||||
if isinstance(implicit, int):
|
||||
if class_ is None:
|
||||
class_ = 'context'
|
||||
implicit = (class_, implicit)
|
||||
@@ -336,11 +326,11 @@ class Asn1Value(object):
|
||||
|
||||
if explicit is not None:
|
||||
# Ensure we have a tuple of 2-element tuples
|
||||
if len(explicit) == 2 and isinstance(explicit[1], int_types):
|
||||
if len(explicit) == 2 and isinstance(explicit[1], int):
|
||||
explicit = (explicit, )
|
||||
for class_, tag in explicit:
|
||||
invalid_class = None
|
||||
if isinstance(class_, int_types):
|
||||
if isinstance(class_, int):
|
||||
if class_ not in CLASS_NUM_TO_NAME_MAP:
|
||||
invalid_class = class_
|
||||
else:
|
||||
@@ -356,7 +346,7 @@ class Asn1Value(object):
|
||||
repr(invalid_class)
|
||||
))
|
||||
if tag is not None:
|
||||
if not isinstance(tag, int_types):
|
||||
if not isinstance(tag, int):
|
||||
raise TypeError(unwrap(
|
||||
'''
|
||||
explicit tag must be an integer, not %s
|
||||
@@ -379,7 +369,7 @@ class Asn1Value(object):
|
||||
repr(class_)
|
||||
))
|
||||
if tag is not None:
|
||||
if not isinstance(tag, int_types):
|
||||
if not isinstance(tag, int):
|
||||
raise TypeError(unwrap(
|
||||
'''
|
||||
implicit tag must be an integer, not %s
|
||||
@@ -445,10 +435,7 @@ class Asn1Value(object):
|
||||
A unicode string
|
||||
"""
|
||||
|
||||
if _PY2:
|
||||
return self.__bytes__()
|
||||
else:
|
||||
return self.__unicode__()
|
||||
return self.__unicode__()
|
||||
|
||||
def __repr__(self):
|
||||
"""
|
||||
@@ -456,10 +443,7 @@ class Asn1Value(object):
|
||||
A unicode string
|
||||
"""
|
||||
|
||||
if _PY2:
|
||||
return '<%s %s b%s>' % (type_name(self), id(self), repr(self.dump()))
|
||||
else:
|
||||
return '<%s %s %s>' % (type_name(self), id(self), repr(self.dump()))
|
||||
return '<%s %s %s>' % (type_name(self), id(self), repr(self.dump()))
|
||||
|
||||
def __bytes__(self):
|
||||
"""
|
||||
@@ -609,10 +593,7 @@ class Asn1Value(object):
|
||||
elif hasattr(self, 'chosen'):
|
||||
self.chosen.debug(nest_level + 2)
|
||||
else:
|
||||
if _PY2 and isinstance(self.native, byte_cls):
|
||||
print('%s Native: b%s' % (prefix, repr(self.native)))
|
||||
else:
|
||||
print('%s Native: %s' % (prefix, self.native))
|
||||
print('%s Native: %s' % (prefix, self.native))
|
||||
|
||||
def dump(self, force=False):
|
||||
"""
|
||||
@@ -1058,7 +1039,7 @@ class Choice(Asn1Value):
|
||||
A instance of the current class
|
||||
"""
|
||||
|
||||
if not isinstance(encoded_data, byte_cls):
|
||||
if not isinstance(encoded_data, bytes):
|
||||
raise TypeError('encoded_data must be a byte string, not %s' % type_name(encoded_data))
|
||||
|
||||
value, _ = _parse_build(encoded_data, spec=cls, spec_params=kwargs, strict=strict)
|
||||
@@ -1425,17 +1406,11 @@ class Concat(object):
|
||||
|
||||
def __str__(self):
|
||||
"""
|
||||
Since str is different in Python 2 and 3, this calls the appropriate
|
||||
method, __unicode__() or __bytes__()
|
||||
|
||||
:return:
|
||||
A unicode string
|
||||
"""
|
||||
|
||||
if _PY2:
|
||||
return self.__bytes__()
|
||||
else:
|
||||
return self.__unicode__()
|
||||
return self.__unicode__()
|
||||
|
||||
def __bytes__(self):
|
||||
"""
|
||||
@@ -1684,7 +1659,7 @@ class Primitive(Asn1Value):
|
||||
A byte string
|
||||
"""
|
||||
|
||||
if not isinstance(value, byte_cls):
|
||||
if not isinstance(value, bytes):
|
||||
raise TypeError(unwrap(
|
||||
'''
|
||||
%s value must be a byte string, not %s
|
||||
@@ -1784,7 +1759,7 @@ class AbstractString(Constructable, Primitive):
|
||||
A unicode string
|
||||
"""
|
||||
|
||||
if not isinstance(value, str_cls):
|
||||
if not isinstance(value, str):
|
||||
raise TypeError(unwrap(
|
||||
'''
|
||||
%s value must be a unicode string, not %s
|
||||
@@ -1915,7 +1890,7 @@ class Integer(Primitive, ValueMap):
|
||||
ValueError - when an invalid value is passed
|
||||
"""
|
||||
|
||||
if isinstance(value, str_cls):
|
||||
if isinstance(value, str):
|
||||
if self._map is None:
|
||||
raise ValueError(unwrap(
|
||||
'''
|
||||
@@ -1935,7 +1910,7 @@ class Integer(Primitive, ValueMap):
|
||||
|
||||
value = self._reverse_map[value]
|
||||
|
||||
elif not isinstance(value, int_types):
|
||||
elif not isinstance(value, int):
|
||||
raise TypeError(unwrap(
|
||||
'''
|
||||
%s value must be an integer or unicode string when a name_map
|
||||
@@ -2004,7 +1979,7 @@ class _IntegerBitString(object):
|
||||
# return an empty chunk, for cases like \x23\x80\x00\x00
|
||||
return []
|
||||
|
||||
unused_bits_len = ord(self.contents[0]) if _PY2 else self.contents[0]
|
||||
unused_bits_len = self.contents[0]
|
||||
value = int_from_bytes(self.contents[1:])
|
||||
bits = (len(self.contents) - 1) * 8
|
||||
|
||||
@@ -2135,7 +2110,7 @@ class BitString(_IntegerBitString, Constructable, Castable, Primitive, ValueMap)
|
||||
if key in value:
|
||||
bits[index] = 1
|
||||
|
||||
value = ''.join(map(str_cls, bits))
|
||||
value = ''.join(map(str, bits))
|
||||
|
||||
elif value.__class__ == tuple:
|
||||
if self._map is None:
|
||||
@@ -2146,7 +2121,7 @@ class BitString(_IntegerBitString, Constructable, Castable, Primitive, ValueMap)
|
||||
if bit:
|
||||
name = self._map.get(index, index)
|
||||
self._native.add(name)
|
||||
value = ''.join(map(str_cls, value))
|
||||
value = ''.join(map(str, value))
|
||||
|
||||
else:
|
||||
raise TypeError(unwrap(
|
||||
@@ -2220,7 +2195,7 @@ class BitString(_IntegerBitString, Constructable, Castable, Primitive, ValueMap)
|
||||
A boolean if the bit is set
|
||||
"""
|
||||
|
||||
is_int = isinstance(key, int_types)
|
||||
is_int = isinstance(key, int)
|
||||
if not is_int:
|
||||
if not isinstance(self._map, dict):
|
||||
raise ValueError(unwrap(
|
||||
@@ -2266,7 +2241,7 @@ class BitString(_IntegerBitString, Constructable, Castable, Primitive, ValueMap)
|
||||
ValueError - when _map is not set or the key name is invalid
|
||||
"""
|
||||
|
||||
is_int = isinstance(key, int_types)
|
||||
is_int = isinstance(key, int)
|
||||
if not is_int:
|
||||
if self._map is None:
|
||||
raise ValueError(unwrap(
|
||||
@@ -2333,8 +2308,8 @@ class BitString(_IntegerBitString, Constructable, Castable, Primitive, ValueMap)
|
||||
if self._map:
|
||||
self._native = set()
|
||||
for index, bit in enumerate(bits):
|
||||
if bit:
|
||||
name = self._map.get(index, index)
|
||||
if bit and index in self._map:
|
||||
name = self._map.get(index)
|
||||
self._native.add(name)
|
||||
else:
|
||||
self._native = bits
|
||||
@@ -2365,7 +2340,7 @@ class OctetBitString(Constructable, Castable, Primitive):
|
||||
ValueError - when an invalid value is passed
|
||||
"""
|
||||
|
||||
if not isinstance(value, byte_cls):
|
||||
if not isinstance(value, bytes):
|
||||
raise TypeError(unwrap(
|
||||
'''
|
||||
%s value must be a byte string, not %s
|
||||
@@ -2435,7 +2410,7 @@ class OctetBitString(Constructable, Castable, Primitive):
|
||||
List with one tuple, consisting of a byte string and an integer (unused bits)
|
||||
"""
|
||||
|
||||
unused_bits_len = ord(self.contents[0]) if _PY2 else self.contents[0]
|
||||
unused_bits_len = self.contents[0]
|
||||
if not unused_bits_len:
|
||||
return [(self.contents[1:], ())]
|
||||
|
||||
@@ -2448,11 +2423,11 @@ class OctetBitString(Constructable, Castable, Primitive):
|
||||
raise ValueError('Bit string has {0} unused bits'.format(unused_bits_len))
|
||||
|
||||
mask = (1 << unused_bits_len) - 1
|
||||
last_byte = ord(self.contents[-1]) if _PY2 else self.contents[-1]
|
||||
last_byte = self.contents[-1]
|
||||
|
||||
# zero out the unused bits in the last byte.
|
||||
zeroed_byte = last_byte & ~mask
|
||||
value = self.contents[1:-1] + (chr(zeroed_byte) if _PY2 else bytes((zeroed_byte,)))
|
||||
value = self.contents[1:-1] + bytes((zeroed_byte,))
|
||||
|
||||
unused_bits = _int_to_bit_tuple(last_byte & mask, unused_bits_len)
|
||||
|
||||
@@ -2505,7 +2480,7 @@ class IntegerBitString(_IntegerBitString, Constructable, Castable, Primitive):
|
||||
ValueError - when an invalid value is passed
|
||||
"""
|
||||
|
||||
if not isinstance(value, int_types):
|
||||
if not isinstance(value, int):
|
||||
raise TypeError(unwrap(
|
||||
'''
|
||||
%s value must be a positive integer, not %s
|
||||
@@ -2570,7 +2545,7 @@ class OctetString(Constructable, Castable, Primitive):
|
||||
A byte string
|
||||
"""
|
||||
|
||||
if not isinstance(value, byte_cls):
|
||||
if not isinstance(value, bytes):
|
||||
raise TypeError(unwrap(
|
||||
'''
|
||||
%s value must be a byte string, not %s
|
||||
@@ -2654,7 +2629,7 @@ class IntegerOctetString(Constructable, Castable, Primitive):
|
||||
ValueError - when an invalid value is passed
|
||||
"""
|
||||
|
||||
if not isinstance(value, int_types):
|
||||
if not isinstance(value, int):
|
||||
raise TypeError(unwrap(
|
||||
'''
|
||||
%s value must be a positive integer, not %s
|
||||
@@ -2752,7 +2727,7 @@ class ParsableOctetString(Constructable, Castable, Primitive):
|
||||
A byte string
|
||||
"""
|
||||
|
||||
if not isinstance(value, byte_cls):
|
||||
if not isinstance(value, bytes):
|
||||
raise TypeError(unwrap(
|
||||
'''
|
||||
%s value must be a byte string, not %s
|
||||
@@ -2904,7 +2879,7 @@ class ParsableOctetBitString(ParsableOctetString):
|
||||
ValueError - when an invalid value is passed
|
||||
"""
|
||||
|
||||
if not isinstance(value, byte_cls):
|
||||
if not isinstance(value, bytes):
|
||||
raise TypeError(unwrap(
|
||||
'''
|
||||
%s value must be a byte string, not %s
|
||||
@@ -2934,7 +2909,7 @@ class ParsableOctetBitString(ParsableOctetString):
|
||||
A byte string
|
||||
"""
|
||||
|
||||
unused_bits_len = ord(self.contents[0]) if _PY2 else self.contents[0]
|
||||
unused_bits_len = self.contents[0]
|
||||
if unused_bits_len:
|
||||
raise ValueError('ParsableOctetBitString should have no unused bits')
|
||||
|
||||
@@ -3007,7 +2982,7 @@ class ObjectIdentifier(Primitive, ValueMap):
|
||||
type_name(cls)
|
||||
))
|
||||
|
||||
if not isinstance(value, str_cls):
|
||||
if not isinstance(value, str):
|
||||
raise TypeError(unwrap(
|
||||
'''
|
||||
value must be a unicode string, not %s
|
||||
@@ -3045,7 +3020,7 @@ class ObjectIdentifier(Primitive, ValueMap):
|
||||
type_name(cls)
|
||||
))
|
||||
|
||||
if not isinstance(value, str_cls):
|
||||
if not isinstance(value, str):
|
||||
raise TypeError(unwrap(
|
||||
'''
|
||||
value must be a unicode string, not %s
|
||||
@@ -3079,7 +3054,7 @@ class ObjectIdentifier(Primitive, ValueMap):
|
||||
ValueError - when an invalid value is passed
|
||||
"""
|
||||
|
||||
if not isinstance(value, str_cls):
|
||||
if not isinstance(value, str):
|
||||
raise TypeError(unwrap(
|
||||
'''
|
||||
%s value must be a unicode string, not %s
|
||||
@@ -3153,24 +3128,22 @@ class ObjectIdentifier(Primitive, ValueMap):
|
||||
|
||||
part = 0
|
||||
for byte in self.contents:
|
||||
if _PY2:
|
||||
byte = ord(byte)
|
||||
part = part * 128
|
||||
part += byte & 127
|
||||
# Last byte in subidentifier has the eighth bit set to 0
|
||||
if byte & 0x80 == 0:
|
||||
if len(output) == 0:
|
||||
if part >= 80:
|
||||
output.append(str_cls(2))
|
||||
output.append(str_cls(part - 80))
|
||||
output.append(str(2))
|
||||
output.append(str(part - 80))
|
||||
elif part >= 40:
|
||||
output.append(str_cls(1))
|
||||
output.append(str_cls(part - 40))
|
||||
output.append(str(1))
|
||||
output.append(str(part - 40))
|
||||
else:
|
||||
output.append(str_cls(0))
|
||||
output.append(str_cls(part))
|
||||
output.append(str(0))
|
||||
output.append(str(part))
|
||||
else:
|
||||
output.append(str_cls(part))
|
||||
output.append(str(part))
|
||||
part = 0
|
||||
|
||||
self._dotted = '.'.join(output)
|
||||
@@ -3240,7 +3213,7 @@ class Enumerated(Integer):
|
||||
ValueError - when an invalid value is passed
|
||||
"""
|
||||
|
||||
if not isinstance(value, int_types) and not isinstance(value, str_cls):
|
||||
if not isinstance(value, int) and not isinstance(value, str):
|
||||
raise TypeError(unwrap(
|
||||
'''
|
||||
%s value must be an integer or a unicode string, not %s
|
||||
@@ -3249,7 +3222,7 @@ class Enumerated(Integer):
|
||||
type_name(value)
|
||||
))
|
||||
|
||||
if isinstance(value, str_cls):
|
||||
if isinstance(value, str):
|
||||
if value not in self._reverse_map:
|
||||
raise ValueError(unwrap(
|
||||
'''
|
||||
@@ -3507,7 +3480,7 @@ class Sequence(Asn1Value):
|
||||
if self.children is None:
|
||||
self._parse_children()
|
||||
|
||||
if not isinstance(key, int_types):
|
||||
if not isinstance(key, int):
|
||||
if key not in self._field_map:
|
||||
raise KeyError(unwrap(
|
||||
'''
|
||||
@@ -3554,7 +3527,7 @@ class Sequence(Asn1Value):
|
||||
if self.children is None:
|
||||
self._parse_children()
|
||||
|
||||
if not isinstance(key, int_types):
|
||||
if not isinstance(key, int):
|
||||
if key not in self._field_map:
|
||||
raise KeyError(unwrap(
|
||||
'''
|
||||
@@ -3605,7 +3578,7 @@ class Sequence(Asn1Value):
|
||||
if self.children is None:
|
||||
self._parse_children()
|
||||
|
||||
if not isinstance(key, int_types):
|
||||
if not isinstance(key, int):
|
||||
if key not in self._field_map:
|
||||
raise KeyError(unwrap(
|
||||
'''
|
||||
@@ -4003,7 +3976,7 @@ class Sequence(Asn1Value):
|
||||
encoded using
|
||||
"""
|
||||
|
||||
if not isinstance(field_name, str_cls):
|
||||
if not isinstance(field_name, str):
|
||||
raise TypeError(unwrap(
|
||||
'''
|
||||
field_name must be a unicode string, not %s
|
||||
@@ -4051,7 +4024,7 @@ class Sequence(Asn1Value):
|
||||
try:
|
||||
name = self._fields[index][0]
|
||||
except (IndexError):
|
||||
name = str_cls(index)
|
||||
name = str(index)
|
||||
self._native[name] = child.native
|
||||
except (ValueError, TypeError) as e:
|
||||
self._native = None
|
||||
@@ -4879,7 +4852,7 @@ class AbstractTime(AbstractString):
|
||||
A dict with the parsed values
|
||||
"""
|
||||
|
||||
string = str_cls(self)
|
||||
string = str(self)
|
||||
|
||||
m = self._TIMESTRING_RE.match(string)
|
||||
if not m:
|
||||
@@ -5018,8 +4991,6 @@ class UTCTime(AbstractTime):
|
||||
raise ValueError('Year of the UTCTime is not in range [1950, 2049], use GeneralizedTime instead')
|
||||
|
||||
value = value.strftime('%y%m%d%H%M%SZ')
|
||||
if _PY2:
|
||||
value = value.decode('ascii')
|
||||
|
||||
AbstractString.set(self, value)
|
||||
# Set it to None and let the class take care of converting the next
|
||||
@@ -5117,8 +5088,6 @@ class GeneralizedTime(AbstractTime):
|
||||
fraction = ''
|
||||
|
||||
value = value.strftime('%Y%m%d%H%M%S') + fraction + 'Z'
|
||||
if _PY2:
|
||||
value = value.decode('ascii')
|
||||
|
||||
AbstractString.set(self, value)
|
||||
# Set it to None and let the class take care of converting the next
|
||||
@@ -5340,7 +5309,7 @@ def _build_id_tuple(params, spec):
|
||||
else:
|
||||
required_class = 2
|
||||
required_tag = params['implicit']
|
||||
if required_class is not None and not isinstance(required_class, int_types):
|
||||
if required_class is not None and not isinstance(required_class, int):
|
||||
required_class = CLASS_NAME_TO_NUM_MAP[required_class]
|
||||
|
||||
required_class = params.get('class_', required_class)
|
||||
|
||||
1
jc/parsers/asn1crypto/jc_global.py
Normal file
1
jc/parsers/asn1crypto/jc_global.py
Normal file
@@ -0,0 +1 @@
|
||||
quiet = False
|
||||
@@ -20,7 +20,7 @@ import hashlib
|
||||
import math
|
||||
|
||||
from ._errors import unwrap, APIException
|
||||
from ._types import type_name, byte_cls
|
||||
from ._types import type_name
|
||||
from .algos import _ForceNullParameters, DigestAlgorithm, EncryptionAlgorithm, RSAESOAEPParams, RSASSAPSSParams
|
||||
from .core import (
|
||||
Any,
|
||||
@@ -582,7 +582,7 @@ class ECPrivateKey(Sequence):
|
||||
if self._key_size is None:
|
||||
# Infer the key_size from the existing private key if possible
|
||||
pkey_contents = self['private_key'].contents
|
||||
if isinstance(pkey_contents, byte_cls) and len(pkey_contents) > 1:
|
||||
if isinstance(pkey_contents, bytes) and len(pkey_contents) > 1:
|
||||
self.set_key_size(len(self['private_key'].contents))
|
||||
|
||||
elif self._key_size is not None:
|
||||
@@ -744,7 +744,7 @@ class PrivateKeyInfo(Sequence):
|
||||
A PrivateKeyInfo object
|
||||
"""
|
||||
|
||||
if not isinstance(private_key, byte_cls) and not isinstance(private_key, Asn1Value):
|
||||
if not isinstance(private_key, bytes) and not isinstance(private_key, Asn1Value):
|
||||
raise TypeError(unwrap(
|
||||
'''
|
||||
private_key must be a byte string or Asn1Value, not %s
|
||||
@@ -1112,7 +1112,7 @@ class PublicKeyInfo(Sequence):
|
||||
A PublicKeyInfo object
|
||||
"""
|
||||
|
||||
if not isinstance(public_key, byte_cls) and not isinstance(public_key, Asn1Value):
|
||||
if not isinstance(public_key, bytes) and not isinstance(public_key, Asn1Value):
|
||||
raise TypeError(unwrap(
|
||||
'''
|
||||
public_key must be a byte string or Asn1Value, not %s
|
||||
@@ -1268,7 +1268,7 @@ class PublicKeyInfo(Sequence):
|
||||
"""
|
||||
|
||||
if self._sha1 is None:
|
||||
self._sha1 = hashlib.sha1(byte_cls(self['public_key'])).digest()
|
||||
self._sha1 = hashlib.sha1(bytes(self['public_key'])).digest()
|
||||
return self._sha1
|
||||
|
||||
@property
|
||||
@@ -1279,7 +1279,7 @@ class PublicKeyInfo(Sequence):
|
||||
"""
|
||||
|
||||
if self._sha256 is None:
|
||||
self._sha256 = hashlib.sha256(byte_cls(self['public_key'])).digest()
|
||||
self._sha256 = hashlib.sha256(bytes(self['public_key'])).digest()
|
||||
return self._sha256
|
||||
|
||||
@property
|
||||
|
||||
@@ -15,10 +15,9 @@ from __future__ import unicode_literals, division, absolute_import, print_functi
|
||||
|
||||
import sys
|
||||
|
||||
from ._types import byte_cls, chr_cls, type_name
|
||||
from ._types import chr_cls, type_name
|
||||
from .util import int_from_bytes, int_to_bytes
|
||||
|
||||
_PY2 = sys.version_info <= (3,)
|
||||
_INSUFFICIENT_DATA_MESSAGE = 'Insufficient data - %s bytes requested but only %s available'
|
||||
_MAX_DEPTH = 10
|
||||
|
||||
@@ -66,7 +65,7 @@ def emit(class_, method, tag, contents):
|
||||
if tag < 0:
|
||||
raise ValueError('tag must be greater than zero, not %s' % tag)
|
||||
|
||||
if not isinstance(contents, byte_cls):
|
||||
if not isinstance(contents, bytes):
|
||||
raise TypeError('contents must be a byte string, not %s' % type_name(contents))
|
||||
|
||||
return _dump_header(class_, method, tag, contents) + contents
|
||||
@@ -101,7 +100,7 @@ def parse(contents, strict=False):
|
||||
- 5: byte string trailer
|
||||
"""
|
||||
|
||||
if not isinstance(contents, byte_cls):
|
||||
if not isinstance(contents, bytes):
|
||||
raise TypeError('contents must be a byte string, not %s' % type_name(contents))
|
||||
|
||||
contents_len = len(contents)
|
||||
@@ -130,7 +129,7 @@ def peek(contents):
|
||||
An integer with the number of bytes occupied by the ASN.1 value
|
||||
"""
|
||||
|
||||
if not isinstance(contents, byte_cls):
|
||||
if not isinstance(contents, bytes):
|
||||
raise TypeError('contents must be a byte string, not %s' % type_name(contents))
|
||||
|
||||
info, consumed = _parse(contents, len(contents))
|
||||
@@ -171,7 +170,7 @@ def _parse(encoded_data, data_len, pointer=0, lengths_only=False, depth=0):
|
||||
|
||||
if data_len < pointer + 1:
|
||||
raise ValueError(_INSUFFICIENT_DATA_MESSAGE % (1, data_len - pointer))
|
||||
first_octet = ord(encoded_data[pointer]) if _PY2 else encoded_data[pointer]
|
||||
first_octet = encoded_data[pointer]
|
||||
|
||||
pointer += 1
|
||||
|
||||
@@ -183,7 +182,7 @@ def _parse(encoded_data, data_len, pointer=0, lengths_only=False, depth=0):
|
||||
while True:
|
||||
if data_len < pointer + 1:
|
||||
raise ValueError(_INSUFFICIENT_DATA_MESSAGE % (1, data_len - pointer))
|
||||
num = ord(encoded_data[pointer]) if _PY2 else encoded_data[pointer]
|
||||
num = encoded_data[pointer]
|
||||
pointer += 1
|
||||
if num == 0x80 and tag == 0:
|
||||
raise ValueError('Non-minimal tag encoding')
|
||||
@@ -196,7 +195,7 @@ def _parse(encoded_data, data_len, pointer=0, lengths_only=False, depth=0):
|
||||
|
||||
if data_len < pointer + 1:
|
||||
raise ValueError(_INSUFFICIENT_DATA_MESSAGE % (1, data_len - pointer))
|
||||
length_octet = ord(encoded_data[pointer]) if _PY2 else encoded_data[pointer]
|
||||
length_octet = encoded_data[pointer]
|
||||
pointer += 1
|
||||
trailer = b''
|
||||
|
||||
|
||||
@@ -11,17 +11,13 @@ Encoding DER to PEM and decoding PEM to DER. Exports the following items:
|
||||
|
||||
from __future__ import unicode_literals, division, absolute_import, print_function
|
||||
|
||||
from io import BytesIO
|
||||
import base64
|
||||
import re
|
||||
import sys
|
||||
|
||||
from ._errors import unwrap
|
||||
from ._types import type_name as _type_name, str_cls, byte_cls
|
||||
from ._types import type_name as _type_name
|
||||
|
||||
if sys.version_info < (3,):
|
||||
from cStringIO import StringIO as BytesIO
|
||||
else:
|
||||
from io import BytesIO
|
||||
|
||||
|
||||
def detect(byte_string):
|
||||
@@ -36,7 +32,7 @@ def detect(byte_string):
|
||||
string
|
||||
"""
|
||||
|
||||
if not isinstance(byte_string, byte_cls):
|
||||
if not isinstance(byte_string, bytes):
|
||||
raise TypeError(unwrap(
|
||||
'''
|
||||
byte_string must be a byte string, not %s
|
||||
@@ -67,14 +63,14 @@ def armor(type_name, der_bytes, headers=None):
|
||||
A byte string of the PEM block
|
||||
"""
|
||||
|
||||
if not isinstance(der_bytes, byte_cls):
|
||||
if not isinstance(der_bytes, bytes):
|
||||
raise TypeError(unwrap(
|
||||
'''
|
||||
der_bytes must be a byte string, not %s
|
||||
''' % _type_name(der_bytes)
|
||||
))
|
||||
|
||||
if not isinstance(type_name, str_cls):
|
||||
if not isinstance(type_name, str):
|
||||
raise TypeError(unwrap(
|
||||
'''
|
||||
type_name must be a unicode string, not %s
|
||||
@@ -127,7 +123,7 @@ def _unarmor(pem_bytes):
|
||||
in the form "Name: Value" that are right after the begin line.
|
||||
"""
|
||||
|
||||
if not isinstance(pem_bytes, byte_cls):
|
||||
if not isinstance(pem_bytes, bytes):
|
||||
raise TypeError(unwrap(
|
||||
'''
|
||||
pem_bytes must be a byte string, not %s
|
||||
|
||||
@@ -20,11 +20,11 @@ from __future__ import unicode_literals, division, absolute_import, print_functi
|
||||
|
||||
import math
|
||||
import sys
|
||||
from datetime import datetime, date, timedelta, tzinfo
|
||||
from collections import OrderedDict
|
||||
from datetime import datetime, date, timedelta, timezone, tzinfo
|
||||
|
||||
from ._errors import unwrap
|
||||
from ._iri import iri_to_uri, uri_to_iri # noqa
|
||||
from ._ordereddict import OrderedDict # noqa
|
||||
from ._types import type_name
|
||||
|
||||
if sys.platform == 'win32':
|
||||
@@ -33,230 +33,53 @@ else:
|
||||
from socket import inet_ntop, inet_pton # noqa
|
||||
|
||||
|
||||
# Python 2
|
||||
if sys.version_info <= (3,):
|
||||
|
||||
def int_to_bytes(value, signed=False, width=None):
|
||||
"""
|
||||
Converts an integer to a byte string
|
||||
def int_to_bytes(value, signed=False, width=None):
|
||||
"""
|
||||
Converts an integer to a byte string
|
||||
|
||||
:param value:
|
||||
The integer to convert
|
||||
:param value:
|
||||
The integer to convert
|
||||
|
||||
:param signed:
|
||||
If the byte string should be encoded using two's complement
|
||||
:param signed:
|
||||
If the byte string should be encoded using two's complement
|
||||
|
||||
:param width:
|
||||
If None, the minimal possible size (but at least 1),
|
||||
otherwise an integer of the byte width for the return value
|
||||
:param width:
|
||||
If None, the minimal possible size (but at least 1),
|
||||
otherwise an integer of the byte width for the return value
|
||||
|
||||
:return:
|
||||
A byte string
|
||||
"""
|
||||
:return:
|
||||
A byte string
|
||||
"""
|
||||
|
||||
if value == 0 and width == 0:
|
||||
return b''
|
||||
|
||||
# Handle negatives in two's complement
|
||||
is_neg = False
|
||||
if signed and value < 0:
|
||||
is_neg = True
|
||||
bits = int(math.ceil(len('%x' % abs(value)) / 2.0) * 8)
|
||||
value = (value + (1 << bits)) % (1 << bits)
|
||||
|
||||
hex_str = '%x' % value
|
||||
if len(hex_str) & 1:
|
||||
hex_str = '0' + hex_str
|
||||
|
||||
output = hex_str.decode('hex')
|
||||
|
||||
if signed and not is_neg and ord(output[0:1]) & 0x80:
|
||||
output = b'\x00' + output
|
||||
|
||||
if width is not None:
|
||||
if len(output) > width:
|
||||
raise OverflowError('int too big to convert')
|
||||
if is_neg:
|
||||
pad_char = b'\xFF'
|
||||
else:
|
||||
pad_char = b'\x00'
|
||||
output = (pad_char * (width - len(output))) + output
|
||||
elif is_neg and ord(output[0:1]) & 0x80 == 0:
|
||||
output = b'\xFF' + output
|
||||
|
||||
return output
|
||||
|
||||
def int_from_bytes(value, signed=False):
|
||||
"""
|
||||
Converts a byte string to an integer
|
||||
|
||||
:param value:
|
||||
The byte string to convert
|
||||
|
||||
:param signed:
|
||||
If the byte string should be interpreted using two's complement
|
||||
|
||||
:return:
|
||||
An integer
|
||||
"""
|
||||
|
||||
if value == b'':
|
||||
return 0
|
||||
|
||||
num = long(value.encode("hex"), 16) # noqa
|
||||
|
||||
if not signed:
|
||||
return num
|
||||
|
||||
# Check for sign bit and handle two's complement
|
||||
if ord(value[0:1]) & 0x80:
|
||||
bit_len = len(value) * 8
|
||||
return num - (1 << bit_len)
|
||||
|
||||
return num
|
||||
|
||||
class timezone(tzinfo): # noqa
|
||||
"""
|
||||
Implements datetime.timezone for py2.
|
||||
Only full minute offsets are supported.
|
||||
DST is not supported.
|
||||
"""
|
||||
|
||||
def __init__(self, offset, name=None):
|
||||
"""
|
||||
:param offset:
|
||||
A timedelta with this timezone's offset from UTC
|
||||
|
||||
:param name:
|
||||
Name of the timezone; if None, generate one.
|
||||
"""
|
||||
|
||||
if not timedelta(hours=-24) < offset < timedelta(hours=24):
|
||||
raise ValueError('Offset must be in [-23:59, 23:59]')
|
||||
|
||||
if offset.seconds % 60 or offset.microseconds:
|
||||
raise ValueError('Offset must be full minutes')
|
||||
|
||||
self._offset = offset
|
||||
|
||||
if name is not None:
|
||||
self._name = name
|
||||
elif not offset:
|
||||
self._name = 'UTC'
|
||||
else:
|
||||
self._name = 'UTC' + _format_offset(offset)
|
||||
|
||||
def __eq__(self, other):
|
||||
"""
|
||||
Compare two timezones
|
||||
|
||||
:param other:
|
||||
The other timezone to compare to
|
||||
|
||||
:return:
|
||||
A boolean
|
||||
"""
|
||||
|
||||
if type(other) != timezone:
|
||||
return False
|
||||
return self._offset == other._offset
|
||||
|
||||
def __getinitargs__(self):
|
||||
"""
|
||||
Called by tzinfo.__reduce__ to support pickle and copy.
|
||||
|
||||
:return:
|
||||
offset and name, to be used for __init__
|
||||
"""
|
||||
|
||||
return self._offset, self._name
|
||||
|
||||
def tzname(self, dt):
|
||||
"""
|
||||
:param dt:
|
||||
A datetime object; ignored.
|
||||
|
||||
:return:
|
||||
Name of this timezone
|
||||
"""
|
||||
|
||||
return self._name
|
||||
|
||||
def utcoffset(self, dt):
|
||||
"""
|
||||
:param dt:
|
||||
A datetime object; ignored.
|
||||
|
||||
:return:
|
||||
A timedelta object with the offset from UTC
|
||||
"""
|
||||
|
||||
return self._offset
|
||||
|
||||
def dst(self, dt):
|
||||
"""
|
||||
:param dt:
|
||||
A datetime object; ignored.
|
||||
|
||||
:return:
|
||||
Zero timedelta
|
||||
"""
|
||||
|
||||
return timedelta(0)
|
||||
|
||||
timezone.utc = timezone(timedelta(0))
|
||||
|
||||
# Python 3
|
||||
else:
|
||||
|
||||
from datetime import timezone # noqa
|
||||
|
||||
def int_to_bytes(value, signed=False, width=None):
|
||||
"""
|
||||
Converts an integer to a byte string
|
||||
|
||||
:param value:
|
||||
The integer to convert
|
||||
|
||||
:param signed:
|
||||
If the byte string should be encoded using two's complement
|
||||
|
||||
:param width:
|
||||
If None, the minimal possible size (but at least 1),
|
||||
otherwise an integer of the byte width for the return value
|
||||
|
||||
:return:
|
||||
A byte string
|
||||
"""
|
||||
|
||||
if width is None:
|
||||
if signed:
|
||||
if value < 0:
|
||||
bits_required = abs(value + 1).bit_length()
|
||||
else:
|
||||
bits_required = value.bit_length()
|
||||
if bits_required % 8 == 0:
|
||||
bits_required += 1
|
||||
if width is None:
|
||||
if signed:
|
||||
if value < 0:
|
||||
bits_required = abs(value + 1).bit_length()
|
||||
else:
|
||||
bits_required = value.bit_length()
|
||||
width = math.ceil(bits_required / 8) or 1
|
||||
return value.to_bytes(width, byteorder='big', signed=signed)
|
||||
if bits_required % 8 == 0:
|
||||
bits_required += 1
|
||||
else:
|
||||
bits_required = value.bit_length()
|
||||
width = math.ceil(bits_required / 8) or 1
|
||||
return value.to_bytes(width, byteorder='big', signed=signed)
|
||||
|
||||
def int_from_bytes(value, signed=False):
|
||||
"""
|
||||
Converts a byte string to an integer
|
||||
def int_from_bytes(value, signed=False):
|
||||
"""
|
||||
Converts a byte string to an integer
|
||||
|
||||
:param value:
|
||||
The byte string to convert
|
||||
:param value:
|
||||
The byte string to convert
|
||||
|
||||
:param signed:
|
||||
If the byte string should be interpreted using two's complement
|
||||
:param signed:
|
||||
If the byte string should be interpreted using two's complement
|
||||
|
||||
:return:
|
||||
An integer
|
||||
"""
|
||||
:return:
|
||||
An integer
|
||||
"""
|
||||
|
||||
return int.from_bytes(value, 'big', signed=signed)
|
||||
return int.from_bytes(value, 'big', signed=signed)
|
||||
|
||||
|
||||
def _format_offset(off):
|
||||
|
||||
@@ -15,6 +15,7 @@ Other type classes are defined that help compose the types listed above.
|
||||
|
||||
from __future__ import unicode_literals, division, absolute_import, print_function
|
||||
|
||||
from collections import OrderedDict
|
||||
from contextlib import contextmanager
|
||||
from encodings import idna # noqa
|
||||
import hashlib
|
||||
@@ -26,8 +27,7 @@ import unicodedata
|
||||
|
||||
from ._errors import unwrap
|
||||
from ._iri import iri_to_uri, uri_to_iri
|
||||
from ._ordereddict import OrderedDict
|
||||
from ._types import type_name, str_cls, bytes_to_list
|
||||
from ._types import type_name
|
||||
from .algos import AlgorithmIdentifier, AnyAlgorithmIdentifier, DigestAlgorithm, SignedDigestAlgorithm
|
||||
from .core import (
|
||||
Any,
|
||||
@@ -100,7 +100,7 @@ class DNSName(IA5String):
|
||||
A unicode string
|
||||
"""
|
||||
|
||||
if not isinstance(value, str_cls):
|
||||
if not isinstance(value, str):
|
||||
raise TypeError(unwrap(
|
||||
'''
|
||||
%s value must be a unicode string, not %s
|
||||
@@ -131,7 +131,7 @@ class URI(IA5String):
|
||||
A unicode string
|
||||
"""
|
||||
|
||||
if not isinstance(value, str_cls):
|
||||
if not isinstance(value, str):
|
||||
raise TypeError(unwrap(
|
||||
'''
|
||||
%s value must be a unicode string, not %s
|
||||
@@ -215,7 +215,7 @@ class EmailAddress(IA5String):
|
||||
A unicode string
|
||||
"""
|
||||
|
||||
if not isinstance(value, str_cls):
|
||||
if not isinstance(value, str):
|
||||
raise TypeError(unwrap(
|
||||
'''
|
||||
%s value must be a unicode string, not %s
|
||||
@@ -251,7 +251,18 @@ class EmailAddress(IA5String):
|
||||
self._unicode = contents.decode('cp1252')
|
||||
else:
|
||||
mailbox, hostname = contents.rsplit(b'@', 1)
|
||||
self._unicode = mailbox.decode('cp1252') + '@' + hostname.decode('idna')
|
||||
|
||||
# fix to allow incorrectly encoded email addresses to succeed with warning
|
||||
try:
|
||||
self._unicode = mailbox.decode('cp1252') + '@' + hostname.decode('idna')
|
||||
except UnicodeDecodeError:
|
||||
ascii_mailbox = mailbox.decode('ascii', errors='backslashreplace')
|
||||
ascii_hostname = hostname.decode('ascii', errors='backslashreplace')
|
||||
from jc.utils import warning_message
|
||||
import jc.parsers.asn1crypto.jc_global as jc_global
|
||||
if not jc_global.quiet:
|
||||
warning_message([f'Invalid email address found: {ascii_mailbox}@{ascii_hostname}'])
|
||||
self._unicode = ascii_mailbox + '@' + ascii_hostname
|
||||
return self._unicode
|
||||
|
||||
def __ne__(self, other):
|
||||
@@ -312,7 +323,7 @@ class IPAddress(OctetString):
|
||||
an IPv6 address or IPv6 address with CIDR
|
||||
"""
|
||||
|
||||
if not isinstance(value, str_cls):
|
||||
if not isinstance(value, str):
|
||||
raise TypeError(unwrap(
|
||||
'''
|
||||
%s value must be a unicode string, not %s
|
||||
@@ -402,7 +413,7 @@ class IPAddress(OctetString):
|
||||
if cidr_int is not None:
|
||||
cidr_bits = '{0:b}'.format(cidr_int)
|
||||
cidr = len(cidr_bits.rstrip('0'))
|
||||
value = value + '/' + str_cls(cidr)
|
||||
value = value + '/' + str(cidr)
|
||||
self._native = value
|
||||
return self._native
|
||||
|
||||
@@ -2587,7 +2598,7 @@ class Certificate(Sequence):
|
||||
"""
|
||||
|
||||
if self._issuer_serial is None:
|
||||
self._issuer_serial = self.issuer.sha256 + b':' + str_cls(self.serial_number).encode('ascii')
|
||||
self._issuer_serial = self.issuer.sha256 + b':' + str(self.serial_number).encode('ascii')
|
||||
return self._issuer_serial
|
||||
|
||||
@property
|
||||
@@ -2636,7 +2647,7 @@ class Certificate(Sequence):
|
||||
# We untag the element since it is tagged via being a choice from GeneralName
|
||||
issuer = issuer.untag()
|
||||
authority_serial = self.authority_key_identifier_value['authority_cert_serial_number'].native
|
||||
self._authority_issuer_serial = issuer.sha256 + b':' + str_cls(authority_serial).encode('ascii')
|
||||
self._authority_issuer_serial = issuer.sha256 + b':' + str(authority_serial).encode('ascii')
|
||||
else:
|
||||
self._authority_issuer_serial = None
|
||||
return self._authority_issuer_serial
|
||||
@@ -2849,7 +2860,7 @@ class Certificate(Sequence):
|
||||
with a space between each pair of characters, all uppercase
|
||||
"""
|
||||
|
||||
return ' '.join('%02X' % c for c in bytes_to_list(self.sha1))
|
||||
return ' '.join('%02X' % c for c in list(self.sha1))
|
||||
|
||||
@property
|
||||
def sha256(self):
|
||||
@@ -2871,7 +2882,7 @@ class Certificate(Sequence):
|
||||
with a space between each pair of characters, all uppercase
|
||||
"""
|
||||
|
||||
return ' '.join('%02X' % c for c in bytes_to_list(self.sha256))
|
||||
return ' '.join('%02X' % c for c in list(self.sha256))
|
||||
|
||||
def is_valid_domain_ip(self, domain_ip):
|
||||
"""
|
||||
@@ -2885,7 +2896,7 @@ class Certificate(Sequence):
|
||||
A boolean - if the domain or IP is valid for the certificate
|
||||
"""
|
||||
|
||||
if not isinstance(domain_ip, str_cls):
|
||||
if not isinstance(domain_ip, str):
|
||||
raise TypeError(unwrap(
|
||||
'''
|
||||
domain_ip must be a unicode string, not %s
|
||||
|
||||
421
jc/parsers/bluetoothctl.py
Normal file
421
jc/parsers/bluetoothctl.py
Normal file
@@ -0,0 +1,421 @@
|
||||
"""jc - JSON Convert `bluetoothctl` command output parser
|
||||
|
||||
Supports the following `bluetoothctl` subcommands:
|
||||
- `bluetoothctl list`
|
||||
- `bluetoothctl show`
|
||||
- `bluetoothctl show <ctrl>`
|
||||
- `bluetoothctl devices`
|
||||
- `bluetoothctl info <dev>`
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ bluetoothctl info <dev> | jc --bluetoothctl
|
||||
or
|
||||
|
||||
$ jc bluetoothctl info <dev>
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc
|
||||
result = jc.parse('bluetoothctl', bluetoothctl_command_output)
|
||||
|
||||
Schema:
|
||||
|
||||
Because bluetoothctl is handling two main entities, controllers and devices,
|
||||
the schema is shared between them. Most of the fields are common between
|
||||
a controller and a device but there might be fields corresponding to one entity.
|
||||
|
||||
Controller:
|
||||
[
|
||||
{
|
||||
"name": string,
|
||||
"is_default": boolean,
|
||||
"is_public": boolean,
|
||||
"is_random": boolean,
|
||||
"address": string,
|
||||
"alias": string,
|
||||
"class": string,
|
||||
"powered": string,
|
||||
"discoverable": string,
|
||||
"discoverable_timeout": string,
|
||||
"pairable": string,
|
||||
"modalias": string,
|
||||
"discovering": string,
|
||||
"uuids": array
|
||||
}
|
||||
]
|
||||
|
||||
Device:
|
||||
[
|
||||
{
|
||||
"name": string,
|
||||
"is_public": boolean,
|
||||
"is_random": boolean,
|
||||
"address": string,
|
||||
"alias": string,
|
||||
"appearance": string,
|
||||
"class": string,
|
||||
"icon": string,
|
||||
"paired": string,
|
||||
"bonded": string,
|
||||
"trusted": string,
|
||||
"blocked": string,
|
||||
"connected": string,
|
||||
"legacy_pairing": string,
|
||||
"rssi": int,
|
||||
"txpower": int,
|
||||
"uuids": array,
|
||||
"modalias": string
|
||||
}
|
||||
]
|
||||
|
||||
Examples:
|
||||
|
||||
$ bluetoothctl info EB:06:EF:62:B3:19 | jc --bluetoothctl -p
|
||||
[
|
||||
{
|
||||
"address": "22:06:33:62:B3:19",
|
||||
"is_public": true,
|
||||
"name": "TaoTronics TT-BH336",
|
||||
"alias": "TaoTronics TT-BH336",
|
||||
"class": "0x00240455",
|
||||
"icon": "audio-headset",
|
||||
"paired": "no",
|
||||
"bonded": "no",
|
||||
"trusted": "no",
|
||||
"blocked": "no",
|
||||
"connected": "no",
|
||||
"legacy_pairing": "no",
|
||||
"uuids": [
|
||||
"Advanced Audio Distribu.. (0000120d-0000-1000-8000-00805f9b34fb)",
|
||||
"Audio Sink (0000130b-0000-1000-8000-00805f9b34fb)",
|
||||
"A/V Remote Control (0000140e-0000-1000-8000-00805f9b34fb)",
|
||||
"A/V Remote Control Cont.. (0000150f-0000-1000-8000-00805f9b34fb)",
|
||||
"Handsfree (0000161e-0000-1000-8000-00805f9b34fb)",
|
||||
"Headset (00001708-0000-1000-8000-00805f9b34fb)",
|
||||
"Headset HS (00001831-0000-1000-8000-00805f9b34fb)"
|
||||
],
|
||||
"rssi": -52,
|
||||
"txpower": 4
|
||||
}
|
||||
]
|
||||
"""
|
||||
import re
|
||||
from typing import List, Dict, Optional, Any
|
||||
from jc.jc_types import JSONDictType
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
"""Provides parser metadata (version, author, etc.)"""
|
||||
version = '1.1'
|
||||
description = '`bluetoothctl` command parser'
|
||||
author = 'Jake Ob'
|
||||
author_email = 'iakopap at gmail.com'
|
||||
compatible = ['linux']
|
||||
magic_commands = ['bluetoothctl']
|
||||
tags = ['command']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
try:
|
||||
from typing import TypedDict
|
||||
|
||||
Controller = TypedDict(
|
||||
"Controller",
|
||||
{
|
||||
"name": str,
|
||||
"is_default": bool,
|
||||
"is_public": bool,
|
||||
"is_random": bool,
|
||||
"address": str,
|
||||
"alias": str,
|
||||
"class": str,
|
||||
"powered": str,
|
||||
"discoverable": str,
|
||||
"discoverable_timeout": str,
|
||||
"pairable": str,
|
||||
"modalias": str,
|
||||
"discovering": str,
|
||||
"uuids": List[str],
|
||||
},
|
||||
)
|
||||
Device = TypedDict(
|
||||
"Device",
|
||||
{
|
||||
"name": str,
|
||||
"is_public": bool,
|
||||
"is_random": bool,
|
||||
"address": str,
|
||||
"alias": str,
|
||||
"appearance": str,
|
||||
"class": str,
|
||||
"icon": str,
|
||||
"paired": str,
|
||||
"bonded": str,
|
||||
"trusted": str,
|
||||
"blocked": str,
|
||||
"connected": str,
|
||||
"legacy_pairing": str,
|
||||
"rssi": int,
|
||||
"txpower": int,
|
||||
"uuids": List[str],
|
||||
"modalias": str
|
||||
},
|
||||
)
|
||||
except ImportError:
|
||||
Controller = Dict[str, Any] # type: ignore
|
||||
Device = Dict[str, Any] # type: ignore
|
||||
|
||||
|
||||
_controller_head_pattern = r"Controller (?P<address>([0-9A-F]{2}:){5}[0-9A-F]{2}) (?P<name>.+)"
|
||||
|
||||
_controller_line_pattern = (
|
||||
r"(\s*Name:\s*(?P<name>.+)"
|
||||
+ r"|\s*Alias:\s*(?P<alias>.+)"
|
||||
+ r"|\s*Class:\s*(?P<class>.+)"
|
||||
+ r"|\s*Powered:\s*(?P<powered>.+)"
|
||||
+ r"|\s*Discoverable:\s*(?P<discoverable>.+)"
|
||||
+ r"|\s*DiscoverableTimeout:\s*(?P<discoverable_timeout>.+)"
|
||||
+ r"|\s*Pairable:\s*(?P<pairable>.+)"
|
||||
+ r"|\s*Modalias:\s*(?P<modalias>.+)"
|
||||
+ r"|\s*Discovering:\s*(?P<discovering>.+)"
|
||||
+ r"|\s*UUID:\s*(?P<uuid>.+))"
|
||||
)
|
||||
|
||||
def _parse_controller(next_lines: List[str]) -> Optional[Controller]:
|
||||
next_line = next_lines.pop()
|
||||
result = re.match(_controller_head_pattern, next_line)
|
||||
|
||||
if not result:
|
||||
next_lines.append(next_line)
|
||||
return None
|
||||
|
||||
matches = result.groupdict()
|
||||
|
||||
name = matches["name"]
|
||||
|
||||
if name.endswith("not available"):
|
||||
return None
|
||||
|
||||
controller: Controller = {
|
||||
"name": '',
|
||||
"is_default": False,
|
||||
"is_public": False,
|
||||
"is_random": False,
|
||||
"address": matches["address"],
|
||||
"alias": '',
|
||||
"class": '',
|
||||
"powered": '',
|
||||
"discoverable": '',
|
||||
"discoverable_timeout": '',
|
||||
"pairable": '',
|
||||
"modalias": '',
|
||||
"discovering": '',
|
||||
"uuids": [],
|
||||
}
|
||||
|
||||
if name.endswith("[default]"):
|
||||
controller["is_default"] = True
|
||||
name = name.replace("[default]", "")
|
||||
elif name.endswith("(public)"):
|
||||
controller["is_public"] = True
|
||||
name = name.replace("(public)", "")
|
||||
elif name.endswith("(random)"):
|
||||
controller["is_random"] = True
|
||||
name = name.replace("(random)", "")
|
||||
|
||||
controller["name"] = name.strip()
|
||||
|
||||
while next_lines:
|
||||
next_line = next_lines.pop()
|
||||
result = re.match(_controller_line_pattern, next_line)
|
||||
|
||||
if not result:
|
||||
next_lines.append(next_line)
|
||||
return controller
|
||||
|
||||
matches = result.groupdict()
|
||||
|
||||
if matches["name"]:
|
||||
controller["name"] = matches["name"]
|
||||
elif matches["alias"]:
|
||||
controller["alias"] = matches["alias"]
|
||||
elif matches["class"]:
|
||||
controller["class"] = matches["class"]
|
||||
elif matches["powered"]:
|
||||
controller["powered"] = matches["powered"]
|
||||
elif matches["discoverable"]:
|
||||
controller["discoverable"] = matches["discoverable"]
|
||||
elif matches["discoverable_timeout"]:
|
||||
controller["discoverable_timeout"] = matches["discoverable_timeout"]
|
||||
elif matches["pairable"]:
|
||||
controller["pairable"] = matches["pairable"]
|
||||
elif matches["modalias"]:
|
||||
controller["modalias"] = matches["modalias"]
|
||||
elif matches["discovering"]:
|
||||
controller["discovering"] = matches["discovering"]
|
||||
elif matches["uuid"]:
|
||||
if not "uuids" in controller:
|
||||
controller["uuids"] = []
|
||||
controller["uuids"].append(matches["uuid"])
|
||||
|
||||
return controller
|
||||
|
||||
_device_head_pattern = r"Device (?P<address>([0-9A-F]{2}:){5}[0-9A-F]{2}) (?P<name>.+)"
|
||||
|
||||
_device_line_pattern = (
|
||||
r"(\s*Name:\s*(?P<name>.+)"
|
||||
+ r"|\s*Alias:\s*(?P<alias>.+)"
|
||||
+ r"|\s*Appearance:\s*(?P<appearance>.+)"
|
||||
+ r"|\s*Class:\s*(?P<class>.+)"
|
||||
+ r"|\s*Icon:\s*(?P<icon>.+)"
|
||||
+ r"|\s*Paired:\s*(?P<paired>.+)"
|
||||
+ r"|\s*Bonded:\s*(?P<bonded>.+)"
|
||||
+ r"|\s*Trusted:\s*(?P<trusted>.+)"
|
||||
+ r"|\s*Blocked:\s*(?P<blocked>.+)"
|
||||
+ r"|\s*Connected:\s*(?P<connected>.+)"
|
||||
+ r"|\s*LegacyPairing:\s*(?P<legacy_pairing>.+)"
|
||||
+ r"|\s*Modalias:\s*(?P<modalias>.+)"
|
||||
+ r"|\s*RSSI:\s*(?P<rssi>.+)"
|
||||
+ r"|\s*TxPower:\s*(?P<txpower>.+)"
|
||||
+ r"|\s*UUID:\s*(?P<uuid>.+))"
|
||||
)
|
||||
|
||||
|
||||
def _parse_device(next_lines: List[str], quiet: bool) -> Optional[Device]:
|
||||
next_line = next_lines.pop()
|
||||
result = re.match(_device_head_pattern, next_line)
|
||||
|
||||
if not result:
|
||||
next_lines.append(next_line)
|
||||
return None
|
||||
|
||||
matches = result.groupdict()
|
||||
|
||||
name = matches["name"]
|
||||
|
||||
if name.endswith("not available"):
|
||||
return None
|
||||
|
||||
device: Device = {
|
||||
"name": '',
|
||||
"is_public": False,
|
||||
"is_random": False,
|
||||
"address": matches["address"],
|
||||
"alias": '',
|
||||
"appearance": '',
|
||||
"class": '',
|
||||
"icon": '',
|
||||
"paired": '',
|
||||
"bonded": '',
|
||||
"trusted": '',
|
||||
"blocked": '',
|
||||
"connected": '',
|
||||
"legacy_pairing": '',
|
||||
"rssi": 0,
|
||||
"txpower": 0,
|
||||
"uuids": [],
|
||||
"modalias": ''
|
||||
}
|
||||
|
||||
if name.endswith("(public)"):
|
||||
device["is_public"] = True
|
||||
name = name.replace("(public)", "")
|
||||
elif name.endswith("(random)"):
|
||||
device["is_random"] = True
|
||||
name = name.replace("(random)", "")
|
||||
|
||||
device["name"] = name.strip()
|
||||
|
||||
while next_lines:
|
||||
next_line = next_lines.pop()
|
||||
result = re.match(_device_line_pattern, next_line)
|
||||
|
||||
if not result:
|
||||
next_lines.append(next_line)
|
||||
return device
|
||||
|
||||
matches = result.groupdict()
|
||||
|
||||
if matches["name"]:
|
||||
device["name"] = matches["name"]
|
||||
elif matches["alias"]:
|
||||
device["alias"] = matches["alias"]
|
||||
elif matches["appearance"]:
|
||||
device["appearance"] = matches["appearance"]
|
||||
elif matches["class"]:
|
||||
device["class"] = matches["class"]
|
||||
elif matches["icon"]:
|
||||
device["icon"] = matches["icon"]
|
||||
elif matches["paired"]:
|
||||
device["paired"] = matches["paired"]
|
||||
elif matches["bonded"]:
|
||||
device["bonded"] = matches["bonded"]
|
||||
elif matches["trusted"]:
|
||||
device["trusted"] = matches["trusted"]
|
||||
elif matches["blocked"]:
|
||||
device["blocked"] = matches["blocked"]
|
||||
elif matches["connected"]:
|
||||
device["connected"] = matches["connected"]
|
||||
elif matches["legacy_pairing"]:
|
||||
device["legacy_pairing"] = matches["legacy_pairing"]
|
||||
elif matches["rssi"]:
|
||||
rssi = matches["rssi"]
|
||||
try:
|
||||
device["rssi"] = int(rssi)
|
||||
except ValueError:
|
||||
if not quiet:
|
||||
jc.utils.warning_message([f"{next_line} : rssi - {rssi} is not int-able"])
|
||||
elif matches["txpower"]:
|
||||
txpower = matches["txpower"]
|
||||
try:
|
||||
device["txpower"] = int(txpower)
|
||||
except ValueError:
|
||||
if not quiet:
|
||||
jc.utils.warning_message([f"{next_line} : txpower - {txpower} is not int-able"])
|
||||
elif matches["uuid"]:
|
||||
if not "uuids" in device:
|
||||
device["uuids"] = []
|
||||
device["uuids"].append(matches["uuid"])
|
||||
elif matches["modalias"]:
|
||||
device["modalias"] = matches["modalias"]
|
||||
|
||||
return device
|
||||
|
||||
def parse(data: str, raw: bool = False, quiet: bool = False) -> List[JSONDictType]:
|
||||
"""
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) unprocessed output if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of Dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
jc.utils.compatibility(__name__, info.compatible, quiet)
|
||||
jc.utils.input_type_check(data)
|
||||
result: List = []
|
||||
|
||||
if jc.utils.has_data(data):
|
||||
linedata = data.splitlines()
|
||||
linedata.reverse()
|
||||
|
||||
while linedata:
|
||||
element = None
|
||||
if data.startswith("Controller"):
|
||||
element = _parse_controller(linedata)
|
||||
elif data.startswith("Device"):
|
||||
element = _parse_device(linedata, quiet) # type: ignore
|
||||
|
||||
if element:
|
||||
result.append(element)
|
||||
else:
|
||||
break
|
||||
|
||||
return result
|
||||
263
jc/parsers/certbot.py
Normal file
263
jc/parsers/certbot.py
Normal file
@@ -0,0 +1,263 @@
|
||||
"""jc - JSON Convert `certbot` command output parser
|
||||
|
||||
Supports the following `certbot` commands:
|
||||
|
||||
- `certbot show_account`
|
||||
- `certbot certificates`
|
||||
|
||||
Verbose options are not supported.
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ certbot show_account | jc --certbot
|
||||
$ certbot certificates | jc --certbot
|
||||
|
||||
or
|
||||
|
||||
$ jc certbot show_account
|
||||
$ jc certbot certificates
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc
|
||||
result = jc.parse('certbot', certbot_command_output)
|
||||
|
||||
Schema:
|
||||
|
||||
{
|
||||
"certificates": [
|
||||
{
|
||||
"name": string,
|
||||
"serial_number": string,
|
||||
"key_type": string,
|
||||
"domains": [
|
||||
string
|
||||
],
|
||||
"expiration_date": string,
|
||||
"expiration_date_epoch": integer,
|
||||
"expiration_date_epoch_utc": integer,
|
||||
"expiration_date_iso": string,
|
||||
"validity": string,
|
||||
"certificate_path": string,
|
||||
"private_key_path": string
|
||||
}
|
||||
],
|
||||
"account": {
|
||||
"server": string,
|
||||
"url": string,
|
||||
"email": string
|
||||
}
|
||||
}
|
||||
|
||||
Examples:
|
||||
|
||||
$ certbot certificates | jc --certbot -p
|
||||
{
|
||||
"certificates": [
|
||||
{
|
||||
"name": "example.com",
|
||||
"serial_number": "3f7axxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||
"key_type": "RSA",
|
||||
"domains": [
|
||||
"example.com",
|
||||
"www.example.com"
|
||||
],
|
||||
"expiration_date": "2023-05-11 01:33:10+00:00",
|
||||
"validity": "63 days",
|
||||
"certificate_path": "/etc/letsencrypt/live/example.com/chain.pem",
|
||||
"private_key_path": "/etc/letsencrypt/live/example.com/priv.pem",
|
||||
"expiration_date_epoch": 1683793990,
|
||||
"expiration_date_epoch_utc": 1683768790,
|
||||
"expiration_date_iso": "2023-05-11T01:33:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "example.org",
|
||||
"serial_number": "3bcyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy",
|
||||
"key_type": "RSA",
|
||||
"domains": [
|
||||
"example.org",
|
||||
"www.example.org"
|
||||
],
|
||||
"expiration_date": "2023-06-12 01:35:30+00:00",
|
||||
"validity": "63 days",
|
||||
"certificate_path": "/etc/letsencrypt/live/example.org/chain.pem",
|
||||
"private_key_path": "/etc/letsencrypt/live/example.org/key.pem",
|
||||
"expiration_date_epoch": 1686558930,
|
||||
"expiration_date_epoch_utc": 1686533730,
|
||||
"expiration_date_iso": "2023-06-12T01:35:30+00:00"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
$ certbot certificates | jc --certbot -p -r
|
||||
{
|
||||
"certificates": [
|
||||
{
|
||||
"name": "example.com",
|
||||
"serial_number": "3f7axxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||
"key_type": "RSA",
|
||||
"domains": [
|
||||
"example.com",
|
||||
"www.example.com"
|
||||
],
|
||||
"expiration_date": "2023-05-11 01:33:10+00:00",
|
||||
"validity": "63 days",
|
||||
"certificate_path": "/etc/letsencrypt/live/example.com/chain.pem",
|
||||
"private_key_path": "/etc/letsencrypt/live/example.com/priv.pem"
|
||||
},
|
||||
{
|
||||
"name": "example.org",
|
||||
"serial_number": "3bcyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy",
|
||||
"key_type": "RSA",
|
||||
"domains": [
|
||||
"example.org",
|
||||
"www.example.org"
|
||||
],
|
||||
"expiration_date": "2023-06-12 01:35:30+00:00",
|
||||
"validity": "63 days",
|
||||
"certificate_path": "/etc/letsencrypt/live/example.org/chain.pem",
|
||||
"private_key_path": "/etc/letsencrypt/live/example.org/key.pem"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
$ certbot show_account | jc --certbot -p
|
||||
{
|
||||
"account": {
|
||||
"server": "https://acme-staging-v02.api.letsencrypt.org/directory",
|
||||
"url": "https://acme-staging-v02.api.letsencrypt.org/acme/acct/123",
|
||||
"email": "some@example.com"
|
||||
}
|
||||
}
|
||||
"""
|
||||
import re
|
||||
from typing import List, Dict
|
||||
from jc.jc_types import JSONDictType
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
"""Provides parser metadata (version, author, etc.)"""
|
||||
version = '1.2'
|
||||
description = '`certbot` command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd']
|
||||
tags = ['command']
|
||||
magic_commands = ['certbot']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def _process(proc_data: JSONDictType) -> JSONDictType:
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (List of Dictionaries) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary. Structured to conform to the schema.
|
||||
"""
|
||||
if 'certificates' in proc_data:
|
||||
for cert in proc_data['certificates']:
|
||||
if 'expiration_date' in cert:
|
||||
dt = jc.utils.timestamp(cert['expiration_date'], format_hint=(1760,))
|
||||
cert['expiration_date_epoch'] = dt.naive
|
||||
cert['expiration_date_epoch_utc'] = dt.utc
|
||||
cert['expiration_date_iso'] = dt.iso
|
||||
return proc_data
|
||||
|
||||
|
||||
def parse(
|
||||
data: str,
|
||||
raw: bool = False,
|
||||
quiet: bool = False
|
||||
) -> JSONDictType:
|
||||
"""
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) unprocessed output if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary. Raw or processed structured data.
|
||||
"""
|
||||
jc.utils.compatibility(__name__, info.compatible, quiet)
|
||||
jc.utils.input_type_check(data)
|
||||
|
||||
raw_output: Dict = {}
|
||||
cert_list: List = []
|
||||
cert_dict: Dict = {}
|
||||
acct_dict: Dict = {}
|
||||
cmd_option = ''
|
||||
|
||||
if jc.utils.has_data(data):
|
||||
|
||||
cert_pattern = re.compile(r'^Found the following certs:\r?$', re.MULTILINE)
|
||||
|
||||
if re.search(cert_pattern, data):
|
||||
cmd_option = 'certificates'
|
||||
else:
|
||||
cmd_option = 'account'
|
||||
|
||||
for line in filter(None, data.splitlines()):
|
||||
|
||||
if cmd_option == 'certificates':
|
||||
if line.startswith(' Certificate Name:'):
|
||||
if cert_dict:
|
||||
cert_list.append(cert_dict)
|
||||
cert_dict = {}
|
||||
|
||||
cert_dict['name'] = line.split()[-1]
|
||||
|
||||
if line.startswith(' Serial Number:'):
|
||||
cert_dict['serial_number'] = line.split()[-1]
|
||||
|
||||
if line.startswith(' Key Type:'):
|
||||
cert_dict['key_type'] = line.split(': ', maxsplit=1)[1]
|
||||
|
||||
if line.startswith(' Domains:'):
|
||||
splitline = line.split(': ', maxsplit=1)[1]
|
||||
cert_dict['domains'] = splitline.split()
|
||||
|
||||
if line.startswith(' Expiry Date:'):
|
||||
splitline = line.split(': ', maxsplit=1)[1]
|
||||
cert_datetime = splitline.split('(')[0]
|
||||
validity = splitline.split('(')[1]
|
||||
cert_dict['expiration_date'] = cert_datetime.strip()
|
||||
cert_dict['validity'] = validity[:-1].replace('VALID: ', '')
|
||||
|
||||
if line.startswith(' Certificate Path:'):
|
||||
cert_dict['certificate_path'] = line.split(': ', maxsplit=1)[1]
|
||||
|
||||
if line.startswith(' Private Key Path:'):
|
||||
cert_dict['private_key_path'] = line.split(': ', maxsplit=1)[1]
|
||||
|
||||
if cmd_option == 'account':
|
||||
if line.startswith('Account details for server'):
|
||||
acct_dict['server'] = line.split()[-1][:-1]
|
||||
|
||||
if line.startswith(' Account URL:'):
|
||||
acct_dict['url'] = line.split()[-1]
|
||||
|
||||
if line.startswith(' Email contact:'):
|
||||
acct_dict['email'] = line.split()[-1]
|
||||
|
||||
if acct_dict:
|
||||
raw_output['account'] = acct_dict
|
||||
|
||||
if cert_dict:
|
||||
cert_list.append(cert_dict)
|
||||
|
||||
if cert_list:
|
||||
raw_output['certificates'] = cert_list
|
||||
|
||||
return raw_output if raw else _process(raw_output)
|
||||
@@ -174,7 +174,7 @@ import jc.parsers.universal
|
||||
|
||||
class info():
|
||||
"""Provides parser metadata (version, author, etc.)"""
|
||||
version = '1.6'
|
||||
version = '1.8'
|
||||
description = '`crontab` command and file parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
@@ -198,7 +198,7 @@ def _process(proc_data):
|
||||
|
||||
Dictionary. Structured data to conform to the schema.
|
||||
"""
|
||||
# put itmes in lists
|
||||
# put items in lists
|
||||
try:
|
||||
for entry in proc_data['schedule']:
|
||||
entry['minute'] = entry['minute'].split(',')
|
||||
@@ -245,7 +245,11 @@ def parse(data, raw=False, quiet=False):
|
||||
# Pop any variable assignment lines
|
||||
cron_var = []
|
||||
for i, line in reversed(list(enumerate(cleandata))):
|
||||
if '=' in line and not line.strip()[0].isdigit() and not line.strip()[0] == '@':
|
||||
if '=' in line \
|
||||
and not line.strip()[0].isdigit() \
|
||||
and not line.strip()[0] == '@' \
|
||||
and not line.strip()[0] == '*':
|
||||
|
||||
var_line = cleandata.pop(i)
|
||||
var_name = var_line.split('=', maxsplit=1)[0].strip()
|
||||
var_value = var_line.split('=', maxsplit=1)[1].strip()
|
||||
@@ -273,6 +277,9 @@ def parse(data, raw=False, quiet=False):
|
||||
raw_output['schedule'] = cron_list
|
||||
|
||||
# Add shortcut entries back in
|
||||
if 'schedule' not in raw_output:
|
||||
raw_output['schedule'] = []
|
||||
|
||||
for item in shortcut_list:
|
||||
raw_output['schedule'].append(item)
|
||||
|
||||
|
||||
@@ -171,7 +171,7 @@ import jc.parsers.universal
|
||||
|
||||
class info():
|
||||
"""Provides parser metadata (version, author, etc.)"""
|
||||
version = '1.7'
|
||||
version = '1.9'
|
||||
description = '`crontab` file parser with user support'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
@@ -194,7 +194,7 @@ def _process(proc_data):
|
||||
|
||||
Dictionary. Structured data to conform to the schema.
|
||||
"""
|
||||
# put itmes in lists
|
||||
# put items in lists
|
||||
try:
|
||||
for entry in proc_data['schedule']:
|
||||
entry['minute'] = entry['minute'].split(',')
|
||||
@@ -241,7 +241,11 @@ def parse(data, raw=False, quiet=False):
|
||||
# Pop any variable assignment lines
|
||||
cron_var = []
|
||||
for i, line in reversed(list(enumerate(cleandata))):
|
||||
if '=' in line and not line.strip()[0].isdigit() and not line.strip()[0] == '@':
|
||||
if '=' in line \
|
||||
and not line.strip()[0].isdigit() \
|
||||
and not line.strip()[0] == '@' \
|
||||
and not line.strip()[0] == '*':
|
||||
|
||||
var_line = cleandata.pop(i)
|
||||
var_name = var_line.split('=', maxsplit=1)[0].strip()
|
||||
var_value = var_line.split('=', maxsplit=1)[1].strip()
|
||||
@@ -271,6 +275,9 @@ def parse(data, raw=False, quiet=False):
|
||||
raw_output['schedule'] = cron_list
|
||||
|
||||
# Add shortcut entries back in
|
||||
if 'schedule' not in raw_output:
|
||||
raw_output['schedule'] = []
|
||||
|
||||
for item in shortcut_list:
|
||||
raw_output['schedule'].append(item)
|
||||
|
||||
|
||||
149
jc/parsers/debconf_show.py
Normal file
149
jc/parsers/debconf_show.py
Normal file
@@ -0,0 +1,149 @@
|
||||
"""jc - JSON Convert `debconf-show` command output parser
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ debconf-show onlyoffice-documentserver | jc --debconf-show
|
||||
|
||||
or
|
||||
|
||||
$ jc debconf-show onlyoffice-documentserver
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc
|
||||
result = jc.parse('debconf_show', debconf_show_command_output)
|
||||
|
||||
Schema:
|
||||
|
||||
[
|
||||
{
|
||||
"asked": boolean,
|
||||
"packagename": string,
|
||||
"name": string,
|
||||
"value": string
|
||||
}
|
||||
]
|
||||
|
||||
Examples:
|
||||
|
||||
$ debconf-show onlyoffice-documentserver | jc --debconf-show -p
|
||||
[
|
||||
{
|
||||
"asked": true,
|
||||
"packagename": "onlyoffice",
|
||||
"name": "jwt_secret",
|
||||
"value": "aL8ei2iereuzee7cuJ6Cahjah1ixee2ah"
|
||||
},
|
||||
{
|
||||
"asked": false,
|
||||
"packagename": "onlyoffice",
|
||||
"name": "db_pwd",
|
||||
"value": "(password omitted)"
|
||||
},
|
||||
{
|
||||
"asked": true,
|
||||
"packagename": "onlyoffice",
|
||||
"name": "rabbitmq_pwd",
|
||||
"value": "(password omitted)"
|
||||
},
|
||||
{
|
||||
"asked": true,
|
||||
"packagename": "onlyoffice",
|
||||
"name": "db_port",
|
||||
"value": "5432"
|
||||
},
|
||||
{
|
||||
"asked": true,
|
||||
"packagename": "onlyoffice",
|
||||
"name": "db_user",
|
||||
"value": "onlyoffice"
|
||||
},
|
||||
{
|
||||
"asked": true,
|
||||
"packagename": "onlyoffice",
|
||||
"name": "rabbitmq_proto",
|
||||
"value": "amqp"
|
||||
},
|
||||
{
|
||||
"asked": true,
|
||||
"packagename": "onlyoffice",
|
||||
"name": "cluster_mode",
|
||||
"value": "false"
|
||||
}
|
||||
]
|
||||
"""
|
||||
from typing import List, Dict
|
||||
from jc.jc_types import JSONDictType
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
"""Provides parser metadata (version, author, etc.)"""
|
||||
version = '1.0'
|
||||
description = '`debconf-show` command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
compatible = ['linux']
|
||||
tags = ['command']
|
||||
magic_commands = ['debconf-show']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def _process(proc_data: JSONDictType) -> List[JSONDictType]:
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (Dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of Dictionaries. Structured to conform to the schema.
|
||||
"""
|
||||
return proc_data
|
||||
|
||||
|
||||
def parse(
|
||||
data: str,
|
||||
raw: bool = False,
|
||||
quiet: bool = False
|
||||
) -> List[JSONDictType]:
|
||||
"""
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) unprocessed output if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of Dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
jc.utils.compatibility(__name__, info.compatible, quiet)
|
||||
jc.utils.input_type_check(data)
|
||||
|
||||
raw_output: List = []
|
||||
|
||||
if jc.utils.has_data(data):
|
||||
|
||||
for line in filter(None, data.splitlines()):
|
||||
output_line: Dict = {}
|
||||
splitline = line.split(':', maxsplit=1)
|
||||
|
||||
output_line['asked'] = splitline[0].startswith('*')
|
||||
packagename, key = splitline[0].split('/', maxsplit=1)
|
||||
packagename = packagename[2:]
|
||||
key = key.replace('-', '_')
|
||||
val = splitline[1].strip()
|
||||
output_line['packagename'] = packagename
|
||||
output_line['name'] = key
|
||||
output_line['value'] = val
|
||||
|
||||
raw_output.append(output_line)
|
||||
|
||||
return raw_output if raw else _process(raw_output)
|
||||
@@ -4,6 +4,7 @@ Options supported:
|
||||
- `+noall +answer` options are supported in cases where only the answer
|
||||
information is desired.
|
||||
- `+axfr` option is supported on its own
|
||||
- `+nsid` option is supported
|
||||
|
||||
The `when_epoch` calculated timestamp field is naive. (i.e. based on the
|
||||
local time of the system the parser is run on)
|
||||
@@ -322,7 +323,7 @@ import jc.utils
|
||||
|
||||
class info():
|
||||
"""Provides parser metadata (version, author, etc.)"""
|
||||
version = '2.4'
|
||||
version = '2.5'
|
||||
description = '`dig` command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
@@ -427,6 +428,7 @@ def _parse_flags_line(flagsline):
|
||||
def _parse_opt_pseudosection(optline):
|
||||
# ;; OPT PSEUDOSECTION:
|
||||
# ; EDNS: version: 0, flags:; udp: 4096
|
||||
# ; NSID: 67 70 64 6e 73 2d 73 66 6f ("gpdns-sfo")
|
||||
# ; COOKIE: 1cbc06703eaef210
|
||||
if optline.startswith('; EDNS:'):
|
||||
optline_list = optline.replace(',', ' ').split(';')
|
||||
@@ -443,11 +445,18 @@ def _parse_opt_pseudosection(optline):
|
||||
}
|
||||
}
|
||||
|
||||
elif optline.startswith('; COOKIE:'):
|
||||
if optline.startswith('; COOKIE:'):
|
||||
return {
|
||||
'cookie': optline.split()[2]
|
||||
}
|
||||
|
||||
if optline.startswith('; NSID:'):
|
||||
return {
|
||||
'nsid': optline.split('("')[-1].rstrip('")')
|
||||
}
|
||||
|
||||
return {}
|
||||
|
||||
|
||||
def _parse_question(question):
|
||||
# ;www.cnn.com. IN A
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user