Пример #1
0
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)
Пример #2
0
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)
Пример #3
0
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)
Пример #4
0
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)
Пример #5
0
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)
Пример #6
0
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))
Пример #7
0
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)
Пример #8
0
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))
Пример #9
0
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])
Пример #10
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)
Пример #11
0
 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'
Пример #12
0
 def test_serror_calls_secho(self):
     with self.monkey_patched_secho():
         click.serror("foobar")
         assert self.RECORDER[-1] == 'foobar'
Пример #13
0
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))