async def untrackword(self, ctx, *, word: str): Data.check_guild_entry(ctx.guild) guild_id = ctx.guild.id word = word.strip() Data.c.execute( "SELECT tracked_words FROM guilds WHERE id = :guild_id", {"guild_id": ctx.guild.id}, ) self.tracked_words[guild_id] = json.loads(Data.c.fetchone()[0]) try: del self.tracked_words[guild_id][word] except KeyError: await ctx.send("This word was never being tracked...") return Data.c.execute( "UPDATE guilds SET tracked_words = :new_words WHERE id = :guild_id", { "new_words": json.dumps(self.tracked_words[guild_id]), "guild_id": ctx.guild.id, }, ) Data.conn.commit() await ctx.send(f"The word **{word}** is no longer being tracked!")
async def warn(self, ctx: commands.Context, member: discord.Member, *, reason: str): if ctx.author.top_role <= member.top_role: await ctx.send( f"You cannot use the command on this person because their top role is higher than or equal to yours." ) return Data.check_guild_entry(ctx.guild) Data.c.execute( "SELECT infractions FROM guilds WHERE id = :guild_id", {"guild_id": ctx.guild.id}, ) guild_infractions: list = json.loads(Data.c.fetchone()[0]) new_infraction = {"member": member.id, "reason": reason} guild_infractions.append(new_infraction) Data.c.execute( "UPDATE guilds SET infractions = :new_infractions WHERE id = :guild_id", { "new_infractions": json.dumps(guild_infractions), "guild_id": ctx.guild.id, }, ) Data.conn.commit() await ctx.send(f"**{member}** has been warned because: *{reason}*")
async def on_message(self, message): if message.author == self.bot.user: return guild_id = message.guild.id Data.check_guild_entry(message.guild) try: for word in self.tracked_words[guild_id]: if word in message.content: self.tracked_words[guild_id][ word ] += message.content.count(word) Data.c.execute( "UPDATE guilds SET tracked_words = :new_words WHERE id = :guild_id", { "new_words": json.dumps( self.tracked_words[guild_id] ), "guild_id": guild_id, }, ) Data.conn.commit() except KeyError: self.tracked_words[guild_id] = {}
async def trackword(self, ctx, *, word: str): Data.check_guild_entry(ctx.guild) guild_id = ctx.guild.id word = word.strip() Data.c.execute( "SELECT tracked_words FROM guilds WHERE id = :guild_id", {"guild_id": ctx.guild.id}, ) self.tracked_words[guild_id] = json.loads(Data.c.fetchone()[0]) if word in self.tracked_words[guild_id]: await ctx.send(f"The word **{word}** is already being tracked!") return self.tracked_words[guild_id][word] = -1 Data.c.execute( "UPDATE guilds SET tracked_words = :new_words WHERE id = :guild_id", { "new_words": json.dumps(self.tracked_words[guild_id]), "guild_id": ctx.guild.id, }, ) Data.conn.commit() await ctx.send(f"The word **{word}** is now being tracked!")
async def remove_auto_response(self, ctx: commands.Context, *, activation: str = None): Data.check_guild_entry(ctx.guild) if activation: Data.c.execute( "SELECT auto_responses FROM guilds WHERE id = :guild_id", {"guild_id": ctx.guild.id}, ) current_auto_resps = json.loads(Data.c.fetchone()[0]) if activation not in current_auto_resps: await ctx.send( "An auto response with this activation phrase does not exist" ) return del current_auto_resps[activation] Data.c.execute( "UPDATE guilds SET auto_responses = :new_responses WHERE id = :guild_id", { "new_responses": json.dumps(current_auto_resps), "guild_id": ctx.guild.id, }, ) Data.conn.commit() await ctx.send( f"Auto response with activation:```{activation}```has been removed" ) else: def check_msg(message: discord.Message): return (message.author == ctx.author and message.channel == ctx.channel) await ctx.send( "You are about to delete all auto responses in this server. Do you want to continue? (Yes to continue, anything else to abort)" ) try: confirmation: discord.Message = await self.bot.wait_for( "message", check=check_msg, timeout=30) if confirmation.content.lower() == "yes": Data.c.execute( "UPDATE guilds SET auto_responses = '{}' WHERE id = :guild_id", {"guild_id": ctx.guild.id}, ) Data.conn.commit() await ctx.send( "All auto responses in this server have been deleted") else: await ctx.send("Aborting!") except asyncio.TimeoutError: await ctx.send("No response received, aborting!")
async def on_member_remove(self, member: discord.Member): guild: discord.Guild = member.guild Data.check_guild_entry(guild) Data.c.execute( """SELECT leave_message, leave_channel FROM guilds WHERE id = :guild_id""", {"guild_id": guild.id}, ) data = Data.c.fetchone() leave_message = data[0] leave_channel_id = data[1] if leave_channel_id == "disabled": return if not leave_channel_id: leave_channel = await self.find_leave_channel(guild) # Exit the function if no leave channel is provided or # automatically found if not leave_channel: return else: leave_channel = guild.get_channel(int(leave_channel_id)) if not leave_message: leave_message = self.default_leave_msg(guild) # Replace placeholders with actual information leave_message = leave_message.replace("[mention]", member.mention) leave_message = leave_message.replace("[member]", str(member)) await leave_channel.send(leave_message)
async def set_mute_role(self, ctx: commands.Context, role: discord.Role): Data.check_guild_entry(ctx.guild) Data.c.execute( "UPDATE guilds SET mute_role = :mute_role_id WHERE id = :guild_id", {"mute_role_id": role.id, "guild_id": ctx.guild.id}, ) Data.conn.commit() await ctx.send(f"The mute role has been set to **{role}**")
async def prefix(self, ctx: commands.Context, pref: str = "s!"): Data.check_guild_entry(ctx.guild) Data.c.execute( "UPDATE guilds SET prefix = :new_prefix WHERE id = :guild_id", {"new_prefix": pref, "guild_id": ctx.guild.id}, ) Data.conn.commit() await ctx.send(f"The prefix has been changed to **{pref}**")
async def add_auto_response(self, ctx: commands.Context, *, options: str): options_split = options.split(",", maxsplit=1) if len(options_split) < 2: await ctx.send("Please provide all the fields.") return Data.check_guild_entry(ctx.guild) activation = options_split[0].strip() response = options_split[1].strip() Data.c.execute( "SELECT auto_responses FROM guilds WHERE id = :guild_id", {"guild_id": ctx.guild.id}, ) current_auto_resps = json.loads(Data.c.fetchone()[0]) if activation in current_auto_resps: def check_msg(message: discord.Message): return (message.author == ctx.author and message.channel == ctx.channel) await ctx.send( "An auto response with this activation already exists and will be overwritten by the new one. Do you want to continue? (Yes to continue, anything else to abort)" ) try: confirmation: discord.Message = await self.bot.wait_for( "message", check=check_msg, timeout=30) if confirmation.content.lower() == "yes": await ctx.send("Overwriting existing auto response!") else: await ctx.send("Aborting!") return except asyncio.TimeoutError: await ctx.send("No response received, aborting!") return current_auto_resps[activation] = response Data.c.execute( "UPDATE guilds SET auto_responses = :new_responses WHERE id = :guild_id", { "new_responses": json.dumps(current_auto_resps), "guild_id": ctx.guild.id, }, ) Data.conn.commit() await ctx.send( f"New auto response added with\n\nActivation Phrase:```{activation}```\nResponse:```{response}```" )
def get_prefix(client, message): if not message.guild: return "sb!" Data.check_guild_entry(message.guild) Data.c.execute( "SELECT prefix FROM guilds WHERE id = :guild_id", {"guild_id": message.guild.id}, ) prefix = Data.c.fetchone()[0] return prefix
async def on_message(self, message: discord.Message): if not message.guild or message.author.bot: return def spam_check(msg): return ((msg.author == message.author) and len(msg.mentions) and ( (datetime.datetime.utcnow() - msg.created_at).seconds < 20)) Data.check_guild_entry(message.guild) Data.c.execute( "SELECT activated_automod FROM guilds WHERE id = :guild_id", {"guild_id": message.guild.id}, ) activated_features = json.loads(Data.c.fetchone()[0]) # if channel id's data contains "links": if "links" in activated_features: if search(self.url_regex, message.content): await message.delete() await message.channel.send( f"{message.author.mention}, You cannot send links " "in this channel!", delete_after=3, ) # if channel id's data contains "images" if "images" in activated_features: if any([hasattr(a, "width") for a in message.attachments]): await message.delete() await message.channel.send( f"{message.author.mention}, You cannot send images " "in this channel!", delete_after=3, ) # if channel id's data contains "spam": if "spam" in activated_features: if (len( list( filter(lambda m: spam_check(m), self.bot.cached_messages))) >= 5): await message.channel.send( f"{message.author.mention}, Do not spam mentions " "in this channel!", delete_after=3, )
async def on_member_join(self, member: discord.Member): guild: discord.Guild = member.guild Data.check_guild_entry(guild) Data.c.execute( """SELECT welcome_message, welcome_channel, auto_role FROM guilds WHERE id = :guild_id""", {"guild_id": guild.id}, ) data = Data.c.fetchone() welcome_message = data[0] welcome_channel_id = data[1] if welcome_channel_id == "disabled": return if not welcome_channel_id: welcome_channel = await self.find_welcome_channel(guild) # Exit the function if no welcome channel is provided or # automatically found if not welcome_channel: return else: welcome_channel = guild.get_channel(int(welcome_channel_id)) if data[2]: auto_role = guild.get_role(int(data[2])) else: auto_role = None if not welcome_message: welcome_message = self.default_welcome_msg(guild) # Replace placeholders with actual information welcome_message = welcome_message.replace("[mention]", member.mention) welcome_message = welcome_message.replace("[member]", str(member)) await welcome_channel.send(welcome_message) # Give auto role to new member if they are not a bot if not member.bot and auto_role: await member.add_roles(auto_role)
async def set_leave_message( self, ctx: commands.Context, *, message: str = None ): Data.check_guild_entry(ctx.guild) Data.c.execute( "UPDATE guilds SET leave_message = :new_message WHERE id = :guild_id", {"new_message": message, "guild_id": ctx.guild.id}, ) Data.conn.commit() if message: await ctx.send( f"This server's leave message has been set to:\n{message}" ) else: await ctx.send( "This server's leave message has been reset to default" )
async def get_guild_mute_role(self, guild: discord.Guild): Data.check_guild_entry(guild) Data.c.execute( "SELECT mute_role FROM guilds WHERE id = :guild_id", {"guild_id": guild.id}, ) mute_role_id = Data.c.fetchone()[0] if mute_role_id is None: # Create mute role if none is provided mute_role = await self.create_mute_role(guild) else: # Get mute role if one was provided mute_role = guild.get_role(mute_role_id) # Check if the role provided still exists if mute_role is None: mute_role = await self.create_mute_role(guild) return mute_role
async def viewwordcount(self, ctx, *, word: str): Data.check_guild_entry(ctx.guild) guild_id = ctx.guild.id word = word.strip() Data.c.execute( "SELECT tracked_words FROM guilds WHERE id = :guild_id", {"guild_id": ctx.guild.id}, ) self.tracked_words[guild_id] = json.loads(Data.c.fetchone()[0]) try: word_count = self.tracked_words[guild_id][word] except KeyError: await ctx.send("This word is not being tracked...") return await ctx.send( f"The word **{word}** has been said **{word_count} times**!" )
async def set_welcome_channel( self, ctx: commands.Context, *, channel: discord.TextChannel = None ): Data.check_guild_entry(ctx.guild) if channel: channel_id = channel.id else: channel_id = "disabled" Data.c.execute( "UPDATE guilds SET welcome_channel = :channel_id WHERE id = :guild_id", {"channel_id": channel_id, "guild_id": ctx.guild.id}, ) Data.conn.commit() if channel: await ctx.send( f"The server's welcome channel has been set to {channel.mention}" ) else: await ctx.send("The server's welcome message has been disabled")
async def clear_infractions(self, ctx: commands.Context, member: discord.Member = None): if ctx.author.top_role <= member.top_role: await ctx.send( f"You cannot use the command on this person because their top role is higher than or equal to yours." ) return Data.check_guild_entry(ctx.guild) if member is None: Data.c.execute( "UPDATE guilds SET infractions = '[]' WHERE id = :guild_id", {"guild_id": ctx.guild.id}, ) Data.conn.commit() await ctx.send("Cleared all infractions in this server...") else: Data.c.execute( "SELECT infractions FROM guilds WHERE id = :guild_id", {"guild_id": ctx.guild.id}, ) user_infractions = json.loads(Data.c.fetchone()[0]) new_infractions = [ inf for inf in user_infractions if inf["member"] != member.id ] Data.c.execute( "UPDATE guilds SET infractions = :new_infractions WHERE id = :guild_id", { "new_infractions": json.dumps(new_infractions), "guild_id": ctx.guild.id, }, ) Data.conn.commit() await ctx.send( f"Cleared all infractions by **{member}** in this server...")
async def view_auto_responses(self, ctx: commands.Context): Data.check_guild_entry(ctx.guild) Data.c.execute( "SELECT auto_responses FROM guilds WHERE id = :guild_id", {"guild_id": ctx.guild.id}, ) auto_resps = json.loads(Data.c.fetchone()[0]) if len(auto_resps) > 0: auto_resps_embed = discord.Embed( title=f"Auto Responses in {ctx.guild}", color=self.theme_color) for activation in auto_resps: response = auto_resps[activation] auto_resps_embed.add_field(name=activation, value=response, inline=False) await ctx.send(embed=auto_resps_embed) else: await ctx.send("This server does not have any auto responses")
async def viewtrackedwords(self, ctx): Data.check_guild_entry(ctx.guild) guild_id = ctx.guild.id Data.c.execute( "SELECT tracked_words FROM guilds WHERE id = :guild_id", {"guild_id": ctx.guild.id}, ) self.tracked_words[guild_id] = json.loads(Data.c.fetchone()[0]) if len(self.tracked_words[guild_id]) > 0: await ctx.send("These are the words currently being tracked:") words_string = "\n".join( [ f"**{i+1}) {word}**: {self.tracked_words[guild_id][word]}" for (i, word) in enumerate(self.tracked_words[guild_id]) ] ) await ctx.send(words_string) else: await ctx.send( "There aren't any words being tracked on this server..." )
async def infractions(self, ctx: commands.Context, member: discord.Member = None): Data.check_guild_entry(ctx.guild) Data.c.execute( "SELECT infractions FROM guilds WHERE id = :guild_id", {"guild_id": ctx.guild.id}, ) if member is None: infracs = json.loads(Data.c.fetchone()[0]) embed_title = f"All Infractions in {ctx.guild.name}" else: infracs = [ infrac for infrac in json.loads(Data.c.fetchone()[0]) if infrac["member"] == member.id ] embed_title = f"Infractions by {member} in {ctx.guild.name}" infractions_embed = discord.Embed(title=embed_title, color=self.theme_color) for infrac in infracs: if member: guild_member = member else: guild_member = ctx.guild.get_member(infrac["member"]) reason = infrac["reason"] infractions_embed.add_field( name=str(guild_member), value=f"Reason: *{reason}*", inline=False, ) await ctx.send(embed=infractions_embed)
async def automod(self, ctx): Data.check_guild_entry(ctx.guild) available_features = ["links", "images", "spam"] Data.c.execute( "SELECT activated_automod FROM guilds WHERE id = :guild_id", {"guild_id": ctx.guild.id}, ) activated_features = json.loads(Data.c.fetchone()[0]) def check(message: discord.Message): return (message.channel == ctx.channel and message.author == ctx.message.author) def save(): Data.c.execute( "UPDATE guilds SET activated_automod = :new_features WHERE id = :guild_id", { "new_features": json.dumps(activated_features), "guild_id": ctx.guild.id, }, ) Data.conn.commit() mod_embed = discord.Embed( title="Auto-Mod", description=("Allow Sparta to administrate on its own. " "Reply with a particular feature."), color=self.theme_color, ) mod_embed.add_field( name="`links`", value="Bans links from being sent to this server", inline=False, ) mod_embed.add_field( name="`images`", value="Bans attachments from being sent to this server", inline=False, ) mod_embed.add_field( name="`spam`", value= "Temporarily mutes users who are spamming mentions in this server", inline=False, ) mod_embed.set_footer( text=("Reply with stop if you want to stop " "adding auto-mod features and save your changes")) await ctx.send(embed=mod_embed) while True: msg = await self.bot.wait_for("message", check=check) msg = str(msg.content) if msg.lower() in available_features: if msg.lower() in activated_features: await ctx.send(f"Removed `{msg}`!") activated_features.remove(msg) else: await ctx.send(f"Added `{msg}`!") activated_features.append(msg) if len(activated_features) == len(available_features): await ctx.send( "You have activated all the features. Changes " "have been saved!") save() break elif msg == "stop": await ctx.send("The changes have been saved!") save() break else: await ctx.send("Not a valid response!")