From 485e65a6c6d070815937842aec718b419b72f652 Mon Sep 17 00:00:00 2001 From: Joe Kaufeld Date: Thu, 28 Jul 2022 13:28:23 -0400 Subject: [PATCH] convert to click --- poetry.lock | 33 ++++++------ pyproject.toml | 1 + src/art.py | 30 +++++++++++ src/cli.py | 111 ++++++++++++++++++++++++++------------- src/commands/__init__.py | 0 src/commands/beautify.py | 22 -------- src/commands/update.py | 26 --------- src/commands/uuid4.py | 6 --- src/helpers.py | 8 +++ 9 files changed, 132 insertions(+), 105 deletions(-) create mode 100644 src/art.py delete mode 100644 src/commands/__init__.py delete mode 100644 src/commands/beautify.py delete mode 100644 src/commands/update.py delete mode 100644 src/commands/uuid4.py create mode 100644 src/helpers.py diff --git a/poetry.lock b/poetry.lock index 7cc7626..7af1e9b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -207,10 +207,10 @@ six = ">=1.9" webencodings = "*" [package.extras] -lxml = ["lxml"] -genshi = ["genshi"] +all = ["genshi", "chardet (>=2.2)", "lxml"] chardet = ["chardet (>=2.2)"] -all = ["lxml", "chardet (>=2.2)", "genshi"] +genshi = ["genshi"] +lxml = ["lxml"] [[package]] name = "httpcore" @@ -597,17 +597,14 @@ python-versions = "*" [metadata] lock-version = "1.1" python-versions = "^3.10" -content-hash = "6f1802f15f85c08e926dc13db45802e5c7bc863ab623d44a1c3b4b2dab1af7b1" +content-hash = "ccfdeb63811daaa93297ab75bfd661b68b7f04683c8310f0d60783ec56a577cc" [metadata.files] anyio = [] black = [] cachecontrol = [] cachy = [] -certifi = [ - {file = "certifi-2022.6.15-py3-none-any.whl", hash = "sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412"}, - {file = "certifi-2022.6.15.tar.gz", hash = "sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d"}, -] +certifi = [] cffi = [] charset-normalizer = [] cleo = [] @@ -616,16 +613,19 @@ click = [ {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, ] clikit = [] -colorama = [ - {file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"}, - {file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"}, -] +colorama = [] crashtest = [] cryptography = [] distlib = [] filelock = [] -h11 = [] -html5lib = [] +h11 = [ + {file = "h11-0.12.0-py3-none-any.whl", hash = "sha256:36a3cb8c0a032f56e2da7084577878a035d3b61d104230d4bd49c0c6b555a9c6"}, + {file = "h11-0.12.0.tar.gz", hash = "sha256:47222cb6067e4a307d535814917cd98fd0a57b6788ce715755fa2b6c28b56042"}, +] +html5lib = [ + {file = "html5lib-1.1-py2.py3-none-any.whl", hash = "sha256:0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d"}, + {file = "html5lib-1.1.tar.gz", hash = "sha256:b2e5b40261e20f354d198eae92afc10d750afb487ed5e50f9c4eaf07c184146f"}, +] httpcore = [] httpx = [] idna = [ @@ -689,4 +689,7 @@ tomli = [ tomlkit = [] urllib3 = [] virtualenv = [] -webencodings = [] +webencodings = [ + {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, + {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, +] diff --git a/pyproject.toml b/pyproject.toml index 5d07957..d84d744 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,6 +8,7 @@ authors = ["Joe Kaufeld "] python = "^3.10" shiv = "^1.0.1" httpx = "^0.23.0" +click = "^8.1.3" [tool.poetry.dev-dependencies] poetry = "^1.1.14" diff --git a/src/art.py b/src/art.py new file mode 100644 index 0000000..c8ce7fd --- /dev/null +++ b/src/art.py @@ -0,0 +1,30 @@ +_BANNER1 = r""" + . o8o oooo o8o . o8o + .o8 `"' `888 `"' .o8 `"' + oooo oooo .o888oo oooo 888 oooo .o888oo oooo .ooooo. .oooo.o + `888 `888 888 `888 888 `888 888 `888 d88' `88b d88( "8 + 888 888 888 888 888 888 888 888 888ooo888 `"Y88b. + 888 888 888 . 888 888 888 888 . 888 888 .o o. )88b + `V88V"V8P' "888" o888o o888o o888o "888" o888o `Y8bod8P' 8""888P' +""" + +_BANNER2 = r""" + __ .__.__ .__ __ .__ + __ ___/ |_|__| | |__|/ |_|__| ____ ______ +| | \ __\ | | | \ __\ |/ __ \ / ___/ +| | /| | | | |_| || | | \ ___/ \___ \ +|____/ |__| |__|____/__||__| |__|\___ >____ > + \/ \/ +""" + +_BANNER3 = r""" + __ __ _______ ___ ___ ___ _______ ___ _______ _______ +| | | || || | | | | | | || | | || | +| | | ||_ _|| | | | | | |_ _|| | | ___|| _____| +| |_| | | | | | | | | | | | | | | |___ | |_____ +| | | | | | | |___ | | | | | | | ___||_____ | +| | | | | | | || | | | | | | |___ _____| | +|_______| |___| |___| |_______||___| |___| |___| |_______||_______| +""" + +BANNERS: list[str] = [_BANNER1, _BANNER2, _BANNER3] diff --git a/src/cli.py b/src/cli.py index d6b26a1..d9396df 100644 --- a/src/cli.py +++ b/src/cli.py @@ -1,43 +1,82 @@ import code -import argparse -import importlib +import random +import string import sys +import uuid + +import click +import httpx import src - -BANNER = """ - . o8o oooo o8o . o8o - .o8 `"' `888 `"' .o8 `"' -oooo oooo .o888oo oooo 888 oooo .o888oo oooo .ooooo. .oooo.o -`888 `888 888 `888 888 `888 888 `888 d88' `88b d88( "8 - 888 888 888 888 888 888 888 888 888ooo888 `"Y88b. - 888 888 888 . 888 888 888 888 . 888 888 .o o. )88b - `V88V"V8P' "888" o888o o888o o888o "888" o888o `Y8bod8P' 8""888P' -""" +from src.helpers import flip_char +from src.art import BANNERS -def main(): - parser = argparse.ArgumentParser( - description="Run a specific script by name. If no name is provided, start a REPL." - ) - parser.add_argument( - "user_input", - type=str, - nargs="*", - help="The name of the script that you want to run plus any arguments for that script.", - ) - parser.add_argument( - "--version", action="store_true", help="Print out the version string." - ) - - args = parser.parse_args() - user_input = args.user_input - if args.version is True: - print(src.__version__) +@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): + if ctx.invoked_subcommand is None: + banner = random.choice(BANNERS) + code.interact(banner=banner, local=locals()) sys.exit() - if len(user_input) == 0: - code.interact(banner=BANNER, local=locals()) - else: - command_name = user_input.pop(0) - module = importlib.import_module(f"src.commands.{command_name}") - sys.exit(module.main(user_input)) + + +@main.command() +def uuid4(): + """Generate a random UUID4.""" + click.echo(uuid.uuid4()) + + +@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: + new_beautiful_string.append(flip_char(letter)) + continue + new_beautiful_string.append(letter) + + click.echo("".join(new_beautiful_string)) + + +@main.command() +def update(): + """Get the newest release from GitHub and install it.""" + release_data = httpx.get( + "https://api.github.com/repos/itsthejoker/utils/releases/latest" + ) + if release_data.status_code != 200: + print( + f"Something went wrong when talking to github; got a" + f" {release_data.status_code} with the following content:\n" + f"{release_data.content}" + ) + return + json_data = release_data.json() + if json_data["name"] == src.__version__: + print("Server version is the same as current version; nothing to update.") + return + + url = json_data["assets"][0]["browser_download_url"] + with open("utils", "wb") as f, httpx.stream("GET", url, follow_redirects=True) as r: + for line in r.iter_bytes(): + f.write(line) + print(f"Updated to {json_data['name']}! 🎉") + + +if __name__ == "__main__": + main() diff --git a/src/commands/__init__.py b/src/commands/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/commands/beautify.py b/src/commands/beautify.py deleted file mode 100644 index 36f7bb9..0000000 --- a/src/commands/beautify.py +++ /dev/null @@ -1,22 +0,0 @@ -import string - - -def flip_char(char: str): - if char in string.ascii_lowercase: - return string.ascii_uppercase[string.ascii_lowercase.find(char)] - else: - return string.ascii_lowercase[string.ascii_uppercase.find(char)] - - -def main(args: list[str]): - message = " ".join(args) - new_beautiful_string = [] - - for num, letter in enumerate(message): - if letter in string.ascii_letters: - if num % 2: - new_beautiful_string.append(flip_char(letter)) - continue - new_beautiful_string.append(letter) - - print("".join(new_beautiful_string)) diff --git a/src/commands/update.py b/src/commands/update.py deleted file mode 100644 index 1f6296f..0000000 --- a/src/commands/update.py +++ /dev/null @@ -1,26 +0,0 @@ -import httpx - -import src - - -def main(args): - release_data = httpx.get( - "https://api.github.com/repos/itsthejoker/utils/releases/latest" - ) - if release_data.status_code != 200: - print( - f"Something went wrong when talking to github; got a" - f" {release_data.status_code} with the following content:\n" - f"{release_data.content}" - ) - return - json_data = release_data.json() - if json_data["name"] == src.__version__: - print("Server version is the same as current version; nothing to update.") - return - - url = json_data["assets"][0]["browser_download_url"] - with open("utils", "wb") as f, httpx.stream("GET", url, follow_redirects=True) as r: - for line in r.iter_bytes(): - f.write(line) - print(f"Updated to {json_data['name']}! 🎉") diff --git a/src/commands/uuid4.py b/src/commands/uuid4.py deleted file mode 100644 index dfa99ef..0000000 --- a/src/commands/uuid4.py +++ /dev/null @@ -1,6 +0,0 @@ -"""Generate and print a random UUID4.""" -import uuid - - -def main(args: list[str]): - print(uuid.uuid4()) diff --git a/src/helpers.py b/src/helpers.py new file mode 100644 index 0000000..fd594ff --- /dev/null +++ b/src/helpers.py @@ -0,0 +1,8 @@ +import string + + +def flip_char(char: str): + if char in string.ascii_lowercase: + return string.ascii_uppercase[string.ascii_lowercase.find(char)] + else: + return string.ascii_lowercase[string.ascii_uppercase.find(char)]