#!/usr/bin/env python3.12 # pylint: disable=broad-exception-caught import traceback import logging import os from typing import Any, Optional import discord import aiosqlite as sqlite3 from discord.ext import bridge, commands from util.lovehate_db import DB from constructors import LoveHateException 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. Args: ctx (Any) user (Optional[str]) Returns: None """ try: if not user: loves: list[tuple] = await self.db.get_lovehates(user=ctx.author.display_name, loves=True) if not loves: return await ctx.respond("You don't seem to love anything...") out_loves: list = [] 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: list[tuple] = 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: 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 Args: ctx (Any) thing (Optional[str]) Returns: None """ try: if not thing: thing: str = ctx.author.display_name if discord.utils.raw_mentions(thing): # There are mentions 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 who_loves: list[tuple] = await self.db.get_wholovehates(thing=thing, loves=True) if not who_loves: 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 Args: ctx (Any) thing (Optional[str]) Returns: None """ try: if not thing: thing: str = ctx.author.display_name if discord.utils.raw_mentions(thing): # There are mentions 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 who_hates: list[tuple] = 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 = [] 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 Args: ctx (Any) thing (str) Returns: None """ 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. Args: ctx (Any) user (Optional[str]) Returns: None """ try: if not user: hates: list[tuple] = await self.db.get_lovehates(user=ctx.author.display_name, hates=True) if not hates: return await ctx.respond("You don't seem to hate anything...") out_hates: list = [] 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"{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) 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 Args: ctx (Any) thing (str) Returns: None """ try: if discord.utils.raw_mentions(thing): # There are mentions 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 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 Args: ctx (Any) thing (str) Returns: None """ try: if discord.utils.raw_mentions(thing): # There are mentions 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 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))