Add instance command

This commit is contained in:
Ivan Habunek 2017-12-29 14:26:40 +01:00
parent 5c0a797b66
commit dfdad045f0
No known key found for this signature in database
GPG Key ID: CDBD63C43A30BB95
6 changed files with 82 additions and 5 deletions

View File

@ -3,9 +3,10 @@ Changelog
**0.16.0 (TBA)** **0.16.0 (TBA)**
* **Dropped support for Python 2** because it's a pain to support and was * **Drop support for Python 2** because it's a pain to support and caused bugs
causing bugs with handling unicode. with handling unicode.
* Remove hacky `login_2fa` command, use `login_browser` instead * Remove hacky `login_2fa` command, use `login_browser` instead
* Add `instance` command
**0.15.1 (2017-12-12)** **0.15.1 (2017-12-12)**

View File

@ -4,10 +4,11 @@ import logging
import re import re
import requests import requests
from urllib.parse import urlparse, urlencode
from requests import Request, Session from requests import Request, Session
from urllib.parse import urlparse, urlencode
from toot import CLIENT_NAME, CLIENT_WEBSITE from toot import CLIENT_NAME, CLIENT_WEBSITE
from toot.utils import domain_exists
SCOPES = 'read write follow' SCOPES = 'read write follow'
@ -28,7 +29,9 @@ class AuthenticationError(ApiError):
def _log_request(request): def _log_request(request):
logger.debug(">>> \033[32m{} {}\033[0m".format(request.method, request.url)) logger.debug(">>> \033[32m{} {}\033[0m".format(request.method, request.url))
logger.debug(">>> HEADERS: \033[33m{}\033[0m".format(request.headers))
if request.headers:
logger.debug(">>> HEADERS: \033[33m{}\033[0m".format(request.headers))
if request.data: if request.data:
logger.debug(">>> DATA: \033[33m{}\033[0m".format(request.data)) logger.debug(">>> DATA: \033[33m{}\033[0m".format(request.data))
@ -83,6 +86,14 @@ def _get(app, user, url, params=None):
return _process_response(response) return _process_response(response)
def _unauthorized_get(url, params=None):
_log_request(Request('GET', url, None, params=params))
response = requests.get(url, params)
return _process_response(response)
def _post(app, user, url, data=None, files=None): def _post(app, user, url, data=None, files=None):
url = app.base_url + url url = app.base_url + url
headers = {"Authorization": "Bearer " + user.access_token} headers = {"Authorization": "Bearer " + user.access_token}
@ -239,3 +250,18 @@ def verify_credentials(app, user):
def get_notifications(app, user): def get_notifications(app, user):
return _get(app, user, '/api/v1/notifications').json() return _get(app, user, '/api/v1/notifications').json()
def get_instance(app, user, domain):
if not domain_exists(domain):
raise ApiError("Domain {} not found".format(domain))
url = "http://{}/api/v1/instance".format(domain)
try:
return _unauthorized_get(url).json()
except NotFoundError:
raise ApiError(
"Instance info not found at {}.\n"
"The given domain probably does not host a Mastodon instance.".format(url)
)

View File

@ -11,7 +11,7 @@ from itertools import chain
from textwrap import TextWrapper, wrap from textwrap import TextWrapper, wrap
from toot import api, config, DEFAULT_INSTANCE, User, App, ConsoleError from toot import api, config, DEFAULT_INSTANCE, User, App, ConsoleError
from toot.output import print_out from toot.output import print_out, print_instance
def register_app(instance): def register_app(instance):
@ -329,3 +329,12 @@ def whoami(app, user, args):
def whois(app, user, args): def whois(app, user, args):
account = _find_account(app, user, args.account) account = _find_account(app, user, args.account)
_print_account(account) _print_account(account)
def instance(app, user, args):
name = args.instance or (app and app.instance)
if not name:
raise ConsoleError("Please specify instance name.")
instance = api.get_instance(app, user, name)
print_instance(instance)

View File

@ -95,6 +95,18 @@ READ_COMMANDS = [
], ],
require_auth=True, require_auth=True,
), ),
Command(
name="instance",
description="Display instance details",
arguments=[
(["instance"], {
"help": "instance domain (e.g. 'mastodon.social') or blank to use current",
"nargs": "?",
}),
],
require_auth=False,
),
Command( Command(
name="search", name="search",
description="Search for users or hashtags", description="Search for users or hashtags",

View File

@ -3,6 +3,9 @@
import sys import sys
import re import re
from textwrap import wrap
from toot.utils import format_content
START_CODES = { START_CODES = {
'red': '\033[31m', 'red': '\033[31m',
'green': '\033[32m', 'green': '\033[32m',
@ -50,3 +53,20 @@ def print_err(*args, **kwargs):
args = ["<red>{}</red>".format(a) for a in args] args = ["<red>{}</red>".format(a) for a in args]
args = [colorize(a) if USE_ANSI_COLOR else strip_tags(a) for a in args] args = [colorize(a) if USE_ANSI_COLOR else strip_tags(a) for a in args]
print(*args, file=sys.stderr, **kwargs) print(*args, file=sys.stderr, **kwargs)
def print_instance(instance):
print_out("<green>{}</green>".format(instance['title']))
print_out("<blue>{}</blue>".format(instance['uri']))
print_out("running Mastodon {}".format(instance['version']))
print_out("")
description = instance['description'].strip()
if not description:
return
lines = [line.strip() for line in format_content(description) if line.strip()]
for line in lines:
for l in wrap(line.strip()):
print(l)
print()

View File

@ -1,6 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import re import re
import socket
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
@ -41,3 +42,11 @@ def format_content(content):
yield line yield line
first = False first = False
def domain_exists(name):
try:
socket.gethostbyname(name)
return True
except OSError:
return False