utils/src/cli.py
2023-03-31 23:55:45 -04:00

142 lines
3.7 KiB
Python

import code
import random
import string
import sys
import uuid
import click
import httpx
from rich import pretty
from rich.status import Status
from rich.traceback import install
from shiv.bootstrap import current_zipfile
import src
from src.helpers import flip_char
from src.art import BANNERS
@click.group(
context_settings=dict(help_option_names=["-h", "--help", "--halp"]),
invoke_without_command=True,
)
@click.pass_context
@click.version_option(version=src.__version__, prog_name="utils")
@click.option(
"--update",
is_flag=True,
help="Check Gitea for a new version and auto-update.",
)
def main(ctx, update):
"""Launch a utility or drop into a command line REPL if no command is given."""
if update:
update_from_gitea()
sys.exit()
elif ctx.invoked_subcommand is None:
banner = random.choice(BANNERS)
pretty.install() # type: ignore
install() # traceback handler
code.interact(banner, None)
sys.exit()
@main.command()
def uuid4():
"""Generate a random UUID4."""
click.echo(uuid.uuid4())
@main.command()
@click.argument("dice")
def roll(dice: str):
"""Roll some dice. Format: utils roll 3d8"""
if "d" not in dice:
click.echo("Missing part of the call. Example: 1d10")
return
if len(dice.split("d")) != 2:
click.echo("Error parsing dice. Example: 2d6")
return
num, sides = dice.split("d")
try:
num = int(num)
sides = int(sides)
except ValueError:
click.echo("Need numbers for the dice. Example: 30d4")
return
if num < 1 or sides < 1:
click.echo("Dude. Example: 2d8")
return
values: list[int] = []
for die in range(num):
values.append(random.randint(1, sides))
if num == 1:
click.echo(f"You rolled a {values[0]}.")
else:
click.echo(f"You rolled: {'+'.join([str(item) for item in values])}")
click.echo(f"Total: {sum(values)}")
@main.command()
@click.argument("words", nargs=-1)
def beautify(words: list[str]):
"""
MAkE YoUr mEsSaGe bEaUtIfUl!!!1!!
WORDS is either a single string surrounded by double quotes or multiple bare words,
e.g. `utils beautify "one two three"` or `utils beautify one two three`.
"""
message = " ".join(words)
new_beautiful_string = []
for num, letter in enumerate(message):
if num % 2:
letter = flip_char(letter)
new_beautiful_string.append(letter)
click.echo("".join(new_beautiful_string))
def update_from_gitea():
"""Get the newest release from Gitea and install it."""
status = Status("Checking for new release...")
status.start()
response = httpx.get(
"https://git.joekaufeld.com/api/v1/repos/jkaufeld/utils/releases/latest"
)
if response.status_code != 200:
status.stop()
click.echo(
f"Something went wrong when talking to Gitea; got a"
f" {response.status_code} with the following content:\n"
f"{response.content}"
)
return
status.update("Checking for new release...")
release_data = response.json()
if release_data["tag_name"] == src.__version__:
status.stop()
click.echo(
"Server version is the same as current version;" " nothing to update."
)
return
status.update("Updating...")
url = release_data["assets"][0]["browser_download_url"]
with current_zipfile() as archive:
with open(archive.filename, "wb") as f, httpx.stream(
"GET", url, follow_redirects=True
) as r:
for line in r.iter_bytes():
f.write(line)
status.stop()
click.echo(f"Updated to {release_data['tag_name']}! 🎉")
if __name__ == "__main__":
main()