diff --git a/funkwhale_cli/cli.py b/funkwhale_cli/cli.py index 2ea751a7f4fc98015003e90078284744a511d91e..e16db3cd1d54fef1de021753fefba823d17e2bd6 100644 --- a/funkwhale_cli/cli.py +++ b/funkwhale_cli/cli.py @@ -482,6 +482,63 @@ def get_ls_command(group, endpoint, output_conf): return ls +def get_show_command(group, url_template, output_conf, name='show', force_id=None): + + available_fields = sorted( + set(output_conf["labels"]) | set(output.FIELDS["*"].keys()) + ) + if force_id: + def id_decorator(f): + @functools.wraps(f) + def inner(raw, column, format): + return f(raw, force_id, column, format) + return inner + else: + id_decorator = click.argument("id") + + @group.command(name) + @id_decorator + @RAW_DECORATOR + @click.option( + "--format", "-t", type=click.Choice(output.TABLE_FORMATS), default="simple" + ) + @click.option( + "--column", + "-c", + multiple=True, + help="Which column to display. Available: {}. \nDefault: {}".format( + ", ".join(available_fields), ", ".join(output_conf["labels"]) + ), + ) + @click.pass_context + @async_command + async def show( + ctx, + raw, + id, + column, + format, + ): + + async with ctx.obj["remote"]: + async with ctx.obj["remote"].request("get", url_template.format(id)) as result: + result.raise_for_status() + payload = await result.json() + if raw: + click.echo(json.dumps(payload, sort_keys=True, indent=4)) + else: + click.echo( + output.obj_table( + payload, + column or output_conf["labels"], + type=output_conf["type"], + format=format, + ) + ) + + return show + + def get_delete_command( group, url_template, @@ -908,5 +965,35 @@ favorites_tracks_ls = get_ls_command( # noqa ) + +@cli.group() +@click.pass_context +def users(ctx): + pass + + +users_me = get_show_command( + users, + "api/v1/users/users/{}/", + output_conf={ + "labels": [ + "ID", + "Username", + "Name", + "Email", + "Federation ID", + "Joined", + "Visibility", + "Staff", + "Admin", + "Permissions", + ], + "type": "USER", + }, + force_id='me', + name='me', +) + + if __name__ == "__main__": cli() diff --git a/funkwhale_cli/output.py b/funkwhale_cli/output.py index 95f978203ca2722c77876967fbc035497e0d5d0d..a2413b6bbd739a3d116f559923d5a89bd7eca97a 100644 --- a/funkwhale_cli/output.py +++ b/funkwhale_cli/output.py @@ -47,9 +47,25 @@ FIELDS = { "Artist": {"field": "track.artist.name"}, "Favorite Date": {"field": "creation_date"}, }, + "USER": { + "Username": {"field": "username"}, + "Federation ID": {"field": "full_username"}, + "Email": {"field": "email"}, + "Joined": {"field": "date_joined"}, + "Staff": {"field": "is_staff"}, + "Admin": {"field": "is_admin"}, + "Permissions": { + "field": "permissions", + "handler": lambda v: ", ".join([k for k, v in v.items() if v]), + }, + }, "*": { + "Name": {"field": "name"}, + "Visibility": {"field": "privacy_level"}, "Created": {"field": "creation_date"}, + "Modified": {"field": "modification_date"}, "UUID": {"field": "uuid", "truncate": 0}, + "ID": {"field": "id", "truncate": 0}, }, } @@ -116,3 +132,27 @@ def table(objects, fields, type, headers=True, format="simple"): ] return tabulate.tabulate(rows, headers=headers, tablefmt=format) + + +def obj_table(obj, fields, type, headers=True, format="simple"): + """ + same as table(), but output a two-column table for a single object, + with fields on the left and values on the right + """ + configs = {} + + for f in fields: + try: + configs[f] = FIELDS[type][f] + except KeyError: + try: + configs[f] = FIELDS["*"][f] + except KeyError: + raise ValueError("{} is not a valid field for type {}".format(f, type)) + + rows = [ + (f, get_value(obj, configs[f], truncate=configs[f].get("truncate", 30))) + for f in fields + ] + + return tabulate.tabulate(rows, headers=[], tablefmt=format) diff --git a/tests/test_cli.py b/tests/test_cli.py index e94e486343a9bce876fee86c11c81fc0beca238f..a45b5c8a579f4c07b0a9046be0bef824d84fcb5b 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -81,6 +81,40 @@ def test_lazy_credential(mocker): assert get_password.call_count == 1 +def test_users_me(cli_ctx, session, responses, get_requests): + command = cli.users_me + url = "https://test.funkwhale/api/v1/users/users/me/" + responses.get( + url, + payload={ + "id": 1, + "username": "user", + "full_username": "user@funkwhale.user.com", + "name": "", + "email": "contact@user.com", + "is_staff": True, + "is_superuser": True, + "permissions": {"library": True, "moderation": True, "settings": True}, + "date_joined": "2016-04-30T13:36:07.747395Z", + "privacy_level": "instance", + "quota_status": { + "max": 100000, + "remaining": 82102.249366, + "current": 17897.750634, + "skipped": 46.135774, + "pending": 0.0, + "finished": 17851.614859999998, + "errored": 0.0, + }, + }, + ) + + command.callback(raw=False, column=None, format=None) + + requests = get_requests("get", url) + assert len(requests) == 1 + + def test_libraries_create(cli_ctx, session, responses, get_requests): command = cli.libraries_create url = "https://test.funkwhale/api/v1/libraries/"