utils/src/cli.py

134 lines
3.8 KiB
Python
Raw Normal View History

2022-07-22 15:24:11 -04:00
import code
2022-07-28 13:28:23 -04:00
import random
import string
2022-07-22 15:24:11 -04:00
import sys
2022-07-28 13:28:23 -04:00
import uuid
import click
import httpx
2022-08-11 16:14:04 -04:00
from rich import pretty
from rich import print as rprint
2022-07-29 11:43:40 -04:00
from shiv.bootstrap import current_zipfile
2022-07-22 15:24:11 -04:00
2022-07-23 14:48:28 -04:00
import src
2022-07-28 13:28:23 -04:00
from src.helpers import flip_char
from src.art import BANNERS
2022-07-23 14:48:28 -04:00
2022-07-22 15:24:11 -04:00
2022-07-28 13:28:23 -04:00
@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")
def main(ctx):
"""Launch a utility or drop into a command line REPL if no command is given."""
2022-07-28 13:28:23 -04:00
if ctx.invoked_subcommand is None:
2022-08-11 16:14:04 -04:00
def print_wrapper(*args, **kwargs):
# I know this is dumb.
# https://github.com/Textualize/rich/discussions/2462
if "crop" in kwargs:
del kwargs["crop"]
rprint(*args, **kwargs)
2022-07-28 13:28:23 -04:00
banner = random.choice(BANNERS)
2022-08-11 16:14:04 -04:00
# source of code.interact, just expanded to fit Rich in there
console = code.InteractiveConsole(globals())
console.print = print_wrapper
pretty.install(console) # type: ignore
try:
import readline
except ImportError:
pass
console.interact(banner, None)
2022-07-28 13:28:23 -04:00
sys.exit()
2022-07-28 13:28:23 -04:00
@main.command()
def uuid4():
"""Generate a random UUID4."""
click.echo(uuid.uuid4())
@main.command()
2022-07-29 14:29:14 -04:00
@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)}")
2022-07-28 13:28:23 -04:00
@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 letter in string.ascii_letters:
if num % 2:
2022-07-29 14:29:14 -04:00
letter = flip_char(letter)
new_beautiful_string.append(letter)
2022-07-28 13:28:23 -04:00
click.echo("".join(new_beautiful_string))
@main.command()
def update():
"""Get the newest release from GitHub and install it."""
2022-07-29 11:43:40 -04:00
response = httpx.get(
2022-07-28 13:28:23 -04:00
"https://api.github.com/repos/itsthejoker/utils/releases/latest"
2022-07-23 14:48:28 -04:00
)
2022-07-29 11:43:40 -04:00
if response.status_code != 200:
2022-07-29 14:29:14 -04:00
click.echo(
f"Something went wrong when talking to GitHub; got a"
2022-07-29 11:43:40 -04:00
f" {response.status_code} with the following content:\n"
f"{response.content}"
2022-07-28 13:28:23 -04:00
)
return
2022-07-29 11:43:40 -04:00
release_data = response.json()
if release_data["name"] == src.__version__:
2022-07-29 14:29:14 -04:00
click.echo("Server version is the same as current version; nothing to update.")
2022-07-28 13:28:23 -04:00
return
2022-07-22 15:24:11 -04:00
2022-07-29 11:43:40 -04:00
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)
2022-07-29 14:29:14 -04:00
click.echo(f"Updated to {release_data['name']}! 🎉")
2022-07-28 13:28:23 -04:00
if __name__ == "__main__":
main()