Exemple #1
0
def info(identifier, multiple, output_format, color):
    _log.debug(f"info for resource id='{identifier}'")
    try:
        resource.identifier_str(identifier, allow_prefix=True)
    except ValueError as err:
        click.echo(f"{err}")
        sys.exit(Code.INPUT_VALUE.value)
    rsrc_list = list(find_by_id(identifier))
    n = len(rsrc_list)
    if n > 1 and not multiple:
        click.echo(f"Too many ({n}) resources match prefix '{identifier}'. "
                   "Add option --multiple to allow multiple matches.")
        sys.exit(Code.DMF_OPER.value)
    elif n == 0:
        click.echo("Resource not found")
        sys.exit(Code.DMF_OPER.value)
    pfxlen = len(identifier)
    si = _ShowInfo(output_format, pfxlen, color=color)
    for rsrc in rsrc_list:
        si.show(rsrc)
Exemple #2
0
def test_identifier_str():
    assert len(resource.identifier_str()) > 1
    assert resource.identifier_str('0' * 32) == '0' * 32
    with pytest.raises(ValueError):
        resource.identifier_str('foobar')
    with pytest.raises(ValueError):
        resource.identifier_str('0' * 31 + 'X')
Exemple #3
0
def test_identifier_str():
    assert len(resource.identifier_str()) > 1
    assert resource.identifier_str("0" * 32) == "0" * 32
    with pytest.raises(ValueError):
        resource.identifier_str("foobar")
    with pytest.raises(ValueError):
        resource.identifier_str("0" * 31 + "X")
Exemple #4
0
def rm(identifier, yes, multiple, list_resources):
    _log.info(f"remove resource '{identifier}'")
    try:
        resource.identifier_str(identifier, allow_prefix=True)
    except ValueError as errmsg:
        click.echo(f"Invalid identifier. Details: {errmsg}")
        sys.exit(Code.INPUT_VALUE.value)
    rsrc_list = list(find_by_id(identifier))
    found_multiple = len(rsrc_list) > 1
    if found_multiple and not multiple:
        click.echo(
            f"Too many ({len(rsrc_list)}) resources match prefix '{identifier}'. "
            "Add option --multiple to allow multiple matches.")
        sys.exit(Code.DMF_OPER.value)
    fields = ["type", "desc", "modified"]  # "id" is prepended by _ls_basic()
    if list_resources:
        _print_resource_table(rsrc_list, fields, ["id"], False, False, True)
    if yes != "yes":
        if found_multiple:
            s = f"these {len(rsrc_list)} resources"
        else:
            s = "this resource"
        do_remove = click.confirm(f"Remove {s}",
                                  prompt_suffix="? ",
                                  default=False)
        if not do_remove:
            click.echo("aborted")
            sys.exit(Code.CANCELED.value)
    d = DMF()
    for r in rsrc_list:
        _log.debug(f"begin remove-resource id={r.id}")
        d.remove(identifier=r.id)
        _log.debug(f"end remove-resource id={r.id}")
    if found_multiple:
        s = f"{len(rsrc_list)} resources removed"
    else:
        s = "resource removed"
    click.echo(s)
Exemple #5
0
def related(identifier, direction, color, unicode):
    _log.info(f"related to resource id='{identifier}'")
    t = _cterm if color else _noterm
    dmf = DMF()
    try:
        resource.identifier_str(identifier, allow_prefix=True)
    except ValueError as err:
        click.echo(f"{err}")
        sys.exit(Code.INPUT_VALUE.value)
    _log.debug(f"begin: finding root resource {identifier}")
    rsrc_list = list(find_by_id(identifier, dmf=dmf))
    n = len(rsrc_list)
    if n > 1:
        click.echo(f"Too many resources matching `{identifier}`")
        sys.exit(Code.INPUT_VALUE)
    rsrc = rsrc_list[0]
    _log.debug(f"end: finding root resource {identifier}")
    # get related resources
    _log.debug(f"begin: finding related resources for {identifier}")
    outgoing = direction == "out"
    rr = list(
        dmf.find_related(rsrc, meta=["aliases", "type"], outgoing=outgoing))
    _log.debug(f"end: finding related resources for {identifier}")
    # stop if no relations
    if not rr:
        _log.warning(f"no resource related to {identifier}")
        click.echo(f"No relations for resource `{identifier}`")
        sys.exit(0)
    _log.info(f"got {len(rr)} related resources")
    # debugging
    if _log.isEnabledFor(logging.DEBUG):
        dbgtree = '\n'.join(['  ' + str(x) for x in rr])
        _log.debug(f"related resources:\n{dbgtree}")
    # extract uuids & determine common UUID prefix length
    uuids = [item[2][resource.Resource.ID_FIELD] for item in rr]
    pfx = util.uuid_prefix_len(uuids)
    # initialize queue with depth=1 items
    q = [item for item in rr if item[0] == 1]
    # print root resource
    print(_related_item(rsrc.id, rsrc.name, rsrc.type, pfx, t, unicode))
    # set up printing style
    if unicode:
        # connector chars
        vrt, vrd, relbow, relbow2, rarr = (
            '\u2502',
            '\u2506',
            '\u2514',
            '\u251C',
            '\u2500\u2500',
        )
        # relation prefix and arrow
        relpre, relarr = (
            ['\u2500\u25C0\u2500\u2524', '\u2524'][outgoing],
            ['\u2502', '\u251C\u2500\u25B6'][outgoing],
        )
    else:
        # connector chars
        vrt, vrd, relbow, relbow2, rarr = '|', '.', '+', '+', '--'
        # relation prefix and arrow
        relpre, relarr = ['<-[', '-['][outgoing], [']-', ']->'][outgoing]
    # create map of #items at each level, so we can easily
    # know when there are more at a given level, for drawing
    n_at_level = {0: 0}
    for item in rr:
        depth = item[0]
        if depth in n_at_level:
            n_at_level[depth] += 1
        else:
            n_at_level[depth] = 1
    # print tree
    while q:
        depth, rel, meta = q.pop()
        n_at_level[depth] -= 1
        indent = ''.join([
            f" {t.blue}{vrd if n_at_level[i - 1] else ' '}{t.normal} "
            for i in range(1, depth + 1)
        ])
        print(f"{indent} {t.blue}{vrt}{t.normal}")
        rstr = f"{t.blue}{relpre}{t.yellow}{rel.predicate}{t.blue}{relarr}{t.normal}"
        if meta["aliases"]:
            item_name = meta["aliases"][0]
        else:
            item_name = meta.get("desc", "-")
        istr = _related_item(meta[resource.Resource.ID_FIELD], item_name,
                             meta["type"], pfx, t, unicode)
        # determine correct connector (whether there is another one down the stack)
        elbow = relbow if (not q or q[-1][0] != depth) else relbow2
        print(f"{indent} {t.blue}{elbow}{rarr}{t.normal}{rstr} {istr}")
        new_rr = []
        for d2, rel2, _ in rr:
            if outgoing:
                is_same = rel2.subject == rel.object
            else:
                is_same = rel2.object == rel.subject
            if d2 == depth + 1 and is_same:
                q.append((d2, rel2, _))
            else:
                new_rr.append((d2, rel2, _))
        rr = new_rr