import traceback from typing import Optional, Union import discord from discord.ext import bridge, commands from util.lovehate_db import DB from disc_havoc import Havoc class LoveHate(commands.Cog): """LoveHate Cog for Havoc""" def __init__(self, bot: Havoc) -> None: self.bot: Havoc = bot self.db = DB(self.bot) def join_with_and(self, items: list) -> str: """ Join list with and added before last item Args: items (list) Returns: str """ if len(items) > 1: return ", ".join(items[:-1]) + " and " + items[-1] return items[0] if items else "" @bridge.bridge_command() async def loves(self, ctx, user: Optional[str] = None) -> None: """ If keyword isn't provided, returns the things YOU love; specify a user to find what THEY love. """ try: if not user: display_name = ctx.author.display_name loves: Union[list[tuple], bool] = await self.db.get_lovehates( user=display_name, loves=True ) if not loves: return await ctx.respond("You don't seem to love anything...") out_loves: list = [] if not isinstance(loves, list): return for love in loves: (love,) = love out_loves.append(love) out_loves_str: str = self.join_with_and(out_loves) return await ctx.respond(f"{ctx.author.mention} loves {out_loves_str}") loves = await self.db.get_lovehates(user=user.strip(), loves=True) if not loves: return await ctx.respond(f"{user} doesn't seem to love anything...") out_loves_str = self.join_with_and(out_loves) return await ctx.respond(f"{user} loves {out_loves_str}") except Exception as e: traceback.print_exc() return await ctx.respond(f"Error: {str(e)}") @bridge.bridge_command() async def wholoves(self, ctx, *, thing: Optional[str] = None) -> None: """ Check who loves """ try: if not thing: _thing: str = ctx.author.display_name else: _thing = thing if discord.utils.raw_mentions(_thing): # 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) if not guild: return thing_member: Optional[discord.Member] = guild.get_member(thing_id) if not thing_member: return _thing = thing_member.display_name if not _thing: return who_loves: Union[list, bool] = await self.db.get_wholovehates( thing=_thing, loves=True ) if not isinstance(who_loves, list): return await ctx.respond(f"I couldn't find anyone who loves {thing}...") out_wholoves: list = [] for lover in who_loves: (lover,) = lover out_wholoves.append(str(lover)) optional_s: str = "s" if len(out_wholoves) == 1 else "" out_wholoves_str: str = self.join_with_and(out_wholoves) return await ctx.respond(f"{out_wholoves_str} love{optional_s} {thing}") except Exception as e: traceback.print_exc() return await ctx.respond(f"Error: {str(e)}") @bridge.bridge_command() async def whohates(self, ctx, *, thing: Optional[str] = None) -> None: """ Check who hates """ try: if not thing: _thing: str = ctx.author.display_name else: _thing = thing if discord.utils.raw_mentions(_thing): # There are mentions guild: Optional[discord.Guild] = self.bot.get_guild(ctx.guild.id) 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: Union[list[tuple], bool] = await self.db.get_wholovehates( thing=_thing, hates=True ) if not who_hates: return await ctx.respond(f"I couldn't find anyone who hates {thing}...") out_whohates: list = [] if not isinstance(who_hates, list): return for hater in who_hates: (hater,) = hater out_whohates.append(str(hater)) optional_s: str = "s" if len(out_whohates) == 1 else "" out_whohates_str: str = self.join_with_and(out_whohates) return await ctx.respond(f"{out_whohates_str} hate{optional_s} {thing}") except Exception as e: traceback.print_exc() return await ctx.respond(f"Error: {str(e)}") @bridge.bridge_command() async def dontcare(self, ctx, thing: str) -> None: """ Make me forget your opinion on """ try: stop_caring: str = await self.db.update(ctx.author.display_name, thing, 0) return await ctx.respond(stop_caring) except Exception as e: await ctx.respond(f"Error: {str(e)}") traceback.print_exc() @bridge.bridge_command() async def hates(self, ctx, user: Optional[str] = None) -> None: """ If keyword isn't provided, returns the things YOU hate; specify a user to find what THEY hate. """ try: if not user: display_name = ctx.author.display_name hates: Union[list[tuple], bool] = await self.db.get_lovehates( user=display_name, hates=True ) if not hates: return await ctx.respond("You don't seem to hate anything...") else: hates = 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: 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}") except Exception as e: await ctx.respond(f"Error: {str(e)}") traceback.print_exc() @bridge.bridge_command(aliases=["sarcastichate"]) async def love(self, ctx, *, thing: str) -> None: """ Love """ try: if discord.utils.raw_mentions(thing): # There are mentions thing_id: int = discord.utils.raw_mentions(thing)[0] # First mention 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, thing, 1) return await ctx.respond(love) except Exception as e: await ctx.respond(f"Error: {str(e)}") traceback.print_exc() @bridge.bridge_command(aliases=["sarcasticlove"]) async def hate(self, ctx, *, thing: str) -> None: """ Hate """ try: if discord.utils.raw_mentions(thing): # 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) 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, thing, -1) return await ctx.respond(hate) except Exception as e: await ctx.respond(f"Error: {str(e)}") traceback.print_exc() def cog_unload(self) -> None: # not needed currently pass def setup(bot) -> None: """Run on Cog Load""" bot.add_cog(LoveHate(bot))