def diagnostics(cause): """Display diagnostic info based on the given cause.""" import pprint if not cause: return response = getattr(cause, 'response', None) request = getattr(response, 'request', None) # pprint.pprint(vars(response)) # pprint.pprint(vars(request)) method = 'HTTP {}'.format(request.method) if request else 'HTTP' try: data = pprint.pformat(response.json(), indent=4) except (AttributeError, TypeError, ValueError): try: data = response.content except AttributeError: data = '' if data: try: data = data.decode('ascii') except (AttributeError, UnicodeDecodeError): pass data = data.splitlines() if len(data) > MAX_ERROR_LINES: data = data[:MAX_ERROR_LINES] + ['...'] data = '| RESPONSE BODY:\n' + '\n'.join(['| ' + x for x in data]) click.serror("{} ERROR: {}".format(method, cause)) if data: click.secho(data)
def tidy(ctx, pages, diff=False, dry_run=0, recursive=False): """Tidy pages after cut&paste migration from other wikis.""" with api.context() as cf: for page_url in pages: try: page = content.ConfluencePage(cf, page_url) except api.ERRORS as cause: # Just log and otherwise ignore any errors click.serror("API ERROR: {}", cause) else: ##print(page._data); xxx body = page.tidy(log=ctx.obj.log) if body == page.body: ctx.obj.log.info('No changes for "%s"', page.title) else: if diff or dry_run == 1: page.dump_diff(body) if dry_run: ctx.obj.log.info('WOULD save page#{0} "{1}" as v. {2}'.format(page.page_id, page.title, page.version + 1)) else: result = page.update(body) if result: ctx.obj.log.info('Updated page#{id} "{title}" to v. {version.number}'.format(**result)) else: ctx.obj.log.info('Changes not saved for "%s"', page.title)
def tree(ctx, rootpage): """Export metadata of a page tree.""" if not rootpage: click.serror("No root page selected via --entity!") return 1 outname = getattr(ctx.obj.outfile, 'name', None) with api.context() as cf: results = [] try: #page = content.ConfluencePage(cf, rootpage, expand='metadata.labels,metadata.properties') #results.append(page.json) pagetree = cf.walk( rootpage, depth_1st=True, expand='metadata.labels,metadata.properties,version') for depth, data in pagetree: data.update(dict(depth=depth)) results.append(data) except api.ERRORS as cause: # Just log and otherwise ignore any errors api.diagnostics(cause) else: ctx.obj.log.info('Got {} results.'.format(len(results))) if results: print_result(ctx, results)
def tidy(ctx, pages, diff=False, dry_run=0, recursive=False): """Tidy pages after cut&paste migration from other wikis.""" with api.context() as cf: for page_url in pages: try: page = content.ConfluencePage(cf, page_url) except api.ERRORS as cause: # Just log and otherwise ignore any errors click.serror("API ERROR: {}", cause) else: ##print(page._data); xxx body = page.tidy(log=ctx.obj.log) if body == page.body: ctx.obj.log.info('No changes for "%s"', page.title) else: if diff or dry_run == 1: page.dump_diff(body) if dry_run: ctx.obj.log.info( 'WOULD save page#{0} "{1}" as v. {2}'.format( page.page_id, page.title, page.version + 1)) else: result = page.update(body) if result: ctx.obj.log.info( 'Updated page#{id} "{title}" to v. {version.number}' .format(**result)) else: ctx.obj.log.info('Changes not saved for "%s"', page.title)
def pretty(ctx, pages, markup, recursive=False): """Pretty-print page content markup.""" content_format = content.CLI_CONTENT_FORMATS[markup] with api.context() as cf: for page_url in pages: try: page = content.ConfluencePage(cf, page_url, markup=content_format) except api.ERRORS as cause: # Just log and otherwise ignore any errors click.serror("API ERROR: {}", cause) else: root = page.etree() root.getroottree().write(sys.stdout, encoding='utf8', pretty_print=True, xml_declaration=False)
def help_command(ctx, config_dump=False): """Print some information on the system environment.""" def banner(title): "Helper" click.echo('') click.secho('~~~ {} ~~~'.format(title), fg='green', bg='black', bold=True) if config_dump: ctx.obj.cfg.dump() sys.exit(0) app_name = ctx.find_root().info_name click.secho('*** "{}" Help & Information ***'.format(app_name), fg='white', bg='blue', bold=True) banner('Version Information') click.echo(config.version_info(ctx)) banner('Configuration') locations = ctx.obj.cfg.locations(exists=False) locations = [(u'✔' if os.path.exists(i) else u'✘', click.pretty_path(i)) for i in locations] click.echo(u'The following configuration files are merged in order, if they exist:\n {0}'.format( u'\n '.join(u'{} {}'.format(*i) for i in locations), )) banner('Vault Information') try: conn = vault.Connection() except ValueError as cause: if "target" in str(cause): click.serror("{} -- forgot to edit configuration or set VAULT_ADDR?", cause) else: raise else: print(conn) policies = conn.api.list_policies() if 'root' in policies: click.secho("WARN: You are connected using a 'root' token!", fg='yellow', bg='black', bold=True, reverse=True) print("Policies: {}".format(', '.join(policies))) print("Auth Backends:") for mount, data in conn.api.list_auth_backends().items(): print(" {mount:15s} {type:15s} {description}".format(mount=mount, **data)) print("Storage:") for mount, data in conn.api.list_secret_backends().items(): print(" {mount:15s} {type:15s} {description}".format(mount=mount, **data)) banner('More Help') click.echo("Call '{} --help' to get a list of available commands & options.".format(app_name)) click.echo("Call '{} «command» --help' to get help on a specific command.".format(app_name)) click.echo("Call '{} --version' to get the above version information separately.".format(app_name)) click.echo("Call '{} --license' to get licensing informatioon.".format(app_name))
def help_command(ctx, config_dump=False): """Print some information on the system environment.""" def banner(title): "Helper" click.echo('') click.secho('~~~ {} ~~~'.format(title), fg='green', bg='black', bold=True) if config_dump: ctx.obj.cfg.dump() sys.exit(0) app_name = ctx.find_root().info_name click.secho('*** "{}" Help & Information ***'.format(app_name), fg='white', bg='blue', bold=True) banner('Version Information') click.echo(config.version_info(ctx)) banner('Configuration') locations = ctx.obj.cfg.locations(exists=False) locations = [(u'✔' if os.path.exists(i) else u'✘', click.pretty_path(i)) for i in locations] click.echo(u'The following configuration files are merged in order, if they exist:\n {0}'.format( u'\n '.join(u'{} {}'.format(*i) for i in locations), )) banner('Confluence Stats') with api.context() as cf: try: spaces = list(cf.getall('space')) except api.ERRORS as cause: # Just log and otherwise ignore any errors click.serror("API ERROR: {}", cause) else: click.echo(u'{} spaces found.'.format(len(spaces))) click.echo(u'\nMost recently created:') for space in itertools.islice(sorted(spaces, key=lambda i: i.id, reverse=True), 5): click.echo(u' {:10} {:>15} {}'.format(space.type, space.key, space.name)) banner('More Help') click.echo("Call '{} --help' to get a list of available commands & options.".format(app_name)) click.echo("Call '{} «command» --help' to get help on a specific command.".format(app_name)) click.echo("Call '{} --version' to get the above version information separately.".format(app_name)) click.echo("Call '{} --license' to get licensing informatioon.".format(app_name))
def usage(ctx, query, top=0): """Create report on usage of different entities (macros, labels, …).""" if not ctx.obj.entity: click.serror("No --entity selected!") return if top: click.echo("TOP {:d}".format(top)) outname = getattr(ctx.obj.outfile, 'name', None) with api.context() as cf: ctx.obj.cql.append('type=page AND macro != "{}"'.format(query)) try: response = cf.get("content/search", cql=' AND '.join(ctx.obj.cql)) except api.ERRORS as cause: # Just log and otherwise ignore any errors api.diagnostics(cause) else: print('Got {} results.'.format(len(response.results))) if response.results: print_result(ctx, response.results[0])
def open_command(ctx, cfgfile=None, bases=None, outfile=''): """Open vault and amend configuration file(s).""" if not cfgfile: raise UsageError("You provided no configuration file names!", ctx=ctx) try: conn = vault.Connection() except ValueError as cause: if "target" in str(cause): click.serror( "{} -- forgot to edit configuration or set VAULT_ADDR?", cause) else: raise data = cfgdata.read_merged_files(cfgfile) secrets = lookup_secrets(data, bases, conn) #ppyaml(cfgdata, sys.stdout) if outfile in ('', '-'): ppyaml(secrets, sys.stdout) else: if not ctx.obj.quiet: click.echo('Writing secrets to "{}"...'.format(outfile)) with io.open(outfile, 'w', encoding='utf-8') as handle: ppyaml(secrets, handle)
def test_serror_formats_its_message(self): with self.monkey_patched_secho(): click.serror("{0} {foo}", 1, foo=2) assert self.RECORDER[-1] == '1 2'
def test_serror_calls_secho(self): with self.monkey_patched_secho(): click.serror("foobar") assert self.RECORDER[-1] == 'foobar'
def help_command(ctx, config_dump=False): """Print some information on the system environment.""" def banner(title): "Helper" click.echo('') click.secho('~~~ {} ~~~'.format(title), fg='green', bg='black', bold=True) if config_dump: ctx.obj.cfg.dump() sys.exit(0) app_name = ctx.find_root().info_name click.secho('*** "{}" Help & Information ***'.format(app_name), fg='white', bg='blue', bold=True) banner('Version Information') click.echo(config.version_info(ctx)) banner('Configuration') locations = ctx.obj.cfg.locations(exists=False) locations = [(u'✔' if os.path.exists(i) else u'✘', click.pretty_path(i)) for i in locations] click.echo( u'The following configuration files are merged in order, if they exist:\n {0}' .format(u'\n '.join(u'{} {}'.format(*i) for i in locations), )) banner('Active Login') try: api = github.api(config=None) # TODO: config object except AssertionError as cause: click.serror("AUTH: {}", cause) else: try: dump_user(api, api.gh_config.user) limit = api.ratelimit_remaining fgcol = 'yellow' if limit >= 100 else 'cyan' click.secho('\n{} calls remaining in this hour.'.format(limit), fg=fgcol, bg='black', bold=True) except ConnectionError as cause: click.serror("HTTP: {}", cause) except github.GitHubError as cause: click.serror(github.pretty_cause(cause, "API")) banner('More Help') click.echo( "Call '{} --help' to get a list of available commands & options.". format(app_name)) click.echo( "Call '{} «command» --help' to get help on a specific command.".format( app_name)) click.echo( "Call '{} --version' to get the above version information separately.". format(app_name)) click.echo( "Call '{} --license' to get licensing informatioon.".format(app_name))