Toot-Mastodon-CLI-TUI-clien.../toot/cli/base.py

106 lines
2.8 KiB
Python
Raw Normal View History

2023-11-30 20:12:04 +01:00
import click
2023-11-26 18:00:57 +01:00
import logging
2023-11-30 20:12:04 +01:00
import os
2023-11-26 18:00:57 +01:00
import sys
import typing as t
2023-11-26 18:00:57 +01:00
2023-11-30 20:12:04 +01:00
from click.testing import Result
2023-11-26 18:00:57 +01:00
from functools import wraps
2023-11-28 10:13:20 +01:00
from toot import App, User, config, __version__
2023-12-05 12:00:45 +01:00
from toot.settings import get_settings
if t.TYPE_CHECKING:
import typing_extensions as te
P = te.ParamSpec("P")
R = t.TypeVar("R")
T = t.TypeVar("T")
2023-11-26 18:00:57 +01:00
2023-11-30 20:12:04 +01:00
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 = t.Callable[..., Result]
2023-11-30 20:12:04 +01:00
def get_default_visibility() -> str:
return os.getenv("TOOT_POST_VISIBILITY", "public")
2023-12-05 10:45:38 +01:00
def get_default_map():
2023-12-05 12:00:45 +01:00
settings = get_settings()
2023-12-05 10:45:38 +01:00
common = settings.get("common", {})
commands = settings.get("commands", {})
return {**common, **commands}
2023-11-26 18:00:57 +01:00
# 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,
2023-12-05 10:45:38 +01:00
# Load command defaults from settings
default_map=get_default_map(),
2023-11-26 18:00:57 +01:00
)
# Data object to add to Click context
class Context(t.NamedTuple):
app: t.Optional[App]
user: t.Optional[User] = None
2023-11-26 18:00:57 +01:00
color: bool = False
debug: bool = False
quiet: bool = False
def pass_context(f: "t.Callable[te.Concatenate[Context, P], R]") -> "t.Callable[P, R]":
2023-11-26 18:00:57 +01:00
"""Pass `obj` from click context as first argument."""
@wraps(f)
def wrapped(*args: "P.args", **kwargs: "P.kwargs") -> R:
2023-11-26 18:00:57 +01:00
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")
2023-11-28 10:13:20 +01:00
@click.version_option(__version__, message="%(prog)s v%(version)s")
2023-11-26 18:00:57 +01:00
@click.pass_context
2023-12-05 09:59:40 +01:00
def cli(
ctx: click.Context,
color: bool,
debug: bool,
quiet: bool,
app: t.Optional[App] = None,
user: t.Optional[User] = None,
):
2023-11-26 18:00:57 +01:00
"""Toot is a Mastodon CLI"""
user, app = config.get_active_user_app()
ctx.obj = Context(app, user, color, debug, quiet)
2023-12-05 09:59:40 +01:00
ctx.color = color
2023-11-26 18:00:57 +01:00
if debug:
logging.basicConfig(level=logging.DEBUG)