toot/toot/cli/base.py

86 wiersze
2.4 KiB
Python

import click
import logging
import os
import sys
from click.testing import Result
from functools import wraps
from toot import App, User, config, __version__
from typing import Callable, Concatenate, NamedTuple, Optional, ParamSpec, TypeVar
PRIVACY_CHOICES = ["public", "unlisted", "private"]
VISIBILITY_CHOICES = ["public", "unlisted", "private", "direct"]
DURATION_EXAMPLES = """e.g. "1 day", "2 hours 30 minutes", "5 minutes 30
seconds" or any combination of above. Shorthand: "1d", "2h30m", "5m30s\""""
# Type alias for run commands
Run = Callable[..., Result]
def get_default_visibility() -> str:
return os.getenv("TOOT_POST_VISIBILITY", "public")
# Tweak the Click context
# https://click.palletsprojects.com/en/8.1.x/api/#context
CONTEXT = dict(
# Enable using environment variables to set options
auto_envvar_prefix="TOOT",
# Add shorthand -h for invoking help
help_option_names=["-h", "--help"],
# Give help some more room (default is 80)
max_content_width=100,
# Always show default values for options
show_default=True,
)
# Data object to add to Click context
class Context(NamedTuple):
app: Optional[App] = None
user: Optional[User] = None
color: bool = False
debug: bool = False
quiet: bool = False
P = ParamSpec("P")
R = TypeVar("R")
T = TypeVar("T")
def pass_context(f: Callable[Concatenate[Context, P], R]) -> Callable[P, R]:
"""Pass `obj` from click context as first argument."""
@wraps(f)
def wrapped(*args: P.args, **kwargs: P.kwargs) -> R:
ctx = click.get_current_context()
return f(ctx.obj, *args, **kwargs)
return wrapped
json_option = click.option(
"--json",
is_flag=True,
default=False,
help="Print data as JSON rather than human readable text"
)
@click.group(context_settings=CONTEXT)
@click.option("--debug/--no-debug", default=False, help="Log debug info to stderr")
@click.option("--color/--no-color", default=sys.stdout.isatty(), help="Use ANSI color in output")
@click.option("--quiet/--no-quiet", default=False, help="Don't print anything to stdout")
@click.version_option(__version__, message="%(prog)s v%(version)s")
@click.pass_context
def cli(ctx, color, debug, quiet, app=None, user=None):
"""Toot is a Mastodon CLI"""
user, app = config.get_active_user_app()
ctx.obj = Context(app, user, color, debug, quiet)
if debug:
logging.basicConfig(level=logging.DEBUG)