From 67b52757a4a22ebd488d3949f400b9bbeb28b3af Mon Sep 17 00:00:00 2001 From: Daniel Schwarz Date: Tue, 20 Dec 2022 12:55:32 -0500 Subject: [PATCH] Command line support for following hashtags (Mastodon 4+) --- toot/api.py | 31 +++++++++++++++++++++++++------ toot/commands.py | 20 +++++++++++++++++++- toot/console.py | 28 +++++++++++++++++++++++++++- toot/output.py | 5 +++++ 4 files changed, 76 insertions(+), 8 deletions(-) diff --git a/toot/api.py b/toot/api.py index 2d84ceb..9e34c83 100644 --- a/toot/api.py +++ b/toot/api.py @@ -24,6 +24,12 @@ def _status_action(app, user, status_id, action, data=None): return http.post(app, user, url, data=data).json() +def _tag_action(app, user, tag_name, action): + url = '/api/v1/tags/{}/{}'.format(tag_name, action) + + return http.post(app, user, url).json() + + def create_app(domain, scheme='https'): url = '{}://{}/api/v1/apps'.format(scheme, domain) @@ -318,23 +324,36 @@ def unfollow(app, user, account): return _account_action(app, user, account, 'unfollow') -def _get_account_list(app, user, path): - accounts = [] +def follow_tag(app, user, tag_name): + return _tag_action(app, user, tag_name, 'follow') + + +def unfollow_tag(app, user, tag_name): + return _tag_action(app, user, tag_name, 'unfollow') + + +def _get_response_list(app, user, path): + items = [] while path: response = http.get(app, user, path) - accounts += response.json() + items += response.json() path = _get_next_path(response.headers) - return accounts + return items def following(app, user, account): path = '/api/v1/accounts/{}/{}'.format(account, 'following') - return _get_account_list(app, user, path) + return _get_response_list(app, user, path) def followers(app, user, account): path = '/api/v1/accounts/{}/{}'.format(account, 'followers') - return _get_account_list(app, user, path) + return _get_response_list(app, user, path) + + +def followed_tags(app, user): + path = '/api/v1/followed_tags' + return _get_response_list(app, user, path) def mute(app, user, account): diff --git a/toot/commands.py b/toot/commands.py index daa155f..b9819dd 100644 --- a/toot/commands.py +++ b/toot/commands.py @@ -8,7 +8,8 @@ from toot import api, config, __version__ from toot.auth import login_interactive, login_browser_interactive, create_app_interactive from toot.exceptions import ApiError, ConsoleError from toot.output import (print_out, print_instance, print_account, print_acct_list, - print_search_results, print_timeline, print_notifications) + print_search_results, print_timeline, print_notifications, + print_tag_list) from toot.tui.utils import parse_datetime from toot.utils import editor_input, multiline_input, EOF_KEY @@ -323,6 +324,23 @@ def followers(app, user, args): print_acct_list(response) +def follow_tag(app, user, args): + tn = args.tag_name if not args.tag_name.startswith("#") else args.tag_name[1:] + api.follow_tag(app, user, tn) + print_out("✓ You are now following #{}".format(tn)) + + +def unfollow_tag(app, user, args): + tn = args.tag_name if not args.tag_name.startswith("#") else args.tag_name[1:] + api.unfollow_tag(app, user, tn) + print_out("✓ You are no longer following #{}".format(tn)) + + +def followed_tags(app, user, args): + response = api.followed_tags(app, user) + print_tag_list(response) + + def mute(app, user, args): account = _find_account(app, user, args.account) api.mute(app, user, account['id']) diff --git a/toot/console.py b/toot/console.py index b11eaee..49df221 100644 --- a/toot/console.py +++ b/toot/console.py @@ -161,6 +161,10 @@ visibility_arg = (["-v", "--visibility"], { "the TOOT_POST_VISIBILITY environment variable", }) +tag_arg = (["tag_name"], { + "type": str, + "help": "tag name, e.g. Caturday, or \"#Caturday\"", +}) # Arguments for selecting a timeline (see `toot.commands.get_timeline_generator`) common_timeline_args = [ @@ -552,7 +556,28 @@ ACCOUNTS_COMMANDS = [ ), ] -COMMANDS = AUTH_COMMANDS + READ_COMMANDS + TUI_COMMANDS + POST_COMMANDS + STATUS_COMMANDS + ACCOUNTS_COMMANDS +TAG_COMMANDS = [ + Command( + name="follow_tag", + description="Follow a hashtag", + arguments=[tag_arg], + require_auth=True, + ), + Command( + name="unfollow_tag", + description="Unfollow a hashtag", + arguments=[tag_arg], + require_auth=True, + ), + Command( + name="followed_tags", + description="List hashtags you follow", + arguments=[], + require_auth=True, + ), +] + +COMMANDS = AUTH_COMMANDS + READ_COMMANDS + TUI_COMMANDS + POST_COMMANDS + STATUS_COMMANDS + ACCOUNTS_COMMANDS + TAG_COMMANDS def print_usage(): @@ -565,6 +590,7 @@ def print_usage(): ("Post", POST_COMMANDS), ("Status", STATUS_COMMANDS), ("Accounts", ACCOUNTS_COMMANDS), + ("Hashtags", TAG_COMMANDS), ] print_out("{}".format(CLIENT_NAME)) diff --git a/toot/output.py b/toot/output.py index 4927e58..bacda1a 100644 --- a/toot/output.py +++ b/toot/output.py @@ -198,6 +198,11 @@ def print_acct_list(accounts): print_out(f"* @{account['acct']} {account['display_name']}") +def print_tag_list(tags): + for tag in tags: + print_out(f"* #{tag['name']}\t {tag['url']}") + + def print_search_results(results): accounts = results['accounts'] hashtags = results['hashtags']