def load_cog(self, *cogs): """ Loads modules passed through cogs parameter """ for name in cogs: path = "modules." + name self.load_extension(path) log("Cog Loaded: {}".format(name)) self.private_cog = self.get_cog("Private")
async def shutdown(self, ctx): """ Shuts the bot down """ await self.bot.send_typing(ctx.message.channel) await self.bot.send_message(ctx.message.channel, "🌬️🕯️") log(">> Bot Shutdown Executed", True, type="warning") await self.bot.close()
async def markov_error(self, ctx, error): log(">> {} attempted to run c|markov, but failed: {}".format(ctx.message.author,error), True, type="error") if isinstance(error, commands.CommandOnCooldown): await self.bot.send_message(ctx.message.channel,"❌ | **{}**".format(error)) elif isinstance(error, commands.CheckFailure): pass else: log(type="trace") await self.bot.send_message(ctx.message.channel,"❌ | **Error! Proper Syntax:** `c|markov @user #channel` **(user and channel optional)**")
async def countdown_exists(self): """ Checks if the countdown message still exists """ try: await self.message.channel.fetch_message(self.message.id) return True except: log(">> Couldn't find countdown message, assuming it doesn't exist...", True, type="warning") return False
async def invite_on_error(self, ctx, error): log(">> An invite command was executed by {}, but it failed: {}". format(ctx.message.author, error), True, type="error") log(type="trace") await self.bot.send_message( ctx.message.channel, "❌ | **Invalid Syntax. Proper usage:** `c|invite \"title\" \"description\" user_limit bannerImg_url #000000` **(Title & Description are required, type \"None\" for all other variables you would like to exclude)**" )
async def countdown_on_error(self, ctx, error): log(">> {} executed a failed countdown: {}".format( ctx.message.author, error), True, type="error") log(type="trace") await self.bot.send_message( ctx.message.channel, "❌ | **Invalid Syntax. Proper usage:** `c|countdown \"title\" HH:MM:SS #000000 -m` **(-m: mention `@everyone` when complete, omit to disable)**" )
async def someone_error(self, ctx, error): log(">> Failed to run c|someone for {}: {}".format( ctx.message.author, error), True, type="error") if isinstance(error, commands.CommandOnCooldown): await self.bot.send_message(ctx.message.channel, "❌ | **{}**".format(error)) elif isinstance(error, commands.CheckFailure): pass
async def overlay_error(self, ctx, error): if isinstance(error, commands.CommandOnCooldown): await self.bot.send_message(ctx.message.channel, "❌ | **{}**".format(error)) else: log(">> overlay command error: {}".format(error), True, type="error") log(type="trace") await self.bot.send_message(ctx.message.channel, "🔍 | **Couldn't find image!**")
def create_db(self): """ Sets up the database that tracks usage frequency """ usage_db = sqlite3.connect(os.path.realpath('db/bot_usage.db')) try: # set up a table if one doesn't exist already c = usage_db.cursor() c.execute('''CREATE TABLE usage_data (month integer, day integer, hour integer, minute integer, weekday text)''' ) usage_db.commit() log(">> No usage data table found, generating a new one...", True, type="warning") usage_db.close() except: pass
def record_invoke(self): """ Records current date and time to database """ current = datetime.datetime.now() weekday = datetime.datetime.today().weekday() w = [ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" ] data = (current.month, current.day, current.hour, current.minute, w[weekday]) usage_db = sqlite3.connect(os.path.realpath('db/bot_usage.db')) c = usage_db.cursor() c.execute('INSERT INTO usage_data VALUES (?,?,?,?,?)', data) usage_db.commit() usage_db.close() log("Invoke has been logged as: {}".format(data), type="debug")
def __init__(self, bot): self.bot = bot # Setting up server groups database groups_db = sqlite3.connect(os.path.realpath('./db/groups.db')) # Set up a table if one doesn't exist already try: c = groups_db.cursor() c.execute('''CREATE TABLE active_groups (server_name text, server_id integer, role_name text, role_id integer)''' ) groups_db.commit() log(">> No groups data table found, generating a new one...", True, type="warning") groups_db.close() except: pass
async def reload(self, ctx, *categories): """ A command to reload Cogs / Modules """ if not categories: await self.bot.send_message( ctx.message.channel, "❌ | **Syntax error, please list a module!**") else: success = "" # tracking successful reloads for cog in categories: try: self.bot.reload_cog(cog) success += "`" + cog + "` " except commands.errors.ExtensionNotLoaded: log(">> Failed to reload cog: {}".format(cog), True, type="error") await self.bot.send_message( ctx.message.channel, "🔄 | **Reloaded the following modules: {}**".format(success))
async def cherrypick(self, ctx, mode, amount=10, *keywords): """ Selectively purges messages containing specific keywords. If the mode is an @ mention of a user, it'll delete messages made by the mentioned user. """ bot = self.bot channel = ctx.message.channel # Different checks for each mode def all_check(m): for keyword in keywords: if not (keyword in m.content): return False return True def any_check(m): for keyword in keywords: if keyword in m.content: return True def usr_check(m): if m.author.id == ctx.message.mentions[0].id and len(keywords) > 0: for keyword in keywords: if keyword in m.content: return True else: return m.author.id == ctx.message.mentions[0].id # no keywords given await bot.send_typing(channel) # Delete messages depending on user's preferences if mode == 'all': # message must have all the keywords await ctx.message.delete() deleted = await channel.purge(limit=amount, check=all_check) log(">> {} deleted {} messages with all these keywords: {}".format(ctx.message.author,len(deleted),keywords), True) elif mode == 'any': # message must have any of the keywords await ctx.message.delete() deleted = await channel.purge(limit=amount, check=any_check) log(">> {} deleted {} messages containing the keyword(s): {}".format(ctx.message.author,len(deleted),keywords), True) elif ctx.message.mentions and str(mode)[0:2] == '<@': # has to be by a certain user await ctx.message.delete() deleted = await channel.purge(limit=amount, check=usr_check) mentionee = ctx.message.mentions[0] log(">> {} deleted {} of {}#{}\'s messages.".format(ctx.message.author, len(deleted), mentionee.name, mentionee.discriminator), True) status = await channel.send("🍒 | **{} messages have been successfully deleted.**".format(len(deleted))) await status.delete(delay=5)
async def vrole_error(self, ctx, error): if isinstance(error, commands.MissingPermissions): await ctx.message.channel.send( "❌ | **Access Denied. {}**".format(error)) log("Denied {} access to c|group: {}".format( ctx.message.author, error), type="warning") else: log(">> A c|vrole command was executed, but it failed: {}".format( error), True, type="error") log(type="trace") await self.bot.send_message( ctx.message.channel, "❌ | **Invalid Syntax. Proper usage:** `c|vrole option` **(options: **`add`**, **`remove`**, **`request`**, **`revoke`**, **`list`**)**" )
async def cherrypick_error(self, ctx, error): if isinstance(error, commands.MissingPermissions): await self.bot.send_message(ctx.message.channel, "❌ | **You do not have permission to use that command!**") else: log(">> {} failed to execute c|cherrypick: {}".format(ctx.message.author,error), True, type="error") await self.bot.send_message(ctx.message.channel,"❌ | **Invalid Syntax. Proper usage:** `c|cherrypick keyword_mode message_limit keyword(s)`")
async def madlib_error(self, ctx, error): log(">> {} attempted to run c|madlib, but failed: {}".format(ctx.message.author,error), True, type="error") log(type="trace")
def usage_counter(ctx): self.record_invoke() log("Command invoked by {}, processing...".format( ctx.message.author)) return True
async def on_maintenance_error(self, ctx, error): log(error, True, type="error") await self.bot.send_message( ctx.message.channel, "❌ | **Error! Please check the console.**")
async def stack_error(self, ctx, error): log(">> c|stack: {}".format(error), type="error") await self.bot.send_message(ctx.message.channel,"❌ | **Please enter a valid search query!**")
async def leavegroup(self, ctx): bot = self.bot botperms = ctx.message.channel.permissions_for(ctx.message.guild.me) await self.update_groupsdb(ctx) def is_author(m): return (m.author == ctx.message.author) and (m.channel == ctx.message.channel) if botperms.manage_roles: # Connect to the database and get the data we need conn = sqlite3.connect(os.path.realpath('./db/groups.db')) c = conn.cursor() grouplist = await self.get_vroles_data(ctx, c) log(">> {}".format(grouplist)) rolelist = await self.list_guild_vanity_roles( ctx, c, "🗒️ | **Type the role numbers you would like to revoke, seperate numbers with a comma if removing more than one. Otherwise, type **`cancel`** to quit.**" ) try: msg = await bot.wait_for('message', check=is_author, timeout=45) except: await ctx.message.channel.send( "❌ | **Canceled** `c|vrole` **execution: {} took too long to respond.**" .format(ctx.message.author)) await rolelist.delete() conn.close() return # Checks user response, leaves groups if valid. if msg.clean_content.lower() == "cancel": await bot.send_message(ctx.message.channel, "**Canceled!**") await rolelist.delete() conn.close() else: try: nums = [ int(s) for s in msg.clean_content.split(',') ] # Converts string of numbers to a list of integers print(">> {} left the following groups:".format( ctx.message.author)) for n in nums: grouprole = discord.utils.get( ctx.message.guild.roles, id=int(grouplist[n])) # Finding the role by ID await ctx.message.author.remove_roles( grouprole, reason="c|vrole command invoke") print(" {}".format(grouprole)) await bot.send_message( ctx.message.channel, "🗒️ | **Successfully unassigned role(s)!**") except ValueError: log(">> {} tried unassigning vanity roles, but the command failed due to invalid arguments." .format(ctx.message.author), True, type="warning") await bot.send_message( ctx.message.channel, "❌ | **Error! That is not a valid response!**") finally: await rolelist.delete() conn.close() else: await bot.send_message( ctx.message.channel, "❌ | **Error! I do not have permission to manage roles!**")
async def removegroup(self, ctx): """ Deletes vanity roles for the server from the database """ bot = self.bot has_perm = ctx.message.author.guild_permissions await self.update_groupsdb(ctx) # Check if they have the right permissions if not (has_perm.manage_roles and has_perm.ban_members): raise commands.MissingPermissions(['manage_roles', 'ban_members']) def is_author(m): return (m.author == ctx.message.author) and (m.channel == ctx.message.channel) # Connect to the database and get the data we need conn = sqlite3.connect(os.path.realpath('./db/groups.db')) c = conn.cursor() grouplist = await self.get_vroles_data(ctx, c) log(">> Role ids for this server: {}".format(grouplist)) rolelist = await self.list_guild_vanity_roles( ctx, c, "🗒️ | **Type the role numbers you would like to remove, seperate numbers with a comma if removing more than one. Otherwise, type **`cancel`** to quit.**" ) try: msg = await bot.wait_for('message', check=is_author, timeout=45) except: await ctx.message.channel.send( "❌ | **Canceled** `c|vrole` **execution: {} took too long to respond.**" .format(ctx.message.author)) await rolelist.delete() conn.close() return # Checks user response, then removes groups from database if valid. if msg.clean_content.lower() == "cancel": await bot.send_message(ctx.message.channel, "**Canceled!**") await rolelist.delete() conn.close() else: try: nums = [int(s) for s in msg.clean_content.split(',') ] # Converts string of numbers to a list of integers print(">> {} removed groups:".format(ctx.message.author)) for n in nums: # Deletes one row at a time await bot.send_typing(ctx.message.channel) c.execute('DELETE FROM active_groups WHERE role_id=?', (grouplist[n], )) conn.commit() print(" {} | {}".format( discord.utils.get(ctx.message.guild.roles, id=int(grouplist[n])), grouplist[n])) await bot.send_message( ctx.message.channel, "🗒️ | **Successfully removed the selected vanity roles! Type **`c|vrole list`** to view them.**" ) except ValueError: log(">> {} tried removing vanity roles, but the command failed due to invalid arguments." .format(ctx.message.author), True, type="warning") await bot.send_message( ctx.message.channel, "❌ | **Error! That is not a valid response!**") finally: await rolelist.delete() conn.close()
async def addgroup(self, ctx): """ Adds new vanity roles for the server to the database """ bot = self.bot has_perm = ctx.message.author.guild_permissions # Check if they have the right permissions if not (has_perm.manage_roles and has_perm.ban_members): raise commands.MissingPermissions(['manage_roles', 'ban_members']) def is_author(m): return (m.author == ctx.message.author) and (m.channel == ctx.message.channel) # Prompt the user rolelist = await self.list_guild_roles( ctx, "🗒️ | **Type the role number(s) you would like to mark as vanity roles. Seperate numbers with a comma if there are multiple. Otherwise, type **`cancel`** to quit.**" ) try: msg = await bot.wait_for('message', check=is_author, timeout=60) except: await ctx.message.channel.send( "❌ | **Canceled** `c|vrole` **execution: {} took too long to respond.**" .format(ctx.message.author)) await rolelist.delete() return roles = list(ctx.message.guild.roles) # Checks user response, then saves groups to database if valid. if msg.clean_content.lower() == "cancel": await bot.send_message(ctx.message.channel, "**Canceled!**") await rolelist.delete() return else: conn = sqlite3.connect(os.path.realpath('./db/groups.db')) c = conn.cursor() try: nums = [int(s) for s in msg.clean_content.split(',') ] # Converts string of numbers to a list of integers print(">> {} created new group(s):".format(ctx.message.author)) # Using index numbers, we'll save information on selected roles to our database for n in nums: await bot.send_typing(ctx.message.channel) role_data = (ctx.message.guild.name, ctx.message.guild.id, roles[n].name, roles[n].id) # Check if role has been added already c.execute( 'SELECT role_id FROM active_groups WHERE role_id=?', (roles[n].id, )) if not c.fetchone( ): # If it doesn't exist, insert the group info as a new row c.execute('INSERT INTO active_groups VALUES (?,?,?,?)', role_data) conn.commit() print(" {}".format(roles[n])) else: print(" {} [ALREADY EXISTS]".format(roles[n].name)) await bot.send_message( ctx.message.channel, "🗒️ | **Successfully added the selected vanity roles! Type **`c|vrole list`** to view them.**" ) except ValueError: log(">> {} tried adding vanity roles, but the command failed due to invalid arguments." .format(ctx.message.author), True, type="warning") await bot.send_message( ctx.message.channel, "❌ | **Error! That is not a valid response!**") finally: await rolelist.delete() conn.close()