diff --git a/README.md b/README.md index b9c39371..3a21f068 100755 --- a/README.md +++ b/README.md @@ -93,6 +93,7 @@ The JSON output can be compact (default) or pretty formatted with the `-p` optio - `--dig` enables the `dig` command parser - `--du` enables the `du` command parser - `--env` enables the `env` command parser +- `--file` enables the `file` command parser - `--free` enables the `free` command parser - `--fstab` enables the `/etc/fstab` file parser - `--group` enables the `/etc/group` file parser @@ -761,6 +762,41 @@ $ env | jc --env -p # or: jc -p env ... ] ``` +### file +``` +$ file * | jc --file -p +[ + { + "filename": "Applications", + "type": "directory" + }, + { + "filename": "another file with spaces", + "type": "empty" + }, + { + "filename": "argstest.py", + "type": "Python script text executable, ASCII text" + }, + { + "filename": "blkid-p.out", + "type": "ASCII text" + }, + { + "filename": "blkid-pi.out", + "type": "ASCII text, with very long lines" + }, + { + "filename": "cd_catalog.xml", + "type": "XML 1.0 document text, ASCII text, with CRLF line terminators" + }, + { + "filename": "centosserial.sh", + "type": "Bourne-Again shell script text executable, UTF-8 Unicode text" + }, + ... +] +``` ### free ``` $ free | jc --free -p # or: jc -p free diff --git a/changelog.txt b/changelog.txt index b5e92fa0..7aadae4a 100644 --- a/changelog.txt +++ b/changelog.txt @@ -4,9 +4,12 @@ jc changelog - Added ntpq command parser - Added timedatectl status command parser - Added airport -I and airport -s command parser +- Added file command parser +- Optimized history command parser by https://github.com/philippeitis +- Magic syntax fix for certain edge cases 20200308 v1.8.1 -- CLI and history parser optimizations by https://github.com/philippeitis +- CLI optimizations by https://github.com/philippeitis - Refactored magic syntax function and added tests (https://github.com/philippeitis) - Github actions for CI testing on multiple platforms by https://github.com/philippeitis - Updated ls parser to fix parsing error in OSX with -lR when there are empty folders diff --git a/docgen.sh b/docgen.sh index cb682684..f09c7f85 100755 --- a/docgen.sh +++ b/docgen.sh @@ -15,6 +15,7 @@ pydocmd simple jc.parsers.df+ > ../docs/parsers/df.md pydocmd simple jc.parsers.dig+ > ../docs/parsers/dig.md pydocmd simple jc.parsers.du+ > ../docs/parsers/du.md pydocmd simple jc.parsers.env+ > ../docs/parsers/env.md +pydocmd simple jc.parsers.file+ > ../docs/parsers/file.md pydocmd simple jc.parsers.free+ > ../docs/parsers/free.md pydocmd simple jc.parsers.fstab+ > ../docs/parsers/fstab.md pydocmd simple jc.parsers.group+ > ../docs/parsers/group.md diff --git a/docs/parsers/file.md b/docs/parsers/file.md new file mode 100644 index 00000000..f7e4e7b1 --- /dev/null +++ b/docs/parsers/file.md @@ -0,0 +1,90 @@ +# jc.parsers.file +jc - JSON CLI output utility file command Parser + +Usage: + + specify --file as the first argument if the piped input is coming from file. + +Compatibility: + + 'linux', 'aix', 'freebsd', 'darwin' + +Examples: + + $ file * | jc --file -p + [ + { + "filename": "Applications", + "type": "directory" + }, + { + "filename": "another file with spaces", + "type": "empty" + }, + { + "filename": "argstest.py", + "type": "Python script text executable, ASCII text" + }, + { + "filename": "blkid-p.out", + "type": "ASCII text" + }, + { + "filename": "blkid-pi.out", + "type": "ASCII text, with very long lines" + }, + { + "filename": "cd_catalog.xml", + "type": "XML 1.0 document text, ASCII text, with CRLF line terminators" + }, + { + "filename": "centosserial.sh", + "type": "Bourne-Again shell script text executable, UTF-8 Unicode text" + }, + ... + ] + +## 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: + + [ + { + "filename": string, + "type ": 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 c7bf174a..e3cd308c 100644 --- a/jc/cli.py +++ b/jc/cli.py @@ -33,6 +33,7 @@ parsers = [ 'dig', 'du', 'env', + 'file', 'free', 'fstab', 'group', diff --git a/jc/parsers/file.py b/jc/parsers/file.py new file mode 100644 index 00000000..e72b4d5e --- /dev/null +++ b/jc/parsers/file.py @@ -0,0 +1,128 @@ +"""jc - JSON CLI output utility file command Parser + +Usage: + + specify --file as the first argument if the piped input is coming from file. + +Compatibility: + + 'linux', 'aix', 'freebsd', 'darwin' + +Examples: + + $ file * | jc --file -p + [ + { + "filename": "Applications", + "type": "directory" + }, + { + "filename": "another file with spaces", + "type": "empty" + }, + { + "filename": "argstest.py", + "type": "Python script text executable, ASCII text" + }, + { + "filename": "blkid-p.out", + "type": "ASCII text" + }, + { + "filename": "blkid-pi.out", + "type": "ASCII text, with very long lines" + }, + { + "filename": "cd_catalog.xml", + "type": "XML 1.0 document text, ASCII text, with CRLF line terminators" + }, + { + "filename": "centosserial.sh", + "type": "Bourne-Again shell script text executable, UTF-8 Unicode text" + }, + ... + ] +""" +import jc.utils +import jc.parsers.universal + + +class info(): + version = '1.0' + description = 'file command parser' + author = 'Kelly Brazil' + author_email = 'kellyjonbrazil@gmail.com' + + # compatible options: linux, darwin, cygwin, win32, aix, freebsd + compatible = ['linux', 'aix', 'freebsd', 'darwin'] + magic_commands = ['file'] + + +__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: + + [ + { + "filename": string, + "type ": string + } + ] + """ + # No further processing + return proc_data + + +def parse(data, raw=False, quiet=False): + """ + Main text parsing function + + Parameters: + + data: (string) text data to parse + raw: (boolean) output preprocessed JSON if True + quiet: (boolean) suppress warning messages if True + + Returns: + + List of dictionaries. Raw or processed structured data. + """ + if not quiet: + jc.utils.compatibility(__name__, info.compatible) + + raw_output = [] + + warned = False + for line in filter(None, data.splitlines()): + linedata = line.rsplit(':', maxsplit=1) + + try: + filename = linedata[0].strip() + filetype = linedata[1].strip() + + raw_output.append( + { + 'filename': filename, + 'type': filetype + } + ) + except IndexError: + if not warned: + jc.utils.warning_message('Filenames with newline characters detected. Some filenames may be truncated.') + warned = True + + if raw: + return raw_output + else: + return process(raw_output)