diff --git a/toot/__init__.py b/toot/__init__.py index 05e15ac..b3f3d1a 100644 --- a/toot/__init__.py +++ b/toot/__init__.py @@ -5,7 +5,7 @@ __version__ = '0.35.0' App = namedtuple('App', ['instance', 'base_url', 'client_id', 'client_secret']) User = namedtuple('User', ['instance', 'username', 'access_token']) -DEFAULT_INSTANCE = 'mastodon.social' +DEFAULT_INSTANCE = 'https://mastodon.social' CLIENT_NAME = 'toot - a Mastodon CLI client' CLIENT_WEBSITE = 'https://github.com/ihabunek/toot' diff --git a/toot/api.py b/toot/api.py index 3bb2c89..672849b 100644 --- a/toot/api.py +++ b/toot/api.py @@ -28,8 +28,8 @@ def _tag_action(app, user, tag_name, action): return http.post(app, user, url).json() -def create_app(domain, scheme='https'): - url = f"{scheme}://{domain}/api/v1/apps" +def create_app(base_url): + url = f"{base_url}/api/v1/apps" json = { 'client_name': CLIENT_NAME, @@ -504,6 +504,6 @@ def clear_notifications(app, user): http.post(app, user, '/api/v1/notifications/clear') -def get_instance(domain, scheme="https"): - url = f"{scheme}://{domain}/api/v1/instance" +def get_instance(base_url): + url = f"{base_url}/api/v1/instance" return http.anon_get(url).json() diff --git a/toot/auth.py b/toot/auth.py index 05b61b6..0ee2bac 100644 --- a/toot/auth.py +++ b/toot/auth.py @@ -9,21 +9,13 @@ from toot.exceptions import ApiError, ConsoleError from toot.output import print_out -def register_app(domain, scheme='https'): - print_out("Looking up instance info...") - instance = api.get_instance(domain, scheme) - - print_out("Found instance {} running Mastodon version {}".format( - instance['title'], instance['version'])) - +def register_app(domain, base_url): try: print_out("Registering application...") - response = api.create_app(domain, scheme) + response = api.create_app(base_url) except ApiError: raise ConsoleError("Registration failed.") - base_url = scheme + '://' + domain - app = App(domain, base_url, response['client_id'], response['client_secret']) config.save_app(app) @@ -32,14 +24,30 @@ def register_app(domain, scheme='https'): return app -def create_app_interactive(instance=None, scheme='https'): - if not instance: - print_out("Choose an instance [{}]: ".format(DEFAULT_INSTANCE), end="") - instance = input() - if not instance: - instance = DEFAULT_INSTANCE +def create_app_interactive(base_url): + if not base_url: + print_out(f"Enter instance URL [{DEFAULT_INSTANCE}]: ", end="") + base_url = input() + if not base_url: + base_url = DEFAULT_INSTANCE - return config.load_app(instance) or register_app(instance, scheme) + domain = get_instance_domain(base_url) + + return config.load_app(domain) or register_app(domain, base_url) + + +def get_instance_domain(base_url): + print_out("Looking up instance info...") + + instance = api.get_instance(base_url) + + print_out( + f"Found instance {instance['title']} " + f"running Mastodon version {instance['version']}" + ) + + # NB: when updating to v2 instance endpoint, this field has been renamed to `domain` + return instance["uri"] def create_user(app, access_token): diff --git a/toot/commands.py b/toot/commands.py index e21f5b3..18e7be6 100644 --- a/toot/commands.py +++ b/toot/commands.py @@ -10,7 +10,7 @@ from toot.output import (print_out, print_instance, print_account, print_acct_li print_search_results, print_timeline, print_notifications, print_tag_list) from toot.tui.utils import parse_datetime -from toot.utils import delete_tmp_status_file, editor_input, multiline_input, EOF_KEY +from toot.utils import args_get_instance, delete_tmp_status_file, editor_input, multiline_input, EOF_KEY def get_timeline_generator(app, user, args): @@ -305,7 +305,8 @@ def update_account(app, user, args): def login_cli(app, user, args): - app = create_app_interactive(instance=args.instance, scheme=args.scheme) + base_url = args_get_instance(args.instance, args.scheme) + app = create_app_interactive(base_url) login_interactive(app, args.email) print_out() @@ -313,7 +314,8 @@ def login_cli(app, user, args): def login(app, user, args): - app = create_app_interactive(instance=args.instance, scheme=args.scheme) + base_url = args_get_instance(args.instance, args.scheme) + app = create_app_interactive(base_url) login_browser_interactive(app) print_out() @@ -452,17 +454,19 @@ def whois(app, user, args): def instance(app, user, args): - name = args.instance or (app and app.instance) - if not name: - raise ConsoleError("Please specify instance name.") + default = app.base_url if app else None + base_url = args_get_instance(args.instance, args.scheme, default) + + if not base_url: + raise ConsoleError("Please specify an instance.") try: - instance = api.get_instance(name, args.scheme) + instance = api.get_instance(base_url) print_instance(instance) except ApiError: raise ConsoleError( - "Instance not found at {}.\n" - "The given domain probably does not host a Mastodon instance.".format(name) + f"Instance not found at {base_url}.\n" + "The given domain probably does not host a Mastodon instance." ) diff --git a/toot/tui/app.py b/toot/tui/app.py index b1d885a..330035b 100644 --- a/toot/tui/app.py +++ b/toot/tui/app.py @@ -336,7 +336,7 @@ class TUI(urwid.Frame): See: https://github.com/mastodon/mastodon/issues/19328 """ def _load_instance(): - return api.get_instance(self.app.instance) + return api.get_instance(self.app.base_url) def _done(instance): if "max_toot_chars" in instance: diff --git a/toot/utils/__init__.py b/toot/utils/__init__.py index 8a39fd2..e8103ac 100644 --- a/toot/utils/__init__.py +++ b/toot/utils/__init__.py @@ -160,3 +160,29 @@ def _use_existing_tmp_file(tmp_path) -> bool: def drop_empty_values(data: Dict) -> Dict: """Remove keys whose values are null""" return {k: v for k, v in data.items() if v is not None} + + +def args_get_instance(instance, scheme, default=None): + if not instance: + return default + + if scheme == "http": + _warn_scheme_deprecated() + + if instance.startswith("http"): + return instance.rstrip("/") + else: + return f"{scheme}://{instance}" + + +def _warn_scheme_deprecated(): + from toot.output import print_err + + print_err("\n".join([ + "--disable-https flag is deprecated and will be removed.", + "Please specify the instance as URL instead.", + "e.g. instead of writing:", + " toot instance unsafehost.com --disable-https", + "instead write:", + " toot instance http://unsafehost.com\n" + ]))