1471 lines
57 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
Args:
ctx (Any)
Returns:
None
"""
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
Args:
ctx (Any)
Returns:
None
"""
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
Args:
ctx (Any)
Returns:
None
"""
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!
Args:
ctx (Any)
Returns:
None
"""
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!
Args:
ctx (Any)
Returns:
None
"""
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)
Args:
ctx (Any)
recipient (Optional[str])
Returns:
None
"""
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)
Args:
ctx (Any)
recipient (Optional[str])
language (Optional[str]) (default: 'en')
Returns:
None
"""
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!
Args:
ctx (Any)
recipient (Optional[str])
Returns:
None
"""
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!
Args:
ctx (Any)
recipient (Optional[str])
Returns:
None
"""
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!
Args:
ctx (Any)
recipient (Optional[str])
Returns:
None
"""
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!
Args:
ctx (Any)
recipient (Optional[str])
Returns:
None
"""
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!
Args:
recipient (Optional[str])
Returns:
None
"""
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!
Args:
ctx (Any)
message (str)
Returns:
None
"""
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!
Args:
cowfile (Optional[str])
Returns:
None
"""
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)
Args:
ctx (Any)
Returns:
None
"""
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!
Args:
ctx (Any)
recipient (Optional[str])
Returns:
None
"""
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)
Args:
ctx (Any)
recipient (Optional[str])
Returns:
None
"""
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.
Args:
ctx (Any)
recipient (Optional[str])
Returns:
None
"""
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)
Args:
ctx (Any)
recipient (Optional[str])
Returns:
None
"""
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!
Args:
ctx (Any)
recipient (Optional[str])
Returns:
None
"""
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!
Args:
ctx (Any)
recipient (Optional[str])
Returns:
None
"""
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!
Args:
ctx (Any)
recipient (Optional[str])
Returns:
None
"""
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!
Args:
ctx (Any)
recipient (Optional[str])
Returns:
None
"""
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!
Args:
ctx (Any)
recipient (Optional[str])
Returns:
None
"""
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!
Args:
ctx (Any)
recipient (Optional[str])
Returns:
None
"""
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!
Args:
ctx (Any)
recipient (Optional[str])
Returns:
None
"""
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!
Args:
ctx (Any)
recipient (Optional[str])
Returns:
None
"""
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!
Args:
ctx (Any)
recipient (Optional[str])
Returns:
None
"""
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!
Args:
ctx (Any)
recipient (Optional[str])
Returns:
None
"""
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!
Args:
ctx (Any)
Returns:
None
"""
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)
Args:
ctx (Any)
Returns;
None
"""
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!
Args:
ctx (Any)
recipient (Optional[str])
Returns:
None
"""
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!?
Args:
ctx (Any)
Returns:
None
"""
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!?
Args:
ctx (Any)
Returns:
None
"""
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.
Args:
ctx (Any)
term (str)
Returns:
None
"""
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
Args:
ctx (Any)
member (discord.Member)
Returns:
None
"""
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
Args:
ctx (Any)
member (discord.Member)
Returns:
None
"""
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))