diff --git a/cogs/Help.py b/cogs/Help.py index f5404a4..fa352bb 100644 --- a/cogs/Help.py +++ b/cogs/Help.py @@ -12,8 +12,7 @@ def __init__(self, client: discord.Client): @commands.command(name="Help", description="Returns all the available commmands") async def help(self, ctx: commands.Context): - local_guild_data = GuildData.get_guild_data(ctx.guild) - prefix = local_guild_data["prefix"] + prefix = GuildData.get_value(ctx.guild, "prefix") embed = create_embed( "Help Command", f"These are the avaliable commands for **{ctx.guild.name}**\nThe client prefix is: `{prefix}`" diff --git a/cogs/Moderation.py b/cogs/Moderation.py index cc78931..04b643b 100644 --- a/cogs/Moderation.py +++ b/cogs/Moderation.py @@ -83,14 +83,14 @@ async def setup(self, ctx: commands.Context, specific_command: str = None, set_t # Invalid Key set embed_obj = functions.create_embed("Invalid Arguments", f"The argument that you passed was invalid.\n\nValid Keys:") for key, value in GuildData.get_valid_keys().items(): - embed_obj.add_field(name=f"** ❯ {key.replace('_', ' ').capitalize()} **", value=f"Key: `{key}`\tType: `{value}`", inline=False) + embed_obj.add_field(name=f"** ❯ {key.replace('_', ' ').capitalize()} **", value=f"Key: `{key}`\tType: `{value}`", inline=True) await ctx.send(embed=embed_obj) else: await ctx.send(embed=functions.create_embed("Success", f"The key {specific_command} was set to {set_to}")) else: - embed_obj = functions.create_embed("Invalid Arguments", f"Please pass two arguments to this command: (`command_to_set`, `value_to_set_to`).\n\nValid Keys:") + embed_obj = functions.create_embed("Invalid Arguments", f"Please pass two arguments to this command: (`command_to_set`, `value_to_set_to`).\n\n```Valid Keys:```") for key, value in GuildData.get_valid_keys().items(): - embed_obj.add_field(name=f"** ❯ {key.replace('_', ' ').capitalize()} **", value=f"Key: `{key}`\tType: `{value}`", inline=False) + embed_obj.add_field(name=f"** ❯ {key.replace('_', ' ').capitalize()} **", value=f"Key: `{key}`\nDefault: `{value}`", inline=True) await ctx.send(embed=embed_obj) @@ -98,8 +98,13 @@ async def setup(self, ctx: commands.Context, specific_command: str = None, set_t @commands.check(functions.is_server_admin) async def settings(self, ctx: commands.Context): embed_obj = functions.create_embed("Settings", f"These are the following settings for this guild. To change the settings for your server, use the `setup` command.") - for key, value in GuildData.get_guild_data(ctx.guild).items(): - embed_obj.add_field(name=f"** ❯ {key.replace('_', ' ').capitalize()} **", value=f"`{value}`", inline=False) + local_data = GuildData.get_guild_data(ctx.guild) + for key, default_value in GuildData.get_valid_keys().items(): + + if (value := local_data.get(key, None)) is None: # The key does not exist + value = default_value + + embed_obj.add_field(name=f"❯ {key.replace('_', ' ').capitalize()}", value=f"```{value}```", inline=True) await ctx.send(embed=embed_obj) @@ -115,10 +120,9 @@ async def register(self, ctx: commands.Context): # Check if user already has role if (local_data := UserData.get_user_data(user_id)) is not None and local_data.get('name', None) is not None and role in author.roles: embed = functions.create_embed("Registered", "You are already registered") - await ctx.send(embed=embed) return # Check if terms of conditions were set up in this guild - if (local_guild_data := GuildData.get_guild_data(ctx.guild)) is None or (terms_of_conditions := local_guild_data.get("terms_and_conditions", None)) is None: + if (terms_of_conditions := GuildData.get_value(ctx.guild, "terms_and_conditions")) == "": embed = functions.create_embed("Terms and Conditions Not Setup", "Terms and Conditions were not set for this server. Please run the setup command to set variables for your server.") await ctx.send(embed=embed); return; diff --git a/cogs/Stats.py b/cogs/Stats.py index 1f55953..001ddad 100644 --- a/cogs/Stats.py +++ b/cogs/Stats.py @@ -55,7 +55,7 @@ async def stat(self): # Guild Checks if (current_guild_settings := GuildData.get_guild_data(guild_obj=guild)) is None: - return + continue; if (stats_channel_id := current_guild_settings["stats_channel_id"]) == 0: # Skip this guild if stats_channel was not filled continue; if (stats_message_id := current_guild_settings["stats_message_id"]) == 0: @@ -111,14 +111,10 @@ async def before_stat(self): @tasks.loop(minutes=1440) async def get_fact_of_day(self): embed = create_embed("Fact of the Day", f"```{get_fact()}```") - # Loop through guilds and send fact of the day for guild for guild in self.client.guilds: - if (current_guild_settings := GuildData.get_guild_data(guild_obj=guild)) is not None: - fact_channel_id = current_guild_settings["fact_channel_id"] - - if fact_channel_id is not None and fact_channel_id != 0: - channel = self.client.get_channel(fact_channel_id) + if (fact_channel_id := GuildData.get_value(guild, "fact_channel_id")) is not None: + if (channel := guild.get_channel(int(fact_channel_id))) is not None: await channel.send(embed=embed) @get_fact_of_day.before_loop diff --git a/main.py b/main.py index 42aaba1..566bb82 100644 --- a/main.py +++ b/main.py @@ -98,42 +98,51 @@ async def convert_to_file(attach_array: list): @client.event async def on_message_delete(message: discord.Message): - embed = functions.create_embed( - "Message Deleted:", - f"User `{message.author.display_name}`'s deleted their message" - ) - - content = f"```{message.content if message.content else ''}```" + guild = message.guild + # CHECKS + if message.bot == True: return; + log_channel_id = GuildData.get_value_default(guild, "chatlogs_channel_id", None) # Get chatlog ID in database + if log_channel_id is None: + log_channel = discord.utils.get(guild.text_channels, name="chatlogs"); # Try finding a channel called chatlogs + else: + log_channel = guild.get_channel(int(log_channel_id)) + if log_channel is None: + return + + embed = functions.create_embed("Message Deleted:", f"User `{message.author.display_name}`'s deleted their message") + + content = f"```{message.content if message.content else 'None'}```" embed.add_field(name="Message Content", value=content, inline=True) embed.add_field(name="Channel", value="```{}```".format(message.channel.name)) channel = discord.utils.get(message.guild.text_channels, name="chatlogs") # Convert attachments to file files = await convert_to_file(message.attachments) - await channel.send(embed=embed, files=files) @client.event async def on_message_edit(before: discord.Message, after: discord.Message): - embed = functions.create_embed( - "Message Edited", - f"User `{before.author.display_name}` edited their message" - ) + guild = before.guild; + log_channel_id = GuildData.get_value_default(guild, "chatlogs_channel_id", None) # Get chatlog ID in database + if log_channel_id is None: + log_channel = discord.utils.get(guild.text_channels, name="chatlogs"); # Try finding a channel called chatlogs + else: + log_channel = guild.get_channel(int(log_channel_id)) + if log_channel is None: + return - # Needed or the embed messes up - bf = f"```{before.content if before.content else 'None'}```" - af = f"```{after.content if after.content else 'None'}```" + embed = functions.create_embed("Message Edited", f"User `{before.author.display_name}` edited their message") - embed.add_field(name="Before", value=bf, inline=True) - embed.add_field(name="After", value=af, inline=True) - embed.add_field(name="Channel", value=f"```{before.channel.name}`guilds``") - channel = discord.utils.get(before.guild.text_channels, name="chatlogs") + before_message = f"```{before.content if before.content else 'None'}```" + after_message = f"```{after.content if after.content else 'None'}```" - # Convert attachments to file - files = await convert_to_file(before.attachments) + embed.add_field(name="Before", value=before_message, inline=True) + embed.add_field(name="After", value=after_message, inline=True) + embed.add_field(name="Channel", value=f"`{before.channel.name}`") - await channel.send(embed=embed, files=files) + files = await convert_to_file(before.attachments) + await log_channel.send(embed=embed, files=files) # Add it to the guilds event diff --git a/modules/data_handler.py b/modules/data_handler.py index c0adade..a46b9cd 100644 --- a/modules/data_handler.py +++ b/modules/data_handler.py @@ -12,6 +12,7 @@ "stats_channel_id": 0, "stats_message_id": 0, "fact_channel_id": 0, + "chatlogs_channel_id": 0, "prefix": "!" } @@ -28,6 +29,10 @@ # for key, value in snap: # print(f"{key} : {pickle.loads(value)}\n") +# Exceptions +class GuildDataNotFound: + pass + class UserData: def get_user_data(user_id: str) -> dict: @@ -48,7 +53,7 @@ def get_guild_data(guild_obj: discord.Guild) -> dict: str_id = str(guild_obj.id).encode() # Convert guild id to bytes if (local_data := guild_data.get(str_id, default=None)) is not None: return pickle.loads(local_data) - else: return None + else: raise GuildDataNotFound def initialize_guild(guild_obj: discord.Guild): str_id = str(guild_obj.id); @@ -71,13 +76,14 @@ def edit_guild_settings(guild_obj: discord.Guild, edit_info: dict) -> bool: str_id = str(guild_obj.id) local_data = GuildData.get_guild_data(guild_obj) - if local_data is None: return 0; # Invalid Data + if local_data is None: + raise GuildDataNotFound; # Invalid Data for key, value in edit_info.items(): # Type check things if key in valid_guild_keys: local_data[key] = value; else: - return 0; + return 0; # Failure # Set values for guild roles_dict[local_data["roles_message_id"]] = str_id # Link Back to Guild @@ -85,7 +91,21 @@ def edit_guild_settings(guild_obj: discord.Guild, edit_info: dict) -> bool: serialized_value = pickle.dumps(local_data) # Serialize Dictionary guild_data.put(str_id.encode(), serialized_value) # Put value in database - return 1; + return 1; # Return Success + + def get_value(guild_obj: discord.Guild, key: str): + if (local_data := GuildData.get_guild_data(guild_obj)) is not None: + if key in valid_guild_keys.keys() and (local_data.get(key, None) is None): # If Key does not exist, set the key + local_data[key] = valid_guild_keys[key] + return local_data[key]; + raise GuildDataNotFound; + + def get_value_default(guild_obj: discord.Guild, key: str, default_value): + if (local_data := GuildData.get_guild_data(guild_obj)) is not None: + if key in valid_guild_keys.keys(): + return local_data.get(key, default_value); + return default_value; # Invalid Key + raise GuildDataNotFound def get_valid_keys(): return valid_guild_keys;