diff --git a/README.md b/README.md index 5525fbee..3bf6c83c 100755 --- a/README.md +++ b/README.md @@ -82,7 +82,8 @@ jc [OPTIONS] COMMAND The JSON output can be compact (default) or pretty formatted with the `-p` option. ### Parsers -- `--airport` enables the `airport` command parser (OSX) +- `--airport` enables the `airport -I` command parser (OSX) +- `--airport-s` enables the `airport -s` command parser (OSX) - `--arp` enables the `arp` command parser - `--blkid` enables the `blkid` command parser - `--crontab` enables the `crontab` command and file parser @@ -165,9 +166,9 @@ Tested on: - Excellent constructive feedback from Ilya Sher (https://github.com/ilyash-b) ## Examples -### airport +### airport -I ``` -$ airport | jc --airport -p +$ airport -I | jc --airport -p { "agrctlrssi": -66, "agrextrssi": 0, @@ -186,6 +187,46 @@ $ airport | jc --airport -p "channel": "48,80" } ``` +### airport -s +``` +$ airport -s | jc --airport-s -p +[ + { + "ssid": "DIRECT-4A-HP OfficeJet 3830", + "bssid": "00:67:eb:2a:a7:3b", + "rssi": -90, + "channel": "6", + "ht": true, + "cc": "--", + "security": [ + "WPA2(PSK/AES/AES)" + ] + }, + { + "ssid": "Latitude38", + "bssid": "c0:ff:d5:d2:7a:f3", + "rssi": -85, + "channel": "11", + "ht": true, + "cc": "US", + "security": [ + "WPA2(PSK/AES/AES)" + ] + }, + { + "ssid": "xfinitywifi", + "bssid": "6e:e3:0e:b8:45:99", + "rssi": -83, + "channel": "11", + "ht": true, + "cc": "US", + "security": [ + "NONE" + ] + }, + ... +] +``` ### arp ``` $ arp | jc --arp -p # or: jc -p arp diff --git a/changelog.txt b/changelog.txt index 35bd791d..b5e92fa0 100644 --- a/changelog.txt +++ b/changelog.txt @@ -3,7 +3,7 @@ jc changelog 20200xxxx vX.X.X - Added ntpq command parser - Added timedatectl status command parser -- Added airport command parser +- Added airport -I and airport -s command parser 20200308 v1.8.1 - CLI and history parser optimizations by https://github.com/philippeitis diff --git a/docgen.sh b/docgen.sh index 462f76eb..cb682684 100755 --- a/docgen.sh +++ b/docgen.sh @@ -5,6 +5,7 @@ cd jc pydocmd simple jc+ > ../docs/readme.md pydocmd simple utils+ > ../docs/utils.md pydocmd simple jc.parsers.airport+ > ../docs/parsers/airport.md +pydocmd simple jc.parsers.airport_s+ > ../docs/parsers/airport_s.md pydocmd simple jc.parsers.arp+ > ../docs/parsers/arp.md pydocmd simple jc.parsers.blkid+ > ../docs/parsers/blkid.md pydocmd simple jc.parsers.crontab+ > ../docs/parsers/crontab.md diff --git a/docs/parsers/airport.md b/docs/parsers/airport.md index ccd89474..3735793d 100644 --- a/docs/parsers/airport.md +++ b/docs/parsers/airport.md @@ -1,9 +1,9 @@ # jc.parsers.airport -jc - JSON CLI output utility airport Parser +jc - JSON CLI output utility airport -I Parser Usage: - specify --airport as the first argument if the piped input is coming from airport (OSX) + specify --airport as the first argument if the piped input is coming from airport -I (OSX) This program can be found at: /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport diff --git a/docs/parsers/airport_s.md b/docs/parsers/airport_s.md new file mode 100644 index 00000000..992fc78d --- /dev/null +++ b/docs/parsers/airport_s.md @@ -0,0 +1,136 @@ +# jc.parsers.airport_s +jc - JSON CLI output utility airport -s Parser + +Usage: + + specify --airport as the first argument if the piped input is coming from airport -s (OSX) + + This program can be found at: + /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport + +Compatibility: + + 'darwin' + +Examples: + + $ airport -s | jc --airport-s -p + [ + { + "ssid": "DIRECT-4A-HP OfficeJet 3830", + "bssid": "00:67:eb:2a:a7:3b", + "rssi": -90, + "channel": "6", + "ht": true, + "cc": "--", + "security": [ + "WPA2(PSK/AES/AES)" + ] + }, + { + "ssid": "Latitude38", + "bssid": "c0:ff:d5:d2:7a:f3", + "rssi": -85, + "channel": "11", + "ht": true, + "cc": "US", + "security": [ + "WPA2(PSK/AES/AES)" + ] + }, + { + "ssid": "xfinitywifi", + "bssid": "6e:e3:0e:b8:45:99", + "rssi": -83, + "channel": "11", + "ht": true, + "cc": "US", + "security": [ + "NONE" + ] + }, + ... + ] + + $ airport -s | jc --airport -p -r + [ + { + "ssid": "DIRECT-F3-HP ENVY 5660 series", + "bssid": "b0:5a:da:6f:0a:d4", + "rssi": "-93", + "channel": "1", + "ht": "Y", + "cc": "--", + "security": "WPA2(PSK/AES/AES)" + }, + { + "ssid": "YouAreInfected-5", + "bssid": "5c:e3:0e:c2:85:da", + "rssi": "-85", + "channel": "36", + "ht": "Y", + "cc": "US", + "security": "WPA(PSK/AES,TKIP/TKIP) WPA2(PSK/AES,TKIP/TKIP)" + }, + { + "ssid": "YuanFamily", + "bssid": "5c:e3:0e:b8:5f:9a", + "rssi": "-84", + "channel": "11", + "ht": "Y", + "cc": "US", + "security": "WPA(PSK/AES,TKIP/TKIP) WPA2(PSK/AES,TKIP/TKIP)" + }, + ... + ] + +## info +```python +info(self, /, *args, **kwargs) +``` + +## process +```python +process(proc_data) +``` + +Final processing to conform to the schema. + +Parameters: + + proc_data: (dictionary) raw structured data to process + +Returns: + + List of dictionaries. Structured data with the following schema: + [ + { + "ssid": string, + "bssid": string, + "rssi": integer, + "channel": string, + "ht": boolean, + "cc": string, + "security": [ + string, + ] + } + ] + +## parse +```python +parse(data, raw=False, quiet=False) +``` + +Main text parsing function + +Parameters: + + data: (string) text data to parse + raw: (boolean) output preprocessed JSON if True + quiet: (boolean) suppress warning messages if True + +Returns: + + List of dictionaries. Raw or processed structured data. + diff --git a/jc/cli.py b/jc/cli.py index c4a1e326..f996563d 100644 --- a/jc/cli.py +++ b/jc/cli.py @@ -23,6 +23,7 @@ __version__ = info.version parsers = [ 'airport', + 'airport-s', 'arp', 'blkid', 'crontab', diff --git a/jc/parsers/airport.py b/jc/parsers/airport.py index 5ea938e6..5a21a689 100644 --- a/jc/parsers/airport.py +++ b/jc/parsers/airport.py @@ -1,8 +1,8 @@ -"""jc - JSON CLI output utility airport Parser +"""jc - JSON CLI output utility airport -I Parser Usage: - specify --airport as the first argument if the piped input is coming from airport (OSX) + specify --airport as the first argument if the piped input is coming from airport -I (OSX) This program can be found at: /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport @@ -63,7 +63,6 @@ class info(): # compatible options: linux, darwin, cygwin, win32, aix, freebsd compatible = ['darwin'] - magic_commands = ['airport'] __version__ = info.version diff --git a/jc/parsers/airport_s.py b/jc/parsers/airport_s.py new file mode 100644 index 00000000..36ada5c4 --- /dev/null +++ b/jc/parsers/airport_s.py @@ -0,0 +1,185 @@ +"""jc - JSON CLI output utility airport -s Parser + +Usage: + + specify --airport as the first argument if the piped input is coming from airport -s (OSX) + + This program can be found at: + /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport + +Compatibility: + + 'darwin' + +Examples: + + $ airport -s | jc --airport-s -p + [ + { + "ssid": "DIRECT-4A-HP OfficeJet 3830", + "bssid": "00:67:eb:2a:a7:3b", + "rssi": -90, + "channel": "6", + "ht": true, + "cc": "--", + "security": [ + "WPA2(PSK/AES/AES)" + ] + }, + { + "ssid": "Latitude38", + "bssid": "c0:ff:d5:d2:7a:f3", + "rssi": -85, + "channel": "11", + "ht": true, + "cc": "US", + "security": [ + "WPA2(PSK/AES/AES)" + ] + }, + { + "ssid": "xfinitywifi", + "bssid": "6e:e3:0e:b8:45:99", + "rssi": -83, + "channel": "11", + "ht": true, + "cc": "US", + "security": [ + "NONE" + ] + }, + ... + ] + + $ airport -s | jc --airport -p -r + [ + { + "ssid": "DIRECT-F3-HP ENVY 5660 series", + "bssid": "b0:5a:da:6f:0a:d4", + "rssi": "-93", + "channel": "1", + "ht": "Y", + "cc": "--", + "security": "WPA2(PSK/AES/AES)" + }, + { + "ssid": "YouAreInfected-5", + "bssid": "5c:e3:0e:c2:85:da", + "rssi": "-85", + "channel": "36", + "ht": "Y", + "cc": "US", + "security": "WPA(PSK/AES,TKIP/TKIP) WPA2(PSK/AES,TKIP/TKIP)" + }, + { + "ssid": "YuanFamily", + "bssid": "5c:e3:0e:b8:5f:9a", + "rssi": "-84", + "channel": "11", + "ht": "Y", + "cc": "US", + "security": "WPA(PSK/AES,TKIP/TKIP) WPA2(PSK/AES,TKIP/TKIP)" + }, + ... + ] +""" +import jc.utils +import jc.parsers.universal + + +class info(): + version = '1.0' + description = 'airport -s command parser' + author = 'Kelly Brazil' + author_email = 'kellyjonbrazil@gmail.com' + # details = 'enter any other details here' + + # compatible options: linux, darwin, cygwin, win32, aix, freebsd + compatible = ['darwin'] + + +__version__ = info.version + + +def process(proc_data): + """ + Final processing to conform to the schema. + + Parameters: + + proc_data: (dictionary) raw structured data to process + + Returns: + + List of dictionaries. Structured data with the following schema: + [ + { + "ssid": string, + "bssid": string, + "rssi": integer, + "channel": string, + "ht": boolean, + "cc": string, + "security": [ + string, + ] + } + ] + """ + for entry in proc_data: + + # integers + int_list = ['rssi'] + for key in int_list: + if key in entry: + try: + entry[key] = int(entry[key]) + except (ValueError): + entry[key] = None + + # booleans + bool_list = ['ht'] + for key in entry: + if key in bool_list: + try: + entry[key] = True if entry[key] == 'Y' else False + except (ValueError): + entry[key] = None + + if 'security' in entry: + entry['security'] = entry['security'].split() + + return proc_data + + +def parse(data, raw=False, quiet=False): + """ + Main text parsing function + + Parameters: + + data: (string) text data to parse + raw: (boolean) output preprocessed JSON if True + quiet: (boolean) suppress warning messages if True + + Returns: + + List of dictionaries. Raw or processed structured data. + """ + if not quiet: + jc.utils.compatibility(__name__, info.compatible) + + cleandata = data.splitlines() + + # fix headers + cleandata[0] = cleandata[0].lower() + cleandata[0] = cleandata[0].replace('-', '_') + cleandata[0] = cleandata[0].replace('security (auth/unicast/group)', 'security') + + # parse the data + raw_output = jc.parsers.universal.sparse_table_parse(cleandata) + + if raw: + return raw_output + else: + return process(raw_output)