1
0
mirror of https://github.com/ihabunek/toot synced 2024-12-22 23:08:17 +01:00

Add --json option to lists commands

This commit is contained in:
Ivan Habunek 2023-12-14 14:10:53 +01:00
parent 438a8ab206
commit 1dac093be7
No known key found for this signature in database
GPG Key ID: F5F0623FF5EBCB3D
7 changed files with 142 additions and 35 deletions

View File

@ -19,7 +19,6 @@ noted below please report any issues.
* Enable passing params via environment variables, see:
https://toot.bezdomni.net/environment_variables.html
* Add shell completion, see: https://toot.bezdomni.net/shell_completion.html
* Add `--json` option to tag commands
* Add `tags info`, `tags featured`, `tags feature`, and `tags unfeature`
commands
* Add `tags followed`, `tags follow`, and `tags unfollow` sub-commands,
@ -27,6 +26,8 @@ noted below please report any issues.
* Add `lists accounts`, `lists add`, `lists create`, `lists delete`, `lists
list`, `lists remove` subcommands, deprecate `lists`, `lists_accounts`,
`lists_add`, `lists_create`, `lists_delete`, `lists_remove` commands.
* Add `--json` option to tags commands
* Add `--json` option to lists commands
* Add `toot --width` option for setting your prefered terminal width
* Add `--media-viewer` and `--colors` options to `toot tui`. These were
previously accessible only via settings.

View File

@ -11,10 +11,11 @@
- "BREAKING: Options `--debug`, `--color`, `--quiet` must be specified after `toot` but before the command"
- "Enable passing params via environment variables, see: https://toot.bezdomni.net/environment_variables.html"
- "Add shell completion, see: https://toot.bezdomni.net/shell_completion.html"
- "Add `--json` option to tag commands"
- "Add `tags info`, `tags featured`, `tags feature`, and `tags unfeature` commands"
- "Add `tags followed`, `tags follow`, and `tags unfollow` sub-commands, deprecate `tags_followed`, `tags_follow`, and `tags tags_unfollow`"
- "Add `lists accounts`, `lists add`, `lists create`, `lists delete`, `lists list`, `lists remove` subcommands, deprecate `lists`, `lists_accounts`, `lists_add`, `lists_create`, `lists_delete`, `lists_remove` commands."
- "Add `--json` option to tags commands"
- "Add `--json` option to lists commands"
- "Add `toot --width` option for setting your prefered terminal width"
- "Add `--media-viewer` and `--colors` options to `toot tui`. These were previously accessible only via settings."

View File

@ -19,7 +19,6 @@ noted below please report any issues.
* Enable passing params via environment variables, see:
https://toot.bezdomni.net/environment_variables.html
* Add shell completion, see: https://toot.bezdomni.net/shell_completion.html
* Add `--json` option to tag commands
* Add `tags info`, `tags featured`, `tags feature`, and `tags unfeature`
commands
* Add `tags followed`, `tags follow`, and `tags unfollow` sub-commands,
@ -27,6 +26,8 @@ noted below please report any issues.
* Add `lists accounts`, `lists add`, `lists create`, `lists delete`, `lists
list`, `lists remove` subcommands, deprecate `lists`, `lists_accounts`,
`lists_add`, `lists_create`, `lists_delete`, `lists_remove` commands.
* Add `--json` option to tags commands
* Add `--json` option to lists commands
* Add `toot --width` option for setting your prefered terminal width
* Add `--media-viewer` and `--colors` options to `toot tui`. These were
previously accessible only via settings.

View File

@ -1,3 +1,4 @@
from uuid import uuid4
from toot import cli
from tests.integration.conftest import register_account
@ -9,6 +10,11 @@ def test_lists_empty(run):
assert result.stdout.strip() == "You have no lists defined."
def test_lists_empty_json(run_json):
lists = run_json(cli.lists.list, "--json")
assert lists == []
def test_list_create_delete(run):
result = run(cli.lists.create, "banana")
assert result.exit_code == 0
@ -49,26 +55,62 @@ def test_list_create_delete(run):
assert result.stderr.strip() == "Error: List not found"
def test_list_add_remove(run, app):
acc = register_account(app)
run(cli.lists.create, "foo")
def test_list_create_delete_json(run, run_json):
result = run_json(cli.lists.list, "--json")
assert result == []
result = run(cli.lists.add, "foo", acc.username)
list = run_json(cli.lists.create, "banana", "--json")
assert list["title"] == "banana"
[list] = run_json(cli.lists.list, "--json")
assert list["title"] == "banana"
list = run_json(cli.lists.create, "mango", "--json")
assert list["title"] == "mango"
lists = run_json(cli.lists.list, "--json")
[list1, list2] = sorted(lists, key=lambda l: l["title"])
assert list1["title"] == "banana"
assert list2["title"] == "mango"
result = run_json(cli.lists.delete, "banana", "--json")
assert result == {}
[list] = run_json(cli.lists.list, "--json")
assert list["title"] == "mango"
result = run_json(cli.lists.delete, "mango", "--json")
assert result == {}
result = run_json(cli.lists.list, "--json")
assert result == []
result = run(cli.lists.delete, "mango", "--json")
assert result.exit_code == 1
assert result.stderr.strip() == "Error: List not found"
def test_list_add_remove(run, app):
list_name = str(uuid4())
acc = register_account(app)
run(cli.lists.create, list_name)
result = run(cli.lists.add, list_name, acc.username)
assert result.exit_code == 1
assert result.stderr.strip() == f"Error: You must follow @{acc.username} before adding this account to a list."
run(cli.accounts.follow, acc.username)
result = run(cli.lists.add, "foo", acc.username)
result = run(cli.lists.add, list_name, acc.username)
assert result.exit_code == 0
assert result.stdout.strip() == f'✓ Added account "{acc.username}"'
result = run(cli.lists.accounts, "foo")
result = run(cli.lists.accounts, list_name)
assert result.exit_code == 0
assert acc.username in result.stdout
# Account doesn't exist
result = run(cli.lists.add, "foo", "does_not_exist")
result = run(cli.lists.add, list_name, "does_not_exist")
assert result.exit_code == 1
assert result.stderr.strip() == "Error: Account not found"
@ -77,10 +119,44 @@ def test_list_add_remove(run, app):
assert result.exit_code == 1
assert result.stderr.strip() == "Error: List not found"
result = run(cli.lists.remove, "foo", acc.username)
result = run(cli.lists.remove, list_name, acc.username)
assert result.exit_code == 0
assert result.stdout.strip() == f'✓ Removed account "{acc.username}"'
result = run(cli.lists.accounts, "foo")
result = run(cli.lists.accounts, list_name)
assert result.exit_code == 0
assert result.stdout.strip() == "This list has no accounts."
def test_list_add_remove_json(run, run_json, app):
list_name = str(uuid4())
acc = register_account(app)
run(cli.lists.create, list_name)
result = run(cli.lists.add, list_name, acc.username, "--json")
assert result.exit_code == 1
assert result.stderr.strip() == f"Error: You must follow @{acc.username} before adding this account to a list."
run(cli.accounts.follow, acc.username)
result = run_json(cli.lists.add, list_name, acc.username, "--json")
assert result == {}
[account] = run_json(cli.lists.accounts, list_name, "--json")
assert account["username"] == acc.username
# Account doesn't exist
result = run(cli.lists.add, list_name, "does_not_exist", "--json")
assert result.exit_code == 1
assert result.stderr.strip() == "Error: Account not found"
# List doesn't exist
result = run(cli.lists.add, "does_not_exist", acc.username, "--json")
assert result.exit_code == 1
assert result.stderr.strip() == "Error: List not found"
result = run_json(cli.lists.remove, list_name, acc.username, "--json")
assert result == {}
result = run_json(cli.lists.accounts, list_name, "--json")
assert result == []

View File

@ -30,7 +30,7 @@ def friend_user(app, user):
@pytest.fixture(scope="module")
def friend_list(app, user, friend_user):
friend_account = api.find_account(app, user, friend_user.username)
list = api.create_list(app, user, str(uuid4()))
list = api.create_list(app, user, str(uuid4())).json()
api.add_accounts_to_list(app, user, list["id"], account_ids=[friend_account["id"]])
return list

View File

@ -639,7 +639,7 @@ def create_list(app, user, title, replies_policy="none"):
json = {'title': title}
if replies_policy:
json['replies_policy'] = replies_policy
return http.post(app, user, url, json=json).json()
return http.post(app, user, url, json=json)
def delete_list(app, user, id):
@ -649,7 +649,7 @@ def delete_list(app, user, id):
def add_accounts_to_list(app, user, list_id, account_ids):
url = f"/api/v1/lists/{list_id}/accounts"
json = {'account_ids': account_ids}
return http.post(app, user, url, json=json).json()
return http.post(app, user, url, json=json)
def remove_accounts_from_list(app, user, list_id, account_ids):

View File

@ -1,7 +1,8 @@
import click
import json as pyjson
from toot import api, config
from toot.cli import Context, cli, pass_context
from toot.cli import Context, cli, pass_context, json_option
from toot.output import print_list_accounts, print_lists, print_warning
@ -24,26 +25,35 @@ def lists(ctx: click.Context):
@lists.command()
@json_option
@pass_context
def list(ctx: Context):
def list(ctx: Context, json: bool):
"""List all your lists"""
lists = api.get_lists(ctx.app, ctx.user)
if lists:
print_lists(lists)
if json:
click.echo(pyjson.dumps(lists))
else:
click.echo("You have no lists defined.")
if lists:
print_lists(lists)
else:
click.echo("You have no lists defined.")
@lists.command()
@click.argument("title", required=False)
@click.option("--id", help="List ID if not title is given")
@json_option
@pass_context
def accounts(ctx: Context, title: str, id: str):
def accounts(ctx: Context, title: str, id: str, json: bool):
"""List the accounts in a list"""
list_id = _get_list_id(ctx, title, id)
response = api.get_list_accounts(ctx.app, ctx.user, list_id)
print_list_accounts(response)
if json:
click.echo(pyjson.dumps(response))
else:
print_list_accounts(response)
@lists.command()
@ -54,36 +64,49 @@ def accounts(ctx: Context, title: str, id: str):
default="none",
help="Replies policy"
)
@json_option
@pass_context
def create(ctx: Context, title: str, replies_policy: str):
def create(ctx: Context, title: str, replies_policy: str, json: bool):
"""Create a list"""
api.create_list(ctx.app, ctx.user, title=title, replies_policy=replies_policy)
click.secho(f"✓ List \"{title}\" created.", fg="green")
response = api.create_list(ctx.app, ctx.user, title=title, replies_policy=replies_policy)
if json:
print(response.text)
else:
click.secho(f"✓ List \"{title}\" created.", fg="green")
@lists.command()
@click.argument("title", required=False)
@click.option("--id", help="List ID if not title is given")
@json_option
@pass_context
def delete(ctx: Context, title: str, id: str):
def delete(ctx: Context, title: str, id: str, json: bool):
"""Delete a list"""
list_id = _get_list_id(ctx, title, id)
api.delete_list(ctx.app, ctx.user, list_id)
click.secho(f"✓ List \"{title if title else id}\" deleted.", fg="green")
response = api.delete_list(ctx.app, ctx.user, list_id)
if json:
click.echo(response.text)
else:
click.secho(f"✓ List \"{title if title else id}\" deleted.", fg="green")
@lists.command()
@click.argument("title", required=False)
@click.argument("account")
@click.option("--id", help="List ID if not title is given")
@json_option
@pass_context
def add(ctx: Context, title: str, account: str, id: str):
def add(ctx: Context, title: str, account: str, id: str, json: bool):
"""Add an account to a list"""
list_id = _get_list_id(ctx, title, id)
found_account = api.find_account(ctx.app, ctx.user, account)
try:
api.add_accounts_to_list(ctx.app, ctx.user, list_id, [found_account["id"]])
response = api.add_accounts_to_list(ctx.app, ctx.user, list_id, [found_account["id"]])
if json:
click.echo(response.text)
else:
click.secho(f"✓ Added account \"{account}\"", fg="green")
except Exception:
# TODO: this is slow, improve
# if we failed to add the account, try to give a
@ -99,20 +122,25 @@ def add(ctx: Context, title: str, account: str, id: str):
raise click.ClickException(f"You must follow @{account} before adding this account to a list.")
raise
click.secho(f"✓ Added account \"{account}\"", fg="green")
@lists.command()
@click.argument("title", required=False)
@click.argument("account")
@click.option("--id", help="List ID if not title is given")
@json_option
@pass_context
def remove(ctx: Context, title: str, account: str, id: str):
def remove(ctx: Context, title: str, account: str, id: str, json: bool):
"""Remove an account from a list"""
list_id = _get_list_id(ctx, title, id)
found_account = api.find_account(ctx.app, ctx.user, account)
api.remove_accounts_from_list(ctx.app, ctx.user, list_id, [found_account["id"]])
click.secho(f"✓ Removed account \"{account}\"", fg="green")
response = api.remove_accounts_from_list(ctx.app, ctx.user, list_id, [found_account["id"]])
if json:
click.echo(response.text)
else:
click.secho(f"✓ Removed account \"{account}\"", fg="green")
# -- Deprecated commands -------------------------------------------------------
@cli.command(name="list_accounts", hidden=True)