diff --git a/README.md b/README.md index 1ad9f9ea..fef0e327 100644 --- a/README.md +++ b/README.md @@ -208,6 +208,13 @@ Tested on: - NixOS - FreeBSD12 + +## Custom Parsers +Custom local plugins may be placed in a "jc/jcparsers" folder in your local "App data directory" (For example, "/home/*myname*/.local/jc/jcparsers" on Linux, "/Users/*myname*/Library/Application Support/jc/jcparsers" on Mac OS X, or "C:\Users\*myname*\AppData\Local\jc\jc\jcparsers" on Windows. + +Use the [`jc/parsers/foo.py`](https://github.com/kellyjonbrazil/jc/blob/master/jc/parsers/foo.py) parser as a template and simply place a `.py` file in the `jcparsers` subfolder. Local plugin file names must be valid python module names, therefore must consist entirely of alphanumerics and start with a letter. Local plugins may override default plugins. + + ## Contributions Feel free to add/improve code or parsers! You can use the [`jc/parsers/foo.py`](https://github.com/kellyjonbrazil/jc/blob/master/jc/parsers/foo.py) parser as a template and submit your parser with a pull request. diff --git a/jc/cli.py b/jc/cli.py index 96bf7b36..1602ec8b 100644 --- a/jc/cli.py +++ b/jc/cli.py @@ -1,8 +1,11 @@ """jc - JSON CLI output utility JC cli module """ +import appdirs import sys import os +import os.path +import re import shlex import importlib import textwrap @@ -79,6 +82,20 @@ parsers = [ 'yaml' ] +# List of custom or override parsers. +# Allow any /jc/jcparsers/*.py +local_parsers = [] +data_dir = appdirs.user_data_dir("jc", "jc") +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)): + plugin_name = name[0:-3] + local_parsers.append(plugin_name) + if plugin_name not in parsers: + parsers.append(plugin_name) + def set_env_colors(): """ @@ -159,8 +176,9 @@ def parser_mod_shortname(parser): def parser_module(parser): """import the module just in time and return the module object""" - importlib.import_module('jc.parsers.' + parser_mod_shortname(parser)) - return getattr(jc.parsers, parser_mod_shortname(parser)) + shortname = parser_mod_shortname(parser) + path = ('jcparsers.' if shortname in local_parsers else 'jc.parsers.') + return importlib.import_module(path + shortname) def parsers_text(indent=0, pad=0): diff --git a/requirements.txt b/requirements.txt index 8ad5147f..694fc281 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ +appdirs>=1.4.0 ruamel.yaml>=0.15.0 xmltodict>=0.12.0 Pygments>=2.4.2 diff --git a/setup.py b/setup.py index 6036b6b0..912c18f3 100755 --- a/setup.py +++ b/setup.py @@ -10,6 +10,7 @@ setuptools.setup( author_email='kellyjonbrazil@gmail.com', description='Converts the output of popular command-line tools and file-types to JSON.', install_requires=[ + 'appdirs>=1.4.0', 'ruamel.yaml>=0.15.0', 'xmltodict>=0.12.0', 'Pygments>=2.4.2'