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() def objectid(): """Generate a random ObjectID.""" new_id = '' for _ in range(24): new_id += random.choice(string.ascii_lowercase[:6] + string.digits) click.echo(new_id) @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()