import os import traceback import urllib import datetime import random from typing import Optional import logging import discord import aiosqlite as sqlite3 from sh import cowsay as cow_say, fortune from discord.ext import bridge, commands from disc_havoc import Havoc from util.misc_util import Util from constructors import MiscException """ This plugin encompasses numerous tiny commands/functions that do not necessitate their own cogs """ DRUGS_CHANID = 1172247451047034910 BOT_CHANIDS = [] class Misc(commands.Cog): """Misc/Assorted Cog for Havoc""" def __init__(self, bot: Havoc): self.bot: Havoc = bot self.util = Util() self.COWS: list[str] = os.listdir( os.path.join("/", "usr", "share", "cowsay", "cows") ) self.FATES: list[str] = [ "into a pile of white dog shit, face first", "onto the floor", "into a volcano", "into a toaster bath", "into a pit of venomous snakes", "into oncoming traffic", "off a bridge", "into the roaring 20's", "into an unknown orifice", "into the large hadron collider", "into an awkward nude group hug", "into a swinger party", "into an adoption agency, because even their parents didn't want them", "into the gas chamber for a shower", "into a tub of Jello", "into a trap full of Devils Snare", "down the stairs", "into Uranus", "into an enthralling and extended conversation about berries", "directly into Mordor", "into a giant mousetrap", "into a room full of exploding balloons", "into a giant blender", "into a giant microwave", ] self.DRUGS_CHANID = DRUGS_CHANID global BOT_CHANIDS BOT_CHANIDS = self.bot.BOT_CHANIDS def is_spamchan() -> bool: # type: ignore """Check if channel is spamchan""" def predicate(ctx): try: if not ctx.channel.id in BOT_CHANIDS: logging.debug("%s not found in %s", ctx.channel.id, BOT_CHANIDS) return ctx.channel.id in BOT_CHANIDS except: traceback.print_exc() return False return commands.check(predicate) # type: ignore def is_spamchan_or_drugs() -> bool: # type: ignore """Check if channel is spamchan or drugs chan""" def predicate(ctx): try: if ( not ctx.channel.id in BOT_CHANIDS and not ctx.channel.id == DRUGS_CHANID ): logging.debug( "%s not found in %s and it isnt %s", ctx.channel.id, BOT_CHANIDS, DRUGS_CHANID, ) return ctx.channel.id in BOT_CHANIDS or ctx.channel.id == DRUGS_CHANID except: traceback.print_exc() return False return commands.check(predicate) # type: ignore async def get_random_guild_member( self, online_only: Optional[bool] = False ) -> Optional[str]: """ Get Random Guild Member Args: online_only (Optional[bool]) Returns: str """ guild: Optional[discord.Guild] = self.bot.get_guild(1145182936002482196) if not guild: return None if not online_only: guild_members = [ str(member.display_name) for member in guild.members if not member.bot ] else: guild_members = [ str(member.display_name) for member in guild.members if not member.bot and member.status in [discord.Status.online, discord.Status.idle] ] return random.choice(guild_members) @bridge.bridge_command() async def stats(self, ctx) -> None: """ Get Stats """ try: stats_embed: Optional[discord.Embed] = await self.util.get_stats_embed() if not stats_embed: return return await ctx.respond(embed=stats_embed) except Exception as e: traceback.print_exc() return await ctx.respond(f"Error: {str(e)}") @bridge.bridge_command() # type: ignore @is_spamchan_or_drugs() async def listcoffees(self, ctx) -> None: """ List Available Coffees """ coffees: str = "" try: for coffee in self.util.COFFEES: coffees += f"**- {coffee}**\n" embed: discord.Embed = discord.Embed( title="Available Coffees", description=coffees.strip() ) return await ctx.respond(embed=embed) except Exception as e: traceback.print_exc() return await ctx.respond(f"Error: {str(e)}") @bridge.bridge_command() # type: ignore @is_spamchan_or_drugs() async def listshoves(self, ctx) -> None: """ List Available Fates for shove command """ fates: str = "" try: for fate in self.FATES: fates += f"**- {fate}**\n" embed: discord.Embed = discord.Embed( title="Available Fates (for .shove)", description=fates.strip() ) return await ctx.respond(embed=embed) except Exception as e: traceback.print_exc() return await ctx.respond(f"Error: {str(e)}") @bridge.bridge_command() async def xmas(self, ctx) -> None: """ Countdown til xmas! """ try: emojis: dict = { "0": "0️⃣", "1": "1️⃣", "2": "2️⃣", "3": "3️⃣", "4": "4️⃣", "5": "5️⃣", "6": "6️⃣", "7": "7️⃣", "8": "8️⃣", "9": "9️⃣", } with ctx.channel.typing(): countdown = self.util.get_days_to_xmas() if not isinstance(countdown, tuple) or len(countdown) < 6: return await ctx.respond( "Oops, Christmas is cancelled." ) # Invalid countdown from util (days, hours, minutes, seconds, ms, _) = countdown now: datetime.datetime = datetime.datetime.now() if now.month == 12 and now.day == 25: return await ctx.respond( "# IT IS CHRISTMAS!!!!!!!!\n-# keep the change, you filthy animal" ) if days > 200 or days < 0: return await ctx.respond("We ain't fuckin talkin bout that yet") xmas_trans: dict = str.maketrans(emojis) try: await ctx.message.add_reaction(emoji="🎄") except Exception as e: logging.debug("Failed to add xmas reaction: %s", str(e)) await ctx.respond( f"Only {days} days, {hours} hours, {minutes} minutes,\ {seconds} seconds and {ms} ms left! (UTC)".translate( xmas_trans ) ) except Exception as e: traceback.print_exc() return await ctx.respond(f"Error: {str(e)}") @bridge.bridge_command() async def randfact(self, ctx) -> None: """ Get a random (useless) fact! """ try: with ctx.channel.typing(): fact: str = await self.util.get_random_fact() return await ctx.respond(discord.utils.escape_markdown(fact.strip())) except Exception as e: traceback.print_exc() return await ctx.respond(f"Error: {str(e)}") @bridge.bridge_command() async def insult(self, ctx, *, recipient: Optional[str] = None) -> None: """ Insult Someone (or yourself) """ try: guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id) if not guild: return authorDisplay: str = ( ctx.author.display_name if not (ctx.author.display_name is None) else ctx.message.author.display_name ) if not recipient: recipient = authorDisplay.strip() else: if discord.utils.raw_mentions(recipient): # There are mentions recipient_id: int = discord.utils.raw_mentions(recipient)[ 0 ] # First mention recipient_member: Optional[discord.Member] = guild.get_member( recipient_id ) if not recipient_member: return recipient = recipient_member.display_name else: recipient = discord.utils.escape_mentions(recipient.strip()) with ctx.channel.typing(): insult: str = await self.util.get_insult(recipient) if insult: return await ctx.respond(insult) return await ctx.respond("Insult failed :(") except Exception as e: traceback.print_exc() return await ctx.respond(f"Insult failed :(\nError: {str(e)}") @bridge.bridge_command() async def compliment( self, ctx, *, recipient: Optional[str] = None, language: Optional[str] = "en" ) -> None: """ Compliment someone (or yourself) """ try: authorDisplay: str = ( ctx.author.display_name if not (ctx.author.display_name is None) else ctx.message.author.display_name ) if not recipient: recipient = authorDisplay.strip() else: if discord.utils.raw_mentions(recipient): # There are mentions recipient_id: int = discord.utils.raw_mentions(recipient)[ 0 ] # First mention guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id) if not guild: return recipient_member: Optional[discord.Member] = guild.get_member( recipient_id ) if not recipient_member: return recipient = recipient_member.display_name else: recipient = discord.utils.escape_mentions(recipient.strip()) with ctx.channel.typing(): compliment: str = await self.util.get_compliment(recipient, language) if compliment: return await ctx.respond(compliment) return await ctx.respond("Compliment failed :(") except Exception as e: traceback.print_exc() return await ctx.respond(f"Compliment failed :(\nError: {str(e)}") @bridge.bridge_command(aliases=["whiskey"]) async def whisky(self, ctx, *, recipient: Optional[str] = None) -> None: """ Get a whisky for yourself or a friend! """ try: if not recipient: recipient = ctx.author.display_name else: if discord.utils.raw_mentions(recipient): # There are mentions recipient_id = discord.utils.raw_mentions(recipient)[ 0 ] # First mention guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id) if not guild: return recipient_member: Optional[discord.Member] = guild.get_member( recipient_id ) if not recipient_member: return recipient = recipient_member.display_name else: recipient = discord.utils.escape_mentions(recipient.strip()) whisky: Optional[tuple] = await self.util.get_whisky() if not whisky: raise MiscException("Failed to get whisky from db") (choice_name, choice_category, choice_description) = whisky embed: discord.Embed = discord.Embed( title=f"Whisky for {recipient}: {choice_name}", description=choice_description.strip(), ) embed.add_field(name="Category", value=choice_category, inline=True) embed.set_footer(text=f"Cheers, {recipient}!") await self.util.increment_counter("whiskeys") return await ctx.respond(embed=embed) except Exception as e: traceback.print_exc() return await ctx.respond(f"Error: {str(e)}") @bridge.bridge_command() async def drink(self, ctx, *, recipient: Optional[str] = None) -> None: """ Get a cocktail for yourself or a friend! """ try: if not recipient: recipient = ctx.author.display_name else: if discord.utils.raw_mentions(recipient): # There are mentions recipient_id = discord.utils.raw_mentions(recipient)[ 0 ] # First mention guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id) if not guild: return recipient_member: Optional[discord.Member] = guild.get_member( recipient_id ) if not recipient_member: return recipient = recipient_member.display_name else: recipient = discord.utils.escape_mentions(recipient.strip()) if not recipient: return drink: Optional[tuple] = await self.util.get_drink() if not drink: raise MiscException("Failed to get drink from db.") (choice_name, choice_ingredients) = drink await ctx.respond( f"*is mixing up **{choice_name}** for {recipient.strip()}*" ) embed: discord.Embed = discord.Embed( title=f"Cocktail for {recipient}", description=choice_name ) embed.add_field( name="Ingredients", value=discord.utils.escape_markdown(choice_ingredients), inline=True, ) embed.set_footer(text=f"Cheers, {recipient}!") await self.util.increment_counter("mixed_drinks") return await ctx.respond(embed=embed) except Exception as e: traceback.print_exc() return await ctx.respond(f"Failed: {str(e)}") @bridge.bridge_command() async def spray(self, ctx, *, recipient: Optional[str] = None) -> None: """ Spray someone with water! """ authorDisplay: str = ( ctx.author.display_name if not (ctx.author.display_name is None) else ctx.message.author.display_name ) if not recipient: recipient = authorDisplay.strip() recipient_normal: str = ctx.author.mention else: recipient_normal = recipient if discord.utils.raw_mentions(recipient): # There are mentions recipient_id: int = discord.utils.raw_mentions(recipient)[ 0 ] # First mention guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id) if not guild: return recipient_member: Optional[discord.Member] = guild.get_member( recipient_id ) if not recipient_member: return recipient = recipient_member.display_name recipient_normal = recipient_member.mention else: recipient = discord.utils.escape_mentions(recipient.strip()) try: await ctx.respond(f"*sprays **{recipient_normal}** with water*") await self.util.increment_counter("water_sprays") except Exception as e: traceback.print_exc() return await ctx.respond(f"Failed: {str(e)}") @bridge.bridge_command() async def barfbag(self, ctx, *, recipient: Optional[str] = None) -> None: """ Pass someone (or yourself) a barf bag! """ authorDisplay: str = ( ctx.author.display_name if not (ctx.author.display_name is None) else ctx.message.author.display_name ) if not recipient: recipient = authorDisplay.strip() recipient_normal = ctx.author.mention else: recipient_normal = recipient if discord.utils.raw_mentions(recipient): # There are mentions recipient_id: int = discord.utils.raw_mentions(recipient)[ 0 ] # First mention guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id) if not guild: return recipient_member: Optional[discord.Member] = guild.get_member( recipient_id ) if not recipient_member: return recipient = recipient_member.display_name recipient_normal = recipient_member.mention else: recipient = discord.utils.escape_mentions(recipient.strip()) try: await ctx.respond(f"*passes **{recipient_normal}** a barf bag*") await self.util.increment_counter("barf_bags") except Exception as e: traceback.print_exc() return await ctx.respond(f"Failed: {str(e)}") @bridge.bridge_command() async def tea(self, ctx, *, recipient: Optional[str] = None) -> None: """ Tea! """ tea: str = "a cup of tea" authorDisplay: str = ( ctx.author.display_name if not (ctx.author.display_name is None) else ctx.message.author.display_name ) if not recipient: recipient = authorDisplay.strip() recipient_normal: str = ctx.author.mention else: recipient_normal = recipient if discord.utils.raw_mentions(recipient): # There are mentions recipient_id: int = discord.utils.raw_mentions(recipient)[ 0 ] # First mention guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id) if not guild: return recipient_member: Optional[discord.Member] = guild.get_member( recipient_id ) if not recipient_member: return recipient = recipient_member.display_name recipient_normal = recipient_member.mention else: recipient = discord.utils.escape_mentions(recipient.strip()) try: if recipient == "rhodes": tea = "a cup of Harney & Sons Hot Cinnamon Spice Tea" elif ctx.author.id == 992437729927376996 or recipient.lower() in [ "kriegerin", "traurigkeit", "krieg", "kriegs", "cyberkrieg", "ck", ]: tea = "a cup of earl grey, light and sweet" response = await ctx.respond(f"*hands **{recipient_normal}** {tea}*") await self.util.increment_counter("teas") try: return await response.add_reaction(emoji="🫖") except Exception as e: logging.debug("Failed to add tea reaction: %s", str(e)) except Exception as e: traceback.print_exc() return await ctx.respond(f"Failed: {str(e)}") @bridge.bridge_command() # type: ignore @is_spamchan_or_drugs() async def cowsay(self, ctx, *, message: str) -> None: """ Cowsay! """ try: cowfile: str = random.choice(self.COWS).replace(".cow", "") cow_said: str = cow_say(f"-f{cowfile}", message) response: str = f"```{cow_said}```\n-# Chosen cow: {cowfile}" return await ctx.respond(response) except Exception as e: traceback.print_exc() return await ctx.respond(f"Failed: {str(e)}") @bridge.bridge_command() # type: ignore @is_spamchan_or_drugs() async def fortune(self, ctx, cowfile: Optional[str] = None) -> None: """ Fortune | Cowsay! """ try: if not cowfile: cowfile = random.choice(self.COWS).replace(".cow", "") if not f"{cowfile}.cow" in self.COWS: return await ctx.respond(f"Unknown cow {cowfile}, who dat?") fortune_said: str = str(fortune("-n1000", "-s")) cow_said: str = cow_say(f"-f{cowfile}", fortune_said) response: str = f"```{cow_said}```\n-# Chosen cow: {cowfile}" return await ctx.respond(response) except Exception as e: traceback.print_exc() return await ctx.respond(f"Failed: {str(e)}") @bridge.bridge_command() # type: ignore @is_spamchan_or_drugs() async def listcows(self, ctx) -> None: """ List available .cow files (for cowsay) """ cow_list: str = "" try: for cow in self.COWS: cow = cow.replace(".cow", "") cow_list += f"- **{cow}**\n" embed: discord.Embed = discord.Embed( title="List of .cows", description=cow_list.strip() ) return await ctx.respond(embed=embed) except Exception as e: traceback.print_exc() return await ctx.respond(f"Failed: {str(e)}") @bridge.bridge_command() async def cyanide(self, ctx, *, recipient: Optional[str] = None) -> None: """ Cyanide! """ authorDisplay: str = ( ctx.author.display_name if not (ctx.author.display_name is None) else ctx.message.author.display_name ) if not recipient: recipient = authorDisplay.strip() recipient_normal: str = ctx.author.mention else: recipient_normal = recipient if discord.utils.raw_mentions(recipient): # There are mentions recipient_id: int = discord.utils.raw_mentions(recipient)[ 0 ] # First mention guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id) if not guild: return recipient_member: Optional[discord.Member] = guild.get_member( recipient_id ) if not recipient_member: return recipient = recipient_member.display_name recipient_normal = recipient_member.mention else: recipient = discord.utils.escape_mentions(recipient.strip()) try: response = await ctx.respond( f"*doses **{recipient_normal}** with Zyklon-B*" ) await self.util.increment_counter("cyanides") try: await response.add_reaction(emoji="☠️") return await response.add_reaction(emoji="🇩🇪") except Exception as e: logging.debug("Failed to add cynaide reaction: %s", str(e)) except Exception as e: traceback.print_exc() return await ctx.respond(f"Failed: {str(e)}") @bridge.bridge_command() async def gravy(self, ctx, *, recipient: Optional[str] = None) -> None: """ School gravy! (It's deadly) """ authorDisplay: str = ( ctx.author.display_name if not (ctx.author.display_name is None) else ctx.message.author.display_name ) if not recipient: recipient = authorDisplay.strip() recipient_normal: str = ctx.author.mention else: recipient_normal = recipient if discord.utils.raw_mentions(recipient): # There are mentions recipient_id: int = discord.utils.raw_mentions(recipient)[ 0 ] # First mention guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id) if not guild: return recipient_member: Optional[discord.Member] = guild.get_member( recipient_id ) if not recipient_member: return recipient = recipient_member.display_name recipient_normal = recipient_member.mention else: recipient = discord.utils.escape_mentions(recipient.strip()) try: response = await ctx.respond( f"*doses **{recipient_normal}** with school gravy*" ) await self.util.increment_counter("gravies") try: await response.add_reaction(emoji="☠️") return await response.add_reaction(emoji="🏫") except Exception as e: logging.debug("Failed to add gravy reaction: %s", str(e)) except Exception as e: traceback.print_exc() return await ctx.respond(f"Failed: {str(e)}") @bridge.bridge_command() async def water(self, ctx, *, recipient: Optional[str] = None) -> None: """ Cold water! Drink up. """ authorDisplay: str = ( ctx.author.display_name if not (ctx.author.display_name is None) else ctx.message.author.display_name ) if not recipient: recipient = authorDisplay.strip() recipient_normal: str = ctx.author.mention else: recipient_normal = recipient if discord.utils.raw_mentions(recipient): # There are mentions recipient_id: int = discord.utils.raw_mentions(recipient)[ 0 ] # First mention guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id) if not guild: return recipient_member: Optional[discord.Member] = guild.get_member( recipient_id ) if not recipient_member: return recipient = recipient_member.display_name recipient_normal = recipient_member.mention else: recipient = discord.utils.escape_mentions(recipient.strip()) try: response = await ctx.respond( f"*hands **{recipient_normal}** a cold glass of water*" ) await self.util.increment_counter("waters") try: return await response.add_reaction(emoji="💧") except Exception as e: logging.debug("Failed to add water reaction: %s", str(e)) except Exception as e: traceback.print_exc() return await ctx.respond(f"Failed: {str(e)}") @bridge.bridge_command(aliases=["bully"]) async def shove(self, ctx, *, recipient: Optional[str] = None) -> None: """ Shove someone! (Or yourself) """ chosen_fate: str = random.choice(self.FATES) authorDisplay: str = ( ctx.author.display_name if not (ctx.author.display_name is None) else ctx.message.author.display_name ) if not recipient: recipient = authorDisplay.strip() recipient_normal: str = ctx.author.mention else: recipient_normal = recipient if discord.utils.raw_mentions(recipient): # There are mentions recipient_id: int = discord.utils.raw_mentions(recipient)[ 0 ] # First mention guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id) if not guild: return recipient_member: Optional[discord.Member] = guild.get_member( recipient_id ) if not recipient_member: return recipient = recipient_member.display_name recipient_normal = recipient_member.mention else: recipient = discord.utils.escape_mentions(recipient.strip()) try: await ctx.respond(f"*shoves **{recipient_normal}** {chosen_fate}*") await self.util.increment_counter("shoves") except Exception as e: traceback.print_exc() return await ctx.respond(f"Failed: {str(e)}") @bridge.bridge_command() async def coffee(self, ctx, *, recipient: Optional[str] = None) -> None: """ Coffee! """ recipient_allergic: bool = False recipient_id: Optional[int] = None # Used for mentions authorDisplay: str = ( ctx.author.display_name if not (ctx.author.display_name is None) else ctx.message.author.display_name ) if not recipient: recipient = authorDisplay.strip() recipient_normal: str = ctx.author.mention else: recipient_normal = recipient if discord.utils.raw_mentions(recipient): # There are mentions recipient_id = discord.utils.raw_mentions(recipient)[0] # First mention guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id) if not guild: return recipient_member: Optional[discord.Member] = guild.get_member( recipient_id ) if not recipient_member: return recipient = recipient_member.display_name recipient_normal = recipient_member.mention else: recipient = discord.utils.escape_mentions(recipient.strip()) try: if ( "pudding" in recipient or recipient_id and recipient_id in [898332028007751741] ): recipient_allergic = True chosen_coffee: Optional[str] = self.util.get_coffee(recipient_allergic) if not chosen_coffee: return response = await ctx.respond( f"*hands **{recipient_normal}** {chosen_coffee}*" ) await self.util.increment_counter("coffees") try: return await response.add_reaction(emoji="☕") except Exception as e: logging.debug("Failed to add coffee reaction: %s", str(e)) except Exception as e: traceback.print_exc() return await ctx.respond(f"Failed: {str(e)}") @bridge.bridge_command(aliases=["cookies"]) async def cookie(self, ctx, *, recipient: Optional[str] = None) -> None: """ Cookies! """ authorDisplay: str = ( ctx.author.display_name if not (ctx.author.display_name is None) else ctx.message.author.display_name ) if not recipient: recipient = authorDisplay.strip() else: if discord.utils.raw_mentions(recipient): # There are mentions recipient_id: int = discord.utils.raw_mentions(recipient)[ 0 ] # First mention guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id) if not guild: return recipient_member: Optional[discord.Member] = guild.get_member( recipient_id ) if not recipient_member: return recipient = recipient_member.display_name else: recipient = discord.utils.escape_mentions(recipient.strip()) try: chosen_cookie: Optional[dict] = await self.util.get_cookie() if not chosen_cookie: raise MiscException("Failed to get cookie from db.") embed: discord.Embed = discord.Embed( title=f"Cookie for {recipient}", description=f"Have a {chosen_cookie.get('name')}", colour=discord.Colour.orange(), image=chosen_cookie.get("image_url"), ) embed.add_field(name="Origin", value=chosen_cookie.get("origin", "N/A")) await ctx.respond(embed=embed) except Exception as e: traceback.print_exc() return await ctx.respond(f"Failed: {str(e)}") @bridge.bridge_command(aliases=["hashbrowns", "potato"]) async def hashbrown(self, ctx, *, recipient: Optional[str] = None) -> None: """ Hashbrowns! """ authorDisplay: str = ( ctx.author.display_name if not (ctx.author.display_name is None) else ctx.message.author.display_name ) if not recipient: recipient = authorDisplay.strip() recipient_normal: str = ctx.author.mention else: recipient_normal = recipient if discord.utils.raw_mentions(recipient): # There are mentions recipient_id: int = discord.utils.raw_mentions(recipient)[ 0 ] # First mention guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id) if not guild: return recipient_member: Optional[discord.Member] = guild.get_member( recipient_id ) if not recipient_member: return recipient = recipient_member.display_name recipient_normal = recipient_member.mention else: recipient = discord.utils.escape_mentions(recipient.strip()) try: await ctx.respond(f"*hands **{recipient_normal}** 2 warm hashbrowns*") await self.util.increment_counter("hashbrowns") except Exception as e: traceback.print_exc() return await ctx.respond(f"Failed: {str(e)}") @bridge.bridge_command() async def ritalini(self, ctx, *, recipient: Optional[str] = None) -> None: """ Ritalini! """ authorDisplay = ( ctx.author.display_name if not (ctx.author.display_name is None) else ctx.message.author.display_name ) if not recipient: recipient = authorDisplay.strip() recipient_normal: str = ctx.author.mention else: recipient_normal = recipient if discord.utils.raw_mentions(recipient): # There are mentions recipient_id: int = discord.utils.raw_mentions(recipient)[ 0 ] # First mention guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id) if not guild: return recipient_member: Optional[discord.Member] = guild.get_member( recipient_id ) if not recipient_member: return recipient = recipient_member.display_name recipient_normal = recipient_member.mention else: recipient = discord.utils.escape_mentions(recipient.strip()) try: response = await ctx.respond( f"*serves **{recipient_normal}** a plate of ritalini* 😉" ) await response.add_reaction(emoji="💊") await response.add_reaction(emoji="🍝") await self.util.increment_counter("ritalinis") except Exception as e: traceback.print_exc() return await ctx.respond(f"Failed: {str(e)}") @bridge.bridge_command(aliases=["gc"]) async def grilledcheese(self, ctx, *, recipient: Optional[str] = None) -> None: """ Grilled Cheese! """ authorDisplay: str = ( ctx.author.display_name if not (ctx.author.display_name is None) else ctx.message.author.display_name ) if not recipient: recipient = authorDisplay.strip() recipient_normal: str = ctx.author.mention else: recipient_normal = recipient if discord.utils.raw_mentions(recipient): # There are mentions recipient_id: int = discord.utils.raw_mentions(recipient)[ 0 ] # First mention guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id) if not guild: return recipient_member: Optional[discord.Member] = guild.get_member( recipient_id ) if not recipient_member: return recipient = recipient_member.display_name recipient_normal = recipient_member.mention else: recipient = discord.utils.escape_mentions(recipient.strip()) try: await ctx.respond(f"*hands **{recipient_normal}** a grilled cheese*") await self.util.increment_counter("grilled_cheeses") except Exception as e: traceback.print_exc() return await ctx.respond(f"Failed: {str(e)}") @bridge.bridge_command() async def soup(self, ctx, *, recipient: Optional[str] = None) -> None: """ Soup! """ authorDisplay: str = ( ctx.author.display_name if not (ctx.author.display_name is None) else ctx.message.author.display_name ) if not recipient: recipient = authorDisplay.strip() recipient_normal: str = ctx.author.mention else: recipient_normal = recipient if discord.utils.raw_mentions(recipient): # There are mentions recipient_id: int = discord.utils.raw_mentions(recipient)[ 0 ] # First mention guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id) if not guild: return recipient_member: Optional[discord.Member] = guild.get_member( recipient_id ) if not recipient_member: return recipient = recipient_member.display_name recipient_normal = recipient_member.mention else: recipient = discord.utils.escape_mentions(recipient.strip()) try: await ctx.respond(f"*hands **{recipient_normal}** a hot bowl of soup*") await self.util.increment_counter("soups") except Exception as e: traceback.print_exc() return await ctx.respond(f"Failed: {str(e)}") @bridge.bridge_command() async def muffin(self, ctx, *, recipient: Optional[str] = None) -> None: """ Muffins! """ authorDisplay: str = ( ctx.author.display_name if not (ctx.author.display_name is None) else ctx.message.author.display_name ) if not recipient: recipient = authorDisplay.strip() recipient_normal: str = ctx.author.mention else: recipient_normal = recipient if discord.utils.raw_mentions(recipient): # There are mentions recipient_id: int = discord.utils.raw_mentions(recipient)[ 0 ] # First mention guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id) if not guild: return recipient_member: Optional[discord.Member] = guild.get_member( recipient_id ) if not recipient_member: return recipient = recipient_member.display_name recipient_normal = recipient_member.mention else: recipient = discord.utils.escape_mentions(recipient.strip()) try: response = await ctx.respond(f"*hands **{recipient_normal}** a muffin*") try: await response.add_reaction(emoji="<:muffin:1314233635586707456>") except Exception as e: logging.debug( "Failed to add muffin reaction: %s", str(e) ) # known: cannot react to interaction await self.util.increment_counter("muffins") except Exception as e: traceback.print_exc() return await ctx.respond(f"Failed: {str(e)}") @bridge.bridge_command() async def bacon(self, ctx, *, recipient: Optional[str] = None) -> None: """ Bacon! """ authorDisplay: str = ( ctx.author.display_name if not (ctx.author.display_name is None) else ctx.message.author.display_name ) if not recipient: recipient = authorDisplay.strip() recipient_normal: str = ctx.author.mention else: recipient_normal = recipient if discord.utils.raw_mentions(recipient): # There are mentions recipient_id: int = discord.utils.raw_mentions(recipient)[ 0 ] # First mention guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id) if not guild: return recipient_member: Optional[discord.Member] = guild.get_member( recipient_id ) if not recipient_member: return recipient = recipient_member.display_name recipient_normal = recipient_member.mention else: recipient = discord.utils.escape_mentions(recipient.strip()) try: response = await ctx.respond( f"*hands **{recipient_normal}** a side of bacon*" ) try: await response.add_reaction(emoji="🥓") except Exception as e: logging.debug( "Failed to add bacon reaction: %s", str(e) ) # known: cannot react to interactions await self.util.increment_counter("bacon_sides") except Exception as e: traceback.print_exc() return await ctx.respond(f"Failed: {str(e)}") @bridge.bridge_command() async def hang(self, ctx, *, recipient: Optional[str] = None) -> None: """ Hang someone! """ authorDisplay = ( ctx.author.display_name if not (ctx.author.display_name is None) else ctx.message.author.display_name ) if not recipient: recipient = authorDisplay.strip() recipient_normal: str = ctx.author.mention else: recipient_normal = recipient if discord.utils.raw_mentions(recipient): # There are mentions recipient_id: int = discord.utils.raw_mentions(recipient)[ 0 ] # First mention guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id) if not guild: return recipient_member: Optional[discord.Member] = guild.get_member( recipient_id ) if not recipient_member: return recipient = recipient_member.display_name recipient_normal = recipient_member.mention else: recipient = discord.utils.escape_mentions(recipient.strip()) try: response = await ctx.respond( f"*sends **{recipient_normal}** to the Gallows to be hanged asynchronely*" ) await self.util.increment_counter("hangings") try: return await response.add_reaction(emoji="☠️") except Exception as e: logging.debug("Failed to add hang reaction: %s", str(e)) except Exception as e: await ctx.respond(f"Failed: {str(e)}") traceback.print_exc() return @bridge.bridge_command() async def touch(self, ctx, *, recipient: Optional[str] = None) -> None: """ Touch someone! """ guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id) if not guild: return no_self_touch: str = ", don't fucking touch yourself here. You disgust me." if not recipient: recipient_normal: str = ctx.author.mention await ctx.respond(f"{recipient_normal}{no_self_touch}") try: await ctx.message.add_reaction(emoji="🤮") except Exception as e: logging.debug( "Failed to add puke reactin for touch command: %s", str(e) ) await self.util.increment_counter("touch_denials") return else: recipient_normal = recipient if discord.utils.raw_mentions(recipient): # There are mentions recipient_id: int = discord.utils.raw_mentions(recipient)[ 0 ] # First mention if not guild: return recipient_member: Optional[discord.Member] = guild.get_member( recipient_id ) if not recipient_member: return recipient = recipient_member.display_name recipient_normal = recipient_member.mention else: recipient = discord.utils.escape_mentions(recipient.strip()) try: response = await ctx.respond( f"*touches **{recipient_normal}** for **{ctx.author.mention}** because they wouldn't touch them with a shitty stick!*" ) await self.util.increment_counter("touches") try: return await response.add_reaction(emoji="👉") except Exception as e: logging.debug("Failed to add touch reaction: %s", str(e)) except Exception as e: traceback.print_exc() return await ctx.respond(f"Failed: {str(e)}") @bridge.bridge_command() # type: ignore @is_spamchan_or_drugs() async def qajoke(self, ctx) -> None: """ Get a joke in Q/A Form! """ try: qajoke: Optional[tuple] = await self.util.get_qajoke() if not qajoke: return (question, answer) = qajoke escaped_question = discord.utils.escape_markdown(question) escasped_answer = discord.utils.escape_markdown(answer) embed: discord.Embed = discord.Embed( title=escaped_question, description=escasped_answer ) return await ctx.respond(embed=embed) except Exception as e: await ctx.respond(f"Error: {str(e)}") @bridge.bridge_command() # type: ignore @is_spamchan_or_drugs() async def rjoke(self, ctx) -> None: """ Get a joke! (from r/jokes scrape) """ try: rjoke: Optional[tuple] = await self.util.get_rjoke() if not rjoke: raise MiscException("Failed to get rjoke from db.") (title, body, score) = rjoke escaped_title = discord.utils.escape_markdown(title) escaped_body = discord.utils.escape_markdown(body) embed: discord.Embed = discord.Embed( title=escaped_title, description=escaped_body ) embed.add_field(name="Score", value=score) return await ctx.respond(embed=embed) except Exception as e: traceback.print_exc() return await ctx.respond(f"Error: {str(e)}") @bridge.bridge_command() # type: ignore @is_spamchan_or_drugs() async def joint(self, ctx, *, recipient: Optional[str] = None) -> None: """ Joints! """ authorDisplay: str = ( ctx.author.display_name if not (ctx.author.display_name is None) else ctx.message.author.display_name ) if not recipient: recipient = authorDisplay.strip() recipient_normal: str = ctx.author.mention else: recipient_normal = recipient if discord.utils.raw_mentions(recipient): # There are mentions recipient_id: int = discord.utils.raw_mentions(recipient)[ 0 ] # First mention guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id) if not guild: return recipient_member: Optional[discord.Member] = guild.get_member( recipient_id ) if not recipient_member: return recipient = recipient_member.display_name recipient_normal = recipient_member.mention else: recipient = discord.utils.escape_mentions(recipient.strip()) try: strain: Optional[tuple] = await self.util.get_strain() if not strain: raise MiscException("Failed to get strain from db.") (choice_strain, choice_desc) = strain escaped_description = discord.utils.escape_markdown(choice_desc.strip()) await ctx.respond( f"*hands **{recipient_normal}** a joint rolled up with some **{choice_strain}***" ) embed: discord.Embed = discord.Embed( title=choice_strain, description=f"*{escaped_description}*" ) await self.util.increment_counter("joints") return await ctx.respond(embed=embed) except Exception as e: traceback.print_exc() return await ctx.respond(f"Failed: {str(e)}") @bridge.bridge_command() async def isitfriday(self, ctx) -> None: """ IS IT FRIDAY!? """ try: today: datetime.datetime = datetime.datetime.today() today_weekday: int = today.weekday() if int(today_weekday) == 4: return await ctx.respond("# FUCK YEAH IT'S FRIDAY!") else: return await ctx.respond("# IT AINT FUCKIN FRIDAY! GOD DAMN IT!") except Exception as e: traceback.print_exc() return await ctx.respond(f"Failed: {str(e)}") @bridge.bridge_command(aliases=["flyday"]) async def isitflyday(self, ctx) -> None: """ IS IT FLYDAY!? """ try: today: datetime.datetime = datetime.datetime.today() today_weekday: int = today.weekday() pony_uid: int = 1090545395110785085 if ctx.author.id == pony_uid: return await ctx.respond("# FUCK YEAH, IT'S ALWAYS FLYDAY FOR U BBY") if int(today_weekday) == 1: return await ctx.respond("# FUCK YEAH IT'S FLYDAY!") else: return await ctx.respond( "# IT AINT FUCKIN FLYDAY! GOD DAMN IT!\n-# Pony may turn into a fly anyway, never any guarantees" ) except Exception as e: traceback.print_exc() return await ctx.respond(f"Failed: {str(e)}") @bridge.bridge_command() async def ud(self, ctx, *, term: str) -> None: """ Not sure what that term means? UD prolly knows. """ try: with ctx.channel.typing(): (ud_word, ud_def) = await self.util.get_ud_def(term=term) term_encoded: str = urllib.parse.quote(ud_word, encoding="utf-8") ud_link = f"https://urbandictionary.com/define.php?term={term_encoded}" embed: discord.Embed = discord.Embed( title=ud_word.strip(), description=f"{ud_def.strip()}\n{ud_link}" ) return await ctx.respond(embed=embed) except Exception as e: traceback.print_exc() return await ctx.respond(f"Error: {str(e)}") """ User Commands """ @commands.user_command(name="Give Joint") # type: ignore @is_spamchan() async def joint_context_menu(self, ctx, member: discord.Member) -> None: """ Joint Context Menu """ strain: Optional[tuple] = await self.util.get_strain() if not strain: raise MiscException("Failed to get strain from db.") (choice_strain, choice_desc) = strain escaped_desc = discord.utils.escape_markdown(choice_desc.strip()) await ctx.interaction.respond( f"*hands **<@{member.id}>** a joint rolled up with some **{choice_strain}***" ) embed: discord.Embed = discord.Embed( title=choice_strain, description=f"*{escaped_desc}*" ) await self.util.increment_counter("joints") return await ctx.send(embed=embed) @commands.user_command(name="Give Coffee") async def coffee_context_menu(self, ctx, member: discord.Member) -> None: """ Coffee Context Menu """ recipient_allergic: bool = False if member.id in [898332028007751741]: recipient_allergic = True chosen_coffee = self.util.get_coffee(recipient_allergic) response = await ctx.interaction.respond( f"*hands <@{member.id}> {chosen_coffee}*" ) await self.util.increment_counter("coffees") try: await response.add_reaction(emoji="☕") except Exception as e: logging.debug( "Failed to add coffee reaction: %s", str(e) ) # known: cannot react to interaction def cog_unload(self) -> None: """Run on Cog Unload""" pass def setup(bot) -> None: """Run on Cog Load""" bot.add_cog(Misc(bot))