diff --git a/src/cogs/anime.py b/src/cogs/anime.py index 2596a55..5526c73 100644 --- a/src/cogs/anime.py +++ b/src/cogs/anime.py @@ -174,7 +174,7 @@ class Anime(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The interaction that triggered this Returns ---------- @@ -190,7 +190,7 @@ class Anime(commands.Cog): Parameters ---------- - text: The raw HTML + text (str): The raw HTML Returns ---------- @@ -210,7 +210,7 @@ class Anime(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The interaction that triggered this query (str): The GraphQL query variables (str): The variables for the query key (str): The key to return from the response @@ -340,7 +340,7 @@ class Anime(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction user (str): The user to get information about """ @@ -468,7 +468,7 @@ class Anime(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction user (str): The user to get information about """ @@ -561,7 +561,7 @@ class Anime(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction user (str): The user to get information about """ @@ -656,7 +656,7 @@ class Anime(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction search (str): The name of the anime to fetch information about """ @@ -812,7 +812,7 @@ class Anime(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction search (str): The name of the manga to fetch information about """ @@ -945,7 +945,7 @@ class Anime(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction search (str): The name of the character to fetch information about """ @@ -1041,7 +1041,7 @@ class Anime(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction search (str): The name of the creator to fetch information about """ @@ -1142,7 +1142,7 @@ class Anime(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction search (str): The name of the studio to fetch information about """ @@ -1236,7 +1236,7 @@ async def setup(bot: commands.Bot): Parameters ---------- - bot (commands.Bot): Bot instance + bot (commands.Bot): The bot instance """ await bot.add_cog(Anime(bot)) diff --git a/src/cogs/aurora.py b/src/cogs/aurora.py index ae12e82..25935af 100644 --- a/src/cogs/aurora.py +++ b/src/cogs/aurora.py @@ -25,6 +25,10 @@ class Aurora(commands.Cog): self.aurora_alarm.start() def cog_unload(self): + """ + Stop the aurora alarm when the cog is unloaded + """ + self.bot.logger.info("Unloading cog") self.aurora_alarm.cancel() @@ -33,8 +37,8 @@ class Aurora(commands.Cog): Get the current aurora and cloud cover forecast for Chateau Neuf Returns - ------- - (dict) The forecast data | None + ---------- + (dict | None): The forecast data. None if it couldn't be fetched """ async with self.bot.http_session.get( @@ -130,7 +134,7 @@ async def setup(bot: commands.Bot): Parameters ---------- - bot (commands.Bot): Bot instance + bot (commands.Bot): The bot instance """ await bot.add_cog(Aurora(bot)) diff --git a/src/cogs/birthday.py b/src/cogs/birthday.py index a9d1d85..064bc84 100644 --- a/src/cogs/birthday.py +++ b/src/cogs/birthday.py @@ -145,6 +145,10 @@ class Birthday(commands.Cog): await channel.send(message) async def cog_unload(self): + """ + Stop the birthday check when the cog is unloaded + """ + self.bot.logger.info("Unloading cog") self.birthday_check.cancel() @@ -270,7 +274,7 @@ class Birthday(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction day (int): Day of the month month (int): Month of the year year (int): Year @@ -310,7 +314,7 @@ class Birthday(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction """ await self.bot.db.execute("DELETE FROM birthdays WHERE discord_id = (%s)", (interaction.user.id,)) @@ -329,8 +333,8 @@ class Birthday(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object - user (discord.Member | discord.User | None): The user to show the birthday of. Defaults to None. + interaction (discord.Interaction): The slash command interaction + user (discord.Member | discord.User | None): The user to show the birthday of. Defaults to the invoking user """ if not user: @@ -380,7 +384,7 @@ class Birthday(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction """ if not interaction.guild: @@ -424,7 +428,7 @@ async def setup(bot: commands.Bot): Parameters ---------- - bot (commands.Bot): Bot instance + bot (commands.Bot): The bot instance """ await bot.add_cog(Birthday(bot)) diff --git a/src/cogs/botinfo.py b/src/cogs/botinfo.py index 7af0209..ffcfff1 100644 --- a/src/cogs/botinfo.py +++ b/src/cogs/botinfo.py @@ -30,7 +30,7 @@ class BotInfo(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction """ # Dev user info @@ -105,7 +105,7 @@ class BotInfo(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction """ embed = discord.Embed(color=interaction.client.user.color) @@ -121,7 +121,7 @@ class BotInfo(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction """ embed = discord.Embed(color=interaction.client.user.color) @@ -134,7 +134,7 @@ class BotInfo(commands.Cog): Returns ---------- - (int) The bot's ping in milliseconds + (int): The bot's ping in milliseconds """ return int(self.bot.latency * 1000) @@ -145,7 +145,7 @@ class BotInfo(commands.Cog): Returns ---------- - (str) The bot's uptime in human readable format + (str): The bot's uptime in human readable format """ now = time() @@ -163,7 +163,7 @@ async def setup(bot: commands.Bot): Parameters ---------- - bot (commands.Bot): Bot instance + bot (commands.Bot): The bot instance """ await bot.add_cog(BotInfo(bot)) diff --git a/src/cogs/cs2_bingo.py b/src/cogs/cs2_bingo.py index ef4884d..1c04c3e 100644 --- a/src/cogs/cs2_bingo.py +++ b/src/cogs/cs2_bingo.py @@ -42,7 +42,7 @@ class CS2Bingo(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction """ await open_lobby(interaction, self.active_lobbies, BingoView, "Bingolobby", timedelta(minutes=10)) @@ -64,6 +64,19 @@ class BingoGenerator: @classmethod async def sample_cells(cls, players: list[str], bot: commands.Bot) -> dict[str, list[str]]: + """ + Pick 25 squares for each player's sheet + + Parameters + ---------- + players (list[str]): The Discord IDs of the players + bot (commands.Bot): The bot instance + + Returns + ---------- + (dict[str, list[str]]): Each player's squares, keyed by their Discord ID + """ + assert 0 < len(players) <= 10 default_space = list(cls.CELLS["all"]) @@ -97,6 +110,7 @@ class BingoGenerator: Parameters ---------- players (list[discord.Member]): The players to generate sheets for + bot (commands.Bot): The bot instance Returns ---------- @@ -118,6 +132,19 @@ class BingoGenerator: @classmethod def generate_sheet(cls, sample_space: list, image: np.ndarray) -> bytes: + """ + Draw the squares on a bingo sheet + + Parameters + ---------- + sample_space (list): The squares to draw. Emptied as they are drawn + image (np.ndarray): The empty bingo sheet + + Returns + ---------- + (bytes): The sheet as PNG data + """ + image = image.copy() # start = 8, 294 @@ -141,12 +168,30 @@ class BingoGenerator: class BingoView(LobbyView): + """Bingo lobby that sends every player a bingo sheet when started""" + def __init__(self, lobby: Lobby, bot: commands.Bot): + """ + Parameters + ---------- + lobby (Lobby): The lobby to show + bot (commands.Bot): The bot instance + """ + super().__init__(lobby, bot) @discord.ui.button(label="Start", style=discord.ButtonStyle.green) @override async def start_lobby(self, interaction: discord.Interaction, button: discord.ui.Button): + """ + Close the lobby and send every player their bingo sheet + + Parameters + ---------- + interaction (discord.Interaction): The interaction that triggered this + button (discord.ui.Button): The button that was pressed + """ + if interaction.user != self.lobby.host: embed = embed_templates.error_warning("Bare hosten kan starte bingoen") return await interaction.response.send_message(embed=embed, ephemeral=True, delete_after=10) @@ -184,7 +229,7 @@ async def setup(bot: commands.Bot): Parameters ---------- - bot (commands.Bot): Bot instance + bot (commands.Bot): The bot instance """ await bot.add_cog(CS2Bingo(bot)) diff --git a/src/cogs/dev_tools.py b/src/cogs/dev_tools.py index 5732435..63986b2 100644 --- a/src/cogs/dev_tools.py +++ b/src/cogs/dev_tools.py @@ -29,7 +29,7 @@ class DevTools(commands.Cog): Parameters ---------- - ctx (commands.Context): Context object + ctx (commands.Context): The command context """ process = await asyncio.create_subprocess_exec( @@ -56,7 +56,7 @@ class DevTools(commands.Cog): Parameters ---------- - ctx (commands.Context): Context object + ctx (commands.Context): The command context channel (int): The channel ID to send the message to text (str): The text to send """ @@ -80,7 +80,7 @@ class DevTools(commands.Cog): Parameters ---------- - ctx (commands.Context): Context object + ctx (commands.Context): The command context activity_type (str): The type of activity to set the bot's status to message (str): The message to set the bot's status to status_type (str): The type of status to set the bot's status to @@ -111,7 +111,7 @@ class DevTools(commands.Cog): Parameters ---------- - ctx (commands.Context): Context object + ctx (commands.Context): The command context guild_id (int): The ID of the guild to leave """ @@ -155,7 +155,7 @@ class DevTools(commands.Cog): Parameters ---------- - ctx (commands.Context): Context object + ctx (commands.Context): The command context """ async with self.bot.http_session.get("https://wtfismyip.com/json") as response: @@ -177,7 +177,7 @@ class DevTools(commands.Cog): Parameters ---------- - ctx (commands.Context): Context object + ctx (commands.Context): The command context """ if not ctx.invoked_subcommand: @@ -190,7 +190,7 @@ class DevTools(commands.Cog): Parameters ---------- - ctx (commands.Context): Context object + ctx (commands.Context): The command context cog (str): The name of the cog to disable """ @@ -214,7 +214,7 @@ class DevTools(commands.Cog): Parameters ---------- - ctx (commands.Context): Context object + ctx (commands.Context): The command context cog (str): The name of the cog to enable """ @@ -238,7 +238,7 @@ class DevTools(commands.Cog): Parameters ---------- - ctx (commands.Context): Context object + ctx (commands.Context): The command context cog (str): The name of the cog to reload """ @@ -262,7 +262,7 @@ class DevTools(commands.Cog): Parameters ---------- - ctx (commands.Context): Context object + ctx (commands.Context): The command context """ extensions = [f"cogs.{file[:-3]}" for file in listdir("./src/cogs") if file.endswith(".py")] @@ -278,7 +278,7 @@ class DevTools(commands.Cog): Parameters ---------- - ctx (commands.Context): Context object + ctx (commands.Context): The command context """ failed = await self.reload_extensions(list(self.bot.extensions)) @@ -339,7 +339,7 @@ async def setup(bot: commands.Bot): Parameters ---------- - bot (commands.Bot): Bot instance + bot (commands.Bot): The bot instance """ await bot.add_cog(DevTools(bot)) diff --git a/src/cogs/errors.py b/src/cogs/errors.py index 9cbb214..216f03a 100644 --- a/src/cogs/errors.py +++ b/src/cogs/errors.py @@ -27,7 +27,7 @@ class Errors(commands.Cog): Parameters ---------- - ctx (commands.Context): Context object + ctx (commands.Context): The command context """ self.bot.logger.info( @@ -45,8 +45,8 @@ class Errors(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object - command (app_commands.Command | app_commands.ContextMenu): Command object + interaction (discord.Interaction): The slash command interaction + command (app_commands.Command | app_commands.ContextMenu): The command that was run """ self.bot.logger.info( @@ -62,8 +62,8 @@ class Errors(commands.Cog): Parameters ---------- - ctx (commands.Context): Context object - error (commands.CommandError): Eror context object + ctx (commands.Context): The command context + error (commands.CommandError): The error the command raised """ # Let the user retry a command that failed without waiting for its cooldown. @@ -126,8 +126,8 @@ class Errors(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object - error (app_commands.AppCommandError): Eror context object + interaction (discord.Interaction): The slash command interaction + error (app_commands.AppCommandError): The error the command raised """ if not interaction.response.is_done(): @@ -187,7 +187,7 @@ async def setup(bot: commands.Bot): Parameters ---------- - bot (commands.Bot): Bot instance + bot (commands.Bot): The bot instance """ await bot.add_cog(Errors(bot)) diff --git a/src/cogs/fun.py b/src/cogs/fun.py index ac09428..da3b03a 100644 --- a/src/cogs/fun.py +++ b/src/cogs/fun.py @@ -13,7 +13,7 @@ class Fun(commands.Cog): Parameters ---------- - ctx (commands.Context): Context object + ctx (commands.Context): The command context """ await ctx.reply("") @@ -26,7 +26,7 @@ class Fun(commands.Cog): Parameters ---------- - ctx (commands.Context): Context object + ctx (commands.Context): The command context """ await ctx.reply("https://i.imgur.com/ypyK1mi.jpg") @@ -39,7 +39,7 @@ class Fun(commands.Cog): Parameters ---------- - ctx (commands.Context): Context object + ctx (commands.Context): The command context """ await ctx.reply("https://i.imgur.com/ZqgZEEA.jpg") @@ -52,7 +52,7 @@ class Fun(commands.Cog): Parameters ---------- - ctx (commands.Context): Context object + ctx (commands.Context): The command context """ await ctx.reply("https://i.imgur.com/Gx9DQE5.jpg") @@ -65,7 +65,7 @@ class Fun(commands.Cog): Parameters ---------- - ctx (commands.Context): Context object + ctx (commands.Context): The command context """ await ctx.reply("https://i.imgur.com/188MoIV.jpg") @@ -78,7 +78,7 @@ class Fun(commands.Cog): Parameters ---------- - ctx (commands.Context): Context object + ctx (commands.Context): The command context """ await ctx.reply("https://twitter.com/NTNU/status/970667413564993536") @@ -91,7 +91,7 @@ class Fun(commands.Cog): Parameters ---------- - ctx (commands.Context): Context object + ctx (commands.Context): The command context """ await ctx.reply("https://i.imgur.com/h84fknj.jpg") @@ -100,11 +100,11 @@ class Fun(commands.Cog): @commands.command() async def erna(self, ctx: commands.Context): """ - erna, vil ikke + Reply with Erna Solberg's "vil ikke" tweet Parameters ---------- - ctx (commands.Context): Context object + ctx (commands.Context): The command context """ await ctx.reply("https://twitter.com/erna_solberg/status/1075333228779765760") @@ -117,7 +117,7 @@ class Fun(commands.Cog): Parameters ---------- - ctx (commands.Context): Context object + ctx (commands.Context): The command context """ await ctx.reply("https://twitter.com/vikingfotball/status/919622148599230465") @@ -130,7 +130,7 @@ class Fun(commands.Cog): Parameters ---------- - ctx (commands.Context): Context object + ctx (commands.Context): The command context """ await ctx.reply("A snake eating its own tail indicates that its excrement provides food for it") @@ -143,7 +143,7 @@ class Fun(commands.Cog): Parameters ---------- - ctx (commands.Context): Context object + ctx (commands.Context): The command context """ await ctx.reply("https://youtube.com/playlist?list=PLFV_L_I9qjsoVvh0KT5kHC2_VB8ZGtQoG&si=CpioMM0k3-XTrHCL") @@ -156,7 +156,7 @@ class Fun(commands.Cog): Parameters ---------- - ctx (commands.Context): Context object + ctx (commands.Context): The command context """ await ctx.reply( @@ -171,7 +171,7 @@ class Fun(commands.Cog): Parameters ---------- - ctx (commands.Context): Context object + ctx (commands.Context): The command context """ await ctx.reply( @@ -186,7 +186,7 @@ class Fun(commands.Cog): Parameters ---------- - ctx (commands.Context): Context object + ctx (commands.Context): The command context """ f = discord.File("./src/assets/edb.png") @@ -199,7 +199,7 @@ async def setup(bot: commands.Bot): Parameters ---------- - bot (commands.Bot): Bot instance + bot (commands.Bot): The bot instance """ await bot.add_cog(Fun(bot)) diff --git a/src/cogs/funreplies.py b/src/cogs/funreplies.py index ae7da29..c47fcda 100644 --- a/src/cogs/funreplies.py +++ b/src/cogs/funreplies.py @@ -12,6 +12,8 @@ from cogs.utils import embed_templates @dataclass class FunReply: + """A reply the bot sends when a message matches its pattern""" + name: str pattern: str reply: str @@ -20,6 +22,8 @@ class FunReply: @dataclass class FunReplySettings: + """Settings changed with /autosvar. None means the reply's default is used""" + enabled: bool = True cooldown: int | None = None chance: int | None = None @@ -161,7 +165,7 @@ class FunReplies(commands.Cog): Parameters ---------- - message (discord.Message): Message object to check for triggers to + message (discord.Message): The message to check for triggers """ if message.author.bot: @@ -177,12 +181,12 @@ class FunReplies(commands.Cog): Parameters ---------- - message (discord.Message): The message object to check for triggers + message (discord.Message): The message to check for triggers fun_reply (FunReply): The fun reply to check Returns ---------- - bool: Whether or not the reply was triggered + (bool): Whether or not the reply was triggered """ settings = self.get_settings(fun_reply.name) @@ -220,7 +224,7 @@ class FunReplies(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction name (str): The name of the fun reply """ @@ -240,7 +244,7 @@ class FunReplies(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction name (str): The name of the fun reply """ @@ -264,7 +268,7 @@ class FunReplies(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction name (str): The name of the fun reply seconds (int | None): The cooldown in seconds. None resets it to the default """ @@ -290,7 +294,7 @@ class FunReplies(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction name (str): The name of the fun reply percent (int | None): The chance in percent. None resets it to the default """ @@ -309,7 +313,7 @@ class FunReplies(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction """ lines = [] @@ -328,7 +332,7 @@ async def setup(bot: commands.Bot): Parameters ---------- - bot (commands.Bot): Bot instance + bot (commands.Bot): The bot instance """ await bot.add_cog(FunReplies(bot)) diff --git a/src/cogs/galtinn.py b/src/cogs/galtinn.py index 96e3bd6..819774b 100644 --- a/src/cogs/galtinn.py +++ b/src/cogs/galtinn.py @@ -65,7 +65,9 @@ class Galtinn(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction + galtinn_username (str | None): The Galtinn username to look up + discord_user (discord.User | None): The Discord user to look up. Defaults to the invoking user """ if discord_user and galtinn_username: @@ -147,7 +149,7 @@ async def setup(bot: commands.Bot): Parameters ---------- - bot (commands.Bot): Bot instance + bot (commands.Bot): The bot instance """ await bot.add_cog(Galtinn(bot)) diff --git a/src/cogs/gullkorn.py b/src/cogs/gullkorn.py index 2f83377..ac9689d 100644 --- a/src/cogs/gullkorn.py +++ b/src/cogs/gullkorn.py @@ -59,7 +59,7 @@ class Gullkorn(commands.Cog): Returns ---------- - str: The input data formatted into a prettified string + (str): The input data formatted into a prettified string """ formatted_string = "" @@ -79,7 +79,7 @@ class Gullkorn(commands.Cog): Parameters ---------- - message (discord.Message): Message object to check for triggers to + message (discord.Message): The message that was sent """ if message.author.bot or message.channel.id != self.bot.channel_ids.get("gullkorn") or not message.mentions: @@ -121,8 +121,8 @@ class Gullkorn(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object - user (discord.Member, optional): Discord user to fetch stats for. Defaults to None. + interaction (discord.Interaction): The slash command interaction + user (discord.Member | None): The user to fetch stats for. Defaults to the invoking user """ # This looks kinda ugly, ngl @@ -186,7 +186,7 @@ async def setup(bot: commands.Bot): Parameters ---------- - bot (commands.Bot): Bot instance + bot (commands.Bot): The bot instance """ await bot.add_cog(Gullkorn(bot)) diff --git a/src/cogs/info.py b/src/cogs/info.py index 47cd3b9..8a8def0 100644 --- a/src/cogs/info.py +++ b/src/cogs/info.py @@ -31,7 +31,7 @@ class Info(commands.Cog): roles (list[discord.Role]): List of roles Returns - ------- + ---------- (str): String of roles """ @@ -49,11 +49,11 @@ class Info(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The interaction that triggered this join_method (callable): Function to join the boosters with Returns - ------- + ---------- (str): String of boosters """ @@ -77,7 +77,7 @@ class Info(commands.Cog): members (list[discord.Member]): List of members Returns - ------- + ---------- (str): String of members """ @@ -97,7 +97,7 @@ class Info(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction """ # Days since guild was created @@ -253,7 +253,7 @@ class Info(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction """ roles = self.construct_role_string(interaction.guild.roles) @@ -276,7 +276,7 @@ class Info(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction """ if len(interaction.guild.premium_subscribers) == 0: @@ -301,7 +301,7 @@ class Info(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction """ embed = discord.Embed(color=interaction.guild.me.color, description=f"[Lenke]({interaction.guild.icon})") @@ -318,7 +318,7 @@ class Info(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction """ if not interaction.guild.splash: @@ -339,7 +339,7 @@ class Info(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction """ if not interaction.guild.banner: @@ -362,7 +362,7 @@ class Info(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction role (discord.Role): Role to fetch information about """ @@ -408,7 +408,7 @@ class Info(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction channel (discord.TextChannel): Text channel to fetch information about """ @@ -442,7 +442,7 @@ class Info(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction channel (discord.VoiceChannel): Voice channel to fetch information about """ @@ -467,7 +467,7 @@ class Info(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction """ roles = sorted( @@ -494,7 +494,7 @@ class Info(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction emoji (discord.Emoji): Emoji to fetch information about """ @@ -534,7 +534,7 @@ class Info(commands.Cog): Parameters ---------- - ctx (commands.Context): Command context object + ctx (commands.Context): The command context """ if ctx.message.type != discord.MessageType.reply: @@ -584,7 +584,7 @@ class Info(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction """ # Sort members by creation date @@ -616,7 +616,7 @@ class Info(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction """ # Sort members by creation date @@ -647,8 +647,8 @@ class Info(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object - user (discord.Member, optional): User to get information about. Defaults to None (invoker). + interaction (discord.Interaction): The slash command interaction + user (discord.Member | None): The user to get information about. Defaults to the invoking user """ if not user: @@ -743,8 +743,8 @@ class Info(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object - user (discord.Member, optional): User to get roles of. Defaults to None (invoker). + interaction (discord.Interaction): The slash command interaction + user (discord.Member | None): The user to get the roles of. Defaults to the invoking user """ if not user: @@ -774,8 +774,8 @@ class Info(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object - user (discord.Member, optional): User to get roles of. Defaults to None (invoker). + interaction (discord.Interaction): The slash command interaction + user (discord.Member | None): The user to get the missing roles of. Defaults to the invoking user """ if not user: @@ -807,8 +807,8 @@ class Info(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object - user (discord.User, optional): User to get avatar of. Defaults to None (invoker). + interaction (discord.Interaction): The slash command interaction + user (discord.User | None): The user to get the avatar of. Defaults to the invoking user """ if not user: @@ -826,7 +826,7 @@ async def setup(bot: commands.Bot): Parameters ---------- - bot (commands.Bot): Bot instance + bot (commands.Bot): The bot instance """ await bot.add_cog(Info(bot)) diff --git a/src/cogs/mc_whitelist.py b/src/cogs/mc_whitelist.py index c4d1d7e..ed4b37b 100644 --- a/src/cogs/mc_whitelist.py +++ b/src/cogs/mc_whitelist.py @@ -52,7 +52,7 @@ class MCWhitelist(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction minecraft_username (str): Minecraft username """ @@ -129,7 +129,7 @@ class MCWhitelist(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction """ # Check if the discord user is in the db @@ -190,7 +190,7 @@ async def setup(bot: commands.Bot): Parameters ---------- - bot (commands.Bot): Bot instance + bot (commands.Bot): The bot instance """ await bot.add_cog(MCWhitelist(bot)) diff --git a/src/cogs/meme.py b/src/cogs/meme.py index f9f6d20..17c61ad 100644 --- a/src/cogs/meme.py +++ b/src/cogs/meme.py @@ -52,7 +52,7 @@ class Meme(commands.Cog): Parameters ---------- - interaction (discord.Interaction): The interaction + interaction (discord.Interaction): The slash command interaction attachment (discord.Attachment): The image to deepfry """ @@ -115,7 +115,7 @@ class Meme(commands.Cog): Parameters ---------- - interaction (discord.Interaction): The interaction + interaction (discord.Interaction): The slash command interaction bad_text (str): The upper text, what's disliked good_text (str): The lower text, what's liked """ @@ -169,7 +169,7 @@ class Meme(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction attachment (discord.Attachment): The image to point at. Only supports png and jpg for now """ @@ -286,9 +286,9 @@ class Meme(commands.Cog): Parameters ---------- - interaction (discord.Interaction): The interaction - query (str|None): Search term to look up the media on YouTube - url (str|None): Link to the source media. Used instead of the search term if both are given + interaction (discord.Interaction): The slash command interaction + query (str | None): Search term to look up the media on YouTube + url (str | None): Link to the source media. Used instead of the search term if both are given """ if not url and not query: @@ -357,7 +357,7 @@ class Meme(commands.Cog): Parameters ---------- - interaction (discord.Interaction): The interaction + interaction (discord.Interaction): The slash command interaction top_text (str): The upper text bottom_text (str): The lower text """ diff --git a/src/cogs/misc.py b/src/cogs/misc.py index 2f17251..311e837 100644 --- a/src/cogs/misc.py +++ b/src/cogs/misc.py @@ -58,7 +58,7 @@ class Misc(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction """ await interaction.response.send_message("<:sven:762725919604473866> Weebs 👉 <#803596668129509417>") @@ -74,7 +74,7 @@ class Misc(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction text (str): Text to translate """ @@ -114,8 +114,8 @@ class Misc(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object - user (discord.Member | discord.User | None): The user you want to see the dicksize of. Defaults to author + interaction (discord.Interaction): The slash command interaction + user (discord.Member | discord.User | None): The user to measure. Defaults to the invoking user """ if not user: @@ -149,7 +149,7 @@ class Misc(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction course_code (str): UiO course code """ @@ -175,24 +175,24 @@ class Misc(commands.Cog): @app_commands.command(name="klappifiser", description="Klappifiser tekst") @app_commands.rename(text="tekst") @app_commands.describe(text="Teksten som skal klappifiseres") - async def clapify(self, interation: discord.Interaction, text: str): + async def clapify(self, interaction: discord.Interaction, text: str): """ Add clap emoji between every word of a string Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction text (str): Text to clapify """ if len(text) >= 1000: embed = embed_templates.error_warning("Teksten er for lang") - return await interation.response.send_message(embed=embed) + return await interaction.response.send_message(embed=embed) text = text.replace(" ", "👏") - embed = discord.Embed(color=interation.client.user.color, description=f"**{text.upper()}**") - await interation.response.send_message(embed=embed) + embed = discord.Embed(color=interaction.client.user.color, description=f"**{text.upper()}**") + await interaction.response.send_message(embed=embed) @app_commands.checks.bot_has_permissions(embed_links=True) @app_commands.checks.cooldown(1, 2) @@ -210,7 +210,7 @@ class Misc(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction text (str): Text to mock user (discord.User | None): User to mention in the reply """ @@ -241,7 +241,7 @@ class Misc(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction country_code (str): Country code year (int): Year """ @@ -287,7 +287,7 @@ class Misc(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction user (discord.Member): User to match with """ @@ -367,7 +367,7 @@ class Misc(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction """ links = [ @@ -390,7 +390,7 @@ class Misc(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction """ random_result = random.randint(1, 100) # We use 1 and not 0 to avoid a tie @@ -411,7 +411,7 @@ class Misc(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction text (str): Human-readable time string """ @@ -439,7 +439,7 @@ class Misc(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction """ copypasta = ( @@ -461,7 +461,7 @@ class Misc(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction """ excuses = [ @@ -489,7 +489,7 @@ class Misc(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction """ bushisms = [ @@ -609,7 +609,7 @@ async def setup(bot: commands.Bot): Parameters ---------- - bot (commands.Bot): Bot instance + bot (commands.Bot): The bot instance """ await bot.add_cog(Misc(bot)) diff --git a/src/cogs/repeated_messages.py b/src/cogs/repeated_messages.py index 82ed5a6..f1702d1 100644 --- a/src/cogs/repeated_messages.py +++ b/src/cogs/repeated_messages.py @@ -11,6 +11,12 @@ class RepeatedMessages(commands.Cog): """Send messages at specific points of time""" def __init__(self, bot: commands.Bot): + """ + Parameters + ---------- + bot (commands.Bot): The bot instance + """ + self.bot = bot # self.fredag.start() @@ -20,6 +26,10 @@ class RepeatedMessages(commands.Cog): def cog_unload(self): # self.fredag.cancel() # self.mandag.cancel() + """ + Stop the repeated messages when the cog is unloaded + """ + self.new_year.cancel() def get_general_channel(self) -> discord.TextChannel | None: @@ -104,7 +114,7 @@ async def setup(bot: commands.Bot): Parameters ---------- - bot (commands.Bot): Bot instance + bot (commands.Bot): The bot instance """ await bot.add_cog(RepeatedMessages(bot)) diff --git a/src/cogs/social_credit.py b/src/cogs/social_credit.py index 8b8b201..217468c 100644 --- a/src/cogs/social_credit.py +++ b/src/cogs/social_credit.py @@ -28,12 +28,22 @@ from cogs.utils import misc_utils @dataclass class CreditUser: + """A user's row in the social credit table""" + user_id: int credit_score: int class SocialCredit(commands.Cog): + """Give and take social credit for things users do""" + def __init__(self, bot: commands.Bot): + """ + Parameters + ---------- + bot (commands.Bot): The bot instance + """ + self.bot = bot self.fuck_uwu.start() self.voice_activity.start() @@ -67,8 +77,12 @@ class SocialCredit(commands.Cog): def add_new_citizen(func): """ - Decorator that, when used, make sure that a user is inserted - into the database before executing the function + Decorator that makes sure the user is in the database before running the function. + The user's ID has to be the function's first argument + + Parameters + ---------- + func (callable): The function to wrap """ async def wrapper(*args, **kwargs): @@ -80,7 +94,11 @@ class SocialCredit(commands.Cog): def roll(percent: int = 50): """ - Decorator that executes the function with a given percent chance + Decorator that only runs the function with a given chance + + Parameters + ---------- + percent (int): The chance of running the function, in percent """ def decorator(func): @@ -175,6 +193,10 @@ class SocialCredit(commands.Cog): await self.bot.wait_until_ready() async def cog_unload(self): + """ + Stop the daily and voice loops when the cog is unloaded + """ + self.bot.logger.info("Unloading cog") self.fuck_uwu.cancel() self.voice_activity.cancel() @@ -236,7 +258,7 @@ class SocialCredit(commands.Cog): Parameters ---------- - interaction (discord.Interaction): The interaction object + interaction (discord.Interaction): The slash command interaction user (discord.Member | None): The user to check the score of. Defaults to the user who invoked the command """ @@ -270,7 +292,7 @@ class SocialCredit(commands.Cog): Parameters ---------- - interaction (discord.Interaction): The interaction object + interaction (discord.Interaction): The slash command interaction """ await interaction.response.defer() @@ -300,7 +322,7 @@ class SocialCredit(commands.Cog): Parameters ---------- - message (discord.Message): The message object + message (discord.Message): The message to check """ if message.author.bot: @@ -320,7 +342,7 @@ class SocialCredit(commands.Cog): Parameters ---------- - message (discord.Message): The message object + message (discord.Message): The message to check """ if message.channel.id == self.bot.channel_ids.get("politics"): @@ -333,7 +355,7 @@ class SocialCredit(commands.Cog): Parameters ---------- - message (discord.Message): The message object + message (discord.Message): The message to check """ if message.channel.id == self.bot.channel_ids.get("member_chat"): @@ -346,7 +368,7 @@ class SocialCredit(commands.Cog): Parameters ---------- - message (discord.Message): The message object + message (discord.Message): The message to check """ illegal_hours = [5, 6, 7, 8, 9] @@ -361,7 +383,7 @@ class SocialCredit(commands.Cog): Parameters ---------- - message (discord.Message): The message object + message (discord.Message): The message to check """ happy_hours = [1, 2, 3, 4] @@ -375,7 +397,7 @@ class SocialCredit(commands.Cog): Parameters ---------- - message (discord.Message): The message object + message (discord.Message): The message to check """ slurs = [ @@ -412,7 +434,7 @@ class SocialCredit(commands.Cog): Parameters ---------- - message (discord.Message): The message object + message (discord.Message): The message to check """ # This only works in the UiO Gaming server as well @@ -427,7 +449,7 @@ class SocialCredit(commands.Cog): Parameters ---------- - reaction (discord.Reaction): The reaction object + reaction (discord.Reaction): The reaction that was added user (discord.User | discord.Member): The user who reacted """ @@ -449,6 +471,11 @@ class SocialCredit(commands.Cog): async def on_star_remove(self, reaction: discord.Reaction, user: discord.User | discord.Member): """ Deducts points from users who have a star reaction removed from their message + + Parameters + ---------- + reaction (discord.Reaction): The reaction that was removed + user (discord.User | discord.Member): The user who removed it """ if user.bot or reaction.emoji != "⭐" or reaction.message.author == user: @@ -467,7 +494,7 @@ async def setup(bot: commands.Bot): Parameters ---------- - bot (commands.Bot): Bot instance + bot (commands.Bot): The bot instance """ await bot.add_cog(SocialCredit(bot)) diff --git a/src/cogs/starboard_scraper.py b/src/cogs/starboard_scraper.py index 1ff20d0..a328f90 100644 --- a/src/cogs/starboard_scraper.py +++ b/src/cogs/starboard_scraper.py @@ -76,8 +76,8 @@ class StarboardScraper(commands.Cog): Get the ID of the last scraped message Returns - ------- - int or None: Last scraped message ID or None if never scraped + ---------- + (int | None): Last scraped message ID or None if never scraped """ result = await self.bot.db.fetchone(""" SELECT last_scraped_message_id @@ -114,8 +114,8 @@ class StarboardScraper(commands.Cog): message (discord.Message): The starboard message to parse Returns - ------- - tuple(int, int) | None: (original_message_id, original_channel_id) or None if parsing failed + ---------- + (tuple[int, int] | None): The original message ID and channel ID. None if parsing failed """ if not message.embeds: @@ -217,6 +217,10 @@ class StarboardScraper(commands.Cog): await self.scrape_starboard_channel() async def cog_unload(self): + """ + Stop the starboard check when the cog is unloaded + """ + self.bot.logger.info("Unloading cog") self.star_check.cancel() @@ -227,7 +231,7 @@ async def setup(bot: commands.Bot): Parameters ---------- - bot (commands.Bot): Bot instance + bot (commands.Bot): The bot instance """ await bot.add_cog(StarboardScraper(bot)) diff --git a/src/cogs/streak.py b/src/cogs/streak.py index c6e6900..680ea3e 100644 --- a/src/cogs/streak.py +++ b/src/cogs/streak.py @@ -65,6 +65,10 @@ class Streak(commands.Cog): """) async def cog_unload(self): + """ + Stop the loops and save the cached streaks when the cog is unloaded + """ + self.bot.logger.info("Unloading cog") self.insert_cache_loop.cancel() self.streak_check.cancel() @@ -233,7 +237,7 @@ class Streak(commands.Cog): Parameters ---------- - interaction (discord.Interaction): The interaction + interaction (discord.Interaction): The slash command interaction user (discord.Member | discord.User | None): The user to get the streak for """ @@ -287,7 +291,7 @@ class Streak(commands.Cog): Parameters ---------- - interaction (discord.Interaction): The interaction + interaction (discord.Interaction): The slash command interaction """ await interaction.response.defer() @@ -318,7 +322,7 @@ async def setup(bot: commands.Bot): Parameters ---------- - bot (commands.Bot): Bot instance + bot (commands.Bot): The bot instance """ await bot.add_cog(Streak(bot)) diff --git a/src/cogs/tempvoice.py b/src/cogs/tempvoice.py index 7a33a28..bf86f79 100644 --- a/src/cogs/tempvoice.py +++ b/src/cogs/tempvoice.py @@ -19,9 +19,17 @@ class TempVoice(commands.Cog): self.temp_voice_helper = TempVoiceHelper(bot) async def cog_load(self): + """ + Set up the temporary voice channel helper before the cog is used + """ + await self.temp_voice_helper.start() async def cog_unload(self): + """ + Stop checking for inactive temporary voice channels when the cog is unloaded + """ + self.temp_voice_helper.check_temp_vc_channels.cancel() @commands.Cog.listener() @@ -30,6 +38,12 @@ class TempVoice(commands.Cog): ): """ Listen for disconnects from the temporary voice channels + + Parameters + ---------- + member (discord.Member): The member whose voice state changed + before (discord.VoiceState): The voice state before the change + after (discord.VoiceState): The voice state after the change """ await self.temp_voice_helper.on_voice_state_update(member, before, after) @@ -50,7 +64,7 @@ class TempVoice(commands.Cog): Parameters ---------- - interaction (discord.Interaction): The interaction object + interaction (discord.Interaction): The slash command interaction name (str): The name of the channel limit (int): The user limit of the channel. 0 means no limit """ @@ -72,7 +86,7 @@ async def setup(bot: commands.Bot): Parameters ---------- - bot (commands.Bot): Bot instance + bot (commands.Bot): The bot instance """ await bot.add_cog(TempVoice(bot)) diff --git a/src/cogs/ten_man.py b/src/cogs/ten_man.py index 6b2b24e..54cad71 100644 --- a/src/cogs/ten_man.py +++ b/src/cogs/ten_man.py @@ -44,7 +44,7 @@ class TenMan(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction """ await open_lobby(interaction, self.active_lobbies, TenManView, "10 Man Lobby", timedelta(minutes=30)) @@ -61,7 +61,7 @@ class TenManView(LobbyView): Parameters ---------- - interaction (discord.Interaction): The interaction object + interaction (discord.Interaction): The interaction that triggered this button (discord.ui.Button): The button that was pressed """ @@ -96,10 +96,22 @@ class TeamDraft: @property def leaders(self) -> list[discord.Member]: + """ + Returns + ---------- + (list[discord.Member]): The two team leaders + """ + return [team[0] for team in self.teams] @property def done(self) -> bool: + """ + Returns + ---------- + (bool): Whether every player has been picked + """ + return not self.remaining def pick(self, player_id: int): @@ -161,7 +173,7 @@ class StageView(discord.ui.View): Parameters ---------- - interaction (discord.Interaction): The interaction object + interaction (discord.Interaction): The interaction that triggered this reason (str): Why the user was denied Returns @@ -174,6 +186,10 @@ class StageView(discord.ui.View): return False async def on_timeout(self): + """ + Disable the step's menus and buttons after SELECTION_TIMEOUT seconds without interaction + """ + for item in self.children: item.disabled = True @@ -183,6 +199,16 @@ class StageView(discord.ui.View): pass # The message has been deleted async def on_error(self, interaction: discord.Interaction, error: Exception, item: discord.ui.Item): + """ + Log the error and tell the user something went wrong + + Parameters + ---------- + interaction (discord.Interaction): The interaction that triggered this + error (Exception): The error that was raised + item (discord.ui.Item): The menu or button that was used + """ + self.bot.logger.error(f"{type(self).__name__} error", exc_info=error) embed = embed_templates.error_fatal("Oopsie woopsie, we made a fucky wucky!") @@ -196,10 +222,30 @@ class TeamLeaderView(StageView): """The host picks two team leaders""" def __init__(self, lobby: Lobby, bot: commands.Bot, message: discord.PartialMessage): + """ + Parameters + ---------- + lobby (Lobby): The closed lobby + bot (commands.Bot): The bot instance + message (discord.PartialMessage): The lobby message + """ + super().__init__(lobby, bot, message) self.add_item(TeamLeaderSelect(lobby.players)) async def interaction_check(self, interaction: discord.Interaction) -> bool: + """ + Only let the host pick team leaders + + Parameters + ---------- + interaction (discord.Interaction): The interaction that triggered this + + Returns + ---------- + (bool): Whether the user may use the menu + """ + if interaction.user != self.lobby.host: return await self.deny(interaction, "Bare hosten kan velge lagledere") return True @@ -222,6 +268,8 @@ class TeamLeaderView(StageView): class TeamLeaderSelect(discord.ui.Select): + """Menu for picking the two team leaders""" + def __init__(self, players: list[discord.Member]): """ Parameters @@ -241,7 +289,7 @@ class TeamLeaderSelect(discord.ui.Select): Parameters ---------- - interaction (discord.Interaction): The interaction object + interaction (discord.Interaction): The interaction that triggered this """ view: TeamLeaderView = self.view @@ -269,6 +317,18 @@ class DraftView(StageView): self.add_item(PlayerSelect(draft.remaining)) async def interaction_check(self, interaction: discord.Interaction) -> bool: + """ + Only let the team leader whose turn it is pick + + Parameters + ---------- + interaction (discord.Interaction): The interaction that triggered this + + Returns + ---------- + (bool): Whether the user may use the menu + """ + if interaction.user not in self.draft.leaders: return await self.deny(interaction, "Bare lagledere kan velge spillere") if interaction.user != self.draft.leaders[self.draft.turn]: @@ -277,6 +337,8 @@ class DraftView(StageView): class PlayerSelect(discord.ui.Select): + """Menu for picking the next player for a team""" + def __init__(self, players: list[discord.Member]): """ Parameters @@ -296,7 +358,7 @@ class PlayerSelect(discord.ui.Select): Parameters ---------- - interaction (discord.Interaction): The interaction object + interaction (discord.Interaction): The interaction that triggered this """ view: DraftView = self.view @@ -323,6 +385,18 @@ class VoiceView(StageView): self.moved_teams: set[int] = set() async def interaction_check(self, interaction: discord.Interaction) -> bool: + """ + Only let team leaders move their team + + Parameters + ---------- + interaction (discord.Interaction): The interaction that triggered this + + Returns + ---------- + (bool): Whether the user may use the button + """ + if interaction.user not in (self.teams[0][0], self.teams[1][0]): return await self.deny(interaction, "Bare lagleder kan flytte laget!") return True @@ -334,7 +408,7 @@ class VoiceView(StageView): Parameters ---------- - interaction (discord.Interaction): The interaction object + interaction (discord.Interaction): The interaction that triggered this button (discord.ui.Button): The button that was pressed """ @@ -373,7 +447,7 @@ async def setup(bot: commands.Bot): Parameters ---------- - bot (commands.Bot): Bot instance + bot (commands.Bot): The bot instance """ await bot.add_cog(TenMan(bot)) diff --git a/src/cogs/user_facts.py b/src/cogs/user_facts.py index f8a9deb..df95049 100644 --- a/src/cogs/user_facts.py +++ b/src/cogs/user_facts.py @@ -13,7 +13,15 @@ from cogs.utils import misc_utils class UserFacts(commands.Cog): + """Let users share facts about themselves, like their height and MBTI""" + def __init__(self, bot): + """ + Parameters + ---------- + bot (commands.Bot): The bot instance + """ + self.bot = bot self.mbti_codes = { @@ -70,7 +78,7 @@ class UserFacts(commands.Cog): Parameters ---------- - interaction (discord.Interaction): The interaction object + interaction (discord.Interaction): The slash command interaction user (discord.Member): The user to see the height of """ @@ -114,7 +122,7 @@ class UserFacts(commands.Cog): Parameters ---------- - interaction (discord.Interaction): The interaction object + interaction (discord.Interaction): The slash command interaction height_cm (int): The height of the user """ @@ -139,7 +147,7 @@ class UserFacts(commands.Cog): Parameters ---------- - interaction (discord.Interaction): The interaction object + interaction (discord.Interaction): The slash command interaction """ updated = await self.bot.db.execute( @@ -167,7 +175,7 @@ class UserFacts(commands.Cog): Parameters ---------- - interaction (discord.Interaction): The interaction object + interaction (discord.Interaction): The slash command interaction """ result = await self.bot.db.fetchall(""" @@ -202,7 +210,7 @@ class UserFacts(commands.Cog): Parameters ---------- - interaction (discord.Interaction): The interaction object + interaction (discord.Interaction): The slash command interaction user (discord.Member): The user to see the MBTI of """ @@ -267,7 +275,7 @@ class UserFacts(commands.Cog): Parameters ---------- - interaction (discord.Interaction): The interaction object + interaction (discord.Interaction): The slash command interaction mbti (str): The MBTI of the user """ @@ -293,7 +301,7 @@ class UserFacts(commands.Cog): Parameters ---------- - interaction (discord.Interaction): The interaction object + interaction (discord.Interaction): The interaction that triggered this current (str): The current input """ @@ -310,7 +318,7 @@ class UserFacts(commands.Cog): Parameters ---------- - interaction (discord.Interaction): The interaction object + interaction (discord.Interaction): The slash command interaction """ updated = await self.bot.db.execute( @@ -338,7 +346,7 @@ class UserFacts(commands.Cog): Parameters ---------- - interaction (discord.Interaction): The interaction object + interaction (discord.Interaction): The slash command interaction """ embed = discord.Embed(title="Hva er MBTI?", color=discord.Color.blurple()) @@ -352,6 +360,14 @@ class UserFacts(commands.Cog): await interaction.response.send_message(embed=embed) def create_similarity_matrix(self): + """ + Count how many letters every pair of MBTI types has in common + + Returns + ---------- + (np.ndarray): The number of shared letters, indexed like mbti_list + """ + def similarity(mbti_1, mbti_2): similarity = 0 for i in range(4): @@ -372,6 +388,19 @@ class UserFacts(commands.Cog): def create_mbti_graph( self, user_mbti: tuple[discord.Member, str], others: list[tuple[discord.Member, str]] ) -> bytes: + """ + Draw a graph of how similar a user's MBTI is to other users' + + Parameters + ---------- + user_mbti (tuple[discord.Member, str]): The invoking user and their MBTI + others (list[tuple[discord.Member, str]]): Other users and their MBTIs + + Returns + ---------- + (bytes): The graph as PNG data + """ + user, mbti = user_mbti # Create a Graphviz graph @@ -403,7 +432,7 @@ async def setup(bot: commands.Bot): Parameters ---------- - bot (commands.Bot): Bot instance + bot (commands.Bot): The bot instance """ await bot.add_cog(UserFacts(bot)) diff --git a/src/cogs/utils/discord_utils.py b/src/cogs/utils/discord_utils.py index c530e82..e9e5283 100644 --- a/src/cogs/utils/discord_utils.py +++ b/src/cogs/utils/discord_utils.py @@ -20,7 +20,7 @@ async def send_as_txt_file(interaction: discord.Interaction, content: str, filen Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The interaction that triggered this content (str): String that's too long to send filename (str): Name of the file as shown in Discord """ @@ -34,11 +34,11 @@ async def get_file_bytesio(file: discord.Attachment | discord.Asset) -> BytesIO: Returns a BytesIO object of the file Parameters - ----------- - file (discord.Attatchment | discord.Asset): The file to get the BytesIO object of + ---------- + file (discord.Attachment | discord.Asset): The file to get the BytesIO object of Returns - ----------- + ---------- (BytesIO): The file as a BytesIO object """ @@ -62,11 +62,13 @@ class ScrollerButton(discord.ui.Button): ): """ Parameters - ----------- + ---------- paginator (Paginator): The paginator object that contains the data to be paginated button_action (callable): The function that returns the requested page content_constructor (callable): A function that takes a paginator object and a page number and returns an embed - owner (discord.User|discord.Member): The user that invoked the paginator. Only this user can use the button + owner (discord.User | discord.Member): The user that invoked the paginator. Only this user can use the button + label (str): The text on the button + disabled (bool): Whether the button starts out disabled """ super().__init__(label=label, disabled=disabled) @@ -80,8 +82,8 @@ class ScrollerButton(discord.ui.Button): What to do when the button is pressed Parameters - ----------- - interaction (discord.Interaction): Slash command context object + ---------- + interaction (discord.Interaction): The interaction that triggered this """ if interaction.user.id != self.owner.id: @@ -101,18 +103,18 @@ class Scroller(discord.ui.View): """View that allows scrolling through pages of data using the pagination module""" def __init__( - self, paginatior: Paginator, owner: discord.User | discord.Member, content_constructor: callable = None + self, paginator: Paginator, owner: discord.User | discord.Member, content_constructor: callable = None ): """ Parameters - ----------- + ---------- paginator (Paginator): The paginator object that contains the data to be paginated - owner (discord.User|discord.Member): The user that invoked the paginator. Only this user can use the buttons + owner (discord.User | discord.Member): The user that invoked the paginator. Only this user can use the buttons content_constructor (callable): A function that takes a paginator object and a page number and returns an embed """ super().__init__() - self.paginator = paginatior + self.paginator = paginator self.content_constructor = content_constructor if content_constructor else self.__default_content_constructor self.add_item( @@ -161,7 +163,7 @@ class Scroller(discord.ui.View): Constructs the embed to be displayed Parameters - ----------- + ---------- base_embed (discord.Embed): The base embed to add fields to """ @@ -173,9 +175,12 @@ class Scroller(discord.ui.View): Parameters ---------- - paginator (Paginator): Paginator dataclass - page (list): List of streaks to display on a page - embed (discord.Embed): Embed to add fields to + page (list): The items to show on the page + embed (discord.Embed): The embed to add the page to + + Returns + ---------- + (discord.Embed): The embed with the page added """ embed.description = "\n".join(page) @@ -185,6 +190,8 @@ class Scroller(discord.ui.View): @dataclass class Lobby: + """Players gathering before an activity starts. Closed once it starts, is deleted or times out""" + host: discord.User players: list[discord.User] ends: datetime @@ -204,7 +211,7 @@ async def open_lobby( Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The interaction that triggered this lobbies (dict[int, Lobby]): The cog's lobbies by host ID. The new lobby is added to it view_class (type[LobbyView]): The view to show the lobby with title (str): The title of the lobby message @@ -241,7 +248,16 @@ async def open_lobby( class LobbyView(discord.ui.View): + """Lobby players can join, leave and be kicked from. Subclasses decide what starting it does""" + def __init__(self, lobby: Lobby, bot: commands.Bot): + """ + Parameters + ---------- + lobby (Lobby): The lobby to show + bot (commands.Bot): The bot instance + """ + lobby_end = (lobby.ends - discord.utils.utcnow()).total_seconds() super().__init__(timeout=lobby_end) @@ -253,6 +269,10 @@ class LobbyView(discord.ui.View): self.add_item(self.kick_menu) async def on_timeout(self): + """ + Close the lobby and disable its buttons when it times out + """ + await self.end_lobby() if self.message: try: @@ -261,12 +281,24 @@ class LobbyView(discord.ui.View): pass # The message has been deleted async def end_lobby(self): + """ + Close the lobby, disable its buttons and stop listening for interactions + """ + self.lobby.closed = True for item in self.children: item.disabled = True self.stop() async def rerender_players(self, interaction: discord.Interaction): + """ + Update the player list and the kick menu in the lobby message + + Parameters + ---------- + interaction (discord.Interaction): The interaction that triggered this + """ + self.kick_menu.update_options() embed = interaction.message.embeds[0].set_field_at( 0, @@ -277,6 +309,15 @@ class LobbyView(discord.ui.View): @discord.ui.button(label="Bli med", style=discord.ButtonStyle.blurple) async def join_lobby(self, interaction: discord.Interaction, button: discord.ui.Button): + """ + Add the user to the lobby + + Parameters + ---------- + interaction (discord.Interaction): The interaction that triggered this + button (discord.ui.Button): The button that was pressed + """ + if self.lobby.closed: embed = embed_templates.error_warning("Lobbyen har allerede startet") return await interaction.response.send_message(embed=embed, ephemeral=True, delete_after=10) @@ -303,6 +344,15 @@ class LobbyView(discord.ui.View): @discord.ui.button(label="Start", style=discord.ButtonStyle.green) async def start_lobby(self, interaction: discord.Interaction, button: discord.ui.Button): + """ + Close the lobby. Subclasses override this to start their activity + + Parameters + ---------- + interaction (discord.Interaction): The interaction that triggered this + button (discord.ui.Button): The button that was pressed + """ + if interaction.user != self.lobby.host: embed = embed_templates.error_warning("Bare hosten kan starte") return await interaction.response.send_message(embed=embed, ephemeral=True, delete_after=10) @@ -319,6 +369,15 @@ class LobbyView(discord.ui.View): @discord.ui.button(label="Forlat", style=discord.ButtonStyle.gray) async def leave_lobby(self, interaction: discord.Interaction, button: discord.ui.Button): + """ + Remove the user from the lobby + + Parameters + ---------- + interaction (discord.Interaction): The interaction that triggered this + button (discord.ui.Button): The button that was pressed + """ + if interaction.user == self.lobby.host: embed = embed_templates.error_warning( "Du kan ikke forlate lobbyen som host. Slett lobbyen i stedet om Ăžnskelig!" @@ -337,6 +396,15 @@ class LobbyView(discord.ui.View): @discord.ui.button(label="Slett", style=discord.ButtonStyle.red) async def delete_lobby(self, interaction: discord.Interaction, button: discord.ui.Button): + """ + Close the lobby and delete its message + + Parameters + ---------- + interaction (discord.Interaction): The interaction that triggered this + button (discord.ui.Button): The button that was pressed + """ + if interaction.user != self.lobby.host: embed = embed_templates.error_warning("Bare hosten kan slette lobbyen") return await interaction.response.send_message(embed=embed, ephemeral=True, delete_after=10) @@ -349,7 +417,15 @@ class LobbyView(discord.ui.View): class _KickSelectMenu(discord.ui.Select): + """Menu the host uses to kick players from the lobby""" + def __init__(self, parent_view: LobbyView): + """ + Parameters + ---------- + parent_view (LobbyView): The lobby view the menu belongs to + """ + self.parent_view = parent_view super().__init__(placeholder="Kick en spiller", max_values=1, min_values=1) self.update_options() @@ -367,6 +443,14 @@ class _KickSelectMenu(discord.ui.Select): ] async def callback(self, interaction: discord.Interaction): + """ + Kick the selected player from the lobby + + Parameters + ---------- + interaction (discord.Interaction): The interaction that triggered this + """ + if interaction.user != self.parent_view.lobby.host: embed = embed_templates.error_warning("Bare hosten kan kicke spillere") return await interaction.response.send_message(embed=embed, ephemeral=True, delete_after=10) @@ -463,6 +547,12 @@ class TempVoiceHelper: ): """ Listen for disconnects from the temporary voice channels + + Parameters + ---------- + member (discord.Member): The member whose voice state changed + before (discord.VoiceState): The voice state before the change + after (discord.VoiceState): The voice state after the change """ for channel in (before.channel, after.channel): @@ -537,13 +627,13 @@ class TempVoiceHelper: Parameters ---------- - interaction (discord.Interaction): The interaction object + interaction (discord.Interaction): The interaction that triggered this name (str): The name of the channel limit (int): The user limit of the channel Returns ---------- - (discord.VoiceChannel) | None: The object for the newly created channel. None if failed + (discord.VoiceChannel | None): The new channel. None if it couldn't be created """ # Get the UiO Gaming server's VC category. If the command is not invoked in that server it should still be fine @@ -592,13 +682,13 @@ class TempVoiceHelper: Parameters ---------- - interaction (discord.Interaction): The interaction object + interaction (discord.Interaction): The interaction that triggered this channel (discord.VoiceChannel): The channel the users should be moved to users (list[discord.User]): A list of users to be moved Returns ---------- - (list[discord.User]) | None: A list of users that failed to be moved. None if all users were moved + (list[discord.User]): The users that couldn't be moved. Empty if everyone was moved """ failed_users = [] diff --git a/src/cogs/utils/embed_templates.py b/src/cogs/utils/embed_templates.py index adf4db7..e98f174 100644 --- a/src/cogs/utils/embed_templates.py +++ b/src/cogs/utils/embed_templates.py @@ -6,11 +6,11 @@ def error_warning(text: str) -> discord.Embed: Creates an embed with a specified error message based on a warning template Parameters - ----------- + ---------- text (str): The error message Returns - ----------- + ---------- (discord.Embed): An embed object based on the template with the specified text """ @@ -23,11 +23,11 @@ def error_fatal(text: str) -> discord.Embed: Creates an embed with a specified error message based on a warning template Parameters - ----------- + ---------- text (str): The error message Returns - ----------- + ---------- (discord.Embed): An embed object based on the template with the specified text """ @@ -40,12 +40,12 @@ def success(text: str) -> discord.Embed: Creates an embed with a specified message using a template signifying success. Parameters - ----------- + ---------- text (str): The message Returns - ----------- - discord.Embed: An embed object based on the template with the specified text + ---------- + (discord.Embed): An embed object based on the template with the specified text """ embed = discord.Embed(color=discord.Color.green(), description=f"✅ {text}") diff --git a/src/cogs/utils/misc_utils.py b/src/cogs/utils/misc_utils.py index e689ec2..5c566d5 100644 --- a/src/cogs/utils/misc_utils.py +++ b/src/cogs/utils/misc_utils.py @@ -114,7 +114,7 @@ class Paginator: Returns ---------- - (list|None): The page you requested + (list | None): The page you requested """ if page < 1 or page > self.total_page_count: diff --git a/src/cogs/viteboka.py b/src/cogs/viteboka.py index 682d702..0ef9d4c 100644 --- a/src/cogs/viteboka.py +++ b/src/cogs/viteboka.py @@ -26,7 +26,7 @@ async def fetch_article(session: aiohttp.ClientSession, title: str): Returns ---------- - tuple: The title, url, text and image of the article + (tuple): The title, url, text and image of the article """ # The wiki renders the article to HTML for us, so templates are already expanded @@ -78,7 +78,7 @@ async def fetch_page_image(session: aiohttp.ClientSession, title: str) -> str | Returns ---------- - str | None: The url of the image. None if the article has no image or it couldn't be fetched + (str | None): The url of the image. None if the article has no image or it couldn't be fetched """ params = { @@ -110,7 +110,7 @@ def shorten(text: str, limit: int) -> str: Returns ---------- - str: The shortened text + (str): The shortened text """ if len(text) <= limit: @@ -146,7 +146,7 @@ def viteboka_embed(title: str, url: str, text: str, image: str): Returns ---------- - discord.Embed: The embed + (discord.Embed): The embed """ embed = discord.Embed(color=discord.Color.orange(), title=title, url=url, description=text) @@ -157,6 +157,8 @@ def viteboka_embed(title: str, url: str, text: str, image: str): class VitebokaException(Exception): + """Raised when an article can't be fetched. The message is shown to the user""" + pass @@ -185,7 +187,7 @@ class Viteboka(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction query (str): The search query """ @@ -243,7 +245,7 @@ class Viteboka(commands.Cog): Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction """ await interaction.response.defer() @@ -286,8 +288,8 @@ class ArticleButton(discord.ui.Button): ): """ Parameters - ----------- - owner (discord.User|discord.Member): The user that invoked the paginator. Only this user can use the button + ---------- + owner (discord.User | discord.Member): The user that invoked the paginator. Only this user can use the button label (str): The label of the button article_title (str): The title of the article the button is associated with """ @@ -301,8 +303,8 @@ class ArticleButton(discord.ui.Button): What to do when the button is pressed Parameters - ----------- - interaction (discord.Interaction): Slash command context object + ---------- + interaction (discord.Interaction): The interaction that triggered this """ await interaction.response.defer() @@ -328,7 +330,7 @@ async def setup(bot: commands.Bot): Parameters ---------- - bot (commands.Bot): Bot instance + bot (commands.Bot): The bot instance """ await bot.add_cog(Viteboka(bot)) diff --git a/src/cogs/website_events.py b/src/cogs/website_events.py index 122c51f..bd1f0f2 100644 --- a/src/cogs/website_events.py +++ b/src/cogs/website_events.py @@ -26,6 +26,10 @@ class WebsiteEvents(commands.Cog): ) async def cog_load(self): + """ + Start syncing events once the bot is ready + """ + asyncio.create_task(self.after_ready()) async def after_ready(self): @@ -153,7 +157,7 @@ async def setup(bot: commands.Bot): Parameters ---------- - bot (commands.Bot): Bot instance + bot (commands.Bot): The bot instance """ await bot.add_cog(WebsiteEvents(bot)) diff --git a/src/cogs/word_cloud.py b/src/cogs/word_cloud.py index 066da03..696025e 100644 --- a/src/cogs/word_cloud.py +++ b/src/cogs/word_cloud.py @@ -166,7 +166,7 @@ class WordCloud(commands.Cog): Returns ---------- - bool: Whether the message can be counted + (bool): Whether the message can be counted """ return ( @@ -184,7 +184,7 @@ class WordCloud(commands.Cog): Returns ---------- - list[str]: List of words + (list[str]): List of words """ tokens = [] @@ -215,7 +215,7 @@ class WordCloud(commands.Cog): """ Returns ---------- - set[str]: Norwegian and english words too common to include in a wordcloud + (set[str]): Norwegian and english words too common to include in a wordcloud """ return set(stopwords.words("norwegian") + stopwords.words("english")) @@ -233,7 +233,7 @@ class WordCloud(commands.Cog): Returns ---------- - BytesIO: BytesIO object containing the wordcloud image + (BytesIO): BytesIO object containing the wordcloud image """ mask = np.array(Image.open("./src/assets/word_cloud_mask.png")) @@ -265,7 +265,7 @@ class WordCloud(commands.Cog): Returns ---------- - BytesIO: BytesIO object containing the wordcloud image + (BytesIO): BytesIO object containing the wordcloud image """ return WordCloud.render_wordcloud(max_words, allow_bigrams, lambda wc: wc.generate(text)) @@ -282,7 +282,7 @@ class WordCloud(commands.Cog): Returns ---------- - BytesIO: BytesIO object containing the wordcloud image + (BytesIO): BytesIO object containing the wordcloud image """ filter_words = WordCloud.filter_words() @@ -305,11 +305,11 @@ class WordCloud(commands.Cog): @wordcloud_group.command(name="samtykke", description="Gi samtykke til Ă„ samle meldingsdataen din for ordskyer") async def consent(self, interaction: discord.Interaction): """ - Gi samtykke til Ă„ samle meldingsdataen din + Consent to having your messages counted for word clouds Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction """ if interaction.user.id in self.consenting_users: @@ -342,11 +342,11 @@ class WordCloud(commands.Cog): @wordcloud_group.command(name="slett", description="Fjern samtykke og slett alle dine ordskydata") async def consent_remove(self, interaction: discord.Interaction): """ - Fjern samtykke og slett meldingsdata + Withdraw consent and delete your word cloud data Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction """ if interaction.user.id not in self.consenting_users: @@ -380,11 +380,11 @@ class WordCloud(commands.Cog): @wordcloud_group.command(name="data", description="FĂ„ tilsendt dine ordskydata i JSON-format") async def data(self, interaction: discord.Interaction): """ - FĂ„ tilsendt dine data + Send the user their word cloud data as a JSON file Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction """ result = await self.bot.db.fetchall( @@ -420,11 +420,11 @@ class WordCloud(commands.Cog): ) async def generate_db(self, interaction: discord.Interaction): """ - Generer en ordsky basert pĂ„ dine mest frekvente sagte ord siden du ga samtykke + Generate a word cloud from the user's most used words since they consented Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction """ await interaction.response.defer() @@ -480,7 +480,7 @@ class WordCloud(commands.Cog): Returns ---------- - list[discord.TextChannel]: Channels the user can write in, the bot can read and that aren't private + (list[discord.TextChannel]): Channels the user can write in, the bot can read and that aren't private """ # The word cloud is posted publicly, so skip private channels like board chats. @@ -513,7 +513,7 @@ class WordCloud(commands.Cog): Returns ---------- - list[str]: The tokens of the user's messages + (list[str]): The tokens of the user's messages """ tokens = [] @@ -547,11 +547,11 @@ class WordCloud(commands.Cog): @app_commands.describe(amount="Hvor mange av de siste meldingene i hver kanal som skal leses. Flere tar lengre tid") async def generate_last(self, interaction: discord.Interaction, amount: app_commands.Range[int, 50, 2000] = 1000): """ - Generer en ordsky basert pĂ„ dine mest frekvente sagte ord fra de siste meldingene dine + Generate a word cloud from the user's most used words in the most recent messages of each channel Parameters ---------- - interaction (discord.Interaction): Slash command context object + interaction (discord.Interaction): The slash command interaction amount (int): How many of the most recent messages in each channel to read """ @@ -587,7 +587,7 @@ async def setup(bot: commands.Bot): Parameters ---------- - bot (commands.Bot): Bot instance + bot (commands.Bot): The bot instance """ await bot.add_cog(WordCloud(bot)) diff --git a/src/logger.py b/src/logger.py index b603aab..73cf61a 100644 --- a/src/logger.py +++ b/src/logger.py @@ -9,6 +9,10 @@ class BotLogger: """Logging config for the bot""" def __init__(self): + """ + Log to the console and to a new file in logs/ for every run + """ + logger = logging.getLogger("discord") logger.setLevel(logging.INFO) formatter = logging.Formatter( diff --git a/src/run.py b/src/run.py index 0f3f146..512c22e 100644 --- a/src/run.py +++ b/src/run.py @@ -43,6 +43,10 @@ class Bot(commands.Bot): """UiO Gaming Bot""" def __init__(self): + """ + Read the config and disable the cogs whose credentials are missing + """ + super().__init__( command_prefix=commands.when_mentioned_or(config["bot"]["prefix"]), case_insensitive=True, @@ -103,6 +107,10 @@ class Bot(commands.Bot): misc_utils.MIDNIGHT = datetime.time(tzinfo=midnight_tz) async def setup_hook(self): + """ + Open the HTTP session and database pool, load the cogs and sync the slash commands + """ + self.http_session = aiohttp.ClientSession(timeout=aiohttp.ClientTimeout(total=15)) if self.db_pool: await self.db_pool.open(wait=True, timeout=30) @@ -127,6 +135,10 @@ class Bot(commands.Bot): await self.tree.sync(guild=discord.Object(id=self.guild_id)) async def close(self): + """ + Close the HTTP session and database pool when the bot shuts down + """ + await super().close() if hasattr(self, "http_session"): await self.http_session.close() @@ -136,6 +148,10 @@ class Bot(commands.Bot): async def configure_db_connection(self, conn): """ Sets the session time zone of every new database connection to the bot's time zone + + Parameters + ---------- + conn (psycopg.AsyncConnection): The new database connection """ if self.timezone_name: @@ -165,13 +181,13 @@ class Bot(commands.Bot): Check if the credentials are valid. Removes cogs from the class' `cog_files` attribute if not Parameters - ----------- + ---------- credentials (dict): The credentials to check dependant_cogs (set): The cogs that depend on the credentials Returns ---------- - bool: Whether the credentials are valid. If not, the dependant cogs are disabled. + (bool): Whether the credentials are valid. If not, the dependant cogs are disabled. """ for credential in credentials.values(): @@ -188,6 +204,10 @@ bot = Bot() @bot.event async def on_ready(): + """ + Print the bot's info and set its presence once it's connected + """ + if not hasattr(bot, "uptime"): bot.uptime = time()