From efd5497e2326c628a5a0420a9bf6f3081fc4ddd9 Mon Sep 17 00:00:00 2001 From: thanos Date: Sat, 5 Apr 2025 03:17:43 -0400 Subject: [PATCH 1/5] feat(fun): Added cowsay cog --- tux/cogs/fun/cowsay.py | 112 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 tux/cogs/fun/cowsay.py diff --git a/tux/cogs/fun/cowsay.py b/tux/cogs/fun/cowsay.py new file mode 100644 index 00000000..af6f9c3c --- /dev/null +++ b/tux/cogs/fun/cowsay.py @@ -0,0 +1,112 @@ +from textwrap import wrap + +from discord.ext import commands + +from tux.bot import Tux +from tux.utils.flags import generate_usage + + +class Cowsay(commands.Cog): + def __init__(self, bot: Tux) -> None: + self.bot = bot + self.cowsay.usage = generate_usage(self.cowsay) + + async def draw_textbox(self, message: str) -> str: + message_lines = wrap(message, 40) + max_line_length = max(len(line) for line in message_lines) + message_box_lines: list[str] = [] + message_box_lines.append("/" + ("-" * (max_line_length + 2)) + "\\\n") + for line in message_lines: + box_line = "| " + line + (" " * (max_line_length - len(line))) + " |\n" + message_box_lines.append(box_line) + message_box_lines.append("\\" + ("-" * (max_line_length + 2)) + "/") + return "".join(message_box_lines) + + @commands.hybrid_group( + name="cowsay", + aliases=["cow"], + ) + @commands.guild_only() + async def cowsay(self, ctx: commands.Context[Tux], message: str, creature: str = "cow") -> None: + """ + xkcd related commands. + + Parameters + ---------- + ctx : commands.Context[Tux] + The context object for the command. + message : str + The message to encode + creature : str + Which creature to use for the drawing + """ + creatures = { + "cow": r""" + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || + """, + "tux": r""" + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + """, + "puffy": r""" + \ + \ + | . + . |L /| + _ . |\ _| \--+._/| . + / ||\| Y J ) / |/| ./ + J |)'( | ` F`.'/ + -<| F __ .-< + | / .-'. `. /-. L___ + J \ < \ | | O\|.-' + _J \ .- \/ O | | \ |F + '-F -<_. \ .-' `-' L__ + __J _ _. >-' )._. |-' + `-|.' /_. \_| F + /.- . _.< + /' /.' .' `\ + /L /' |/ _.-'-\ + /'J ___.---'\| + |\ .--' V | `. ` + |/`. `-. `._) + / .-.\ + VK \ ( `\ + `.\ + """, + } + + if creature not in creatures: + valid_creatures: list[str] = [] + for idx, key in enumerate(creatures.keys()): + if idx < len(creatures) - 1: + valid_creatures.append(f"{key}, ") + else: + valid_creatures.append(f" and {key}") + + await ctx.send( + f'Error: "{creature}" is not a valid creature! valid creatures are: {"".join(valid_creatures)}', + ephemeral=True, + ) + return + + if len(message) > 250: + await ctx.send(f"Error! Message too long! ({len(message)} > 250)") + return + + textbox = await self.draw_textbox(message) + await ctx.send("```" + textbox + creatures[creature] + "```") + + +async def setup(bot: Tux) -> None: + await bot.add_cog(Cowsay(bot)) From 10b2cf86757fa60524e4b846b7213bca9ceab919 Mon Sep 17 00:00:00 2001 From: thanos Date: Sat, 5 Apr 2025 03:40:11 -0400 Subject: [PATCH 2/5] fix(cowsay): Refactored to to pass sourcery checks --- tux/cogs/fun/cowsay.py | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/tux/cogs/fun/cowsay.py b/tux/cogs/fun/cowsay.py index af6f9c3c..386ae2c0 100644 --- a/tux/cogs/fun/cowsay.py +++ b/tux/cogs/fun/cowsay.py @@ -11,15 +11,18 @@ def __init__(self, bot: Tux) -> None: self.bot = bot self.cowsay.usage = generate_usage(self.cowsay) + # Helper function that word-wraps text and surrounds it with an ascii art box async def draw_textbox(self, message: str) -> str: message_lines = wrap(message, 40) max_line_length = max(len(line) for line in message_lines) - message_box_lines: list[str] = [] - message_box_lines.append("/" + ("-" * (max_line_length + 2)) + "\\\n") - for line in message_lines: - box_line = "| " + line + (" " * (max_line_length - len(line))) + " |\n" - message_box_lines.append(box_line) - message_box_lines.append("\\" + ("-" * (max_line_length + 2)) + "/") + border = f"/{'-' * (max_line_length + 2)}\\\n" + + message_box_lines = [ + border, + *[f"| {line}{' ' * (max_line_length - len(line))} |\n" for line in message_lines], + f"\\{'-' * (max_line_length + 2)}/", + ] + return "".join(message_box_lines) @commands.hybrid_group( @@ -29,7 +32,7 @@ async def draw_textbox(self, message: str) -> str: @commands.guild_only() async def cowsay(self, ctx: commands.Context[Tux], message: str, creature: str = "cow") -> None: """ - xkcd related commands. + cowsay command Parameters ---------- @@ -85,17 +88,15 @@ async def cowsay(self, ctx: commands.Context[Tux], message: str, creature: str = `.\ """, } + if message == "": + await ctx.send("Error! Message is empty!") + return if creature not in creatures: - valid_creatures: list[str] = [] - for idx, key in enumerate(creatures.keys()): - if idx < len(creatures) - 1: - valid_creatures.append(f"{key}, ") - else: - valid_creatures.append(f" and {key}") - + keys = list(creatures.keys()) + valid_creatures = ", ".join(keys[:-1]) + " and " + keys[-1] if len(keys) > 1 else keys[0] await ctx.send( - f'Error: "{creature}" is not a valid creature! valid creatures are: {"".join(valid_creatures)}', + f'Error: "{creature}" is not a valid creature! Valid creatures are: {valid_creatures}', ephemeral=True, ) return @@ -105,7 +106,7 @@ async def cowsay(self, ctx: commands.Context[Tux], message: str, creature: str = return textbox = await self.draw_textbox(message) - await ctx.send("```" + textbox + creatures[creature] + "```") + await ctx.send(f"```{textbox}{creatures[creature]}```") async def setup(bot: Tux) -> None: From 3302b20b4b554a80c7740364dc225f0ccf2bbfae Mon Sep 17 00:00:00 2001 From: thanos Date: Sat, 5 Apr 2025 14:52:39 -0400 Subject: [PATCH 3/5] feat(fun/cowsay): Added ability to make the textbox curved, and change the eye character --- tux/cogs/fun/cowsay.py | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/tux/cogs/fun/cowsay.py b/tux/cogs/fun/cowsay.py index 386ae2c0..7e777b1b 100644 --- a/tux/cogs/fun/cowsay.py +++ b/tux/cogs/fun/cowsay.py @@ -12,15 +12,16 @@ def __init__(self, bot: Tux) -> None: self.cowsay.usage = generate_usage(self.cowsay) # Helper function that word-wraps text and surrounds it with an ascii art box - async def draw_textbox(self, message: str) -> str: + async def draw_textbox(self, message: str, curviness: bool) -> str: message_lines = wrap(message, 40) max_line_length = max(len(line) for line in message_lines) - border = f"/{'-' * (max_line_length + 2)}\\\n" + corners = ["╭", "╮", "╰", "╯"] if curviness else ["/", "\\", "\\", "/"] + border = f"{corners[0]}{'-' * (max_line_length + 2)}{corners[1]}\n" message_box_lines = [ border, *[f"| {line}{' ' * (max_line_length - len(line))} |\n" for line in message_lines], - f"\\{'-' * (max_line_length + 2)}/", + f"{corners[2]}{'-' * (max_line_length + 2)}{corners[3]}", ] return "".join(message_box_lines) @@ -30,7 +31,9 @@ async def draw_textbox(self, message: str) -> str: aliases=["cow"], ) @commands.guild_only() - async def cowsay(self, ctx: commands.Context[Tux], message: str, creature: str = "cow") -> None: + async def cowsay( + self, ctx: commands.Context[Tux], message: str, creature: str = "cow", eyes: str = "o", curviness: bool = True + ) -> None: """ cowsay command @@ -42,26 +45,27 @@ async def cowsay(self, ctx: commands.Context[Tux], message: str, creature: str = The message to encode creature : str Which creature to use for the drawing + curviness: bool + whether to use slashes or curves for the box corners + eyes: str + What char to use for the eyes """ creatures = { "cow": r""" \ ^__^ - \ (oo)\_______ + \ (??)\_______ (__)\ )\/\ ||----w | - || || - """, + || ||""", "tux": r""" \ - \ - .--. - |o_o | + \ .--. + |?_? | |:_/ | // \ \ (| | ) /'\_ _/`\ - \___)=(___/ - """, + \___)=(___/""", "puffy": r""" \ \ @@ -72,8 +76,8 @@ async def cowsay(self, ctx: commands.Context[Tux], message: str, creature: str = J |)'( | ` F`.'/ -<| F __ .-< | / .-'. `. /-. L___ - J \ < \ | | O\|.-' - _J \ .- \/ O | | \ |F + J \ < \ | | ?\|.-' + _J \ .- \/ ? | | \ |F '-F -<_. \ .-' `-' L__ __J _ _. >-' )._. |-' `-|.' /_. \_| F @@ -85,9 +89,9 @@ async def cowsay(self, ctx: commands.Context[Tux], message: str, creature: str = |/`. `-. `._) / .-.\ VK \ ( `\ - `.\ - """, + `.\ """, } + if message == "": await ctx.send("Error! Message is empty!") return @@ -105,8 +109,8 @@ async def cowsay(self, ctx: commands.Context[Tux], message: str, creature: str = await ctx.send(f"Error! Message too long! ({len(message)} > 250)") return - textbox = await self.draw_textbox(message) - await ctx.send(f"```{textbox}{creatures[creature]}```") + textbox = await self.draw_textbox(message, curviness) + await ctx.send(f"```{textbox}{creatures[creature].replace('?', eyes[0])}```") async def setup(bot: Tux) -> None: From 97d09d3285ec4e2d038675e8691c5d4a07003ad3 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 5 Apr 2025 18:54:02 +0000 Subject: [PATCH 4/5] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tux/cogs/fun/cowsay.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tux/cogs/fun/cowsay.py b/tux/cogs/fun/cowsay.py index 7e777b1b..a197da2e 100644 --- a/tux/cogs/fun/cowsay.py +++ b/tux/cogs/fun/cowsay.py @@ -32,7 +32,7 @@ async def draw_textbox(self, message: str, curviness: bool) -> str: ) @commands.guild_only() async def cowsay( - self, ctx: commands.Context[Tux], message: str, creature: str = "cow", eyes: str = "o", curviness: bool = True + self, ctx: commands.Context[Tux], message: str, creature: str = "cow", eyes: str = "o", curviness: bool = True, ) -> None: """ cowsay command From 84746c7cb4b014b879b7f70f5cf81ae633d90e44 Mon Sep 17 00:00:00 2001 From: thanos Date: Sat, 5 Apr 2025 16:45:00 -0400 Subject: [PATCH 5/5] refactor(cowsay): Minor formatting changes, shortened puffy art --- tux/cogs/fun/cowsay.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tux/cogs/fun/cowsay.py b/tux/cogs/fun/cowsay.py index a197da2e..5f63eb6b 100644 --- a/tux/cogs/fun/cowsay.py +++ b/tux/cogs/fun/cowsay.py @@ -32,7 +32,12 @@ async def draw_textbox(self, message: str, curviness: bool) -> str: ) @commands.guild_only() async def cowsay( - self, ctx: commands.Context[Tux], message: str, creature: str = "cow", eyes: str = "o", curviness: bool = True, + self, + ctx: commands.Context[Tux], + message: str, + creature: str = "cow", + eyes: str = "o", + curviness: bool = True, ) -> None: """ cowsay command @@ -50,6 +55,8 @@ async def cowsay( eyes: str What char to use for the eyes """ + + # Creature dict. "?" will be replaced with the user-specified eye character. creatures = { "cow": r""" \ ^__^ @@ -68,8 +75,7 @@ async def cowsay( \___)=(___/""", "puffy": r""" \ - \ - | . + \ | . . |L /| _ . |\ _| \--+._/| . / ||\| Y J ) / |/| ./