if recipient is None
This commit is contained in:
		@@ -9,6 +9,7 @@ import traceback
 | 
				
			|||||||
import time
 | 
					import time
 | 
				
			||||||
import importlib
 | 
					import importlib
 | 
				
			||||||
import logging
 | 
					import logging
 | 
				
			||||||
 | 
					from typing import Optional
 | 
				
			||||||
import discord
 | 
					import discord
 | 
				
			||||||
import regex
 | 
					import regex
 | 
				
			||||||
from regex import Pattern
 | 
					from regex import Pattern
 | 
				
			||||||
@@ -30,7 +31,7 @@ class Util:
 | 
				
			|||||||
        self.timers: dict = {} # discord uid : timestamp, used for rate limiting
 | 
					        self.timers: dict = {} # discord uid : timestamp, used for rate limiting
 | 
				
			||||||
        self.karma_cooldown: int = 15 # 15 seconds between karma updates        
 | 
					        self.karma_cooldown: int = 15 # 15 seconds between karma updates        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def get_karma(self, keyword: str) -> int|str:
 | 
					    async def get_karma(self, keyword: str) -> int:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Get Karma for Keyword
 | 
					        Get Karma for Keyword
 | 
				
			||||||
        Args:
 | 
					        Args:
 | 
				
			||||||
@@ -50,15 +51,15 @@ class Util:
 | 
				
			|||||||
                    return resp.get('count')
 | 
					                    return resp.get('count')
 | 
				
			||||||
        except Exception as e:
 | 
					        except Exception as e:
 | 
				
			||||||
            traceback.print_exc()
 | 
					            traceback.print_exc()
 | 
				
			||||||
            return f"Failed-- {type(e).__name__}: {str(e)}"
 | 
					            return False
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
    async def get_top(self, n: int = 10) -> dict:
 | 
					    async def get_top(self, n: int = 10) -> Optional[dict]:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Get top (n=10) Karma
 | 
					        Get top (n=10) Karma
 | 
				
			||||||
        Args:
 | 
					        Args:
 | 
				
			||||||
            n (int): Number of top results to return, default 10
 | 
					            n (int): Number of top results to return, default 10
 | 
				
			||||||
        Returns:
 | 
					        Returns:
 | 
				
			||||||
            dict
 | 
					            Optional[dict]
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            async with ClientSession() as session:
 | 
					            async with ClientSession() as session:
 | 
				
			||||||
@@ -74,8 +75,9 @@ class Util:
 | 
				
			|||||||
                    return resp
 | 
					                    return resp
 | 
				
			||||||
        except:
 | 
					        except:
 | 
				
			||||||
            traceback.print_exc()
 | 
					            traceback.print_exc()
 | 
				
			||||||
 | 
					            return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def get_top_embed(self, n:int = 10) -> discord.Embed:
 | 
					    async def get_top_embed(self, n:int = 10) -> Optional[discord.Embed]:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Get Top Karma Embed
 | 
					        Get Top Karma Embed
 | 
				
			||||||
        Args:
 | 
					        Args:
 | 
				
			||||||
@@ -83,11 +85,13 @@ class Util:
 | 
				
			|||||||
        Returns:
 | 
					        Returns:
 | 
				
			||||||
            discord.Embed
 | 
					            discord.Embed
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        top: dict = await self.get_top(n)
 | 
					        top: Optional[dict] = await self.get_top(n)
 | 
				
			||||||
 | 
					        if not top:
 | 
				
			||||||
 | 
					            return None
 | 
				
			||||||
        top_formatted: str = ""
 | 
					        top_formatted: str = ""
 | 
				
			||||||
        for x, item in enumerate(top):
 | 
					        for x, item in enumerate(top):
 | 
				
			||||||
            top_formatted += f"{x+1}. **{discord.utils.escape_markdown(item[0])}**: *{item[1]}*\n"
 | 
					            top_formatted += f"{x+1}. **{discord.utils.escape_markdown(item[0])}**: *{item[1]}*\n"
 | 
				
			||||||
        top_formatted: str = top_formatted.strip()
 | 
					        top_formatted = top_formatted.strip()
 | 
				
			||||||
        embed: discord.Embed = discord.Embed(title=f"Top {n} Karma",
 | 
					        embed: discord.Embed = discord.Embed(title=f"Top {n} Karma",
 | 
				
			||||||
                            description=top_formatted,
 | 
					                            description=top_formatted,
 | 
				
			||||||
                            colour=0xff00ff)
 | 
					                            colour=0xff00ff)
 | 
				
			||||||
@@ -103,7 +107,7 @@ class Util:
 | 
				
			|||||||
            flag (int)
 | 
					            flag (int)
 | 
				
			||||||
            """
 | 
					            """
 | 
				
			||||||
        if not flag in [0, 1]:
 | 
					        if not flag in [0, 1]:
 | 
				
			||||||
            return
 | 
					            return False
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        reqObj: dict = {
 | 
					        reqObj: dict = {
 | 
				
			||||||
            'granter': f"Discord: {display} ({_id})",
 | 
					            'granter': f"Discord: {display} ({_id})",
 | 
				
			||||||
@@ -171,6 +175,8 @@ class Karma(commands.Cog):
 | 
				
			|||||||
        try:
 | 
					        try:
 | 
				
			||||||
            top_embed = await self.util.get_top_embed(n=25)
 | 
					            top_embed = await self.util.get_top_embed(n=25)
 | 
				
			||||||
            channel = self.bot.get_channel(self.karma_chanid)
 | 
					            channel = self.bot.get_channel(self.karma_chanid)
 | 
				
			||||||
 | 
					            if not isinstance(channel, discord.TextChannel):
 | 
				
			||||||
 | 
					                return
 | 
				
			||||||
            message_to_edit = await channel.fetch_message(self.karma_msgid)
 | 
					            message_to_edit = await channel.fetch_message(self.karma_msgid)
 | 
				
			||||||
            await message_to_edit.edit(embed=top_embed,
 | 
					            await message_to_edit.edit(embed=top_embed,
 | 
				
			||||||
                                    content="## This message will automatically update periodically.")
 | 
					                                    content="## This message will automatically update periodically.")
 | 
				
			||||||
@@ -184,7 +190,10 @@ class Karma(commands.Cog):
 | 
				
			|||||||
        Message hook, to monitor for ++/--
 | 
					        Message hook, to monitor for ++/--
 | 
				
			||||||
        Also monitors for messages to #karma to autodelete, only Havoc may post in #karma!
 | 
					        Also monitors for messages to #karma to autodelete, only Havoc may post in #karma!
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
 | 
					        if not self.bot.user: # No valid client instance
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					        if not isinstance(message.channel, discord.TextChannel):
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
        if message.channel.id == self.karma_chanid and not message.author.id == self.bot.user.id:
 | 
					        if message.channel.id == self.karma_chanid and not message.author.id == self.bot.user.id:
 | 
				
			||||||
            """Message to #karma not by Havoc, delete it"""
 | 
					            """Message to #karma not by Havoc, delete it"""
 | 
				
			||||||
            await message.delete(reason="Messages to #karma are not allowed")
 | 
					            await message.delete(reason="Messages to #karma are not allowed")
 | 
				
			||||||
@@ -192,12 +201,13 @@ class Karma(commands.Cog):
 | 
				
			|||||||
                title="Message Deleted",
 | 
					                title="Message Deleted",
 | 
				
			||||||
                description=f"Your message to **#{message.channel.name}** has been automatically deleted.\n**Reason**: Messages to this channel by users is not allowed."
 | 
					                description=f"Your message to **#{message.channel.name}** has been automatically deleted.\n**Reason**: Messages to this channel by users is not allowed."
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            return await message.author.send(embed=removal_embed)
 | 
					            await message.author.send(embed=removal_embed)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if message.author.id == self.bot.user.id: # Bots own message
 | 
					        if message.author.id == self.bot.user.id: # Bots own message
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
        
 | 
					        if not message.guild:
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
        if not message.guild.id in [1145182936002482196, 1228740575235149855]: # Not a valid guild for cmd
 | 
					        if not message.guild.id in [1145182936002482196, 1228740575235149855]: # Not a valid guild for cmd
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
@@ -209,15 +219,19 @@ class Karma(commands.Cog):
 | 
				
			|||||||
                logging.debug("Mention: %s", mention)
 | 
					                logging.debug("Mention: %s", mention)
 | 
				
			||||||
                mentioned_uid: int = int(mention[1])
 | 
					                mentioned_uid: int = int(mention[1])
 | 
				
			||||||
                friendly_flag: int = int(mention[2])
 | 
					                friendly_flag: int = int(mention[2])
 | 
				
			||||||
                guild: discord.Guild = self.bot.get_guild(message.guild.id)
 | 
					                guild: Optional[discord.Guild] = self.bot.get_guild(message.guild.id)
 | 
				
			||||||
                guild_member: discord.Member = guild.get_member(mentioned_uid)
 | 
					                if not guild:
 | 
				
			||||||
 | 
					                    return
 | 
				
			||||||
 | 
					                guild_member: Optional[discord.Member] = guild.get_member(mentioned_uid)
 | 
				
			||||||
 | 
					                if not guild_member:
 | 
				
			||||||
 | 
					                    return
 | 
				
			||||||
                display: str = guild_member.display_name
 | 
					                display: str = guild_member.display_name
 | 
				
			||||||
                message_content: str = message_content.replace(mention[0], display)
 | 
					                message_content = message_content.replace(mention[0], display)
 | 
				
			||||||
                logging.debug("New message: %s", message_content)
 | 
					                logging.debug("New message: %s", message_content)
 | 
				
			||||||
            except:
 | 
					            except:
 | 
				
			||||||
                traceback.print_exc()
 | 
					                traceback.print_exc()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        message_content: str = discord.utils.escape_markdown(message_content)
 | 
					        message_content = discord.utils.escape_markdown(message_content)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        karma_regex: list[str] = regex.findall(self.karma_regex, message_content.strip())
 | 
					        karma_regex: list[str] = regex.findall(self.karma_regex, message_content.strip())
 | 
				
			||||||
        if not karma_regex:  # Not a request to adjust karma
 | 
					        if not karma_regex:  # Not a request to adjust karma
 | 
				
			||||||
@@ -233,6 +247,8 @@ class Karma(commands.Cog):
 | 
				
			|||||||
        logging.debug("Matched: %s", karma_regex)
 | 
					        logging.debug("Matched: %s", karma_regex)
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        for matched_keyword in karma_regex:
 | 
					        for matched_keyword in karma_regex:
 | 
				
			||||||
 | 
					            if not isinstance(matched_keyword, tuple):
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
            if len(matched_keyword) == 4:
 | 
					            if len(matched_keyword) == 4:
 | 
				
			||||||
                (keyword, friendly_flag, _, __) = matched_keyword
 | 
					                (keyword, friendly_flag, _, __) = matched_keyword
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
@@ -242,9 +258,9 @@ class Karma(commands.Cog):
 | 
				
			|||||||
            flag: int = None
 | 
					            flag: int = None
 | 
				
			||||||
            match friendly_flag:
 | 
					            match friendly_flag:
 | 
				
			||||||
                case "++":
 | 
					                case "++":
 | 
				
			||||||
                    flag: int = 0
 | 
					                    flag = 0
 | 
				
			||||||
                case "--":
 | 
					                case "--":
 | 
				
			||||||
                    flag: int = 1
 | 
					                    flag = 1
 | 
				
			||||||
                case _:
 | 
					                case _:
 | 
				
			||||||
                    logging.info("Unknown flag %s", flag)
 | 
					                    logging.info("Unknown flag %s", flag)
 | 
				
			||||||
                    continue
 | 
					                    continue
 | 
				
			||||||
@@ -266,18 +282,24 @@ class Karma(commands.Cog):
 | 
				
			|||||||
        """With no arguments, top 10 karma is provided; a keyword can also be provided to lookup."""
 | 
					        """With no arguments, top 10 karma is provided; a keyword can also be provided to lookup."""
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            if not keyword:
 | 
					            if not keyword:
 | 
				
			||||||
                top_10_embed: discord.Embed = await self.util.get_top_embed()
 | 
					                top_10_embed: Optional[discord.Embed] = await self.util.get_top_embed()
 | 
				
			||||||
 | 
					                if not top_10_embed:
 | 
				
			||||||
 | 
					                    return
 | 
				
			||||||
                return await ctx.respond(embed=top_10_embed)
 | 
					                return await ctx.respond(embed=top_10_embed)
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            keyword: str = discord.utils.escape_markdown(keyword)
 | 
					            keyword = discord.utils.escape_markdown(keyword)
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            mentions: list[str] = regex.findall(self.mention_regex_no_flag, keyword)
 | 
					            mentions: list[str] = regex.findall(self.mention_regex_no_flag, keyword)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            for mention in mentions:
 | 
					            for mention in mentions:
 | 
				
			||||||
                try:
 | 
					                try:
 | 
				
			||||||
                    mentioned_uid = int(mention[1])
 | 
					                    mentioned_uid = int(mention[1])
 | 
				
			||||||
                    guild = self.bot.get_guild(ctx.guild.id)
 | 
					                    guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id)
 | 
				
			||||||
                    guild_member = guild.get_member(mentioned_uid)
 | 
					                    if not guild:
 | 
				
			||||||
 | 
					                        return
 | 
				
			||||||
 | 
					                    guild_member: Optional[discord.Member] = guild.get_member(mentioned_uid)
 | 
				
			||||||
 | 
					                    if not guild_member:
 | 
				
			||||||
 | 
					                        return
 | 
				
			||||||
                    display = guild_member.display_name
 | 
					                    display = guild_member.display_name
 | 
				
			||||||
                    keyword = keyword.replace(mention[0], display)
 | 
					                    keyword = keyword.replace(mention[0], display)
 | 
				
			||||||
                except:
 | 
					                except:
 | 
				
			||||||
@@ -286,8 +308,6 @@ class Karma(commands.Cog):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            score: int = await self.util.get_karma(keyword)
 | 
					            score: int = await self.util.get_karma(keyword)
 | 
				
			||||||
            description: str = f"**{keyword}** has a karma of *{score}*"
 | 
					            description: str = f"**{keyword}** has a karma of *{score}*"
 | 
				
			||||||
            if isinstance(score, dict) and score.get('err'):
 | 
					 | 
				
			||||||
                description: str = f"*{score.get('errorText')}*"
 | 
					 | 
				
			||||||
            embed: discord.Embed = discord.Embed(title=f"Karma for {keyword}",
 | 
					            embed: discord.Embed = discord.Embed(title=f"Karma for {keyword}",
 | 
				
			||||||
                                                 description=description)
 | 
					                                                 description=description)
 | 
				
			||||||
            return await ctx.respond(embed=embed)
 | 
					            return await ctx.respond(embed=embed)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										102
									
								
								cogs/lovehate.py
									
									
									
									
									
								
							
							
						
						
									
										102
									
								
								cogs/lovehate.py
									
									
									
									
									
								
							@@ -4,7 +4,7 @@
 | 
				
			|||||||
import traceback
 | 
					import traceback
 | 
				
			||||||
import logging
 | 
					import logging
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
from typing import Any, Optional
 | 
					from typing import Any, Optional, Union
 | 
				
			||||||
import discord
 | 
					import discord
 | 
				
			||||||
import aiosqlite as sqlite3
 | 
					import aiosqlite as sqlite3
 | 
				
			||||||
from discord.ext import bridge, commands
 | 
					from discord.ext import bridge, commands
 | 
				
			||||||
@@ -43,11 +43,15 @@ class LoveHate(commands.Cog):
 | 
				
			|||||||
        """
 | 
					        """
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            if not user:
 | 
					            if not user:
 | 
				
			||||||
                loves: list[tuple] = await self.db.get_lovehates(user=ctx.author.display_name, loves=True)
 | 
					                display_name = ctx.author.display_name
 | 
				
			||||||
 | 
					                loves: Union[list[tuple], bool] = await self.db.get_lovehates(user=display_name,
 | 
				
			||||||
 | 
					                                                                              loves=True)
 | 
				
			||||||
                if not loves:
 | 
					                if not loves:
 | 
				
			||||||
                    return await ctx.respond("You don't seem to love anything...")
 | 
					                    return await ctx.respond("You don't seem to love anything...")
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                out_loves: list = []
 | 
					                out_loves: list = []
 | 
				
			||||||
 | 
					                if not isinstance(loves, list):
 | 
				
			||||||
 | 
					                    return
 | 
				
			||||||
                for love in loves:
 | 
					                for love in loves:
 | 
				
			||||||
                    (love,) = love
 | 
					                    (love,) = love
 | 
				
			||||||
                    out_loves.append(love)
 | 
					                    out_loves.append(love)
 | 
				
			||||||
@@ -55,11 +59,11 @@ class LoveHate(commands.Cog):
 | 
				
			|||||||
                out_loves_str: str = self.join_with_and(out_loves)
 | 
					                out_loves_str: str = self.join_with_and(out_loves)
 | 
				
			||||||
                return await ctx.respond(f"{ctx.author.mention} loves {out_loves_str}")
 | 
					                return await ctx.respond(f"{ctx.author.mention} loves {out_loves_str}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            loves: list[tuple] = await self.db.get_lovehates(user=user.strip(), loves=True)
 | 
					            loves = await self.db.get_lovehates(user=user.strip(), loves=True)
 | 
				
			||||||
            if not loves:
 | 
					            if not loves:
 | 
				
			||||||
                return await ctx.respond(f"{user} doesn't seem to love anything...")            
 | 
					                return await ctx.respond(f"{user} doesn't seem to love anything...")            
 | 
				
			||||||
              
 | 
					              
 | 
				
			||||||
            out_loves_str: str = self.join_with_and(out_loves)
 | 
					            out_loves_str = self.join_with_and(out_loves)
 | 
				
			||||||
            return await ctx.respond(f"{user} loves {out_loves_str}")
 | 
					            return await ctx.respond(f"{user} loves {out_loves_str}")
 | 
				
			||||||
        except Exception as e:
 | 
					        except Exception as e:
 | 
				
			||||||
            traceback.print_exc()
 | 
					            traceback.print_exc()
 | 
				
			||||||
@@ -77,15 +81,27 @@ class LoveHate(commands.Cog):
 | 
				
			|||||||
        """
 | 
					        """
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            if not thing:
 | 
					            if not thing:
 | 
				
			||||||
                thing: str = ctx.author.display_name
 | 
					                _thing: str = ctx.author.display_name
 | 
				
			||||||
            if discord.utils.raw_mentions(thing):
 | 
					            else:
 | 
				
			||||||
 | 
					                _thing = thing
 | 
				
			||||||
 | 
					            if discord.utils.raw_mentions(_thing):
 | 
				
			||||||
                # There are mentions
 | 
					                # There are mentions
 | 
				
			||||||
                thing_id: int = discord.utils.raw_mentions(thing)[0] # First mention
 | 
					                thing_id: int = discord.utils.raw_mentions(_thing)[0] # First mention
 | 
				
			||||||
                thing: str = self.bot.get_guild(ctx.guild.id).get_member(thing_id).display_name
 | 
					                guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id)
 | 
				
			||||||
 | 
					                if not guild:
 | 
				
			||||||
 | 
					                    return
 | 
				
			||||||
 | 
					                thing_member: Optional[discord.Member] = guild.get_member(thing_id)
 | 
				
			||||||
 | 
					                if not thing_member:
 | 
				
			||||||
 | 
					                    return
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                _thing = thing_member.display_name
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            who_loves: list[tuple] = await self.db.get_wholovehates(thing=thing,
 | 
					            if not _thing:
 | 
				
			||||||
 | 
					                return
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					            who_loves: Union[list, bool] = await self.db.get_wholovehates(thing=_thing,
 | 
				
			||||||
                                                    loves=True)
 | 
					                                                    loves=True)
 | 
				
			||||||
            if not who_loves:
 | 
					            if not isinstance(who_loves, list):
 | 
				
			||||||
                return await ctx.respond(f"I couldn't find anyone who loves {thing}...")
 | 
					                return await ctx.respond(f"I couldn't find anyone who loves {thing}...")
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            out_wholoves: list = []
 | 
					            out_wholoves: list = []
 | 
				
			||||||
@@ -114,18 +130,28 @@ class LoveHate(commands.Cog):
 | 
				
			|||||||
        """
 | 
					        """
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            if not thing:
 | 
					            if not thing:
 | 
				
			||||||
                thing: str = ctx.author.display_name
 | 
					                _thing: str = ctx.author.display_name
 | 
				
			||||||
            if discord.utils.raw_mentions(thing):
 | 
					            else:
 | 
				
			||||||
 | 
					                _thing = thing
 | 
				
			||||||
 | 
					            if discord.utils.raw_mentions(_thing):
 | 
				
			||||||
                # There are mentions
 | 
					                # There are mentions
 | 
				
			||||||
                thing_id: int = discord.utils.raw_mentions(thing)[0] # First mention
 | 
					                guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id)
 | 
				
			||||||
                thing: str = self.bot.get_guild(ctx.guild.id).get_member(thing_id).display_name        
 | 
					                if not guild:
 | 
				
			||||||
 | 
					                    return
 | 
				
			||||||
 | 
					                thing_id: int = discord.utils.raw_mentions(_thing)[0] # First mention
 | 
				
			||||||
 | 
					                thing_member: Optional[discord.Member] = guild.get_member(thing_id)
 | 
				
			||||||
 | 
					                if not thing_member:
 | 
				
			||||||
 | 
					                    return
 | 
				
			||||||
 | 
					                _thing = thing_member.display_name        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            who_hates: list[tuple] = await self.db.get_wholovehates(thing=thing,
 | 
					            who_hates: Union[list[tuple], bool] = await self.db.get_wholovehates(thing=_thing,
 | 
				
			||||||
                                                    hates=True)
 | 
					                                                    hates=True)
 | 
				
			||||||
            if not who_hates:
 | 
					            if not who_hates:
 | 
				
			||||||
                return await ctx.respond(f"I couldn't find anyone who hates {thing}...")
 | 
					                return await ctx.respond(f"I couldn't find anyone who hates {thing}...")
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            out_whohates: list = []
 | 
					            out_whohates: list = []
 | 
				
			||||||
 | 
					            if not isinstance(who_hates, list):
 | 
				
			||||||
 | 
					                return
 | 
				
			||||||
            for hater in who_hates:
 | 
					            for hater in who_hates:
 | 
				
			||||||
                (hater,) = hater
 | 
					                (hater,) = hater
 | 
				
			||||||
                out_whohates.append(str(hater))
 | 
					                out_whohates.append(str(hater))
 | 
				
			||||||
@@ -170,26 +196,24 @@ class LoveHate(commands.Cog):
 | 
				
			|||||||
        """
 | 
					        """
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            if not user:
 | 
					            if not user:
 | 
				
			||||||
                hates: list[tuple] = await self.db.get_lovehates(user=ctx.author.display_name,
 | 
					                display_name = ctx.author.display_name
 | 
				
			||||||
 | 
					                hates: Union[list[tuple], bool] = await self.db.get_lovehates(user=display_name,
 | 
				
			||||||
                                                                 hates=True)
 | 
					                                                                 hates=True)
 | 
				
			||||||
                if not hates:
 | 
					                if not hates:
 | 
				
			||||||
                    return await ctx.respond("You don't seem to hate anything...")
 | 
					                    return await ctx.respond("You don't seem to hate anything...")
 | 
				
			||||||
                
 | 
					            else:
 | 
				
			||||||
                out_hates: list = []
 | 
					                hates = await self.db.get_lovehates(user=user.strip(), hates=True)
 | 
				
			||||||
                for hated_thing in hates:
 | 
					                if not hates:
 | 
				
			||||||
                    (hated_thing,) = hated_thing
 | 
					                    return await ctx.respond(f"{user} doesn't seem to hate anything...")            
 | 
				
			||||||
                    out_hates.append(str(hated_thing))
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                out_hates_str: str = self.join_with_and(out_hates)
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                return await ctx.respond(f"{ctx.author.mention} hates {out_hates_str}")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            hates: list[tuple] = await self.db.get_lovehates(user=user.strip(), hates=True)
 | 
					 | 
				
			||||||
            if not hates:
 | 
					 | 
				
			||||||
                return await ctx.respond(f"{user} doesn't seem to hate anything...")            
 | 
					 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            out_hates_str: str = self.join_with_and(hates)
 | 
					            out_hates: list = []
 | 
				
			||||||
 | 
					            if not isinstance(hates, list):
 | 
				
			||||||
 | 
					                return
 | 
				
			||||||
 | 
					            for hated_thing in hates:
 | 
				
			||||||
 | 
					                (hated_thing,) = hated_thing
 | 
				
			||||||
 | 
					                out_hates.append(str(hated_thing))
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            out_hates_str: str = self.join_with_and(out_hates)            
 | 
				
			||||||
            return await ctx.respond(f"{user} hates {out_hates_str}")
 | 
					            return await ctx.respond(f"{user} hates {out_hates_str}")
 | 
				
			||||||
        except Exception as e:
 | 
					        except Exception as e:
 | 
				
			||||||
            await ctx.respond(f"Error: {str(e)}")
 | 
					            await ctx.respond(f"Error: {str(e)}")
 | 
				
			||||||
@@ -209,7 +233,13 @@ class LoveHate(commands.Cog):
 | 
				
			|||||||
            if discord.utils.raw_mentions(thing):
 | 
					            if discord.utils.raw_mentions(thing):
 | 
				
			||||||
                # There are mentions
 | 
					                # There are mentions
 | 
				
			||||||
                thing_id: int = discord.utils.raw_mentions(thing)[0] # First mention
 | 
					                thing_id: int = discord.utils.raw_mentions(thing)[0] # First mention
 | 
				
			||||||
                thing: str = self.bot.get_guild(ctx.guild.id).get_member(thing_id).display_name
 | 
					                guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild)
 | 
				
			||||||
 | 
					                if not guild:
 | 
				
			||||||
 | 
					                    return
 | 
				
			||||||
 | 
					                thing_member: Optional[discord.Member] = guild.get_member(thing_id)
 | 
				
			||||||
 | 
					                if not thing_member:
 | 
				
			||||||
 | 
					                    return
 | 
				
			||||||
 | 
					                thing = thing_member.display_name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            love: str = await self.db.update(ctx.author.display_name,
 | 
					            love: str = await self.db.update(ctx.author.display_name,
 | 
				
			||||||
                                               thing, 1)
 | 
					                                               thing, 1)
 | 
				
			||||||
@@ -232,7 +262,13 @@ class LoveHate(commands.Cog):
 | 
				
			|||||||
            if discord.utils.raw_mentions(thing):
 | 
					            if discord.utils.raw_mentions(thing):
 | 
				
			||||||
                # There are mentions
 | 
					                # There are mentions
 | 
				
			||||||
                thing_id: int = discord.utils.raw_mentions(thing)[0] # First mention
 | 
					                thing_id: int = discord.utils.raw_mentions(thing)[0] # First mention
 | 
				
			||||||
                thing: str = self.bot.get_guild(ctx.guild.id).get_member(thing_id).display_name
 | 
					                guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id)
 | 
				
			||||||
 | 
					                if not guild:
 | 
				
			||||||
 | 
					                    return
 | 
				
			||||||
 | 
					                thing_member: Optional[discord.Member] = guild.get_member(thing_id)
 | 
				
			||||||
 | 
					                if not thing_member:
 | 
				
			||||||
 | 
					                    return
 | 
				
			||||||
 | 
					                thing = thing_member.display_name
 | 
				
			||||||
            hate: str = await self.db.update(ctx.author.display_name,
 | 
					            hate: str = await self.db.update(ctx.author.display_name,
 | 
				
			||||||
                                               thing, -1)
 | 
					                                               thing, -1)
 | 
				
			||||||
            return await ctx.respond(hate)            
 | 
					            return await ctx.respond(hate)            
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										542
									
								
								cogs/misc.py
									
									
									
									
									
								
							
							
						
						
									
										542
									
								
								cogs/misc.py
									
									
									
									
									
								
							@@ -8,11 +8,12 @@ import random
 | 
				
			|||||||
from typing import Optional, LiteralString
 | 
					from typing import Optional, LiteralString
 | 
				
			||||||
import logging
 | 
					import logging
 | 
				
			||||||
import discord
 | 
					import discord
 | 
				
			||||||
from .misc_util import Util
 | 
					from cogs.misc_util import Util
 | 
				
			||||||
import aiosqlite as sqlite3
 | 
					import aiosqlite as sqlite3
 | 
				
			||||||
from sh import cowsay as cow_say, fortune # pylint: disable=no-name-in-module
 | 
					from sh import cowsay as cow_say, fortune # pylint: disable=no-name-in-module
 | 
				
			||||||
from discord.ext import bridge, commands, tasks
 | 
					from discord.ext import bridge, commands, tasks
 | 
				
			||||||
from disc_havoc import Havoc
 | 
					from disc_havoc import Havoc
 | 
				
			||||||
 | 
					from constructors import MiscException
 | 
				
			||||||
# pylint: disable=bare-except, broad-exception-caught, broad-exception-raised, global-statement
 | 
					# pylint: disable=bare-except, broad-exception-caught, broad-exception-raised, global-statement
 | 
				
			||||||
# pylint: disable=too-many-lines, invalid-name
 | 
					# pylint: disable=too-many-lines, invalid-name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -64,7 +65,7 @@ class Misc(commands.Cog):
 | 
				
			|||||||
        global BOT_CHANIDS
 | 
					        global BOT_CHANIDS
 | 
				
			||||||
        BOT_CHANIDS = self.bot.BOT_CHANIDS
 | 
					        BOT_CHANIDS = self.bot.BOT_CHANIDS
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
    def is_spamchan() -> bool: # pylint: disable=no-method-argument
 | 
					    def is_spamchan() -> bool: # type: ignore
 | 
				
			||||||
        """Check if channel is spamchan"""
 | 
					        """Check if channel is spamchan"""
 | 
				
			||||||
        def predicate(ctx):
 | 
					        def predicate(ctx):
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
@@ -74,9 +75,9 @@ class Misc(commands.Cog):
 | 
				
			|||||||
            except:
 | 
					            except:
 | 
				
			||||||
                traceback.print_exc()
 | 
					                traceback.print_exc()
 | 
				
			||||||
                return False
 | 
					                return False
 | 
				
			||||||
        return commands.check(predicate)
 | 
					        return commands.check(predicate) # type: ignore
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    def is_spamchan_or_drugs() -> bool: # pylint: disable=no-method-argument
 | 
					    def is_spamchan_or_drugs() -> bool: # type: ignore
 | 
				
			||||||
        """Check if channel is spamchan or drugs chan"""
 | 
					        """Check if channel is spamchan or drugs chan"""
 | 
				
			||||||
        def predicate(ctx):
 | 
					        def predicate(ctx):
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
@@ -86,10 +87,10 @@ class Misc(commands.Cog):
 | 
				
			|||||||
            except:
 | 
					            except:
 | 
				
			||||||
                traceback.print_exc()
 | 
					                traceback.print_exc()
 | 
				
			||||||
                return False
 | 
					                return False
 | 
				
			||||||
        return commands.check(predicate)     
 | 
					        return commands.check(predicate) # type: ignore     
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def get_random_guild_member(self, online_only: Optional[bool] = False) -> str:
 | 
					    async def get_random_guild_member(self, online_only: Optional[bool] = False) -> Optional[str]:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Get Random Guild Member
 | 
					        Get Random Guild Member
 | 
				
			||||||
        Args:
 | 
					        Args:
 | 
				
			||||||
@@ -97,7 +98,9 @@ class Misc(commands.Cog):
 | 
				
			|||||||
        Returns:
 | 
					        Returns:
 | 
				
			||||||
            str
 | 
					            str
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        guild = self.bot.get_guild(1145182936002482196)
 | 
					        guild: Optional[discord.Guild] = self.bot.get_guild(1145182936002482196)
 | 
				
			||||||
 | 
					        if not guild:
 | 
				
			||||||
 | 
					            return None
 | 
				
			||||||
        if not online_only:
 | 
					        if not online_only:
 | 
				
			||||||
            guild_members = [str(member.display_name) for member in guild.members if not member.bot]
 | 
					            guild_members = [str(member.display_name) for member in guild.members if not member.bot]
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
@@ -115,14 +118,16 @@ class Misc(commands.Cog):
 | 
				
			|||||||
            None
 | 
					            None
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            stats_embed: discord.Embed = await self.util.get_stats_embed()
 | 
					            stats_embed: Optional[discord.Embed] = await self.util.get_stats_embed()
 | 
				
			||||||
 | 
					            if not stats_embed:
 | 
				
			||||||
 | 
					                return
 | 
				
			||||||
            return await ctx.respond(embed=stats_embed)
 | 
					            return await ctx.respond(embed=stats_embed)
 | 
				
			||||||
        except Exception as e:
 | 
					        except Exception as e:
 | 
				
			||||||
            traceback.print_exc()
 | 
					            traceback.print_exc()
 | 
				
			||||||
            return await ctx.respond(f"Error: {str(e)}")
 | 
					            return await ctx.respond(f"Error: {str(e)}")
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
    @bridge.bridge_command()
 | 
					    @bridge.bridge_command() # type: ignore
 | 
				
			||||||
    @is_spamchan_or_drugs() # pylint: disable=too-many-function-args
 | 
					    @is_spamchan_or_drugs() 
 | 
				
			||||||
    async def listcoffees(self, ctx) -> None:
 | 
					    async def listcoffees(self, ctx) -> None:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        List Available Coffees
 | 
					        List Available Coffees
 | 
				
			||||||
@@ -142,8 +147,8 @@ class Misc(commands.Cog):
 | 
				
			|||||||
            traceback.print_exc()            
 | 
					            traceback.print_exc()            
 | 
				
			||||||
            return await ctx.respond(f"Error: {str(e)}")
 | 
					            return await ctx.respond(f"Error: {str(e)}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @bridge.bridge_command()
 | 
					    @bridge.bridge_command() # type: ignore
 | 
				
			||||||
    @is_spamchan_or_drugs() # pylint: disable=too-many-function-args
 | 
					    @is_spamchan_or_drugs() 
 | 
				
			||||||
    async def listshoves(self, ctx) -> None:
 | 
					    async def listshoves(self, ctx) -> None:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        List Available Fates for shove command
 | 
					        List Available Fates for shove command
 | 
				
			||||||
@@ -187,7 +192,10 @@ class Misc(commands.Cog):
 | 
				
			|||||||
                '9': '9️⃣',
 | 
					                '9': '9️⃣',
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            with ctx.channel.typing():
 | 
					            with ctx.channel.typing():
 | 
				
			||||||
                (days, hours, minutes, seconds, ms, us) = self.util.get_days_to_xmas() # pylint: disable=unused-variable
 | 
					                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()
 | 
					                now: datetime.datetime = datetime.datetime.now()
 | 
				
			||||||
                if now.month == 12 and now.day == 25:
 | 
					                if now.month == 12 and now.day == 25:
 | 
				
			||||||
                    return await ctx.respond("# IT IS CHRISTMAS!!!!!!!!\n-# keep the change, you filthy animal")                    
 | 
					                    return await ctx.respond("# IT IS CHRISTMAS!!!!!!!!\n-# keep the change, you filthy animal")                    
 | 
				
			||||||
@@ -235,19 +243,24 @@ class Misc(commands.Cog):
 | 
				
			|||||||
            None
 | 
					            None
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        try:
 | 
					        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)\
 | 
					            authorDisplay: str = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
				
			||||||
                else ctx.message.author.display_name
 | 
					                else ctx.message.author.display_name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if recipient is None:
 | 
					            if not recipient:
 | 
				
			||||||
                recipient: str = authorDisplay.strip()
 | 
					                recipient = authorDisplay.strip()
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                if discord.utils.raw_mentions(recipient):
 | 
					                if discord.utils.raw_mentions(recipient):
 | 
				
			||||||
                    # There are mentions
 | 
					                    # There are mentions
 | 
				
			||||||
                    recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
					                    recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
				
			||||||
                    recipient: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                    recipient_member: Optional[discord.Member] = guild.get_member(recipient_id)
 | 
				
			||||||
                        .get_member(recipient_id).display_name
 | 
					                    if not recipient_member:
 | 
				
			||||||
 | 
					                        return 
 | 
				
			||||||
 | 
					                    recipient = recipient_member.display_name
 | 
				
			||||||
                else:
 | 
					                else:
 | 
				
			||||||
                    recipient: str = discord.utils.escape_mentions(recipient.strip())         
 | 
					                    recipient = discord.utils.escape_mentions(recipient.strip())         
 | 
				
			||||||
            with ctx.channel.typing():
 | 
					            with ctx.channel.typing():
 | 
				
			||||||
                insult: str = await self.util.get_insult(recipient)
 | 
					                insult: str = await self.util.get_insult(recipient)
 | 
				
			||||||
                if insult:
 | 
					                if insult:
 | 
				
			||||||
@@ -272,16 +285,21 @@ class Misc(commands.Cog):
 | 
				
			|||||||
            authorDisplay: str = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
					            authorDisplay: str = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
				
			||||||
                else ctx.message.author.display_name
 | 
					                else ctx.message.author.display_name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if recipient is None:
 | 
					            if not recipient:
 | 
				
			||||||
                recipient: str = authorDisplay.strip()
 | 
					                recipient = authorDisplay.strip()
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                if discord.utils.raw_mentions(recipient):
 | 
					                if discord.utils.raw_mentions(recipient):
 | 
				
			||||||
                    # There are mentions
 | 
					                    # There are mentions
 | 
				
			||||||
                    recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
					                    recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
				
			||||||
                    recipient: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                    guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id)
 | 
				
			||||||
                        .get_member(recipient_id).display_name
 | 
					                    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:
 | 
					                else:
 | 
				
			||||||
                    recipient: str = discord.utils.escape_mentions(recipient.strip())         
 | 
					                    recipient = discord.utils.escape_mentions(recipient.strip())         
 | 
				
			||||||
            with ctx.channel.typing():
 | 
					            with ctx.channel.typing():
 | 
				
			||||||
                compliment: str = await self.util.get_compliment(recipient)
 | 
					                compliment: str = await self.util.get_compliment(recipient)
 | 
				
			||||||
                if compliment:
 | 
					                if compliment:
 | 
				
			||||||
@@ -304,17 +322,25 @@ class Misc(commands.Cog):
 | 
				
			|||||||
        """
 | 
					        """
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            if not recipient:
 | 
					            if not recipient:
 | 
				
			||||||
                recipient: str = ctx.author.display_name
 | 
					                recipient = ctx.author.display_name
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                if discord.utils.raw_mentions(recipient):
 | 
					                if discord.utils.raw_mentions(recipient):
 | 
				
			||||||
                    # There are mentions
 | 
					                    # There are mentions
 | 
				
			||||||
                    recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
					                    recipient_id = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
				
			||||||
                    recipient: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                    guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id)
 | 
				
			||||||
                        .get_member(recipient_id).display_name
 | 
					                    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:
 | 
					                else:
 | 
				
			||||||
                    recipient: str = discord.utils.escape_mentions(recipient.strip())
 | 
					                    recipient = discord.utils.escape_mentions(recipient.strip())
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            (choice_name, choice_category, choice_description) = await self.util.get_whisky()
 | 
					            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}",
 | 
					            embed: discord.Embed = discord.Embed(title=f"Whisky for {recipient}: {choice_name}",
 | 
				
			||||||
                                                 description=choice_description.strip())
 | 
					                                                 description=choice_description.strip())
 | 
				
			||||||
            embed.add_field(name="Category", value=choice_category, inline=True)
 | 
					            embed.add_field(name="Category", value=choice_category, inline=True)
 | 
				
			||||||
@@ -339,17 +365,27 @@ class Misc(commands.Cog):
 | 
				
			|||||||
        """
 | 
					        """
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            if not recipient:
 | 
					            if not recipient:
 | 
				
			||||||
                recipient: str = ctx.author.display_name
 | 
					                recipient = ctx.author.display_name
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                if discord.utils.raw_mentions(recipient):
 | 
					                if discord.utils.raw_mentions(recipient):
 | 
				
			||||||
                    # There are mentions
 | 
					                    # There are mentions
 | 
				
			||||||
                    recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
					                    recipient_id = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
				
			||||||
                    recipient: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                    guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id)
 | 
				
			||||||
                        .get_member(recipient_id).display_name
 | 
					                    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:
 | 
					                else:
 | 
				
			||||||
                    recipient: str = discord.utils.escape_mentions(recipient.strip())
 | 
					                    recipient = discord.utils.escape_mentions(recipient.strip())
 | 
				
			||||||
        
 | 
					            
 | 
				
			||||||
            (choice_name, choice_ingredients) = await self.util.get_drink()
 | 
					            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()}*")
 | 
					            await ctx.respond(f"*is mixing up **{choice_name}** for {recipient.strip()}*")
 | 
				
			||||||
            embed: discord.Embed = discord.Embed(title=f"Cocktail for {recipient}",
 | 
					            embed: discord.Embed = discord.Embed(title=f"Cocktail for {recipient}",
 | 
				
			||||||
                                                 description=choice_name)
 | 
					                                                 description=choice_name)
 | 
				
			||||||
@@ -377,20 +413,24 @@ class Misc(commands.Cog):
 | 
				
			|||||||
        authorDisplay: str = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
					        authorDisplay: str = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
				
			||||||
            else ctx.message.author.display_name
 | 
					            else ctx.message.author.display_name
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        if recipient is None:
 | 
					        if not recipient:
 | 
				
			||||||
            recipient: str = authorDisplay.strip()
 | 
					            recipient = authorDisplay.strip()
 | 
				
			||||||
            recipient_normal: str = ctx.author.mention
 | 
					            recipient_normal: str = ctx.author.mention
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            recipient_normal: str = recipient
 | 
					            recipient_normal = recipient
 | 
				
			||||||
            if discord.utils.raw_mentions(recipient):
 | 
					            if discord.utils.raw_mentions(recipient):
 | 
				
			||||||
                # There are mentions
 | 
					                # There are mentions
 | 
				
			||||||
                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
					                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
				
			||||||
                recipient: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id)
 | 
				
			||||||
                    .get_member(recipient_id).display_name
 | 
					                if not guild:
 | 
				
			||||||
                recipient_normal: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                    return
 | 
				
			||||||
                    .get_member(recipient_id).mention
 | 
					                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:
 | 
					            else:
 | 
				
			||||||
                recipient: str = discord.utils.escape_mentions(recipient.strip())
 | 
					                recipient = discord.utils.escape_mentions(recipient.strip())
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            await ctx.respond(f"*sprays **{recipient_normal}** with water*")
 | 
					            await ctx.respond(f"*sprays **{recipient_normal}** with water*")
 | 
				
			||||||
            await self.util.increment_counter("water_sprays")            
 | 
					            await self.util.increment_counter("water_sprays")            
 | 
				
			||||||
@@ -412,20 +452,24 @@ class Misc(commands.Cog):
 | 
				
			|||||||
        authorDisplay: str = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
					        authorDisplay: str = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
				
			||||||
            else ctx.message.author.display_name
 | 
					            else ctx.message.author.display_name
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        if recipient is None:
 | 
					        if not recipient:
 | 
				
			||||||
            recipient: str = authorDisplay.strip()
 | 
					            recipient = authorDisplay.strip()
 | 
				
			||||||
            recipient_normal: str = ctx.author.mention
 | 
					            recipient_normal = ctx.author.mention
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            recipient_normal: str = recipient
 | 
					            recipient_normal = recipient
 | 
				
			||||||
            if discord.utils.raw_mentions(recipient):
 | 
					            if discord.utils.raw_mentions(recipient):
 | 
				
			||||||
                # There are mentions
 | 
					                # There are mentions
 | 
				
			||||||
                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
					                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
				
			||||||
                recipient: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id)
 | 
				
			||||||
                    .get_member(recipient_id).display_name
 | 
					                if not guild:
 | 
				
			||||||
                recipient_normal: str =  self.bot.get_guild(ctx.guild.id)\
 | 
					                    return
 | 
				
			||||||
                    .get_member(recipient_id).mention
 | 
					                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:
 | 
					            else:
 | 
				
			||||||
                recipient: str = discord.utils.escape_mentions(recipient.strip())
 | 
					                recipient = discord.utils.escape_mentions(recipient.strip())
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            await ctx.respond(f"*passes **{recipient_normal}** a barf bag*")
 | 
					            await ctx.respond(f"*passes **{recipient_normal}** a barf bag*")
 | 
				
			||||||
            await self.util.increment_counter("barf_bags")            
 | 
					            await self.util.increment_counter("barf_bags")            
 | 
				
			||||||
@@ -448,30 +492,34 @@ class Misc(commands.Cog):
 | 
				
			|||||||
        authorDisplay: str = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
					        authorDisplay: str = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
				
			||||||
            else ctx.message.author.display_name
 | 
					            else ctx.message.author.display_name
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        if recipient is None:
 | 
					        if not recipient:
 | 
				
			||||||
            recipient: str = authorDisplay.strip()
 | 
					            recipient = authorDisplay.strip()
 | 
				
			||||||
            recipient_normal: str = ctx.author.mention
 | 
					            recipient_normal: str = ctx.author.mention
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            recipient_normal: str = recipient
 | 
					            recipient_normal = recipient
 | 
				
			||||||
            if discord.utils.raw_mentions(recipient):
 | 
					            if discord.utils.raw_mentions(recipient):
 | 
				
			||||||
                # There are mentions
 | 
					                # There are mentions
 | 
				
			||||||
                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
					                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
				
			||||||
                recipient: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id)
 | 
				
			||||||
                    .get_member(recipient_id).display_name
 | 
					                if not guild:
 | 
				
			||||||
                recipient_normal: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                    return
 | 
				
			||||||
                    .get_member(recipient_id).mention
 | 
					                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:
 | 
					            else:
 | 
				
			||||||
                recipient: str = discord.utils.escape_mentions(recipient.strip())
 | 
					                recipient = discord.utils.escape_mentions(recipient.strip())
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            if recipient == "rhodes":
 | 
					            if recipient == "rhodes":
 | 
				
			||||||
                tea: str = "a cup of Harney & Sons Hot Cinnamon Spice Tea"
 | 
					                tea = "a cup of Harney & Sons Hot Cinnamon Spice Tea"
 | 
				
			||||||
            elif ctx.author.id == 992437729927376996 or recipient.lower() in ["kriegerin",
 | 
					            elif ctx.author.id == 992437729927376996 or recipient.lower() in ["kriegerin",
 | 
				
			||||||
                                                                            "traurigkeit",
 | 
					                                                                            "traurigkeit",
 | 
				
			||||||
                                                                            "krieg",
 | 
					                                                                            "krieg",
 | 
				
			||||||
                                                                            "kriegs",
 | 
					                                                                            "kriegs",
 | 
				
			||||||
                                                                            "cyberkrieg",
 | 
					                                                                            "cyberkrieg",
 | 
				
			||||||
                                                                            "ck"]:
 | 
					                                                                            "ck"]:
 | 
				
			||||||
                tea: str = "a cup of earl grey, light and sweet"
 | 
					                tea = "a cup of earl grey, light and sweet"
 | 
				
			||||||
            response = await ctx.respond(f"*hands **{recipient_normal}** {tea}*")
 | 
					            response = await ctx.respond(f"*hands **{recipient_normal}** {tea}*")
 | 
				
			||||||
            await self.util.increment_counter("teas")            
 | 
					            await self.util.increment_counter("teas")            
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
@@ -483,8 +531,8 @@ class Misc(commands.Cog):
 | 
				
			|||||||
            traceback.print_exc()
 | 
					            traceback.print_exc()
 | 
				
			||||||
            return await ctx.respond(f"Failed: {str(e)}")
 | 
					            return await ctx.respond(f"Failed: {str(e)}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @bridge.bridge_command()
 | 
					    @bridge.bridge_command() # type: ignore
 | 
				
			||||||
    @is_spamchan_or_drugs() # pylint: disable=too-many-function-args
 | 
					    @is_spamchan_or_drugs() 
 | 
				
			||||||
    async def cowsay(self, ctx, *,
 | 
					    async def cowsay(self, ctx, *,
 | 
				
			||||||
                     message: str) -> None:
 | 
					                     message: str) -> None:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
@@ -505,8 +553,8 @@ class Misc(commands.Cog):
 | 
				
			|||||||
            return await ctx.respond(f"Failed: {str(e)}")
 | 
					            return await ctx.respond(f"Failed: {str(e)}")
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @bridge.bridge_command()
 | 
					    @bridge.bridge_command() # type: ignore
 | 
				
			||||||
    @is_spamchan_or_drugs() # pylint: disable=too-many-function-args
 | 
					    @is_spamchan_or_drugs()
 | 
				
			||||||
    async def fortune(self, ctx,
 | 
					    async def fortune(self, ctx,
 | 
				
			||||||
                      cowfile: Optional[str] = None) -> None:
 | 
					                      cowfile: Optional[str] = None) -> None:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
@@ -518,7 +566,7 @@ class Misc(commands.Cog):
 | 
				
			|||||||
        """
 | 
					        """
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            if not cowfile:
 | 
					            if not cowfile:
 | 
				
			||||||
                cowfile: str = random.choice(self.COWS).replace(".cow", "")
 | 
					                cowfile = random.choice(self.COWS).replace(".cow", "")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if not f'{cowfile}.cow' in self.COWS:
 | 
					            if not f'{cowfile}.cow' in self.COWS:
 | 
				
			||||||
                return await ctx.respond(f"Unknown cow {cowfile}, who dat?")
 | 
					                return await ctx.respond(f"Unknown cow {cowfile}, who dat?")
 | 
				
			||||||
@@ -531,8 +579,8 @@ class Misc(commands.Cog):
 | 
				
			|||||||
            traceback.print_exc()
 | 
					            traceback.print_exc()
 | 
				
			||||||
            return await ctx.respond(f"Failed: {str(e)}")
 | 
					            return await ctx.respond(f"Failed: {str(e)}")
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
    @bridge.bridge_command()
 | 
					    @bridge.bridge_command() # type: ignore
 | 
				
			||||||
    @is_spamchan_or_drugs() # pylint: disable=too-many-function-args
 | 
					    @is_spamchan_or_drugs() 
 | 
				
			||||||
    async def listcows(self, ctx) -> None:
 | 
					    async def listcows(self, ctx) -> None:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        List available .cow files (for cowsay)
 | 
					        List available .cow files (for cowsay)
 | 
				
			||||||
@@ -544,7 +592,7 @@ class Misc(commands.Cog):
 | 
				
			|||||||
        cow_list: str = ""
 | 
					        cow_list: str = ""
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            for cow in self.COWS:
 | 
					            for cow in self.COWS:
 | 
				
			||||||
                cow: str = cow.replace(".cow", "")
 | 
					                cow = cow.replace(".cow", "")
 | 
				
			||||||
                cow_list += f"- **{cow}**\n"
 | 
					                cow_list += f"- **{cow}**\n"
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            embed: discord.Embed = discord.Embed(title="List of .cows",
 | 
					            embed: discord.Embed = discord.Embed(title="List of .cows",
 | 
				
			||||||
@@ -568,20 +616,24 @@ class Misc(commands.Cog):
 | 
				
			|||||||
        authorDisplay: str = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
					        authorDisplay: str = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
				
			||||||
            else ctx.message.author.display_name
 | 
					            else ctx.message.author.display_name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if recipient is None:
 | 
					        if not recipient:
 | 
				
			||||||
            recipient: str = authorDisplay.strip()
 | 
					            recipient = authorDisplay.strip()
 | 
				
			||||||
            recipient_normal: str = ctx.author.mention
 | 
					            recipient_normal: str = ctx.author.mention
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            recipient_normal: str = recipient
 | 
					            recipient_normal = recipient
 | 
				
			||||||
            if discord.utils.raw_mentions(recipient):
 | 
					            if discord.utils.raw_mentions(recipient):
 | 
				
			||||||
                # There are mentions
 | 
					                # There are mentions
 | 
				
			||||||
                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
					                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
				
			||||||
                recipient: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id)
 | 
				
			||||||
                    .get_member(recipient_id).display_name
 | 
					                if not guild:
 | 
				
			||||||
                recipient_normal: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                    return
 | 
				
			||||||
                    .get_member(recipient_id).mention
 | 
					                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:
 | 
					            else:
 | 
				
			||||||
                recipient: str = discord.utils.escape_mentions(recipient.strip())
 | 
					                recipient = discord.utils.escape_mentions(recipient.strip())
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            response = await ctx.respond(f"*doses **{recipient_normal}** with Zyklon-B*")
 | 
					            response = await ctx.respond(f"*doses **{recipient_normal}** with Zyklon-B*")
 | 
				
			||||||
            await self.util.increment_counter("cyanides")            
 | 
					            await self.util.increment_counter("cyanides")            
 | 
				
			||||||
@@ -591,7 +643,7 @@ class Misc(commands.Cog):
 | 
				
			|||||||
            except Exception as e:
 | 
					            except Exception as e:
 | 
				
			||||||
                logging.debug("Failed to add cynaide reaction: %s",
 | 
					                logging.debug("Failed to add cynaide reaction: %s",
 | 
				
			||||||
                              str(e))
 | 
					                              str(e))
 | 
				
			||||||
        except:
 | 
					        except Exception as e:
 | 
				
			||||||
            traceback.print_exc()
 | 
					            traceback.print_exc()
 | 
				
			||||||
            return await ctx.respond(f"Failed: {str(e)}")
 | 
					            return await ctx.respond(f"Failed: {str(e)}")
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
@@ -609,20 +661,24 @@ class Misc(commands.Cog):
 | 
				
			|||||||
        authorDisplay: str = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
					        authorDisplay: str = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
				
			||||||
            else ctx.message.author.display_name
 | 
					            else ctx.message.author.display_name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if recipient is None:
 | 
					        if not recipient:
 | 
				
			||||||
            recipient: str = authorDisplay.strip()
 | 
					            recipient = authorDisplay.strip()
 | 
				
			||||||
            recipient_normal: str = ctx.author.mention
 | 
					            recipient_normal: str = ctx.author.mention
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            recipient_normal: str = recipient
 | 
					            recipient_normal = recipient
 | 
				
			||||||
            if discord.utils.raw_mentions(recipient):
 | 
					            if discord.utils.raw_mentions(recipient):
 | 
				
			||||||
                # There are mentions
 | 
					                # There are mentions
 | 
				
			||||||
                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
					                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
				
			||||||
                recipient: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id)
 | 
				
			||||||
                    .get_member(recipient_id).display_name
 | 
					                if not guild:
 | 
				
			||||||
                recipient_normal: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                    return
 | 
				
			||||||
                    .get_member(recipient_id).mention
 | 
					                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:
 | 
					            else:
 | 
				
			||||||
                recipient: str = discord.utils.escape_mentions(recipient.strip())
 | 
					                recipient = discord.utils.escape_mentions(recipient.strip())
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            response = await ctx.respond(f"*doses **{recipient_normal}** with school gravy*")
 | 
					            response = await ctx.respond(f"*doses **{recipient_normal}** with school gravy*")
 | 
				
			||||||
            await self.util.increment_counter("gravies")            
 | 
					            await self.util.increment_counter("gravies")            
 | 
				
			||||||
@@ -650,20 +706,24 @@ class Misc(commands.Cog):
 | 
				
			|||||||
        authorDisplay: str = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
					        authorDisplay: str = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
				
			||||||
            else ctx.message.author.display_name
 | 
					            else ctx.message.author.display_name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if recipient is None:
 | 
					        if not recipient:
 | 
				
			||||||
            recipient: str = authorDisplay.strip()
 | 
					            recipient = authorDisplay.strip()
 | 
				
			||||||
            recipient_normal: str = ctx.author.mention
 | 
					            recipient_normal: str = ctx.author.mention
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            recipient_normal: str = recipient
 | 
					            recipient_normal = recipient
 | 
				
			||||||
            if discord.utils.raw_mentions(recipient):
 | 
					            if discord.utils.raw_mentions(recipient):
 | 
				
			||||||
                # There are mentions
 | 
					                # There are mentions
 | 
				
			||||||
                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
					                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
				
			||||||
                recipient: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id)
 | 
				
			||||||
                    .get_member(recipient_id).display_name
 | 
					                if not guild:
 | 
				
			||||||
                recipient_normal: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                    return
 | 
				
			||||||
                    .get_member(recipient_id).mention
 | 
					                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:
 | 
					            else:
 | 
				
			||||||
                recipient: str = discord.utils.escape_mentions(recipient.strip())
 | 
					                recipient = discord.utils.escape_mentions(recipient.strip())
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            response = await ctx.respond(f"*hands **{recipient_normal}** a cold glass of water*")
 | 
					            response = await ctx.respond(f"*hands **{recipient_normal}** a cold glass of water*")
 | 
				
			||||||
            await self.util.increment_counter("waters")            
 | 
					            await self.util.increment_counter("waters")            
 | 
				
			||||||
@@ -692,20 +752,24 @@ class Misc(commands.Cog):
 | 
				
			|||||||
        authorDisplay: str = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
					        authorDisplay: str = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
				
			||||||
            else ctx.message.author.display_name
 | 
					            else ctx.message.author.display_name
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        if recipient is None:
 | 
					        if not recipient:
 | 
				
			||||||
            recipient: str = authorDisplay.strip()
 | 
					            recipient = authorDisplay.strip()
 | 
				
			||||||
            recipient_normal: str = ctx.author.mention
 | 
					            recipient_normal: str = ctx.author.mention
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            recipient_normal: str = recipient
 | 
					            recipient_normal = recipient
 | 
				
			||||||
            if discord.utils.raw_mentions(recipient):
 | 
					            if discord.utils.raw_mentions(recipient):
 | 
				
			||||||
                # There are mentions
 | 
					                # There are mentions
 | 
				
			||||||
                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
					                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
				
			||||||
                recipient: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id)
 | 
				
			||||||
                    .get_member(recipient_id).display_name
 | 
					                if not guild:
 | 
				
			||||||
                recipient_normal: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                    return
 | 
				
			||||||
                    .get_member(recipient_id).mention
 | 
					                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:
 | 
					            else:
 | 
				
			||||||
                recipient: str = discord.utils.escape_mentions(recipient.strip())
 | 
					                recipient = discord.utils.escape_mentions(recipient.strip())
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            await ctx.respond(f"*shoves **{recipient_normal}** {chosen_fate}*")
 | 
					            await ctx.respond(f"*shoves **{recipient_normal}** {chosen_fate}*")
 | 
				
			||||||
            await self.util.increment_counter("shoves")
 | 
					            await self.util.increment_counter("shoves")
 | 
				
			||||||
@@ -727,22 +791,28 @@ class Misc(commands.Cog):
 | 
				
			|||||||
        authorDisplay: str = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
					        authorDisplay: str = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
				
			||||||
            else ctx.message.author.display_name
 | 
					            else ctx.message.author.display_name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if recipient is None:
 | 
					        if not recipient:
 | 
				
			||||||
            recipient: str = authorDisplay.strip()
 | 
					            recipient = authorDisplay.strip()
 | 
				
			||||||
            recipient_normal: str = ctx.author.mention
 | 
					            recipient_normal: str = ctx.author.mention
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            recipient_normal: str = recipient
 | 
					            recipient_normal = recipient
 | 
				
			||||||
            if discord.utils.raw_mentions(recipient):
 | 
					            if discord.utils.raw_mentions(recipient):
 | 
				
			||||||
                # There are mentions
 | 
					                # There are mentions
 | 
				
			||||||
                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
					                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
				
			||||||
                recipient: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id)
 | 
				
			||||||
                    .get_member(recipient_id).display_name
 | 
					                if not guild:
 | 
				
			||||||
                recipient_normal: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                    return
 | 
				
			||||||
                    .get_member(recipient_id).mention
 | 
					                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:
 | 
					            else:
 | 
				
			||||||
                recipient: str = discord.utils.escape_mentions(recipient.strip())
 | 
					                recipient = discord.utils.escape_mentions(recipient.strip())
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            chosen_coffee: str = self.util.get_coffee()
 | 
					            chosen_coffee: Optional[str] = self.util.get_coffee()
 | 
				
			||||||
 | 
					            if not chosen_coffee:
 | 
				
			||||||
 | 
					                return
 | 
				
			||||||
            response = await ctx.respond(f"*hands **{recipient_normal}** {chosen_coffee}*")            
 | 
					            response = await ctx.respond(f"*hands **{recipient_normal}** {chosen_coffee}*")            
 | 
				
			||||||
            await self.util.increment_counter("coffees")
 | 
					            await self.util.increment_counter("coffees")
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
@@ -768,24 +838,31 @@ class Misc(commands.Cog):
 | 
				
			|||||||
        authorDisplay: str = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
					        authorDisplay: str = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
				
			||||||
            else ctx.message.author.display_name
 | 
					            else ctx.message.author.display_name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if recipient is None:
 | 
					        if not recipient:
 | 
				
			||||||
            recipient: str = authorDisplay.strip()
 | 
					            recipient = authorDisplay.strip()
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            if discord.utils.raw_mentions(recipient):
 | 
					            if discord.utils.raw_mentions(recipient):
 | 
				
			||||||
                # There are mentions
 | 
					                # There are mentions
 | 
				
			||||||
                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
					                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
				
			||||||
                recipient: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id)
 | 
				
			||||||
                    .get_member(recipient_id).display_name
 | 
					                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:
 | 
					            else:
 | 
				
			||||||
                recipient: str = discord.utils.escape_mentions(recipient.strip())
 | 
					                recipient  = discord.utils.escape_mentions(recipient.strip())
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            chosen_cookie: dict = await self.util.get_cookie()
 | 
					            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}",
 | 
					            embed: discord.Embed = discord.Embed(title=f"Cookie for {recipient}",
 | 
				
			||||||
                                  description=f"Have a {chosen_cookie.get('name')}",
 | 
					                                  description=f"Have a {chosen_cookie.get('name')}",
 | 
				
			||||||
                                  colour=discord.Colour.orange(),
 | 
					                                  colour=discord.Colour.orange(),
 | 
				
			||||||
                                  image=chosen_cookie.get('image_url'))
 | 
					                                  image=chosen_cookie.get('image_url'))
 | 
				
			||||||
            embed.add_field(name="Origin",
 | 
					            embed.add_field(name="Origin",
 | 
				
			||||||
                            value=chosen_cookie.get('origin'))
 | 
					                            value=chosen_cookie.get('origin', 'N/A'))
 | 
				
			||||||
            await ctx.respond(embed=embed)
 | 
					            await ctx.respond(embed=embed)
 | 
				
			||||||
        except Exception as e:
 | 
					        except Exception as e:
 | 
				
			||||||
            traceback.print_exc()
 | 
					            traceback.print_exc()
 | 
				
			||||||
@@ -803,20 +880,24 @@ class Misc(commands.Cog):
 | 
				
			|||||||
        authorDisplay: str = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
					        authorDisplay: str = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
				
			||||||
            else ctx.message.author.display_name
 | 
					            else ctx.message.author.display_name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if recipient is None:
 | 
					        if not recipient:
 | 
				
			||||||
            recipient: str = authorDisplay.strip()
 | 
					            recipient = authorDisplay.strip()
 | 
				
			||||||
            recipient_normal: str = ctx.author.mention
 | 
					            recipient_normal: str = ctx.author.mention
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            recipient_normal: str = recipient
 | 
					            recipient_normal = recipient
 | 
				
			||||||
            if discord.utils.raw_mentions(recipient):
 | 
					            if discord.utils.raw_mentions(recipient):
 | 
				
			||||||
                # There are mentions
 | 
					                # There are mentions
 | 
				
			||||||
                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
					                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
				
			||||||
                recipient: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id)
 | 
				
			||||||
                    .get_member(recipient_id).display_name
 | 
					                if not guild:
 | 
				
			||||||
                recipient_normal: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                    return
 | 
				
			||||||
                    .get_member(recipient_id).mention
 | 
					                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:
 | 
					            else:
 | 
				
			||||||
                recipient: str = discord.utils.escape_mentions(recipient.strip())
 | 
					                recipient = discord.utils.escape_mentions(recipient.strip())
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            await ctx.respond(f"*hands **{recipient_normal}** 2 warm hashbrowns*")
 | 
					            await ctx.respond(f"*hands **{recipient_normal}** 2 warm hashbrowns*")
 | 
				
			||||||
            await self.util.increment_counter("hashbrowns")
 | 
					            await self.util.increment_counter("hashbrowns")
 | 
				
			||||||
@@ -838,20 +919,24 @@ class Misc(commands.Cog):
 | 
				
			|||||||
        authorDisplay = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
					        authorDisplay = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
				
			||||||
            else ctx.message.author.display_name
 | 
					            else ctx.message.author.display_name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if recipient is None:
 | 
					        if not recipient:
 | 
				
			||||||
            recipient: str = authorDisplay.strip()
 | 
					            recipient = authorDisplay.strip()
 | 
				
			||||||
            recipient_normal: str = ctx.author.mention
 | 
					            recipient_normal: str = ctx.author.mention
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            recipient_normal: str = recipient
 | 
					            recipient_normal = recipient
 | 
				
			||||||
            if discord.utils.raw_mentions(recipient):
 | 
					            if discord.utils.raw_mentions(recipient):
 | 
				
			||||||
                # There are mentions
 | 
					                # There are mentions
 | 
				
			||||||
                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
					                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
				
			||||||
                recipient: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id)
 | 
				
			||||||
                    .get_member(recipient_id).display_name
 | 
					                if not guild:
 | 
				
			||||||
                recipient_normal: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                    return
 | 
				
			||||||
                    .get_member(recipient_id).mention
 | 
					                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:
 | 
					            else:
 | 
				
			||||||
                recipient: str = discord.utils.escape_mentions(recipient.strip())
 | 
					                recipient = discord.utils.escape_mentions(recipient.strip())
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            response = await ctx.respond(f"*serves **{recipient_normal}** a plate of ritalini* 😉")
 | 
					            response = await ctx.respond(f"*serves **{recipient_normal}** a plate of ritalini* 😉")
 | 
				
			||||||
            await response.add_reaction(emoji="💊")
 | 
					            await response.add_reaction(emoji="💊")
 | 
				
			||||||
@@ -875,20 +960,24 @@ class Misc(commands.Cog):
 | 
				
			|||||||
        authorDisplay: str = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
					        authorDisplay: str = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
				
			||||||
            else ctx.message.author.display_name
 | 
					            else ctx.message.author.display_name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if recipient is None:
 | 
					        if not recipient:
 | 
				
			||||||
            recipient: str = authorDisplay.strip()
 | 
					            recipient = authorDisplay.strip()
 | 
				
			||||||
            recipient_normal: str = ctx.author.mention
 | 
					            recipient_normal: str = ctx.author.mention
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            recipient_normal: str = recipient
 | 
					            recipient_normal = recipient
 | 
				
			||||||
            if discord.utils.raw_mentions(recipient):
 | 
					            if discord.utils.raw_mentions(recipient):
 | 
				
			||||||
                # There are mentions
 | 
					                # There are mentions
 | 
				
			||||||
                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
					                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
				
			||||||
                recipient: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id)
 | 
				
			||||||
                    .get_member(recipient_id).display_name
 | 
					                if not guild:
 | 
				
			||||||
                recipient_normal: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                    return
 | 
				
			||||||
                    .get_member(recipient_id).mention
 | 
					                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:
 | 
					            else:
 | 
				
			||||||
                recipient: str = discord.utils.escape_mentions(recipient.strip())
 | 
					                recipient = discord.utils.escape_mentions(recipient.strip())
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            await ctx.respond(f"*hands **{recipient_normal}** a grilled cheese*")
 | 
					            await ctx.respond(f"*hands **{recipient_normal}** a grilled cheese*")
 | 
				
			||||||
            await self.util.increment_counter("grilled_cheeses")
 | 
					            await self.util.increment_counter("grilled_cheeses")
 | 
				
			||||||
@@ -910,20 +999,24 @@ class Misc(commands.Cog):
 | 
				
			|||||||
        authorDisplay: str = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
					        authorDisplay: str = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
				
			||||||
            else ctx.message.author.display_name
 | 
					            else ctx.message.author.display_name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if recipient is None:
 | 
					        if not recipient:
 | 
				
			||||||
            recipient: str = authorDisplay.strip()
 | 
					            recipient = authorDisplay.strip()
 | 
				
			||||||
            recipient_normal: str = ctx.author.mention
 | 
					            recipient_normal: str = ctx.author.mention
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            recipient_normal: str = recipient
 | 
					            recipient_normal = recipient
 | 
				
			||||||
            if discord.utils.raw_mentions(recipient):
 | 
					            if discord.utils.raw_mentions(recipient):
 | 
				
			||||||
                # There are mentions
 | 
					                # There are mentions
 | 
				
			||||||
                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
					                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
				
			||||||
                recipient: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id)
 | 
				
			||||||
                    .get_member(recipient_id).display_name
 | 
					                if not guild:
 | 
				
			||||||
                recipient_normal: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                    return
 | 
				
			||||||
                    .get_member(recipient_id).mention
 | 
					                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:
 | 
					            else:
 | 
				
			||||||
                recipient: str = discord.utils.escape_mentions(recipient.strip())
 | 
					                recipient = discord.utils.escape_mentions(recipient.strip())
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            await ctx.respond(f"*hands **{recipient_normal}** a hot bowl of soup*")
 | 
					            await ctx.respond(f"*hands **{recipient_normal}** a hot bowl of soup*")
 | 
				
			||||||
            await self.util.increment_counter("soups")
 | 
					            await self.util.increment_counter("soups")
 | 
				
			||||||
@@ -945,18 +1038,22 @@ class Misc(commands.Cog):
 | 
				
			|||||||
        authorDisplay: str = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
					        authorDisplay: str = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
				
			||||||
            else ctx.message.author.display_name
 | 
					            else ctx.message.author.display_name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if recipient is None:
 | 
					        if not recipient:
 | 
				
			||||||
            recipient: str = authorDisplay.strip()
 | 
					            recipient = authorDisplay.strip()
 | 
				
			||||||
            recipient_normal: str = ctx.author.mention
 | 
					            recipient_normal: str = ctx.author.mention
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            recipient_normal: str = recipient
 | 
					            recipient_normal = recipient
 | 
				
			||||||
            if discord.utils.raw_mentions(recipient):
 | 
					            if discord.utils.raw_mentions(recipient):
 | 
				
			||||||
                # There are mentions
 | 
					                # There are mentions
 | 
				
			||||||
                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
					                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
				
			||||||
                recipient: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id)
 | 
				
			||||||
                    .get_member(recipient_id).display_name
 | 
					                if not guild:
 | 
				
			||||||
                recipient_normal: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                    return
 | 
				
			||||||
                    .get_member(recipient_id).mention
 | 
					                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:
 | 
					            else:
 | 
				
			||||||
                recipient = discord.utils.escape_mentions(recipient.strip())
 | 
					                recipient = discord.utils.escape_mentions(recipient.strip())
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
@@ -981,20 +1078,24 @@ class Misc(commands.Cog):
 | 
				
			|||||||
        authorDisplay: str = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
					        authorDisplay: str = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
				
			||||||
            else ctx.message.author.display_name
 | 
					            else ctx.message.author.display_name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if recipient is None:
 | 
					        if not recipient:
 | 
				
			||||||
            recipient: str = authorDisplay.strip()
 | 
					            recipient = authorDisplay.strip()
 | 
				
			||||||
            recipient_normal: str = ctx.author.mention
 | 
					            recipient_normal: str = ctx.author.mention
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            recipient_normal: str = recipient
 | 
					            recipient_normal = recipient
 | 
				
			||||||
            if discord.utils.raw_mentions(recipient):
 | 
					            if discord.utils.raw_mentions(recipient):
 | 
				
			||||||
                # There are mentions
 | 
					                # There are mentions
 | 
				
			||||||
                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
					                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
				
			||||||
                recipient: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id)
 | 
				
			||||||
                    .get_member(recipient_id).display_name
 | 
					                if not guild:
 | 
				
			||||||
                recipient_normal: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                    return
 | 
				
			||||||
                    .get_member(recipient_id).mention
 | 
					                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:
 | 
					            else:
 | 
				
			||||||
                recipient: str = discord.utils.escape_mentions(recipient.strip())
 | 
					                recipient = discord.utils.escape_mentions(recipient.strip())
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            response = await ctx.respond(f"*hands **{recipient_normal}** a side of bacon*")
 | 
					            response = await ctx.respond(f"*hands **{recipient_normal}** a side of bacon*")
 | 
				
			||||||
            await response.add_reaction(emoji="🥓")
 | 
					            await response.add_reaction(emoji="🥓")
 | 
				
			||||||
@@ -1017,20 +1118,24 @@ class Misc(commands.Cog):
 | 
				
			|||||||
        authorDisplay = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
					        authorDisplay = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
				
			||||||
            else ctx.message.author.display_name
 | 
					            else ctx.message.author.display_name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if recipient is None:
 | 
					        if not recipient:
 | 
				
			||||||
            recipient: str = authorDisplay.strip()
 | 
					            recipient = authorDisplay.strip()
 | 
				
			||||||
            recipient_normal: str = ctx.author.mention
 | 
					            recipient_normal: str = ctx.author.mention
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            recipient_normal: str = recipient
 | 
					            recipient_normal = recipient
 | 
				
			||||||
            if discord.utils.raw_mentions(recipient):
 | 
					            if discord.utils.raw_mentions(recipient):
 | 
				
			||||||
                # There are mentions
 | 
					                # There are mentions
 | 
				
			||||||
                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
					                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
				
			||||||
                recipient: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id)
 | 
				
			||||||
                    .get_member(recipient_id).display_name
 | 
					                if not guild:
 | 
				
			||||||
                recipient_normal: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                    return
 | 
				
			||||||
                    .get_member(recipient_id).mention
 | 
					                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:
 | 
					            else:
 | 
				
			||||||
                recipient: str = discord.utils.escape_mentions(recipient.strip())
 | 
					                recipient = discord.utils.escape_mentions(recipient.strip())
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            response = await ctx.respond(f"*sends **{recipient_normal}** to the Gallows to be hanged asynchronely*")
 | 
					            response = await ctx.respond(f"*sends **{recipient_normal}** to the Gallows to be hanged asynchronely*")
 | 
				
			||||||
            await self.util.increment_counter("hangings")
 | 
					            await self.util.increment_counter("hangings")
 | 
				
			||||||
@@ -1043,8 +1148,7 @@ class Misc(commands.Cog):
 | 
				
			|||||||
            await ctx.respond(f"Failed: {str(e)}")
 | 
					            await ctx.respond(f"Failed: {str(e)}")
 | 
				
			||||||
            traceback.print_exc()
 | 
					            traceback.print_exc()
 | 
				
			||||||
            return 
 | 
					            return 
 | 
				
			||||||
    
 | 
					     
 | 
				
			||||||
            
 | 
					 | 
				
			||||||
    @bridge.bridge_command()
 | 
					    @bridge.bridge_command()
 | 
				
			||||||
    async def touch(self, ctx, *,
 | 
					    async def touch(self, ctx, *,
 | 
				
			||||||
                    recipient: Optional[str] = None) -> None:
 | 
					                    recipient: Optional[str] = None) -> None:
 | 
				
			||||||
@@ -1056,9 +1160,12 @@ class Misc(commands.Cog):
 | 
				
			|||||||
        Returns:
 | 
					        Returns:
 | 
				
			||||||
            None
 | 
					            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."
 | 
					        no_self_touch: str = ", don't fucking touch yourself here.  You disgust me."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if recipient is None:
 | 
					        if not recipient:
 | 
				
			||||||
            recipient_normal: str = ctx.author.mention
 | 
					            recipient_normal: str = ctx.author.mention
 | 
				
			||||||
            await ctx.respond(f"{recipient_normal}{no_self_touch}")
 | 
					            await ctx.respond(f"{recipient_normal}{no_self_touch}")
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
@@ -1066,18 +1173,21 @@ class Misc(commands.Cog):
 | 
				
			|||||||
            except Exception as e:
 | 
					            except Exception as e:
 | 
				
			||||||
                logging.debug("Failed to add puke reactin for touch command: %s",
 | 
					                logging.debug("Failed to add puke reactin for touch command: %s",
 | 
				
			||||||
                             str(e))
 | 
					                             str(e))
 | 
				
			||||||
            return await self.util.increment_counter("touch_denials")
 | 
					            await self.util.increment_counter("touch_denials")
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            recipient_normal: str = recipient
 | 
					            recipient_normal = recipient
 | 
				
			||||||
            if discord.utils.raw_mentions(recipient):
 | 
					            if discord.utils.raw_mentions(recipient):
 | 
				
			||||||
                # There are mentions
 | 
					                # There are mentions
 | 
				
			||||||
                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
					                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
				
			||||||
                recipient: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                if not guild:
 | 
				
			||||||
                    .get_member(recipient_id).display_name
 | 
					                    return
 | 
				
			||||||
                recipient_normal: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                recipient_member: Optional[discord.Member] = guild.get_member(recipient_id)
 | 
				
			||||||
                    .get_member(recipient_id).mention
 | 
					                if not recipient_member:
 | 
				
			||||||
 | 
					                    return
 | 
				
			||||||
 | 
					                recipient = recipient_member.display_name
 | 
				
			||||||
 | 
					                recipient_normal = recipient_member.mention
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                recipient: str = discord.utils.escape_mentions(recipient.strip())
 | 
					                recipient = discord.utils.escape_mentions(recipient.strip())
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            response = await ctx.respond(f"*touches **{recipient_normal}** for **{ctx.author.mention}** because they wouldn't touch them with a shitty stick!*")
 | 
					            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")
 | 
					            await self.util.increment_counter("touches")
 | 
				
			||||||
@@ -1090,8 +1200,8 @@ class Misc(commands.Cog):
 | 
				
			|||||||
            traceback.print_exc()
 | 
					            traceback.print_exc()
 | 
				
			||||||
            return await ctx.respond(f"Failed: {str(e)}")    
 | 
					            return await ctx.respond(f"Failed: {str(e)}")    
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
    @bridge.bridge_command()
 | 
					    @bridge.bridge_command() # type: ignore
 | 
				
			||||||
    @is_spamchan_or_drugs() # pylint: disable=too-many-function-args
 | 
					    @is_spamchan_or_drugs()
 | 
				
			||||||
    async def qajoke(self, ctx) -> None:
 | 
					    async def qajoke(self, ctx) -> None:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Get a joke in Q/A Form!
 | 
					        Get a joke in Q/A Form!
 | 
				
			||||||
@@ -1101,7 +1211,10 @@ class Misc(commands.Cog):
 | 
				
			|||||||
            None
 | 
					            None
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            (question, answer) = await self.util.get_qajoke()
 | 
					            qajoke: Optional[tuple] = await self.util.get_qajoke()
 | 
				
			||||||
 | 
					            if not qajoke: 
 | 
				
			||||||
 | 
					                return
 | 
				
			||||||
 | 
					            (question, answer) = qajoke
 | 
				
			||||||
            escaped_question = discord.utils.escape_markdown(question)
 | 
					            escaped_question = discord.utils.escape_markdown(question)
 | 
				
			||||||
            escasped_answer = discord.utils.escape_markdown(answer)
 | 
					            escasped_answer = discord.utils.escape_markdown(answer)
 | 
				
			||||||
            embed: discord.Embed = discord.Embed(title=escaped_question,
 | 
					            embed: discord.Embed = discord.Embed(title=escaped_question,
 | 
				
			||||||
@@ -1110,8 +1223,8 @@ class Misc(commands.Cog):
 | 
				
			|||||||
        except Exception as e:
 | 
					        except Exception as e:
 | 
				
			||||||
            await ctx.respond(f"Error: {str(e)}")
 | 
					            await ctx.respond(f"Error: {str(e)}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @bridge.bridge_command()
 | 
					    @bridge.bridge_command() # type: ignore
 | 
				
			||||||
    @is_spamchan_or_drugs() # pylint: disable=too-many-function-args
 | 
					    @is_spamchan_or_drugs() 
 | 
				
			||||||
    async def rjoke(self, ctx) -> None:
 | 
					    async def rjoke(self, ctx) -> None:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Get a joke! (from r/jokes scrape)
 | 
					        Get a joke! (from r/jokes scrape)
 | 
				
			||||||
@@ -1121,7 +1234,10 @@ class Misc(commands.Cog):
 | 
				
			|||||||
            None
 | 
					            None
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            (title, body, score) = await self.util.get_rjoke()
 | 
					            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_title = discord.utils.escape_markdown(title)
 | 
				
			||||||
            escaped_body = discord.utils.escape_markdown(body)
 | 
					            escaped_body = discord.utils.escape_markdown(body)
 | 
				
			||||||
            embed: discord.Embed = discord.Embed(title=escaped_title,
 | 
					            embed: discord.Embed = discord.Embed(title=escaped_title,
 | 
				
			||||||
@@ -1132,8 +1248,8 @@ class Misc(commands.Cog):
 | 
				
			|||||||
            traceback.print_exc()
 | 
					            traceback.print_exc()
 | 
				
			||||||
            return await ctx.respond(f"Error: {str(e)}")
 | 
					            return await ctx.respond(f"Error: {str(e)}")
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    @bridge.bridge_command()
 | 
					    @bridge.bridge_command() # type: ignore
 | 
				
			||||||
    @is_spamchan_or_drugs() # pylint: disable=too-many-function-args
 | 
					    @is_spamchan_or_drugs() 
 | 
				
			||||||
    async def joint(self, ctx, *, 
 | 
					    async def joint(self, ctx, *, 
 | 
				
			||||||
                    recipient: Optional[str] = None) -> None:
 | 
					                    recipient: Optional[str] = None) -> None:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
@@ -1146,23 +1262,31 @@ class Misc(commands.Cog):
 | 
				
			|||||||
        """
 | 
					        """
 | 
				
			||||||
        authorDisplay: str = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
					        authorDisplay: str = ctx.author.display_name if not(ctx.author.display_name is None)\
 | 
				
			||||||
            else ctx.message.author.display_name
 | 
					            else ctx.message.author.display_name
 | 
				
			||||||
 | 
					         
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if recipient is None:
 | 
					        if not recipient:
 | 
				
			||||||
            recipient: str = authorDisplay.strip()
 | 
					            recipient = authorDisplay.strip()
 | 
				
			||||||
            recipient_normal: str = ctx.user.mention
 | 
					            recipient_normal: str = ctx.user.mention
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            recipient_normal: str = recipient
 | 
					            recipient_normal = recipient
 | 
				
			||||||
            if discord.utils.raw_mentions(recipient):
 | 
					            if discord.utils.raw_mentions(recipient):
 | 
				
			||||||
                # There are mentions
 | 
					                # There are mentions
 | 
				
			||||||
                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
					                recipient_id: int = discord.utils.raw_mentions(recipient)[0] # First mention
 | 
				
			||||||
                recipient: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id)
 | 
				
			||||||
                    .get_member(recipient_id).display_name
 | 
					                if not guild:
 | 
				
			||||||
                recipient_normal: str = self.bot.get_guild(ctx.guild.id)\
 | 
					                    return
 | 
				
			||||||
                    .get_member(recipient_id).mention
 | 
					                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:
 | 
					            else:
 | 
				
			||||||
                recipient: str = discord.utils.escape_mentions(recipient.strip())
 | 
					                recipient = discord.utils.escape_mentions(recipient.strip())
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            (choice_strain, choice_desc) = await self.util.get_strain()
 | 
					            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())
 | 
					            escaped_description = discord.utils.escape_markdown(choice_desc.strip())
 | 
				
			||||||
            await ctx.send_followup(f"*hands **{recipient_normal}** a joint rolled up with some **{choice_strain}***", username="Joint Granter")
 | 
					            await ctx.send_followup(f"*hands **{recipient_normal}** a joint rolled up with some **{choice_strain}***", username="Joint Granter")
 | 
				
			||||||
            embed: discord.Embed = discord.Embed(title=choice_strain,
 | 
					            embed: discord.Embed = discord.Embed(title=choice_strain,
 | 
				
			||||||
@@ -1239,8 +1363,8 @@ class Misc(commands.Cog):
 | 
				
			|||||||
            
 | 
					            
 | 
				
			||||||
    """ User Commands """
 | 
					    """ User Commands """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @commands.user_command(name="Give Joint")
 | 
					    @commands.user_command(name="Give Joint") # type: ignore
 | 
				
			||||||
    @is_spamchan() # pylint: disable=too-many-function-args
 | 
					    @is_spamchan()
 | 
				
			||||||
    async def joint_context_menu(self, ctx, member: discord.Member) -> None:
 | 
					    async def joint_context_menu(self, ctx, member: discord.Member) -> None:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Joint Context Menu
 | 
					        Joint Context Menu
 | 
				
			||||||
@@ -1250,7 +1374,10 @@ class Misc(commands.Cog):
 | 
				
			|||||||
        Returns:
 | 
					        Returns:
 | 
				
			||||||
            None
 | 
					            None
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        (choice_strain, choice_desc) = await self.util.get_strain()
 | 
					        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())
 | 
					        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}***")
 | 
					        await ctx.interaction.respond(f"*hands **<@{member.id}>** a joint rolled up with some **{choice_strain}***")
 | 
				
			||||||
        embed: discord.Embed = discord.Embed(title=choice_strain,
 | 
					        embed: discord.Embed = discord.Embed(title=choice_strain,
 | 
				
			||||||
@@ -1278,10 +1405,7 @@ class Misc(commands.Cog):
 | 
				
			|||||||
        
 | 
					        
 | 
				
			||||||
    def cog_unload(self) -> None:
 | 
					    def cog_unload(self) -> None:
 | 
				
			||||||
        """Run on Cog Unload"""
 | 
					        """Run on Cog Unload"""
 | 
				
			||||||
        try:
 | 
					        pass
 | 
				
			||||||
            self.randstat_loop.cancel()
 | 
					 | 
				
			||||||
        except Exception as e:
 | 
					 | 
				
			||||||
            logging.debug("Failed to cancel randstat loop: %s", str(e))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
def setup(bot) -> None: 
 | 
					def setup(bot) -> None: 
 | 
				
			||||||
    """Run on Cog Load"""
 | 
					    """Run on Cog Load"""
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,7 @@ import traceback
 | 
				
			|||||||
import random
 | 
					import random
 | 
				
			||||||
import datetime
 | 
					import datetime
 | 
				
			||||||
import pytz
 | 
					import pytz
 | 
				
			||||||
from typing import Optional, LiteralString
 | 
					from typing import Any, Optional, LiteralString, Union
 | 
				
			||||||
import regex
 | 
					import regex
 | 
				
			||||||
import aiosqlite as sqlite3
 | 
					import aiosqlite as sqlite3
 | 
				
			||||||
from aiohttp import ClientSession, ClientTimeout
 | 
					from aiohttp import ClientSession, ClientTimeout
 | 
				
			||||||
@@ -19,7 +19,7 @@ class Util:
 | 
				
			|||||||
        self.URL_URBANDICTIONARY: str = "http://api.urbandictionary.com/v0/define"
 | 
					        self.URL_URBANDICTIONARY: str = "http://api.urbandictionary.com/v0/define"
 | 
				
			||||||
        self.URL_INSULTAPI: str = "https://insult.mattbas.org/api/insult"
 | 
					        self.URL_INSULTAPI: str = "https://insult.mattbas.org/api/insult"
 | 
				
			||||||
        self.COMPLIMENT_GENERATOR = ComplimentGenerator()
 | 
					        self.COMPLIMENT_GENERATOR = ComplimentGenerator()
 | 
				
			||||||
        self.dbs: dict[str|LiteralString] = {
 | 
					        self.dbs: dict[str, str|LiteralString] = {
 | 
				
			||||||
            'whisky': os.path.join("/usr/local/share",
 | 
					            'whisky': os.path.join("/usr/local/share",
 | 
				
			||||||
                                   "sqlite_dbs", "whiskey.db"),
 | 
					                                   "sqlite_dbs", "whiskey.db"),
 | 
				
			||||||
            'drinks': os.path.join("/usr/local/share",
 | 
					            'drinks': os.path.join("/usr/local/share",
 | 
				
			||||||
@@ -73,50 +73,42 @@ class Util:
 | 
				
			|||||||
        (mics, mils) = _t(td.microseconds, 1000)
 | 
					        (mics, mils) = _t(td.microseconds, 1000)
 | 
				
			||||||
        return (td.days, h, m, s, mics, mils)
 | 
					        return (td.days, h, m, s, mics, mils)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def sqlite_dict_factory(self, cursor: sqlite3.Cursor, row: sqlite3.Row) -> dict:
 | 
					    async def get_counter(self, counter: Optional[str] = None) -> Optional[dict]:
 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        SQLite Dict Factory for Rows Returned
 | 
					 | 
				
			||||||
        Args:
 | 
					 | 
				
			||||||
            cursor (sqlite3.Row)
 | 
					 | 
				
			||||||
            row (sqlite3.Row)
 | 
					 | 
				
			||||||
        Returns:
 | 
					 | 
				
			||||||
            dict
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        fields = [column[0] for column in cursor.description]
 | 
					 | 
				
			||||||
        return { key: value for key, value in zip(fields, row) }
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    async def get_counter(self, counter: Optional[str] = None) -> dict:
 | 
					 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Get Counter
 | 
					        Get Counter
 | 
				
			||||||
        Args:
 | 
					        Args:
 | 
				
			||||||
            counter (Optional[str])
 | 
					            counter (Optional[str])
 | 
				
			||||||
        Returns:
 | 
					        Returns:
 | 
				
			||||||
            dict
 | 
					            Optional[dict]
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        async with sqlite3.connect(self.dbs.get('stats'),
 | 
					        stats_db: str|LiteralString = self.dbs.get('stats', '')
 | 
				
			||||||
 | 
					        if not stats_db:
 | 
				
			||||||
 | 
					            return None
 | 
				
			||||||
 | 
					        async with sqlite3.connect(stats_db,
 | 
				
			||||||
                                         timeout=3) as db_conn:
 | 
					                                         timeout=3) as db_conn:
 | 
				
			||||||
            db_conn.row_factory = self.sqlite_dict_factory
 | 
					            db_conn.row_factory = sqlite3.Row
 | 
				
			||||||
            query: str = "SELECT ? FROM stats LIMIT 1"
 | 
					            query: str = "SELECT ? FROM stats LIMIT 1"
 | 
				
			||||||
            if not counter:
 | 
					            if not counter:
 | 
				
			||||||
                query: str = "SELECT * FROM stats LIMIT 1"
 | 
					                query = "SELECT * FROM stats LIMIT 1"
 | 
				
			||||||
            async with await db_conn.execute(query, (counter,) if counter else None) as db_cursor:
 | 
					            async with await db_conn.execute(query, (counter,) if counter else None) as db_cursor:
 | 
				
			||||||
                result: dict = await db_cursor.fetchone()
 | 
					                result = await db_cursor.fetchone()
 | 
				
			||||||
                return result
 | 
					                return result
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
    async def get_stats_embed(self) -> Embed:
 | 
					    async def get_stats_embed(self) -> Optional[Embed]:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Get Stats Embed
 | 
					        Get Stats Embed
 | 
				
			||||||
        Returns:
 | 
					        Returns:
 | 
				
			||||||
            Embed
 | 
					            Optional[Embed]
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        counters: dict = await self.get_counter()
 | 
					        counters: Optional[dict] = await self.get_counter()
 | 
				
			||||||
 | 
					        if not counters:
 | 
				
			||||||
 | 
					            return None
 | 
				
			||||||
        embed: Embed = Embed(title="Stats")
 | 
					        embed: Embed = Embed(title="Stats")
 | 
				
			||||||
        counter_message: str = ""
 | 
					        counter_message: str = ""
 | 
				
			||||||
        counters_sorted: dict = dict(sorted(counters.items(), 
 | 
					        counters_sorted: dict = dict(sorted(counters.items(), 
 | 
				
			||||||
                          key=lambda item: item[1], reverse=True))
 | 
					                          key=lambda item: item[1], reverse=True))
 | 
				
			||||||
        for counter, value in counters_sorted.items():
 | 
					        for counter, value in counters_sorted.items():
 | 
				
			||||||
            counter: str = regex.sub(r'_', ' ',
 | 
					            counter = regex.sub(r'_', ' ',
 | 
				
			||||||
                                     counter.strip()).title()
 | 
					                                     counter.strip()).title()
 | 
				
			||||||
            counter_message += f"- {value} {counter}\n"
 | 
					            counter_message += f"- {value} {counter}\n"
 | 
				
			||||||
        embed.description = counter_message.strip()
 | 
					        embed.description = counter_message.strip()
 | 
				
			||||||
@@ -130,7 +122,10 @@ class Util:
 | 
				
			|||||||
        Returns:
 | 
					        Returns:
 | 
				
			||||||
            bool
 | 
					            bool
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        async with sqlite3.connect(self.dbs.get('stats'),
 | 
					        stats_db: str|LiteralString = self.dbs.get('stats', '')
 | 
				
			||||||
 | 
					        if not stats_db:
 | 
				
			||||||
 | 
					            return False
 | 
				
			||||||
 | 
					        async with sqlite3.connect(stats_db,
 | 
				
			||||||
                                         timeout=3) as db_conn:
 | 
					                                         timeout=3) as db_conn:
 | 
				
			||||||
            async with await db_conn.execute(f"UPDATE stats SET {counter} = {counter} + 1") as db_cursor:
 | 
					            async with await db_conn.execute(f"UPDATE stats SET {counter} = {counter} + 1") as db_cursor:
 | 
				
			||||||
                if db_cursor.rowcount < 0:
 | 
					                if db_cursor.rowcount < 0:
 | 
				
			||||||
@@ -139,11 +134,11 @@ class Util:
 | 
				
			|||||||
                await db_conn.commit()
 | 
					                await db_conn.commit()
 | 
				
			||||||
                return True
 | 
					                return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def get_ud_def(self, term: Optional[str] = None) -> tuple[str, str]:
 | 
					    async def get_ud_def(self, term: str) -> tuple[str, str]:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Get Definition from UD
 | 
					        Get Definition from UD
 | 
				
			||||||
        Args:
 | 
					        Args:
 | 
				
			||||||
            term (Optional[str])
 | 
					            term (str)
 | 
				
			||||||
        Returns:
 | 
					        Returns:
 | 
				
			||||||
            tuple[str, str]
 | 
					            tuple[str, str]
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
@@ -202,93 +197,107 @@ class Util:
 | 
				
			|||||||
            return self.COMPLIMENT_GENERATOR.compliment(subject)
 | 
					            return self.COMPLIMENT_GENERATOR.compliment(subject)
 | 
				
			||||||
        return self.COMPLIMENT_GENERATOR.compliment_in_language(subject, language)
 | 
					        return self.COMPLIMENT_GENERATOR.compliment_in_language(subject, language)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def get_whisky(self) -> tuple:
 | 
					    async def get_whisky(self) -> Optional[tuple]:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Get Whisky
 | 
					        Get Whisky
 | 
				
			||||||
        Returns:
 | 
					        Returns:
 | 
				
			||||||
            tuple
 | 
					            Optional[tuple]
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        whisky_db: str|LiteralString = self.dbs.get('whisky')
 | 
					        whisky_db: str|LiteralString = self.dbs.get('whisky', '')
 | 
				
			||||||
        db_conn = await sqlite3.connect(database=whisky_db, timeout=2)
 | 
					        if not whisky_db:
 | 
				
			||||||
        db_query: str = "SELECT name, category, description FROM whiskeys ORDER BY random() LIMIT 1"
 | 
					            return None
 | 
				
			||||||
        db_cursor: sqlite3.Cursor = await db_conn.execute(db_query)
 | 
					        async with sqlite3.connect(database=whisky_db,
 | 
				
			||||||
        db_result: tuple = await db_cursor.fetchone()
 | 
					                                   timeout=2) as db_conn:
 | 
				
			||||||
        
 | 
					            db_query: str = "SELECT name, category, description FROM whiskeys ORDER BY random() LIMIT 1"
 | 
				
			||||||
        (name, category, description) = db_result
 | 
					            async with await db_conn.execute(db_query) as db_cursor:
 | 
				
			||||||
        name: str = regex.sub(r'(^\p{White_Space}|\r|\n)', '',
 | 
					                db_result: Optional[Union[sqlite3.Row, tuple]] = await db_cursor.fetchone()
 | 
				
			||||||
                         regex.sub(r'\p{White_Space}{2,}', ' ',
 | 
					                if not db_result:
 | 
				
			||||||
                                   name.strip()))
 | 
					                    return None
 | 
				
			||||||
        category: str = regex.sub(r'(^\p{White_Space}|\r|\n)', '',
 | 
					                (name, category, description) = db_result
 | 
				
			||||||
                             regex.sub(r'\p{White_Space}{2,}', ' ',
 | 
					                name = regex.sub(r'(^\p{White_Space}|\r|\n)', '',
 | 
				
			||||||
                                       category.strip()))
 | 
					 | 
				
			||||||
        description: str = regex.sub(r'(^\p{White_Space}|\r|\n)', '',
 | 
					 | 
				
			||||||
                                regex.sub(r'\p{White_Space}{2,}', ' ',
 | 
					                                regex.sub(r'\p{White_Space}{2,}', ' ',
 | 
				
			||||||
                                          description.strip()))
 | 
					                                        name.strip()))
 | 
				
			||||||
        return (name, category, description)
 | 
					                category = regex.sub(r'(^\p{White_Space}|\r|\n)', '',
 | 
				
			||||||
 | 
					                                    regex.sub(r'\p{White_Space}{2,}', ' ',
 | 
				
			||||||
 | 
					                                            category.strip()))
 | 
				
			||||||
 | 
					                description = regex.sub(r'(^\p{White_Space}|\r|\n)', '',
 | 
				
			||||||
 | 
					                                        regex.sub(r'\p{White_Space}{2,}', ' ',
 | 
				
			||||||
 | 
					                                                description.strip()))
 | 
				
			||||||
 | 
					                return (name, category, description)
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
    async def get_drink(self) -> tuple:
 | 
					    async def get_drink(self) -> Optional[tuple]:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Get Drink
 | 
					        Get Drink
 | 
				
			||||||
        Returns:
 | 
					        Returns:
 | 
				
			||||||
            tuple
 | 
					            Optional[tuple]
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        drinks_db: str|LiteralString = self.dbs.get('drinks')
 | 
					        drinks_db: str|LiteralString = self.dbs.get('drinks', '')
 | 
				
			||||||
        db_conn = await sqlite3.connect(database=drinks_db, timeout=2)
 | 
					        if not drinks_db:
 | 
				
			||||||
        db_query: str = "SELECT name, ingredients FROM cocktails ORDER BY random() LIMIT 1"
 | 
					            return None
 | 
				
			||||||
        db_cursor: sqlite3.Cursor = await db_conn.execute(db_query)
 | 
					        async with sqlite3.connect(database=drinks_db,
 | 
				
			||||||
        db_result: tuple = await db_cursor.fetchone()
 | 
					                                   timeout=2) as db_conn:
 | 
				
			||||||
 | 
					            db_query: str = "SELECT name, ingredients FROM cocktails ORDER BY random() LIMIT 1"
 | 
				
			||||||
 | 
					            async with await db_conn.execute(db_query) as db_cursor:
 | 
				
			||||||
 | 
					                db_result: tuple = await db_cursor.fetchone()
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                (name, ingredients) = db_result
 | 
				
			||||||
 | 
					                name = regex.sub(r'(^\p{White_Space}|\r|\n)', '', regex.sub(r'\p{White_Space}{2,}', ' ', name.strip()))
 | 
				
			||||||
 | 
					                ingredients = regex.sub(r'(^\p{White_Space}|\r|\n)', '', regex.sub(r'\p{White_Space}{2,}', ' ', ingredients.strip()))
 | 
				
			||||||
 | 
					                ingredients = regex.sub(r'\*', '\u2731', ingredients.strip())
 | 
				
			||||||
 | 
					                return (name, ingredients)
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        (name, ingredients) = db_result
 | 
					    async def get_strain(self, strain: Optional[str] = None) -> Optional[tuple]:
 | 
				
			||||||
        name = regex.sub(r'(^\p{White_Space}|\r|\n)', '', regex.sub(r'\p{White_Space}{2,}', ' ', name.strip()))
 | 
					 | 
				
			||||||
        ingredients = regex.sub(r'(^\p{White_Space}|\r|\n)', '', regex.sub(r'\p{White_Space}{2,}', ' ', ingredients.strip()))
 | 
					 | 
				
			||||||
        ingredients = regex.sub(r'\*', '\u2731', ingredients.strip())
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        return (name, ingredients)
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
    async def get_strain(self, strain: Optional[str] = None) -> tuple:
 | 
					 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Get Strain
 | 
					        Get Strain
 | 
				
			||||||
        Args:
 | 
					        Args:
 | 
				
			||||||
            strain (Optional[str])
 | 
					            strain (Optional[str])
 | 
				
			||||||
        Returns:
 | 
					        Returns:
 | 
				
			||||||
            tuple
 | 
					            Optional[tuple]
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        strains_db: str|LiteralString = self.dbs.get('strains')
 | 
					        strains_db: str|LiteralString = self.dbs.get('strains', '')
 | 
				
			||||||
        db_conn = await sqlite3.connect(database=strains_db, timeout=2)
 | 
					        if not strains_db:
 | 
				
			||||||
        db_params: Optional[tuple] = None
 | 
					            return None
 | 
				
			||||||
        if not strain:
 | 
					        async with sqlite3.connect(database=strains_db,
 | 
				
			||||||
            db_query: str = "SELECT name, description FROM strains_w_desc ORDER BY random() LIMIT 1"
 | 
					                                   timeout=2) as db_conn:
 | 
				
			||||||
        else:
 | 
					            db_params: Optional[tuple] = None
 | 
				
			||||||
            db_query: str = "SELECT name, description FROM strains_w_desc WHERE name LIKE ?"
 | 
					            if not strain:
 | 
				
			||||||
            db_params: tuple = (f"%{strain.strip()}%",) 
 | 
					                db_query: str = "SELECT name, description FROM strains_w_desc ORDER BY random() LIMIT 1"
 | 
				
			||||||
            
 | 
					            else:
 | 
				
			||||||
        db_cursor: sqlite3.Cursor = await db_conn.execute(db_query, db_params)
 | 
					                db_query = "SELECT name, description FROM strains_w_desc WHERE name LIKE ?"
 | 
				
			||||||
        db_result: tuple = await db_cursor.fetchone()
 | 
					                db_params = (f"%{strain.strip()}%",) 
 | 
				
			||||||
 | 
					            async with await db_conn.execute(db_query, db_params) as db_cursor:
 | 
				
			||||||
 | 
					                db_result: Optional[tuple] = await db_cursor.fetchone()
 | 
				
			||||||
 | 
					                return db_result
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        return db_result
 | 
					    async def get_qajoke(self) -> Optional[tuple]:
 | 
				
			||||||
        
 | 
					 | 
				
			||||||
    async def get_qajoke(self) -> tuple:
 | 
					 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Get QA Joke
 | 
					        Get QA Joke
 | 
				
			||||||
        Returns:
 | 
					        Returns:
 | 
				
			||||||
            tuple
 | 
					            Optional[tuple]
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        qajoke_db: str|LiteralString = self.dbs.get('qajoke')
 | 
					        qajoke_db: str|LiteralString = self.dbs.get('qajoke', '')
 | 
				
			||||||
        async with sqlite3.connect(database=qajoke_db, timeout=2) as db:
 | 
					        if not qajoke_db:
 | 
				
			||||||
            async with await db.execute('SELECT question, answer FROM jokes ORDER BY RANDOM() LIMIT 1') as cursor:
 | 
					            return None
 | 
				
			||||||
 | 
					        async with sqlite3.connect(database=qajoke_db,
 | 
				
			||||||
 | 
					                                   timeout=2) as db_conn:
 | 
				
			||||||
 | 
					            db_query: str = "SELECT question, answer FROM jokes ORDER BY RANDOM() LIMIT 1"
 | 
				
			||||||
 | 
					            async with await db_conn.execute(db_query) as cursor:
 | 
				
			||||||
                (question, answer) = await cursor.fetchone()
 | 
					                (question, answer) = await cursor.fetchone()
 | 
				
			||||||
                return (question, answer)
 | 
					                return (question, answer)
 | 
				
			||||||
        return None
 | 
					        return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def get_rjoke(self) -> tuple:
 | 
					    async def get_rjoke(self) -> Optional[tuple]:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Get r/joke Joke
 | 
					        Get r/joke Joke
 | 
				
			||||||
        Returns:
 | 
					        Returns:
 | 
				
			||||||
            tuple
 | 
					            Optional[tuple]
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        rjokes_db: str|LiteralString = self.dbs.get('rjokes')
 | 
					        rjokes_db: str|LiteralString = self.dbs.get('rjokes', '')
 | 
				
			||||||
        async with sqlite3.connect(database=rjokes_db, timeout=2) as db:
 | 
					        if not rjokes_db:
 | 
				
			||||||
            async with await db.execute('SELECT title, body, score FROM jokes WHERE score >= 100 ORDER BY RANDOM() LIMIT 1') as cursor:
 | 
					            return None
 | 
				
			||||||
 | 
					        async with sqlite3.connect(database=rjokes_db, timeout=2) as db_conn:
 | 
				
			||||||
 | 
					            db_query: str = "SELECT title, body, score FROM jokes WHERE score >= 100 ORDER BY RANDOM() LIMIT 1'"
 | 
				
			||||||
 | 
					            async with await db_conn.execute(db_query) as cursor:
 | 
				
			||||||
                (title, body, score) = await cursor.fetchone()
 | 
					                (title, body, score) = await cursor.fetchone()
 | 
				
			||||||
                return (title, body, score)
 | 
					                return (title, body, score)
 | 
				
			||||||
        return None        
 | 
					        return None        
 | 
				
			||||||
@@ -307,29 +316,34 @@ class Util:
 | 
				
			|||||||
                try:
 | 
					                try:
 | 
				
			||||||
                    async with await client.get(facts_api_url,
 | 
					                    async with await client.get(facts_api_url,
 | 
				
			||||||
                                                timeout=ClientTimeout(connect=5, sock_read=5)) as request:
 | 
					                                                timeout=ClientTimeout(connect=5, sock_read=5)) as request:
 | 
				
			||||||
                        json: dict = await request.json()
 | 
					                        _json: dict = await request.json()
 | 
				
			||||||
                        fact: str = json.get('text')
 | 
					                        fact: str = _json.get('text', None)
 | 
				
			||||||
                        if not fact:
 | 
					                        if not fact:
 | 
				
			||||||
                            raise BaseException("RandFact Src 1 Failed")
 | 
					                            raise BaseException("RandFact Src 1 Failed")
 | 
				
			||||||
                        return fact
 | 
					                        return fact
 | 
				
			||||||
                except:
 | 
					                except:
 | 
				
			||||||
                    async with await client.get(facts_backup_url,
 | 
					                    async with await client.get(facts_backup_url,
 | 
				
			||||||
                                                timeout=ClientTimeout(connect=5, sock_read=5)) as request:
 | 
					                                                timeout=ClientTimeout(connect=5, sock_read=5)) as request:
 | 
				
			||||||
                        json: dict = await request.json()
 | 
					                        _json = await request.json()
 | 
				
			||||||
                        fact: str = json.get('fact')
 | 
					                        fact = _json.get('fact', None)
 | 
				
			||||||
                        return fact
 | 
					                        return fact
 | 
				
			||||||
        except Exception as e:
 | 
					        except Exception as e:
 | 
				
			||||||
            traceback.print_exc()
 | 
					            traceback.print_exc()
 | 
				
			||||||
            return f"Failed to get a random fact :( [{str(e)}]"
 | 
					            return f"Failed to get a random fact :( [{str(e)}]"
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
    async def get_cookie(self) -> dict:
 | 
					    async def get_cookie(self) -> Optional[dict]:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Get Cookie
 | 
					        Get Cookie
 | 
				
			||||||
        Returns:
 | 
					        Returns:
 | 
				
			||||||
            dict
 | 
					            Optional[dict]
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        async with sqlite3.connect(self.dbs.get('cookies'), timeout=2) as db_conn:
 | 
					        cookies_db = self.dbs.get('cookies', '')
 | 
				
			||||||
            async with await db_conn.execute("SELECT name, origin, image_url FROM cookies ORDER BY RANDOM() LIMIT 1") as db_cursor:
 | 
					        if not cookies_db:
 | 
				
			||||||
 | 
					            return None
 | 
				
			||||||
 | 
					        async with sqlite3.connect(cookies_db,
 | 
				
			||||||
 | 
					                                   timeout=2) as db_conn:
 | 
				
			||||||
 | 
					            db_query: str = "SELECT name, origin, image_url FROM cookies ORDER BY RANDOM() LIMIT 1"
 | 
				
			||||||
 | 
					            async with await db_conn.execute(db_query) as db_cursor:
 | 
				
			||||||
                (name, origin, image_url) = await db_cursor.fetchone()
 | 
					                (name, origin, image_url) = await db_cursor.fetchone()
 | 
				
			||||||
                return {
 | 
					                return {
 | 
				
			||||||
                    'name': name,
 | 
					                    'name': name,
 | 
				
			||||||
@@ -338,7 +352,7 @@ class Util:
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_coffee(self) -> str:
 | 
					    def get_coffee(self) -> Optional[str]:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Get Coffee
 | 
					        Get Coffee
 | 
				
			||||||
        Returns:
 | 
					        Returns:
 | 
				
			||||||
@@ -354,16 +368,16 @@ class Util:
 | 
				
			|||||||
            return randomCoffee
 | 
					            return randomCoffee
 | 
				
			||||||
        except:
 | 
					        except:
 | 
				
			||||||
            traceback.print_exc()
 | 
					            traceback.print_exc()
 | 
				
			||||||
            return False
 | 
					            return None
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
    def get_days_to_xmas(self) -> tuple[int|float]:
 | 
					    def get_days_to_xmas(self) -> Optional[tuple]:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Get # of Days until Xmas
 | 
					        Get # of Days until Xmas
 | 
				
			||||||
        Returns:
 | 
					        Returns:
 | 
				
			||||||
            tuple[int|float]
 | 
					            Optional[tuple]
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        today: datetime = datetime.datetime.now(tz=pytz.UTC)
 | 
					        today: datetime.datetime = datetime.datetime.now(tz=pytz.UTC)
 | 
				
			||||||
        xmas: datetime = datetime.datetime(
 | 
					        xmas: datetime.datetime = datetime.datetime(
 | 
				
			||||||
            year=today.year,
 | 
					            year=today.year,
 | 
				
			||||||
            month=12,
 | 
					            month=12,
 | 
				
			||||||
            day=25,
 | 
					            day=25,
 | 
				
			||||||
@@ -374,15 +388,18 @@ class Util:
 | 
				
			|||||||
        
 | 
					        
 | 
				
			||||||
        return (days, hours, minutes, seconds, ms, us)
 | 
					        return (days, hours, minutes, seconds, ms, us)
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    async def get_randmsg(self) -> str:
 | 
					    async def get_randmsg(self) -> Optional[str]:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Get Random Message from randmsg.db
 | 
					        Get Random Message from randmsg.db
 | 
				
			||||||
        Returns:
 | 
					        Returns:
 | 
				
			||||||
            str
 | 
					            Optional[str]
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        randmsg_db = self.dbs.get('randmsg')
 | 
					        randmsg_db: str|LiteralString = self.dbs.get('randmsg', '')
 | 
				
			||||||
 | 
					        if not randmsg_db:
 | 
				
			||||||
 | 
					            return None
 | 
				
			||||||
        async with sqlite3.connect(database=randmsg_db,
 | 
					        async with sqlite3.connect(database=randmsg_db,
 | 
				
			||||||
                                         timeout=2) as db_conn:
 | 
					                                         timeout=2) as db_conn:
 | 
				
			||||||
            async with await db_conn.execute("SELECT msg FROM msgs ORDER BY RANDOM() LIMIT 1") as db_cursor:
 | 
					            db_query: str = "SELECT msg FROM msgs ORDER BY RANDOM() LIMIT 1"
 | 
				
			||||||
 | 
					            async with await db_conn.execute(db_query) as db_cursor:
 | 
				
			||||||
                (result,) = await db_cursor.fetchone()
 | 
					                (result,) = await db_cursor.fetchone()
 | 
				
			||||||
                return result
 | 
					                return result
 | 
				
			||||||
							
								
								
									
										321
									
								
								cogs/quote.py
									
									
									
									
									
								
							
							
						
						
									
										321
									
								
								cogs/quote.py
									
									
									
									
									
								
							@@ -1,321 +0,0 @@
 | 
				
			|||||||
#!/usr/bin/env python3.12
 | 
					 | 
				
			||||||
# pylint: disable=bare-except, broad-exception-caught
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
"""
 | 
					 | 
				
			||||||
Quote cog for Havoc
 | 
					 | 
				
			||||||
"""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import traceback
 | 
					 | 
				
			||||||
import time
 | 
					 | 
				
			||||||
import os
 | 
					 | 
				
			||||||
import datetime
 | 
					 | 
				
			||||||
import asyncio
 | 
					 | 
				
			||||||
import discord
 | 
					 | 
				
			||||||
import aiosqlite as sqlite3
 | 
					 | 
				
			||||||
from discord.ext import bridge, commands
 | 
					 | 
				
			||||||
from disc_havoc import Havoc
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class DB:
 | 
					 | 
				
			||||||
    """DB Utility for Quote Cog"""
 | 
					 | 
				
			||||||
    def __init__(self, bot: Havoc):
 | 
					 | 
				
			||||||
        self.bot: Havoc = bot
 | 
					 | 
				
			||||||
        self.db_path = os.path.join("/", "usr", "local", "share",
 | 
					 | 
				
			||||||
                                    "sqlite_dbs", "quotes.db")
 | 
					 | 
				
			||||||
        self.hp_chanid = 1157529874936909934
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    async def get_quote_count(self):
 | 
					 | 
				
			||||||
        """Get Quote Count"""
 | 
					 | 
				
			||||||
        async with sqlite3.connect(self.db_path, timeout=2) as db_conn:
 | 
					 | 
				
			||||||
            async with await db_conn.execute("SELECT COUNT (*) FROM quotes") as db_cursor:
 | 
					 | 
				
			||||||
                result = await db_cursor.fetchone()
 | 
					 | 
				
			||||||
                return result[-1]
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
    async def remove_quote(self, quote_id: int):
 | 
					 | 
				
			||||||
        """Remove Quote from DB"""
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            async with sqlite3.connect(self.db_path, timeout=2) as db_conn:
 | 
					 | 
				
			||||||
                async with await db_conn.execute("DELETE FROM quotes WHERE id = ?", (quote_id,)) as _:
 | 
					 | 
				
			||||||
                    await db_conn.commit()
 | 
					 | 
				
			||||||
                    return True
 | 
					 | 
				
			||||||
        except:
 | 
					 | 
				
			||||||
            await self.bot.get_channel(self.hp_chanid).send(traceback.format_exc())
 | 
					 | 
				
			||||||
            return False
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
    async def add_quote(self, message_id: int, channel_id: int,
 | 
					 | 
				
			||||||
                        quoted_member_id: int,
 | 
					 | 
				
			||||||
                        message_time: int,
 | 
					 | 
				
			||||||
                        quoter_friendly: str,
 | 
					 | 
				
			||||||
                        quoted_friendly: str,
 | 
					 | 
				
			||||||
                        channel_friendly: str,
 | 
					 | 
				
			||||||
                        message_content: str,
 | 
					 | 
				
			||||||
                        ):
 | 
					 | 
				
			||||||
        """Add Quote to DB"""
 | 
					 | 
				
			||||||
        params = (
 | 
					 | 
				
			||||||
            quoter_friendly,
 | 
					 | 
				
			||||||
            int(time.time()),
 | 
					 | 
				
			||||||
            quoted_friendly,
 | 
					 | 
				
			||||||
            quoted_member_id,
 | 
					 | 
				
			||||||
            channel_friendly,
 | 
					 | 
				
			||||||
            channel_id,
 | 
					 | 
				
			||||||
            message_id,
 | 
					 | 
				
			||||||
            message_time,
 | 
					 | 
				
			||||||
            quoter_friendly,
 | 
					 | 
				
			||||||
            message_content,
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            async with sqlite3.connect(self.db_path, timeout=2) as db_conn:
 | 
					 | 
				
			||||||
                # pylint: disable=line-too-long
 | 
					 | 
				
			||||||
                db_conn.row_factory = lambda c, r: dict([(col[0], r[idx]) for idx, col in enumerate(c.description)])
 | 
					 | 
				
			||||||
                async with await db_conn.execute("INSERT INTO quotes (added_by, added_at, quoted_user_display, quoted_user_memberid, quoted_channel_display, quoted_channel_id, quoted_message_id, quoted_message_time, added_by_friendly, quoted_message) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
 | 
					 | 
				
			||||||
                                           params) as _: # pylint: enable=line-too-long
 | 
					 | 
				
			||||||
                    await db_conn.commit()
 | 
					 | 
				
			||||||
                    return True
 | 
					 | 
				
			||||||
        except:
 | 
					 | 
				
			||||||
            return traceback.format_exc()
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
    async def fetch_quote(self, random: bool = False, quoteid: int = None, added_by: str = None, quoted_user: str = None, content: str = None):
 | 
					 | 
				
			||||||
        """Fetch Quote from DB"""
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            query_head = "SELECT id, added_by_friendly, added_at, quoted_user_display, quoted_channel_display, quoted_message_time, quoted_message FROM quotes"
 | 
					 | 
				
			||||||
            query = ""
 | 
					 | 
				
			||||||
            params = None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if random:
 | 
					 | 
				
			||||||
                query = f"{query_head} ORDER BY RANDOM() LIMIT 1"
 | 
					 | 
				
			||||||
            elif quoteid:
 | 
					 | 
				
			||||||
                query = f"{query_head} WHERE id = ? LIMIT 1"
 | 
					 | 
				
			||||||
                params = (quoteid,)
 | 
					 | 
				
			||||||
            elif added_by:
 | 
					 | 
				
			||||||
                query = f"{query_head} WHERE added_by_friendly LIKE ? ORDER BY RANDOM() LIMIT 5"
 | 
					 | 
				
			||||||
                params = (f"%{added_by}%",)
 | 
					 | 
				
			||||||
            elif quoted_user:
 | 
					 | 
				
			||||||
                query = f"{query_head} WHERE quoted_user_display LIKE ? ORDER BY RANDOM() LIMIT 5"
 | 
					 | 
				
			||||||
                params = (f"%{quoted_user}%",)
 | 
					 | 
				
			||||||
            elif content:
 | 
					 | 
				
			||||||
                query = f"{query_head} WHERE quoted_message LIKE ? ORDER BY RANDOM() LIMIT 5"
 | 
					 | 
				
			||||||
                params = (f"%{content}%",)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            async with sqlite3.connect(self.db_path, timeout=2) as db_conn:
 | 
					 | 
				
			||||||
                db_conn.row_factory = lambda c, r: dict([(col[0], r[idx]) for idx, col in enumerate(c.description)])
 | 
					 | 
				
			||||||
                async with await db_conn.execute(query, params) as db_cursor:
 | 
					 | 
				
			||||||
                    results = await db_cursor.fetchall()
 | 
					 | 
				
			||||||
                    if not results:
 | 
					 | 
				
			||||||
                        return {
 | 
					 | 
				
			||||||
                            'err': 'No results for query',
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    if random or quoteid:
 | 
					 | 
				
			||||||
                        chosen = results[-1]
 | 
					 | 
				
			||||||
                        return {
 | 
					 | 
				
			||||||
                            str(k): v for k,v in chosen.items()
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    else:
 | 
					 | 
				
			||||||
                        return [
 | 
					 | 
				
			||||||
                            { str(k): v for k,v in _.items() }
 | 
					 | 
				
			||||||
                            for _ in results
 | 
					 | 
				
			||||||
                        ]
 | 
					 | 
				
			||||||
        except:
 | 
					 | 
				
			||||||
            return traceback.format_exc()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Quote(commands.Cog):
 | 
					 | 
				
			||||||
    """Quote Cog for Havoc"""
 | 
					 | 
				
			||||||
    def __init__(self, bot: Havoc):
 | 
					 | 
				
			||||||
        self.bot: Havoc = bot
 | 
					 | 
				
			||||||
        self.db = DB(self.bot)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def is_homeserver(): # pylint: disable=no-method-argument
 | 
					 | 
				
			||||||
        """Check if channel/interaction is within homeserver"""
 | 
					 | 
				
			||||||
        def predicate(ctx):
 | 
					 | 
				
			||||||
            try:
 | 
					 | 
				
			||||||
                return ctx.guild.id == 1145182936002482196
 | 
					 | 
				
			||||||
            except:
 | 
					 | 
				
			||||||
                traceback.print_exc()
 | 
					 | 
				
			||||||
                return False
 | 
					 | 
				
			||||||
        return commands.check(predicate)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @commands.message_command(name="Add Quote")
 | 
					 | 
				
			||||||
    async def add_quote(self, ctx, message: discord.Message):
 | 
					 | 
				
			||||||
        """Add A Quote"""
 | 
					 | 
				
			||||||
        hp_chanid = 1157529874936909934
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            if message.author.bot:
 | 
					 | 
				
			||||||
                return await ctx.respond("Quotes are for real users, not bots.", ephemeral=True)
 | 
					 | 
				
			||||||
            quoter_friendly = ctx.author.display_name
 | 
					 | 
				
			||||||
            quoted_message_id = message.id            
 | 
					 | 
				
			||||||
            quoted_channel_friendly = f'#{ctx.channel.name}'
 | 
					 | 
				
			||||||
            quoted_channel_id = ctx.channel.id
 | 
					 | 
				
			||||||
            message_content = message.content
 | 
					 | 
				
			||||||
            message_author_friendly = message.author.display_name
 | 
					 | 
				
			||||||
            message_author_id = message.author.id
 | 
					 | 
				
			||||||
            message_time = int(message.created_at.timestamp())
 | 
					 | 
				
			||||||
            message_escaped = discord.utils.escape_mentions(discord.utils.escape_markdown(message_content)).strip()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if len(message_escaped) < 3:
 | 
					 | 
				
			||||||
                return await ctx.respond("**Error**: Message (text content) is not long enough to quote.", ephemeral=True)
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            if len(message_escaped) > 512:
 | 
					 | 
				
			||||||
                return await ctx.respond("**Error**: Message (text content) is too long to quote.", ephemeral=True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            result = await self.db.add_quote(message_id=quoted_message_id,
 | 
					 | 
				
			||||||
                                    channel_id=quoted_channel_id,
 | 
					 | 
				
			||||||
                                    quoted_member_id=message_author_id,
 | 
					 | 
				
			||||||
                                    message_time=message_time,
 | 
					 | 
				
			||||||
                                    quoter_friendly=quoter_friendly,
 | 
					 | 
				
			||||||
                                    quoted_friendly=message_author_friendly,
 | 
					 | 
				
			||||||
                                    channel_friendly=quoted_channel_friendly,
 | 
					 | 
				
			||||||
                                    message_content=message_content)
 | 
					 | 
				
			||||||
            if not result:
 | 
					 | 
				
			||||||
                return await ctx.respond("Failed!", ephemeral=True)
 | 
					 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
                return await ctx.respond("OK!", ephemeral=True)
 | 
					 | 
				
			||||||
        except:
 | 
					 | 
				
			||||||
            await self.bot.get_channel(hp_chanid).send(traceback.format_exc())
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    @bridge.bridge_command(aliases=['rand'])
 | 
					 | 
				
			||||||
    @is_homeserver() # pylint: disable=too-many-function-args
 | 
					 | 
				
			||||||
    async def randquote(self, ctx):
 | 
					 | 
				
			||||||
        """Get a random quote"""
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            random_quote = await self.db.fetch_quote(random=True)
 | 
					 | 
				
			||||||
            if random_quote.get('err'):
 | 
					 | 
				
			||||||
                return await ctx.respond("Failed to get a quote")
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            quote_id = random_quote.get('id')
 | 
					 | 
				
			||||||
            quoted_friendly = random_quote.get('quoted_user_display', 'Unknown')
 | 
					 | 
				
			||||||
            adder_friendly = random_quote.get('added_by_friendly', 'Unknown')
 | 
					 | 
				
			||||||
            message_time = datetime.datetime.fromtimestamp(random_quote.get('quoted_message_time'))
 | 
					 | 
				
			||||||
            message_channel = random_quote.get('quoted_channel_display')
 | 
					 | 
				
			||||||
            quote_added_at = datetime.datetime.fromtimestamp(random_quote.get('added_at'))
 | 
					 | 
				
			||||||
            quote_content = random_quote.get('quoted_message')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            embed = discord.Embed(
 | 
					 | 
				
			||||||
                colour=discord.Colour.orange(),
 | 
					 | 
				
			||||||
                title=f"Quote #{quote_id}",
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
            embed.description = f"**{quoted_friendly}:** {quote_content}"
 | 
					 | 
				
			||||||
            embed.add_field(name="Original Message Time", value=message_time)
 | 
					 | 
				
			||||||
            embed.add_field(name="Channel", value=message_channel)
 | 
					 | 
				
			||||||
            embed.add_field(name="Quote ID", value=quote_id)
 | 
					 | 
				
			||||||
            embed.footer = discord.EmbedFooter(text=f"Added by {adder_friendly} {quote_added_at}")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return await ctx.respond(embed=embed)
 | 
					 | 
				
			||||||
        except:
 | 
					 | 
				
			||||||
            error = await ctx.respond(traceback.format_exc())
 | 
					 | 
				
			||||||
            await asyncio.sleep(10)
 | 
					 | 
				
			||||||
            await error.delete()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @bridge.bridge_command(aliases=['qg'])
 | 
					 | 
				
			||||||
    @is_homeserver() # pylint: disable=too-many-function-args
 | 
					 | 
				
			||||||
    async def quoteget(self, ctx, quoteid):
 | 
					 | 
				
			||||||
        """Get a specific quote by ID"""
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            if not str(quoteid).strip().isnumeric():
 | 
					 | 
				
			||||||
                return await ctx.respond("**Error**: Quote ID must be numeric.")
 | 
					 | 
				
			||||||
            fetched_quote = await self.db.fetch_quote(quoteid=quoteid)
 | 
					 | 
				
			||||||
            if fetched_quote.get('err'):
 | 
					 | 
				
			||||||
                return await ctx.respond("**Error**: Quote not found")
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            quote_id = fetched_quote.get('id')
 | 
					 | 
				
			||||||
            quoted_friendly = fetched_quote.get('quoted_user_display', 'Unknown')
 | 
					 | 
				
			||||||
            adder_friendly = fetched_quote.get('added_by_friendly', 'Unknown')
 | 
					 | 
				
			||||||
            message_time = datetime.datetime.fromtimestamp(fetched_quote.get('quoted_message_time'))
 | 
					 | 
				
			||||||
            message_channel = fetched_quote.get('quoted_channel_display')
 | 
					 | 
				
			||||||
            quote_added_at = datetime.datetime.fromtimestamp(fetched_quote.get('added_at'))
 | 
					 | 
				
			||||||
            quote_content = fetched_quote.get('quoted_message')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            embed = discord.Embed(
 | 
					 | 
				
			||||||
                colour=discord.Colour.orange(),
 | 
					 | 
				
			||||||
                title=f"Quote #{quote_id}",
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
            embed.description = f"**{quoted_friendly}:** {quote_content}"
 | 
					 | 
				
			||||||
            embed.add_field(name="Original Message Time", value=message_time)
 | 
					 | 
				
			||||||
            embed.add_field(name="Channel", value=message_channel)
 | 
					 | 
				
			||||||
            embed.add_field(name="Quote ID", value=quote_id)
 | 
					 | 
				
			||||||
            embed.footer = discord.EmbedFooter(text=f"Added by {adder_friendly} {quote_added_at}")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return await ctx.respond(embed=embed)
 | 
					 | 
				
			||||||
        except:
 | 
					 | 
				
			||||||
            error = await ctx.respond(traceback.format_exc())
 | 
					 | 
				
			||||||
            await asyncio.sleep(10)
 | 
					 | 
				
			||||||
            await error.delete()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @bridge.bridge_command(aliases=['qs'])
 | 
					 | 
				
			||||||
    @is_homeserver() # pylint: disable=too-many-function-args
 | 
					 | 
				
			||||||
    async def quotesearch(self, ctx, *, content: str):
 | 
					 | 
				
			||||||
        """Search for a quote (by content)"""
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            found_quotes = await self.db.fetch_quote(content=content)
 | 
					 | 
				
			||||||
            if isinstance(found_quotes, dict) and found_quotes.get('err'):
 | 
					 | 
				
			||||||
                return await ctx.respond(f"Quote search failed: {found_quotes.get('err')}")
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            embeds = []
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            for quote in found_quotes:
 | 
					 | 
				
			||||||
                quote_id = quote.get('id')
 | 
					 | 
				
			||||||
                quoted_friendly = quote.get('quoted_user_display', 'Unknown')
 | 
					 | 
				
			||||||
                adder_friendly = quote.get('added_by_friendly', 'Unknown')
 | 
					 | 
				
			||||||
                message_time = datetime.datetime.fromtimestamp(quote.get('quoted_message_time'))
 | 
					 | 
				
			||||||
                message_channel = quote.get('quoted_channel_display')
 | 
					 | 
				
			||||||
                quote_added_at = datetime.datetime.fromtimestamp(quote.get('added_at'))
 | 
					 | 
				
			||||||
                quote_content = quote.get('quoted_message')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                # await ctx.respond(f"**{quoted_friendly}**: {quote}")ed_friendly = quote.get('quoted_user_display', 'Unknown')
 | 
					 | 
				
			||||||
                adder_friendly = quote.get('added_by_friendly', 'Unknown')
 | 
					 | 
				
			||||||
                message_time = datetime.datetime.fromtimestamp(quote.get('quoted_message_time'))
 | 
					 | 
				
			||||||
                message_channel = quote.get('quoted_channel_display')
 | 
					 | 
				
			||||||
                quote_added_at = datetime.datetime.fromtimestamp(quote.get('added_at'))
 | 
					 | 
				
			||||||
                quote = quote.get('quoted_message')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                # await ctx.respond(f"**{quoted_friendly}**: {quote}")
 | 
					 | 
				
			||||||
                embed = discord.Embed(
 | 
					 | 
				
			||||||
                    colour=discord.Colour.orange(),
 | 
					 | 
				
			||||||
                    title=f"Quote #{quote_id}",
 | 
					 | 
				
			||||||
                )
 | 
					 | 
				
			||||||
                embed.description = f"**{quoted_friendly}:** {quote_content}"
 | 
					 | 
				
			||||||
                embed.add_field(name="Original Message Time", value=message_time)
 | 
					 | 
				
			||||||
                embed.add_field(name="Channel", value=message_channel)
 | 
					 | 
				
			||||||
                embed.add_field(name="Quote ID", value=quote_id)
 | 
					 | 
				
			||||||
                embed.footer = discord.EmbedFooter(text=f"Added by {adder_friendly} {quote_added_at}")
 | 
					 | 
				
			||||||
                embeds.append(embed)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return await ctx.respond(embeds=embeds)
 | 
					 | 
				
			||||||
        except Exception as e:
 | 
					 | 
				
			||||||
            await ctx.respond(f"Error: {type(e).__name__} - {str(e)}")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @bridge.bridge_command(aliases=['nq'])
 | 
					 | 
				
			||||||
    @is_homeserver() # pylint: disable=too-many-function-args
 | 
					 | 
				
			||||||
    async def nquotes(self, ctx):
 | 
					 | 
				
			||||||
        """Get # of quotes stored"""
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            quote_count = await self.db.get_quote_count()
 | 
					 | 
				
			||||||
            if not quote_count:
 | 
					 | 
				
			||||||
                return await ctx.respond("**Error**: No quotes found!")
 | 
					 | 
				
			||||||
            return await ctx.respond(f"I currently have **{quote_count}** quotes stored.")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        except Exception as e:
 | 
					 | 
				
			||||||
            await ctx.respond(f"Error: {type(e).__name__} - {str(e)}")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @bridge.bridge_command(aliases=['qr'])
 | 
					 | 
				
			||||||
    @commands.is_owner()
 | 
					 | 
				
			||||||
    @is_homeserver() # pylint: disable=too-many-function-args
 | 
					 | 
				
			||||||
    async def quoteremove(self, ctx, quoteid):
 | 
					 | 
				
			||||||
        """Remove a quote (by id)
 | 
					 | 
				
			||||||
        Owner only"""
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            if not str(quoteid).strip().isnumeric():
 | 
					 | 
				
			||||||
                return await ctx.respond("**Error**: Quote ID must be numeric.")
 | 
					 | 
				
			||||||
            quoteid = int(quoteid)
 | 
					 | 
				
			||||||
            remove_quote = await self.db.remove_quote(quoteid) 
 | 
					 | 
				
			||||||
            if not remove_quote:
 | 
					 | 
				
			||||||
                return await ctx.respond("**Error**: Failed!", ephemeral=True)
 | 
					 | 
				
			||||||
            return await ctx.respond("Removed!", ephemeral=True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        except Exception as e:
 | 
					 | 
				
			||||||
            await ctx.respond(f"Error: {type(e).__name__} - {str(e)}")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def setup(bot):
 | 
					 | 
				
			||||||
    """Run on Cog Load"""
 | 
					 | 
				
			||||||
    bot.add_cog(Quote(bot))
 | 
					 | 
				
			||||||
@@ -29,7 +29,7 @@ class Radio(commands.Cog):
 | 
				
			|||||||
        """Run on Bot Ready"""
 | 
					        """Run on Bot Ready"""
 | 
				
			||||||
        await self.radio_init()
 | 
					        await self.radio_init()
 | 
				
			||||||
         
 | 
					         
 | 
				
			||||||
    def is_radio_chan(): # pylint: disable=no-method-argument
 | 
					    def is_radio_chan(): # type: ignore
 | 
				
			||||||
        """Check if channel is radio chan"""
 | 
					        """Check if channel is radio chan"""
 | 
				
			||||||
        def predicate(ctx):
 | 
					        def predicate(ctx):
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
@@ -59,8 +59,12 @@ class Radio(commands.Cog):
 | 
				
			|||||||
        """
 | 
					        """
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            (radio_guild, radio_chan) = self.channels['sfm']
 | 
					            (radio_guild, radio_chan) = self.channels['sfm']
 | 
				
			||||||
            channel: discord.TextChannel = self.bot.get_guild(radio_guild)\
 | 
					            guild: Optional[discord.Guild] = self.bot.get_guild(radio_guild)
 | 
				
			||||||
                .get_channel(radio_chan)             
 | 
					            if not guild:
 | 
				
			||||||
 | 
					                return
 | 
				
			||||||
 | 
					            channel = guild.get_channel(radio_chan)             
 | 
				
			||||||
 | 
					            if not isinstance(channel, discord.VoiceChannel):
 | 
				
			||||||
 | 
					                return
 | 
				
			||||||
            if not self.bot.voice_clients:
 | 
					            if not self.bot.voice_clients:
 | 
				
			||||||
                await channel.connect()
 | 
					                await channel.connect()
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
@@ -84,24 +88,35 @@ class Radio(commands.Cog):
 | 
				
			|||||||
        try:
 | 
					        try:
 | 
				
			||||||
            (radio_guild, radio_chan) = self.channels['sfm']
 | 
					            (radio_guild, radio_chan) = self.channels['sfm']
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
                vc: discord.VoiceClient = self.bot.voice_clients[-1]
 | 
					                vc: discord.VoiceProtocol = self.bot.voice_clients[-1]
 | 
				
			||||||
            except:
 | 
					            except:
 | 
				
			||||||
                logging.debug("No voice client, establishing new VC connection...")
 | 
					                logging.debug("No voice client, establishing new VC connection...")
 | 
				
			||||||
                channel = self.bot.get_guild(radio_guild)\
 | 
					                guild: Optional[discord.Guild] = self.bot.get_guild(radio_guild)
 | 
				
			||||||
                    .get_channel(radio_chan)
 | 
					                if not guild:
 | 
				
			||||||
 | 
					                    return
 | 
				
			||||||
 | 
					                channel = guild.get_channel(radio_chan)
 | 
				
			||||||
 | 
					                if not isinstance(channel, discord.VoiceChannel):
 | 
				
			||||||
 | 
					                    return
 | 
				
			||||||
                await channel.connect()
 | 
					                await channel.connect()
 | 
				
			||||||
                vc = self.bot.voice_clients[-1]
 | 
					                vc = self.bot.voice_clients[-1]
 | 
				
			||||||
            if not(vc.is_playing()) or vc.is_paused():
 | 
					            
 | 
				
			||||||
 | 
					            if not vc.is_playing() or vc.is_paused():  # type: ignore
 | 
				
			||||||
 | 
					                """
 | 
				
			||||||
 | 
					                Mypy does not seem aware of the is_playing, play, and is_paused methods,
 | 
				
			||||||
 | 
					                but they exist.
 | 
				
			||||||
 | 
					                """
 | 
				
			||||||
                logging.info("Detected VC not playing... playing!")
 | 
					                logging.info("Detected VC not playing... playing!")
 | 
				
			||||||
                source = discord.FFmpegOpusAudio(self.STREAM_URL,
 | 
					                source = discord.FFmpegOpusAudio(self.STREAM_URL,
 | 
				
			||||||
                                                 before_options="-timeout 3000000")
 | 
					                                                 before_options="-timeout 3000000")
 | 
				
			||||||
                vc.play(source, after=lambda e: logging.info("Error: %s", e)\
 | 
					                
 | 
				
			||||||
                    if e else None)
 | 
					                vc.play(source, after=lambda e: logging.info("Error: %s", e) if e else None) # type: ignore
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # Get Now Playing
 | 
					            # Get Now Playing
 | 
				
			||||||
            np_track = await get_now_playing()
 | 
					            np_track = await get_now_playing()
 | 
				
			||||||
            if np_track and not self.LAST_NP_TRACK == np_track:
 | 
					            if np_track and not self.LAST_NP_TRACK == np_track:
 | 
				
			||||||
                self.LAST_NP_TRACK: str = np_track
 | 
					                self.LAST_NP_TRACK = np_track
 | 
				
			||||||
                await vc.channel.set_status(f"Now playing: {np_track}")
 | 
					                if isinstance(vc.channel, discord.VoiceChannel):
 | 
				
			||||||
 | 
					                    await vc.channel.set_status(f"Now playing: {np_track}")
 | 
				
			||||||
        except:
 | 
					        except:
 | 
				
			||||||
            traceback.print_exc()
 | 
					            traceback.print_exc()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,3 +13,12 @@ LoveHate
 | 
				
			|||||||
class LoveHateException(Exception):
 | 
					class LoveHateException(Exception):
 | 
				
			||||||
    """Love Hate Exception (generic)"""
 | 
					    """Love Hate Exception (generic)"""
 | 
				
			||||||
    pass
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					Misc
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MiscException(Exception):
 | 
				
			||||||
 | 
					    """Misc Exception (generic)"""
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
@@ -29,7 +29,6 @@ cogs_list: list[str] = [
 | 
				
			|||||||
    'meme',
 | 
					    'meme',
 | 
				
			||||||
    'karma',
 | 
					    'karma',
 | 
				
			||||||
    'lovehate',
 | 
					    'lovehate',
 | 
				
			||||||
    'quote',
 | 
					 | 
				
			||||||
    'radio',
 | 
					    'radio',
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -46,6 +45,8 @@ class Havoc(bridge.Bot):
 | 
				
			|||||||
                              owner_ids=OWNERS, activity=bot_activity,
 | 
					                              owner_ids=OWNERS, activity=bot_activity,
 | 
				
			||||||
                              help_command=commands.MinimalHelpCommand())
 | 
					                              help_command=commands.MinimalHelpCommand())
 | 
				
			||||||
        self.BOT_CHANIDS = BOT_CHANIDS
 | 
					        self.BOT_CHANIDS = BOT_CHANIDS
 | 
				
			||||||
 | 
					        self.load_exts()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
    def load_exts(self, initialRun: Optional[bool] = True) -> None:
 | 
					    def load_exts(self, initialRun: Optional[bool] = True) -> None:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,13 +31,13 @@ class DB:
 | 
				
			|||||||
        if hates and loves:
 | 
					        if hates and loves:
 | 
				
			||||||
            raise LoveHateException("Both hates and loves may not be True")
 | 
					            raise LoveHateException("Both hates and loves may not be True")
 | 
				
			||||||
        elif hates:
 | 
					        elif hates:
 | 
				
			||||||
            flag: int = -1
 | 
					            flag = -1
 | 
				
			||||||
        elif loves:
 | 
					        elif loves:
 | 
				
			||||||
            flag: int = 1
 | 
					            flag = 1
 | 
				
			||||||
        elif not hates and not loves:
 | 
					        elif not hates and not loves:
 | 
				
			||||||
            raise LoveHateException("Neither loves nor hates were requested")
 | 
					            raise LoveHateException("Neither loves nor hates were requested")
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        params: tuple = (thing, flag,)
 | 
					        params = (thing, flag,)
 | 
				
			||||||
        async with sqlite3.connect(self.db_path, timeout=2) as db_conn:
 | 
					        async with sqlite3.connect(self.db_path, timeout=2) as db_conn:
 | 
				
			||||||
            async with await db_conn.execute(query, params) as db_cursor:
 | 
					            async with await db_conn.execute(query, params) as db_cursor:
 | 
				
			||||||
                result: list[tuple] = await db_cursor.fetchall()
 | 
					                result: list[tuple] = await db_cursor.fetchall()
 | 
				
			||||||
@@ -47,7 +47,7 @@ class DB:
 | 
				
			|||||||
                return result
 | 
					                return result
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
    async def get_lovehates(self, loves: bool = False, hates: bool = False,
 | 
					    async def get_lovehates(self, loves: bool = False, hates: bool = False,
 | 
				
			||||||
                            user: str = None, thing: str = None) -> list[tuple]|bool:
 | 
					                            user: Optional[str] = None, thing: Optional[str] = None) -> list[tuple]|bool:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Get a list of either 1) what {user} loves/hates, or who loves/hates {thing}, depending on bools loves, hates
 | 
					        Get a list of either 1) what {user} loves/hates, or who loves/hates {thing}, depending on bools loves, hates
 | 
				
			||||||
        Args:
 | 
					        Args:
 | 
				
			||||||
@@ -70,18 +70,18 @@ class DB:
 | 
				
			|||||||
        if hates and loves:
 | 
					        if hates and loves:
 | 
				
			||||||
            raise LoveHateException("Both hates and loves may not be True")
 | 
					            raise LoveHateException("Both hates and loves may not be True")
 | 
				
			||||||
        elif hates:
 | 
					        elif hates:
 | 
				
			||||||
            flag: int = -1
 | 
					            flag = -1
 | 
				
			||||||
        elif loves:
 | 
					        elif loves:
 | 
				
			||||||
            flag: int = 1
 | 
					            flag = 1
 | 
				
			||||||
        elif not hates and not loves:
 | 
					        elif not hates and not loves:
 | 
				
			||||||
            raise LoveHateException("Neither loves nor hates were requested")
 | 
					            raise LoveHateException("Neither loves nor hates were requested")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if user:
 | 
					        if user:
 | 
				
			||||||
            query: str = "SELECT thing FROM lovehate WHERE display_name LIKE ? AND flag == ?"
 | 
					            query = "SELECT thing FROM lovehate WHERE display_name LIKE ? AND flag == ?"
 | 
				
			||||||
            params: tuple  = (user, flag,)
 | 
					            params = (user, flag,)
 | 
				
			||||||
        elif thing:
 | 
					        elif thing:
 | 
				
			||||||
            query: str = "SELECT display_name FROM lovehate WHERE thing LIKE ? AND flag == ?"
 | 
					            query = "SELECT display_name FROM lovehate WHERE thing LIKE ? AND flag == ?"
 | 
				
			||||||
            params: tuple = (thing, flag,)
 | 
					            params = (thing, flag,)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        async with sqlite3.connect(self.db_path, timeout=2) as db_conn:
 | 
					        async with sqlite3.connect(self.db_path, timeout=2) as db_conn:
 | 
				
			||||||
            async with await db_conn.execute(query, params) as db_cursor:
 | 
					            async with await db_conn.execute(query, params) as db_cursor:
 | 
				
			||||||
@@ -127,21 +127,21 @@ class DB:
 | 
				
			|||||||
        db_query: str = ""
 | 
					        db_query: str = ""
 | 
				
			||||||
        params: tuple = (user, thing,)
 | 
					        params: tuple = (user, thing,)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        already_opinionated: bool = await self.check_existence(user, thing)
 | 
					        already_opinionated: Optional[int] = await self.check_existence(user, thing)
 | 
				
			||||||
        if already_opinionated: 
 | 
					        if already_opinionated: 
 | 
				
			||||||
            if flag == 0:
 | 
					            if flag == 0:
 | 
				
			||||||
                db_query: str = "DELETE FROM lovehate WHERE display_name LIKE ? AND thing LIKE ?"
 | 
					                db_query = "DELETE FROM lovehate WHERE display_name LIKE ? AND thing LIKE ?"
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                loves_or_hates: str = "loves"
 | 
					                loves_or_hates: str = "loves"
 | 
				
			||||||
                if already_opinionated == -1:
 | 
					                if already_opinionated == -1:
 | 
				
			||||||
                    loves_or_hates: str = "hates"
 | 
					                    loves_or_hates = "hates"
 | 
				
			||||||
                raise LoveHateException(f"But {user} already {loves_or_hates} {thing}...")
 | 
					                raise LoveHateException(f"But {user} already {loves_or_hates} {thing}...")
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            match flag:
 | 
					            match flag:
 | 
				
			||||||
                case -1:
 | 
					                case -1:
 | 
				
			||||||
                    db_query: str = "INSERT INTO lovehate(display_name, flag, thing) VALUES(?, -1, ?)"
 | 
					                    db_query = "INSERT INTO lovehate(display_name, flag, thing) VALUES(?, -1, ?)"
 | 
				
			||||||
                case 1:
 | 
					                case 1:
 | 
				
			||||||
                    db_query: str = "INSERT INTO lovehate(display_name, flag, thing) VALUES(?, 1, ?)"
 | 
					                    db_query = "INSERT INTO lovehate(display_name, flag, thing) VALUES(?, 1, ?)"
 | 
				
			||||||
                case _:
 | 
					                case _:
 | 
				
			||||||
                    raise LoveHateException("Unknown error, default case matched")
 | 
					                    raise LoveHateException("Unknown error, default case matched")
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user