From 9df3b37619e59b9f34db3488681bc02b2891c798 Mon Sep 17 00:00:00 2001 From: codey Date: Sun, 16 Feb 2025 20:07:02 -0500 Subject: [PATCH] cleanup --- README.md | 4 ++- cogs/karma.py | 17 +++++---- cogs/lovehate.py | 14 ++++++-- cogs/meme.py | 7 ++-- cogs/misc.py | 54 +++++++++++++++++++++++++---- cogs/misc_util.py | 34 ++++++++++++++++++ cogs/owner.py | 9 +++++ cogs/radio.py | 5 ++- cogs/sing.py | 2 ++ disc_havoc.py | 4 ++- util/catbox.py | 2 ++ util/discord_helpers.py | 2 ++ util/jesusmemes.py | 3 ++ util/litterbox.py | 2 ++ util/lovehate_db.py | 10 ++++-- util/radio_util.py | 6 ++++ util/sing_util.py | 77 +++++++++++++++++++++++++---------------- 17 files changed, 196 insertions(+), 56 deletions(-) diff --git a/README.md b/README.md index 1a64dea..998b2b3 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ ![](https://codey.lol/havoc-fv.jpg) -# Discord-Havoc Rewrite (Pycord) \ No newline at end of file +# Discord-Havoc Rewrite (Pycord) + +## [Wiki](/wiki) \ No newline at end of file diff --git a/cogs/karma.py b/cogs/karma.py index a085415..2421f98 100644 --- a/cogs/karma.py +++ b/cogs/karma.py @@ -17,8 +17,6 @@ from aiohttp import ClientSession, ClientTimeout from discord.ext import bridge, commands, tasks from disc_havoc import Havoc - - class Util: """Karma Utility""" def __init__(self, bot: Havoc): @@ -34,10 +32,11 @@ class Util: async def get_karma(self, keyword: str) -> int: """ Get Karma for Keyword + Args: keyword (str) Returns: - int|str + int """ try: async with ClientSession() as session: @@ -56,10 +55,11 @@ class Util: async def get_top(self, n: int = 10) -> Optional[dict]: """ Get top (n=10) Karma + Args: n (int): Number of top results to return, default 10 Returns: - Optional[dict] + Optional[dict] """ try: async with ClientSession() as session: @@ -80,10 +80,11 @@ class Util: async def get_top_embed(self, n:int = 10) -> Optional[discord.Embed]: """ Get Top Karma Embed + Args: n (int): Number of top results to return, default 10 Returns: - discord.Embed + Optional[discord.Embed] """ top: Optional[dict] = await self.get_top(n) if not top: @@ -101,11 +102,14 @@ class Util: """ Update Karma for Keyword Args: + display (str): Display name of the user who requested the update _id (int): Discord UID of the user who requested the update keyword (str): Keyword to update flag (int) - """ + Returns: + bool + """ if not flag in [0, 1]: return False @@ -134,6 +138,7 @@ class Util: async def check_cooldown(self, user_id: int) -> bool: """ Check if member has met cooldown period prior to adjusting karma + Args: user_id (int): The Discord UID to check Returns: diff --git a/cogs/lovehate.py b/cogs/lovehate.py index fb4af68..0449b1b 100644 --- a/cogs/lovehate.py +++ b/cogs/lovehate.py @@ -21,10 +21,11 @@ class LoveHate(commands.Cog): def join_with_and(self, items: list) -> str: """ Join list with and added before last item + Args: items (list) Returns: - str + str """ if len(items) > 1: return ', '.join(items[:-1]) + ' and ' + items[-1] @@ -35,11 +36,12 @@ class LoveHate(commands.Cog): 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 + None """ try: if not user: @@ -73,6 +75,7 @@ class LoveHate(commands.Cog): async def wholoves(self, ctx, *, thing: Optional[str] = None) -> None: """ Check who loves + Args: ctx (Any) thing (Optional[str]) @@ -122,6 +125,7 @@ class LoveHate(commands.Cog): async def whohates(self, ctx, *, thing: Optional[str] = None) -> None: """ Check who hates + Args: ctx (Any) thing (Optional[str]) @@ -170,6 +174,7 @@ class LoveHate(commands.Cog): async def dontcare(self, ctx, thing: str) -> None: """ Make me forget your opinion on + Args: ctx (Any) thing (str) @@ -188,11 +193,12 @@ class LoveHate(commands.Cog): 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 + None """ try: if not user: @@ -223,6 +229,7 @@ class LoveHate(commands.Cog): async def love(self, ctx, *, thing: str) -> None: """ Love + Args: ctx (Any) thing (str) @@ -252,6 +259,7 @@ class LoveHate(commands.Cog): async def hate(self, ctx, *, thing: str) -> None: """ Hate + Args: ctx (Any) thing (str) diff --git a/cogs/meme.py b/cogs/meme.py index ea77457..feb9bf4 100644 --- a/cogs/meme.py +++ b/cogs/meme.py @@ -90,9 +90,11 @@ class MemeModal(discord.ui.Modal): await interaction.response.send_message("ERR: Text is limited to 80 characters for each the top and bottom lines.") return - meme_link: str = await self.meme_generator.create_meme(top_line=meme_top_line, + meme_link: Optional[str] = await self.meme_generator.create_meme(top_line=meme_top_line, bottom_line=meme_bottom_line, meme=selected_meme) - + if not meme_link: + await interaction.response.send_message("Failed!") + return embed: discord.Embed = discord.Embed(title="Generated Meme") embed.set_image(url=meme_link) embed.add_field(name="Meme", value=selected_meme, inline=True) @@ -159,6 +161,7 @@ class Meme(commands.Cog): async def do_autos(self, only_comics: Optional[bool] = False) -> None: """ Run Auto Posters + Args: only_comics (Optional[bool]): default False Returns: diff --git a/cogs/misc.py b/cogs/misc.py index cb4b439..0634ac0 100644 --- a/cogs/misc.py +++ b/cogs/misc.py @@ -93,6 +93,7 @@ class Misc(commands.Cog): async def get_random_guild_member(self, online_only: Optional[bool] = False) -> Optional[str]: """ Get Random Guild Member + Args: online_only (Optional[bool]) Returns: @@ -112,6 +113,7 @@ class Misc(commands.Cog): async def stats(self, ctx) -> None: """ Get Stats + Args: ctx (Any) Returns: @@ -131,6 +133,7 @@ class Misc(commands.Cog): async def listcoffees(self, ctx) -> None: """ List Available Coffees + Args: ctx (Any) Returns: @@ -152,10 +155,11 @@ class Misc(commands.Cog): async def listshoves(self, ctx) -> None: """ List Available Fates for shove command + Args: ctx (Any) Returns: - None + None """ fates: str = "" try: @@ -173,10 +177,11 @@ class Misc(commands.Cog): async def xmas(self, ctx) -> None: """ Countdown til xmas! + Args: ctx (Any) Returns: - None + None """ try: emojis: dict = { @@ -217,6 +222,7 @@ class Misc(commands.Cog): async def randfact(self, ctx) -> None: """ Get a random (useless) fact! + Args: ctx (Any) Returns: @@ -236,6 +242,7 @@ class Misc(commands.Cog): recipient: Optional[str] = None) -> None: """ Insult Someone (or yourself) + Args: ctx (Any) recipient (Optional[str]) @@ -275,6 +282,7 @@ class Misc(commands.Cog): recipient: Optional[str] = None) -> None: """ Compliment someone (or yourself) + Args: ctx (Any) recipient (Optional[str]) @@ -314,6 +322,7 @@ class Misc(commands.Cog): recipient: Optional[str] = None) -> None: """ Get a whisky for yourself or a friend! + Args: ctx (Any) recipient (Optional[str]) @@ -357,6 +366,7 @@ class Misc(commands.Cog): recipient: Optional[str] = None) -> None: """ Get a cocktail for yourself or a friend! + Args: ctx (Any) recipient (Optional[str]) @@ -404,6 +414,7 @@ class Misc(commands.Cog): recipient: Optional[str] = None) -> None: """ Spray someone with water! + Args: ctx (Any) recipient (Optional[str]) @@ -443,6 +454,7 @@ class Misc(commands.Cog): recipient: Optional[str] = None) -> None: """ Pass someone (or yourself) a barf bag! + Args: ctx (Any) recipient (Optional[str]) @@ -482,6 +494,7 @@ class Misc(commands.Cog): recipient: Optional[str] = None) -> None: """ Tea! + Args: recipient (Optional[str]) Returns: @@ -537,6 +550,7 @@ class Misc(commands.Cog): message: str) -> None: """ Cowsay! + Args: ctx (Any) message (str) @@ -559,10 +573,11 @@ class Misc(commands.Cog): cowfile: Optional[str] = None) -> None: """ Fortune | Cowsay! + Args: cowfile (Optional[str]) Returns: - None + None """ try: if not cowfile: @@ -584,6 +599,7 @@ class Misc(commands.Cog): async def listcows(self, ctx) -> None: """ List available .cow files (for cowsay) + Args: ctx (Any) Returns: @@ -607,6 +623,7 @@ class Misc(commands.Cog): recipient: Optional[str] = None) -> None: """ Cyanide! + Args: ctx (Any) recipient (Optional[str]) @@ -652,6 +669,7 @@ class Misc(commands.Cog): recipient: Optional[str] = None) -> None: """ School gravy! (It's deadly) + Args: ctx (Any) recipient (Optional[str]) @@ -697,6 +715,7 @@ class Misc(commands.Cog): recipient: Optional[str] = None) -> None: """ Cold water! Drink up. + Args: ctx (Any) recipient (Optional[str]) @@ -741,6 +760,7 @@ class Misc(commands.Cog): recipient: Optional[str] = None) -> None: """ Shove someone! (Or yourself) + Args: ctx (Any) recipient (Optional[str]) @@ -782,6 +802,7 @@ class Misc(commands.Cog): recipient: Optional[str] = None) -> None: """ Coffee! + Args: ctx (Any) recipient (Optional[str]) @@ -829,6 +850,7 @@ class Misc(commands.Cog): recipient: Optional[str] = None) -> None: """ Cookies! + Args: ctx (Any) recipient (Optional[str]) @@ -873,9 +895,12 @@ class Misc(commands.Cog): recipient: Optional[str] = None) -> None: """ Hashbrowns! + Args: ctx (Any) recipient (Optional[str]) + Returns: + None """ authorDisplay: str = ctx.author.display_name if not(ctx.author.display_name is None)\ else ctx.message.author.display_name @@ -910,6 +935,7 @@ class Misc(commands.Cog): recipient: Optional[str] = None) -> None: """ Ritalini! + Args: ctx (Any) recipient (Optional[str]) @@ -951,6 +977,7 @@ class Misc(commands.Cog): recipient: Optional[str] = None) -> None: """ Grilled Cheese! + Args: ctx (Any) recipient (Optional[str]) @@ -990,6 +1017,7 @@ class Misc(commands.Cog): recipient: Optional[str] = None) -> None: """ Soup! + Args: ctx (Any) recipient (Optional[str]) @@ -1029,6 +1057,7 @@ class Misc(commands.Cog): recipient: Optional[str] = None) -> None: """ Muffins! + Args: ctx (Any) recipient (Optional[str]) @@ -1069,6 +1098,7 @@ class Misc(commands.Cog): recipient: Optional[str] = None) -> None: """ Bacon! + Args: ctx (Any) recipient (Optional[str]) @@ -1109,6 +1139,7 @@ class Misc(commands.Cog): recipient: Optional[str] = None) -> None: """ Hang someone! + Args: ctx (Any) recipient (Optional[str]) @@ -1154,6 +1185,7 @@ class Misc(commands.Cog): recipient: Optional[str] = None) -> None: """ Touch someone! + Args: ctx (Any) recipient (Optional[str]) @@ -1205,6 +1237,7 @@ class Misc(commands.Cog): async def qajoke(self, ctx) -> None: """ Get a joke in Q/A Form! + Args: ctx (Any) Returns: @@ -1228,10 +1261,11 @@ class Misc(commands.Cog): async def rjoke(self, ctx) -> None: """ Get a joke! (from r/jokes scrape) + Args: ctx (Any) Returns; - None + None """ try: rjoke: Optional[tuple] = await self.util.get_rjoke() @@ -1254,6 +1288,7 @@ class Misc(commands.Cog): recipient: Optional[str] = None) -> None: """ Joints! + Args: ctx (Any) recipient (Optional[str]) @@ -1301,6 +1336,7 @@ class Misc(commands.Cog): async def isitfriday(self, ctx) -> None: """ IS IT FRIDAY!? + Args: ctx (Any) Returns: @@ -1321,10 +1357,11 @@ class Misc(commands.Cog): async def isitflyday(self, ctx) -> None: """ IS IT FLYDAY!? + Args: ctx (Any) Returns: - None + None """ try: today: datetime.datetime = datetime.datetime.today() @@ -1343,11 +1380,12 @@ class Misc(commands.Cog): term: str) -> None: """ Not sure what that term means? UD prolly knows. + Args: ctx (Any) term (str) Returns: - None + None """ try: with ctx.channel.typing(): @@ -1368,6 +1406,7 @@ class Misc(commands.Cog): async def joint_context_menu(self, ctx, member: discord.Member) -> None: """ Joint Context Menu + Args: ctx (Any) member (discord.Member) @@ -1389,11 +1428,12 @@ class Misc(commands.Cog): async def coffee_context_menu(self, ctx, member: discord.Member) -> None: """ Coffee Context Menu + Args: ctx (Any) member (discord.Member) Returns: - None + None """ chosen_coffee = self.util.get_coffee() response = await ctx.interaction.respond(f"*hands <@{member.id}> {chosen_coffee}*") diff --git a/cogs/misc_util.py b/cogs/misc_util.py index 0b824b9..3fa7663 100644 --- a/cogs/misc_util.py +++ b/cogs/misc_util.py @@ -58,10 +58,12 @@ class Util: def tdTuple(self, td:datetime.timedelta) -> tuple: """ Create TimeDelta Tuple + Args: td (datetime.timedelta) Returns: tuple + """ def _t(t, n): if t < n: @@ -76,10 +78,12 @@ class Util: async def get_counter(self, counter: Optional[str] = None) -> Optional[dict]: """ Get Counter + Args: counter (Optional[str]) Returns: Optional[dict] + """ stats_db: str|LiteralString = self.dbs.get('stats', '') if not stats_db: @@ -97,8 +101,10 @@ class Util: async def get_stats_embed(self) -> Optional[Embed]: """ Get Stats Embed + Returns: Optional[Embed] + """ counters: Optional[dict] = await self.get_counter() if not counters: @@ -117,10 +123,12 @@ class Util: async def increment_counter(self, counter: str) -> bool: """ Increment Counter + Args: counter (str) Returns: bool + """ stats_db: str|LiteralString = self.dbs.get('stats', '') if not stats_db: @@ -137,10 +145,12 @@ class Util: async def get_ud_def(self, term: str) -> tuple[str, str]: """ Get Definition from UD + Args: term (str) Returns: tuple[str, str] + """ try: async with ClientSession() as session: @@ -172,10 +182,12 @@ class Util: async def get_insult(self, recipient: str) -> str: """ Get Insult + Args: recipient (str) Returns: str + """ async with ClientSession() as session: async with await session.get(f"{self.URL_INSULTAPI}?who={recipient}") as request: @@ -187,11 +199,13 @@ class Util: language: Optional[str] = None) -> str: """ Get Compliment + Args: subject (str) language (Optional[str]) Returns: str + """ if not language: return self.COMPLIMENT_GENERATOR.compliment(subject) @@ -200,8 +214,10 @@ class Util: async def get_whisky(self) -> Optional[tuple]: """ Get Whisky + Returns: Optional[tuple] + """ whisky_db: str|LiteralString = self.dbs.get('whisky', '') if not whisky_db: @@ -228,8 +244,10 @@ class Util: async def get_drink(self) -> Optional[tuple]: """ Get Drink + Returns: Optional[tuple] + """ drinks_db: str|LiteralString = self.dbs.get('drinks', '') if not drinks_db: @@ -249,10 +267,12 @@ class Util: async def get_strain(self, strain: Optional[str] = None) -> Optional[tuple]: """ Get Strain + Args: strain (Optional[str]) Returns: Optional[tuple] + """ strains_db: str|LiteralString = self.dbs.get('strains', '') if not strains_db: @@ -272,8 +292,10 @@ class Util: async def get_qajoke(self) -> Optional[tuple]: """ Get QA Joke + Returns: Optional[tuple] + """ qajoke_db: str|LiteralString = self.dbs.get('qajoke', '') if not qajoke_db: @@ -289,8 +311,10 @@ class Util: async def get_rjoke(self) -> Optional[tuple]: """ Get r/joke Joke + Returns: Optional[tuple] + """ rjokes_db: str|LiteralString = self.dbs.get('rjokes', '') if not rjokes_db: @@ -306,8 +330,10 @@ class Util: async def get_random_fact(self) -> str: """ Get Random Fact + Returns: str + """ try: facts_api_url: str = "https://uselessfacts.jsph.pl/api/v2/facts/random" @@ -334,8 +360,10 @@ class Util: async def get_cookie(self) -> Optional[dict]: """ Get Cookie + Returns: Optional[dict] + """ cookies_db = self.dbs.get('cookies', '') if not cookies_db: @@ -355,8 +383,10 @@ class Util: def get_coffee(self) -> Optional[str]: """ Get Coffee + Returns: str + """ try: randomCoffee: str = random.choice(self.COFFEES) @@ -373,8 +403,10 @@ class Util: def get_days_to_xmas(self) -> Optional[tuple]: """ Get # of Days until Xmas + Returns: Optional[tuple] + """ today: datetime.datetime = datetime.datetime.now(tz=pytz.UTC) xmas: datetime.datetime = datetime.datetime( @@ -391,8 +423,10 @@ class Util: async def get_randmsg(self) -> Optional[str]: """ Get Random Message from randmsg.db + Returns: Optional[str] + """ randmsg_db: str|LiteralString = self.dbs.get('randmsg', '') if not randmsg_db: diff --git a/cogs/owner.py b/cogs/owner.py index f96d402..336fdc5 100644 --- a/cogs/owner.py +++ b/cogs/owner.py @@ -23,6 +23,7 @@ class Owner(commands.Cog): async def temperature(self, ctx, temp: Optional[int|str] = None) -> None: """ Set Temperature + Args: ctx (Any): Discord context temperature (Optional[int|str]): New temperature @@ -50,6 +51,7 @@ class Owner(commands.Cog): async def reload(self, ctx) -> None: """ Reload Cogs + Args: ctx (Any): Discord context Returns: @@ -66,6 +68,7 @@ class Owner(commands.Cog): parameters: str) -> None: """ Make me say something in a channel + Args: ctx (Any): Discord context parameters (str): Channel Message @@ -92,6 +95,7 @@ class Owner(commands.Cog): status: Optional[str] = None) -> None: """ Change bots status + Args: ctx (Any): Discord context status (Optional[str]): The new status to set @@ -111,6 +115,7 @@ class Owner(commands.Cog): async def purge(self, ctx, message: discord.Message) -> None: """ Purge Messages + Args: ctx (Any): Discord context message (discord.Message): Discord message @@ -137,6 +142,7 @@ class Owner(commands.Cog): async def movememe(self, ctx, message: discord.Message) -> None: """ Move to Memes + Args: ctx (Any): Discord context message (discord.Message): Discord message @@ -173,6 +179,7 @@ class Owner(commands.Cog): async def movedrugs(self, ctx, message: discord.Message) -> None: """ Move to Drugs + Args: ctx (Any): Discord context message (discord.Message): Discord message @@ -210,6 +217,7 @@ class Owner(commands.Cog): async def movefunhouse(self, ctx, message: discord.Message) -> None: """ Move to fun-house + Args: ctx (Any): Discord context message (discord.Message): Discord message @@ -245,6 +253,7 @@ class Owner(commands.Cog): async def einsperren(self, ctx, member: discord.Member) -> None: """ Einsperren! + Args: ctx (Any): Discord context member (discord.Member): Discord member diff --git a/cogs/radio.py b/cogs/radio.py index fe628f5..bbbf197 100644 --- a/cogs/radio.py +++ b/cogs/radio.py @@ -44,6 +44,7 @@ class Radio(commands.Cog): async def reinitradio(self, ctx) -> None: """ Reinitialize serious.FM + Args: ctx (Any): Discord context Returns: @@ -54,9 +55,7 @@ class Radio(commands.Cog): await ctx.respond("Done!", ephemeral=True) async def radio_init(self) -> None: - """ - Init Radio - """ + """Init Radio""" try: (radio_guild, radio_chan) = self.channels['sfm'] guild: Optional[discord.Guild] = self.bot.get_guild(radio_guild) diff --git a/cogs/sing.py b/cogs/sing.py index 2a731e5..a7bb575 100644 --- a/cogs/sing.py +++ b/cogs/sing.py @@ -42,6 +42,7 @@ class Sing(commands.Cog): song: Optional[str] = None) -> None: """ Search for lyrics, format is artist : song. Also reads activity. + Args: ctx (Any): Discord context song (Optional[str]): Song to search @@ -120,6 +121,7 @@ class Sing(commands.Cog): async def sing_context_menu(self, ctx, member: discord.Member) -> None: """ Sing Context Menu Command + Args: ctx (Any): Discord context member (discord.Member): Discord member diff --git a/disc_havoc.py b/disc_havoc.py index 76e0f82..589aa0e 100644 --- a/disc_havoc.py +++ b/disc_havoc.py @@ -51,10 +51,12 @@ class Havoc(bridge.Bot): def load_exts(self, initialRun: Optional[bool] = True) -> None: """ Load Cogs/Extensions + Args: initialRun (Optional[bool]) default: True Returns: - None""" + None + """ load_method = self.load_extension if initialRun\ else self.reload_extension diff --git a/util/catbox.py b/util/catbox.py index 7df84f5..5c6d7a0 100644 --- a/util/catbox.py +++ b/util/catbox.py @@ -29,6 +29,7 @@ class CatboxAsync: def generateRandomFileName(self, fileExt: Optional[str] = None) -> str: """ Generate random file name + Args: fileExt (Optional[str]): File extension to use for naming Returns: @@ -41,6 +42,7 @@ class CatboxAsync: async def upload(self, file: str) -> Optional[str]: """ Upload file to catbox + Args: file (str): Path of file to be uploaded Returns: diff --git a/util/discord_helpers.py b/util/discord_helpers.py index c8fa722..627ae37 100644 --- a/util/discord_helpers.py +++ b/util/discord_helpers.py @@ -11,6 +11,7 @@ async def get_channel_by_name(bot: discord.Bot, channel: str, guild: int | None = None) -> Optional[Any]: # Optional[Any] used as pycord channel types can be ambigious """ Get Channel by Name + Args: bot (discord.Bot) channel (str) @@ -37,6 +38,7 @@ async def send_message(bot: discord.Bot, channel: str, """ Send Message to the provided channel. If guild is provided, will limit to channels within that guild to ensure the correct channel is selected. Useful in the event a channel exists in more than one guild that the bot resides in. + Args: bot (discord.Bot) channel (str) diff --git a/util/jesusmemes.py b/util/jesusmemes.py index c5c4138..5efd837 100644 --- a/util/jesusmemes.py +++ b/util/jesusmemes.py @@ -35,12 +35,15 @@ class JesusMemeGenerator(): meme="Jesus-Talking-To-Cool-Dude") -> Optional[str]: """ Create Meme + Args: top_line (str): Top line of meme bottom_line (str): Bottom line of meme meme (str): The meme to use, defaults to Jesus-Talking-To-Cool-Dude + Returns: Optional[str] + """ try: if not top_line or not bottom_line: diff --git a/util/litterbox.py b/util/litterbox.py index 7f091ce..ba0a274 100644 --- a/util/litterbox.py +++ b/util/litterbox.py @@ -30,6 +30,7 @@ class LitterboxAsync: def generateRandomFileName(self, fileExt: Optional[str] = None) -> str: """ Generate Random Filename + Args: fileExt (Optional[str]): File extension to use for naming Returns: @@ -44,6 +45,7 @@ class LitterboxAsync: time='1h') -> Optional[str]: """ Upload File to Litterbox + Args: file (Union[str, bytes, BufferedReader]): File to upload (accepts either filepath or io.BufferedReader) time (str): Expiration time, default: 1h diff --git a/util/lovehate_db.py b/util/lovehate_db.py index 4458f72..9f76c39 100644 --- a/util/lovehate_db.py +++ b/util/lovehate_db.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3.12 import os import logging -from typing import Optional, LiteralString +from typing import LiteralString, Optional, Union import aiosqlite as sqlite3 from constructors import LoveHateException @@ -47,16 +47,18 @@ class DB: return result async def get_lovehates(self, loves: bool = False, hates: bool = False, - user: Optional[str] = None, thing: Optional[str] = None) -> list[tuple]|bool: + user: Optional[str] = None, thing: Optional[str] = None) -> Union[list[tuple], bool]: """ Get a list of either 1) what {user} loves/hates, or who loves/hates {thing}, depending on bools loves, hates + Args: loves (bool): Are we looking for loves? hates (bool): ...OR are we looking for hates? user (Optional[str]): the user to query against thing (Optional[str]): ... OR the thing to query against + Returns: - list[tuple]|bool + Union[list[tuple], bool] """ query: str = "" @@ -94,6 +96,7 @@ class DB: async def check_existence(self, user: str, thing: str) -> Optional[int]: """ Determine whether a user is opinionated on a + Args: user (str): The user to check thing (str): The thing to check if the user has an opinion on @@ -114,6 +117,7 @@ class DB: async def update(self, user: str, thing: str, flag: int) -> str: """ Updates the lovehate database, and returns an appropriate response + Args: user (str): The user to update thing (str): The thing the user loves/hates/doesn't care about anymore diff --git a/util/radio_util.py b/util/radio_util.py index b794df9..d369eed 100644 --- a/util/radio_util.py +++ b/util/radio_util.py @@ -7,6 +7,12 @@ from aiohttp import ClientSession, ClientTimeout """Radio Utils""" async def get_now_playing() -> Optional[str]: + """ + Get radio now playing + + Returns: + str + """ np_url: str = "https://api.codey.lol/radio/np" try: async with ClientSession() as session: diff --git a/util/sing_util.py b/util/sing_util.py index 4876314..1e7e86e 100644 --- a/util/sing_util.py +++ b/util/sing_util.py @@ -4,23 +4,26 @@ import regex import aiohttp import textwrap import traceback -from typing import Optional from discord import Activity +from typing import Optional, Union class Utility: """Sing Utility""" - def __init__(self): + def __init__(self) -> None: self.api_url: str = "http://127.0.0.1:52111/lyric/search" self.api_src: str = "DISC-HAVOC" def parse_song_input(self, song: Optional[str] = None, - activity: Optional[Activity] = None) -> bool|tuple: - """Parse Song (Sing Command) Input + activity: Optional[Activity] = None) -> Union[bool, tuple]: + """ + Parse Song (Sing Command) Input + Args: song (Optional[str]): Song to search activity (Optional[discord.Activity]): Discord activity, used to attempt lookup if no song is provided + Returns: - bool|tuple + Union[bool, tuple] """ logging.debug("Activity? %s", activity) try: @@ -28,58 +31,70 @@ class Utility: # pylint: disable=superfluous-parens return False # pylint: enable=superfluous-parens - if not song and activity: + if not song and isinstance(activity, Activity): + if not activity.name: + return False # No valid activity found match activity.name.lower(): case "codey toons" | "cider" | "sonixd": search_artist: str = " ".join(str(activity.state)\ .strip().split(" ")[1:]) - search_artist: str = regex.sub(r"(\s{0,})(\[(spotify|tidal|sonixd|browser|yt music)])$", "", + search_artist = regex.sub(r"(\s{0,})(\[(spotify|tidal|sonixd|browser|yt music)])$", "", search_artist.strip(), flags=regex.IGNORECASE) - search_song: str = str(activity.details) - song: str = f"{search_artist} : {search_song}" + search_song = str(activity.details) + song = f"{search_artist} : {search_song}" case "tidal hi-fi": - search_artist: str = str(activity.state) - search_song: str = str(activity.details) - song: str = f"{search_artist} : {search_song}" + search_artist = str(activity.state) + search_song = str(activity.details) + song = f"{search_artist} : {search_song}" case "spotify": - search_artist: str = str(activity.title) - search_song: str = str(activity.artist) - song: str = f"{search_artist} : {search_song}" + if not activity.title or not activity.artist: # type: ignore + """ + Attributes exist, but mypy does not recognize them. Ignored. + """ + return False + search_artist = str(activity.title) # type: ignore + search_song = str(activity.artist) # type: ignore + song = f"{search_artist} : {search_song}" case "serious.fm" | "cocks.fm" | "something": if not activity.details: - song: str = str(activity.state) + song = str(activity.state) else: - search_artist: str = str(activity.state) - search_song: str = str(activity.details) - song: str = f"{search_artist} : {search_song}" + search_artist = str(activity.state) + search_song = str(activity.details) + song = f"{search_artist} : {search_song}" case _: return False # Unsupported activity detected search_split_by: str = ":" if not(song) or len(song.split(":")) > 1\ else "-" # Support either : or - to separate artist/track - search_artist: str = song.split(search_split_by)[0].strip() - search_song: str = "".join(song.split(search_split_by)[1:]).strip() + if not song: + return False + search_artist = song.split(search_split_by)[0].strip() + search_song = "".join(song.split(search_split_by)[1:]).strip() search_subsearch: Optional[str] = None if search_split_by == ":" and len(song.split(":")) > 2: # Support sub-search if : is used (per instructions) - search_song: str = song.split(search_split_by)[1].strip() # Reduce search_song to only the 2nd split of : [the rest is meant to be lyric text] - search_subsearch: str = "".join(song.split(search_split_by)[2:]) # Lyric text from split index 2 and beyond + search_song = song.split(search_split_by)[1].strip() # Reduce search_song to only the 2nd split of : [the rest is meant to be lyric text] + search_subsearch = "".join(song.split(search_split_by)[2:]) # Lyric text from split index 2 and beyond return (search_artist, search_song, search_subsearch) except: traceback.print_exc() return False async def lyric_search(self, artist: str, song: str, - sub: Optional[str] = None) -> list[str]: + sub: Optional[str] = None) -> Optional[list]: """ Lyric Search + Args: artist (str): Artist to search song (str): Song to search - sub (Optional[str]): Lyrics for subsearch + sub (Optional[str]): Lyrics for subsearch + Returns: + Optional[list] """ try: if not artist or not song: - return ["FAIL! Artist/Song not provided"] + return [("FAIL! Artist/Song not provided",)] search_obj: dict = { 'a': artist.strip(), @@ -103,7 +118,7 @@ class Utility: request.raise_for_status() response: dict = await request.json() if response.get('err'): - return [f"ERR: {response.get('errorText')}"] + return [(f"ERR: {response.get('errorText')}",)] out_lyrics = regex.sub(r'
', '\u200B\n', response.get('lyrics')) response_obj: dict = { @@ -111,11 +126,13 @@ class Utility: 'song': response.get('song'), 'lyrics': out_lyrics, 'src': response.get('src'), - 'confidence': float(response.get('confidence')), - 'time': float(response.get('time')), + 'confidence': float(response.get('confidence', 0.0)), + 'time': float(response.get('time', -1.0)), } lyrics = response_obj.get('lyrics') + if not lyrics: + return None response_obj['lyrics'] = textwrap.wrap(text=lyrics.strip(), width=4000, drop_whitespace=False, replace_whitespace=False, break_long_words=True, @@ -128,7 +145,7 @@ class Utility: return [ ( response_obj.get('artist'), response_obj.get('song'), response_obj.get('src'), - f"{int(response_obj.get('confidence'))}%", + f"{int(response_obj.get('confidence', -1.0))}%", f"{response_obj.get('time', -666.0):.4f}s", ), response_obj.get('lyrics'),