aboutsummaryrefslogtreecommitdiffstats
path: root/bot/exts/evergreen/fun.py
diff options
context:
space:
mode:
Diffstat (limited to 'bot/exts/evergreen/fun.py')
-rw-r--r--bot/exts/evergreen/fun.py250
1 files changed, 0 insertions, 250 deletions
diff --git a/bot/exts/evergreen/fun.py b/bot/exts/evergreen/fun.py
deleted file mode 100644
index 4bbfe859..00000000
--- a/bot/exts/evergreen/fun.py
+++ /dev/null
@@ -1,250 +0,0 @@
-import functools
-import json
-import logging
-import random
-from collections.abc import Iterable
-from pathlib import Path
-from typing import Callable, Optional, Union
-
-from discord import Embed, Message
-from discord.ext import commands
-from discord.ext.commands import BadArgument, Cog, Context, MessageConverter, clean_content
-
-from bot import utils
-from bot.bot import Bot
-from bot.constants import Client, Colours, Emojis
-from bot.utils import helpers
-
-log = logging.getLogger(__name__)
-
-UWU_WORDS = {
- "fi": "fwi",
- "l": "w",
- "r": "w",
- "some": "sum",
- "th": "d",
- "thing": "fing",
- "tho": "fo",
- "you're": "yuw'we",
- "your": "yur",
- "you": "yuw",
-}
-
-
-def caesar_cipher(text: str, offset: int) -> Iterable[str]:
- """
- Implements a lazy Caesar Cipher algorithm.
-
- Encrypts a `text` given a specific integer `offset`. The sign
- of the `offset` dictates the direction in which it shifts to,
- with a negative value shifting to the left, and a positive
- value shifting to the right.
- """
- for char in text:
- if not char.isascii() or not char.isalpha() or char.isspace():
- yield char
- continue
-
- case_start = 65 if char.isupper() else 97
- true_offset = (ord(char) - case_start + offset) % 26
-
- yield chr(case_start + true_offset)
-
-
-class Fun(Cog):
- """A collection of general commands for fun."""
-
- def __init__(self, bot: Bot):
- self.bot = bot
-
- self._caesar_cipher_embed = json.loads(Path("bot/resources/evergreen/caesar_info.json").read_text("UTF-8"))
-
- @staticmethod
- def _get_random_die() -> str:
- """Generate a random die emoji, ready to be sent on Discord."""
- die_name = f"dice_{random.randint(1, 6)}"
- return getattr(Emojis, die_name)
-
- @commands.command()
- async def roll(self, ctx: Context, num_rolls: int = 1) -> None:
- """Outputs a number of random dice emotes (up to 6)."""
- if 1 <= num_rolls <= 6:
- dice = " ".join(self._get_random_die() for _ in range(num_rolls))
- await ctx.send(dice)
- else:
- raise BadArgument(f"`{Client.prefix}roll` only supports between 1 and 6 rolls.")
-
- @commands.command(name="uwu", aliases=("uwuwize", "uwuify",))
- async def uwu_command(self, ctx: Context, *, text: clean_content(fix_channel_mentions=True)) -> None:
- """Converts a given `text` into it's uwu equivalent."""
- conversion_func = functools.partial(
- utils.replace_many, replacements=UWU_WORDS, ignore_case=True, match_case=True
- )
- text, embed = await Fun._get_text_and_embed(ctx, text)
- # Convert embed if it exists
- if embed is not None:
- embed = Fun._convert_embed(conversion_func, embed)
- converted_text = conversion_func(text)
- converted_text = helpers.suppress_links(converted_text)
- # Don't put >>> if only embed present
- if converted_text:
- converted_text = f">>> {converted_text.lstrip('> ')}"
- await ctx.send(content=converted_text, embed=embed)
-
- @commands.command(name="randomcase", aliases=("rcase", "randomcaps", "rcaps",))
- async def randomcase_command(self, ctx: Context, *, text: clean_content(fix_channel_mentions=True)) -> None:
- """Randomly converts the casing of a given `text`."""
- def conversion_func(text: str) -> str:
- """Randomly converts the casing of a given string."""
- return "".join(
- char.upper() if round(random.random()) else char.lower() for char in text
- )
- text, embed = await Fun._get_text_and_embed(ctx, text)
- # Convert embed if it exists
- if embed is not None:
- embed = Fun._convert_embed(conversion_func, embed)
- converted_text = conversion_func(text)
- converted_text = helpers.suppress_links(converted_text)
- # Don't put >>> if only embed present
- if converted_text:
- converted_text = f">>> {converted_text.lstrip('> ')}"
- await ctx.send(content=converted_text, embed=embed)
-
- @commands.group(name="caesarcipher", aliases=("caesar", "cc",))
- async def caesarcipher_group(self, ctx: Context) -> None:
- """
- Translates a message using the Caesar Cipher.
-
- See `decrypt`, `encrypt`, and `info` subcommands.
- """
- if ctx.invoked_subcommand is None:
- await ctx.invoke(self.bot.get_command("help"), "caesarcipher")
-
- @caesarcipher_group.command(name="info")
- async def caesarcipher_info(self, ctx: Context) -> None:
- """Information about the Caesar Cipher."""
- embed = Embed.from_dict(self._caesar_cipher_embed)
- embed.colour = Colours.dark_green
-
- await ctx.send(embed=embed)
-
- @staticmethod
- async def _caesar_cipher(ctx: Context, offset: int, msg: str, left_shift: bool = False) -> None:
- """
- Given a positive integer `offset`, translates and sends the given `msg`.
-
- Performs a right shift by default unless `left_shift` is specified as `True`.
-
- Also accepts a valid Discord Message ID or link.
- """
- if offset < 0:
- await ctx.send(":no_entry: Cannot use a negative offset.")
- return
-
- if left_shift:
- offset = -offset
-
- def conversion_func(text: str) -> str:
- """Encrypts the given string using the Caesar Cipher."""
- return "".join(caesar_cipher(text, offset))
-
- text, embed = await Fun._get_text_and_embed(ctx, msg)
-
- if embed is not None:
- embed = Fun._convert_embed(conversion_func, embed)
-
- converted_text = conversion_func(text)
-
- if converted_text:
- converted_text = f">>> {converted_text.lstrip('> ')}"
-
- await ctx.send(content=converted_text, embed=embed)
-
- @caesarcipher_group.command(name="encrypt", aliases=("rightshift", "rshift", "enc",))
- async def caesarcipher_encrypt(self, ctx: Context, offset: int, *, msg: str) -> None:
- """
- Given a positive integer `offset`, encrypt the given `msg`.
-
- Performs a right shift of the letters in the message.
-
- Also accepts a valid Discord Message ID or link.
- """
- await self._caesar_cipher(ctx, offset, msg, left_shift=False)
-
- @caesarcipher_group.command(name="decrypt", aliases=("leftshift", "lshift", "dec",))
- async def caesarcipher_decrypt(self, ctx: Context, offset: int, *, msg: str) -> None:
- """
- Given a positive integer `offset`, decrypt the given `msg`.
-
- Performs a left shift of the letters in the message.
-
- Also accepts a valid Discord Message ID or link.
- """
- await self._caesar_cipher(ctx, offset, msg, left_shift=True)
-
- @staticmethod
- async def _get_text_and_embed(ctx: Context, text: str) -> tuple[str, Optional[Embed]]:
- """
- Attempts to extract the text and embed from a possible link to a discord Message.
-
- Does not retrieve the text and embed from the Message if it is in a channel the user does
- not have read permissions in.
-
- Returns a tuple of:
- str: If `text` is a valid discord Message, the contents of the message, else `text`.
- Optional[Embed]: The embed if found in the valid Message, else None
- """
- embed = None
-
- msg = await Fun._get_discord_message(ctx, text)
- # Ensure the user has read permissions for the channel the message is in
- if isinstance(msg, Message):
- permissions = msg.channel.permissions_for(ctx.author)
- if permissions.read_messages:
- text = msg.clean_content
- # Take first embed because we can't send multiple embeds
- if msg.embeds:
- embed = msg.embeds[0]
-
- return (text, embed)
-
- @staticmethod
- async def _get_discord_message(ctx: Context, text: str) -> Union[Message, str]:
- """
- Attempts to convert a given `text` to a discord Message object and return it.
-
- Conversion will succeed if given a discord Message ID or link.
- Returns `text` if the conversion fails.
- """
- try:
- text = await MessageConverter().convert(ctx, text)
- except commands.BadArgument:
- log.debug(f"Input '{text:.20}...' is not a valid Discord Message")
- return text
-
- @staticmethod
- def _convert_embed(func: Callable[[str, ], str], embed: Embed) -> Embed:
- """
- Converts the text in an embed using a given conversion function, then return the embed.
-
- Only modifies the following fields: title, description, footer, fields
- """
- embed_dict = embed.to_dict()
-
- embed_dict["title"] = func(embed_dict.get("title", ""))
- embed_dict["description"] = func(embed_dict.get("description", ""))
-
- if "footer" in embed_dict:
- embed_dict["footer"]["text"] = func(embed_dict["footer"].get("text", ""))
-
- if "fields" in embed_dict:
- for field in embed_dict["fields"]:
- field["name"] = func(field.get("name", ""))
- field["value"] = func(field.get("value", ""))
-
- return Embed.from_dict(embed_dict)
-
-
-def setup(bot: Bot) -> None:
- """Load the Fun cog."""
- bot.add_cog(Fun(bot))