diff --git a/nc_password_client/nc_password_client.py b/nc_password_client/nc_password_client.py index 3fa2e94..c7a44ec 100755 --- a/nc_password_client/nc_password_client.py +++ b/nc_password_client/nc_password_client.py @@ -22,8 +22,12 @@ import click import click_config_file import passpy import secretstorage -from contextlib import closing from cryptography.fernet import Fernet +from yaml import dump +try: + from yaml import CDumper as Dumper +except ImportError: + from yaml import Dumper try: import requests HAS_REQUESTS_LIB = True @@ -100,6 +104,7 @@ def decrypt_item(item_key, item, key='label'): class NextcloudHandler: '''Handle Nextcloud Password API''' def __init__(self, params): + self.output_format = params.get('output_format', 'json') if 'logger' in params: self._log = params['logger'] else: @@ -301,29 +306,37 @@ class NextcloudHandler: item = self._safer_obj(item, fields=fields) return obj + def _output(self, obj): + if self.output_format == 'json': + return json.dumps(self._safer_obj(obj), indent=2) + elif self.output_format == 'yaml': + return dump(obj, Dumper=Dumper) + else: + return f"{obj}" + def debug(self, obj): '''Show debug information''' self._log.debug( - json.dumps(self._safer_obj(obj), indent=2) + self._output(obj) ) def warning(self, obj): '''Show warning information''' self._log.warning( - json.dumps(self._safer_obj(obj), indent=2) + self._output(obj) ) def info(self, obj): '''Show information''' self._log.info( - json.dumps(self._safer_obj(obj), indent=2) + self._output(obj) ) def error(self, obj): '''Show error information''' try: self._log.error( - json.dumps(self._safer_obj(obj), indent=2) + self._output(obj) ) except TypeError as error: self._log.error( @@ -980,9 +993,10 @@ class NcPasswordClient: def __init__( self, debug_level, log_file, host, user, api_token, cse_password, - timeout, cache_duration, https_proxy + timeout, cache_duration, https_proxy, output_format ): self.config = {} + self.output_format = output_format self.config['debug_level'] = debug_level if log_file is None: self.config['log_file'] = os.path.join( @@ -1006,6 +1020,7 @@ class NcPasswordClient: "cache_duration": cache_duration, "https_proxy": https_proxy, "logger": self._log, + "output_format": output_format, } self.nc = NextcloudHandler(params) @@ -1024,29 +1039,48 @@ class NcPasswordClient: item = self._safer_obj(item, fields=fields) return obj + def _output(self, obj): + if self.output_format == 'json': + return json.dumps(self._safer_obj(obj), indent=2) + elif self.output_format == 'yaml': + return dump(obj, Dumper=Dumper) + else: + output = '' + if isinstance(obj, list): + output += '-' * os.get_terminal_size(0)[0] + for item in obj: + output += f"{self._output(item)}\n" + elif isinstance(obj, dict): + output += '-' * os.get_terminal_size(0)[0] + for key in obj.keys(): + output += f"{key} = {self._output(obj[key])}\n" + else: + output += f"{obj}\n" + return output.strip('\n') + def debug(self, obj): '''Show debug information''' self._log.debug( - json.dumps(self._safer_obj(obj), indent=2) + self._output(obj) ) def warning(self, obj): '''Show warning information''' self._log.warning( - json.dumps(self._safer_obj(obj), indent=2) + self._output(obj) ) def info(self, obj): '''Show information''' self._log.info( - json.dumps(self._safer_obj(obj), indent=2) + self._output(obj) ) def error(self, obj): '''Show error information''' try: self._log.error( - json.dumps(self._safer_obj(obj), indent=2) + self._output(obj) ) except TypeError as error: self._log.error( @@ -1260,6 +1294,16 @@ class NcPasswordClient: ), help='Set the debug level for the standard output.' ) +@click.option( + "--output-format", + "-f", + default="json", + type=click.Choice( + ["json", "yaml", "plain"], + case_sensitive=False, + ), + help='Set the output format.' +) @click.option('--log-file', '-l', help="File to store all debug messages.") # @click.option("--dummy","-n", is_flag=True, # help="Don't do anything, just show what would be done.") @@ -1302,13 +1346,13 @@ class NcPasswordClient: @click.pass_context def cli( ctx, debug_level, log_file, host, user, api_token, cse_password, - timeout, cache_duration, https_proxy + timeout, cache_duration, https_proxy, output_format ): '''Client function to pass context''' ctx.ensure_object(dict) ctx.obj['NcPasswordClient'] = NcPasswordClient( debug_level, log_file, host, user, api_token, cse_password, - timeout, cache_duration, https_proxy + timeout, cache_duration, https_proxy, output_format ) @cli.command() diff --git a/requirements.txt b/requirements.txt index 7d8bdaf..7f8998e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,3 +4,4 @@ requests pysodium passpy secretstorage +pyyaml