mirror of
https://github.com/ihabunek/toot
synced 2025-01-10 16:52:40 +01:00
Add support for custom instance domains
The instance domain can be different from their base url, for example the instance at https://social.vivaldi.net uses the vivaldi.net domain, sans 'social'. This commit requires the user to provide the base url of the instance, instead of domain name. The domain is then fetched from the server. fixes #217
This commit is contained in:
parent
9baa0823f9
commit
d5b5c89996
@ -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'
|
||||
|
@ -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()
|
||||
|
42
toot/auth.py
42
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 <blue>{}</blue> running Mastodon version <yellow>{}</yellow>".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 [<green>{}</green>]: ".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 [<green>{DEFAULT_INSTANCE}</green>]: ", 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 <blue>{instance['title']}</blue> "
|
||||
f"running Mastodon version <yellow>{instance['version']}</yellow>"
|
||||
)
|
||||
|
||||
# NB: when updating to v2 instance endpoint, this field has been renamed to `domain`
|
||||
return instance["uri"]
|
||||
|
||||
|
||||
def create_user(app, access_token):
|
||||
|
@ -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."
|
||||
)
|
||||
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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"
|
||||
]))
|
||||
|
Loading…
Reference in New Issue
Block a user