async def newrole(self, ctx, roleToAdd): logger.info("[RoleCommands newrole()] " + str(ctx.message.author) + " called newrole with following argument: roleToAdd=" + roleToAdd) roleToAdd = roleToAdd.lower() guild = ctx.guild for role in guild.roles: if role.name == roleToAdd: eObj = embed(author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description="Role '" + roleToAdd + "' exists. Calling .iam " + roleToAdd + " will add you to it.") await ctx.send(embed=eObj) logger.info("[RoleCommands newrole()] " + roleToAdd + " already exists") return role = await guild.create_role(name=roleToAdd) await role.edit(mentionable=True) logger.info("[RoleCommands newrole()] " + str(roleToAdd) + " created and is set to mentionable") eObj = embed(author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description="You have successfully created role **`" + roleToAdd + "`**.\nCalling `.iam " + roleToAdd + "` will add it to you.") await ctx.send(embed=eObj)
async def deleterole(self, ctx, roleToDelete): logger.info("[RoleCommands deleterole()] " + str(ctx.message.author) + " called deleterole with role " + str(roleToDelete) + ".") roleToDelete = roleToDelete.lower() role = discord.utils.get(ctx.guild.roles, name=roleToDelete) if role == None: logger.info( "[RoleCommands deleterole()] role that user wants to delete doesnt seem to exist." ) eObj = embed(author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description="Role **`" + roleToDelete + "`** does not exist.") await ctx.send(embed=eObj) return membersOfRole = role.members if not membersOfRole: deleteRole = await role.delete() logger.info( "[RoleCommands deleterole()] no members were detected, role has been deleted." ) eObj = embed(author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description="Role **`" + roleToDelete + "`** deleted.") await ctx.send(embed=eObj) else: logger.info( "[RoleCommands deleterole()] members were detected, role can't be deleted." ) eObj = embed(author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description="Role **`" + roleToDelete + "`** has members. Cannot delete.") await ctx.send(embed=eObj)
async def deletereminder(self, ctx, messageId): logger.info( "[Reminders deletereminder()] deletereminder command detected from user " + str(ctx.message.author)) try: if self.curs is not None: sqlCommand = "SELECT * FROM Reminders WHERE message_id = '" + str( messageId) + "';" self.curs.execute(sqlCommand) result = self.curs.fetchone() print("result=" + str(result)) if result is None: eObj = embed( title='Delete Reminder', author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description= "ERROR\nSpecified reminder could not be found") await ctx.send(embed=eObj) logger.info( "[Reminders deletereminder()] Specified reminder could not be found " ) else: if str(result[4]) == str(ctx.message.author): ##check to make sure its the right author sqlCommand = "DELETE FROM Reminders WHERE message_id = '" + str( messageId) + "';" self.curs.execute(sqlCommand) logger.info( "[Reminders deletereminder()] following reminder was deleted = " + str(result)) eObj = embed( title='Delete Reminder', author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description="Following reminder has been deleted:\n" + str(result[2])) await ctx.send(embed=eObj) else: eObj = embed( title='Delete Reminder', author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description= "ERROR\nYou are trying to delete a reminder that is not yours" ) await ctx.send(embed=eObj) logger.info( "[Reminders deletereminder()] It seems that " + str(ctx.message.author) + " was trying to delete " + str(result[4]) + "'s reminder.") except Exception as error: logger.error( '[Reminders.py showreminders()] Ignoring exception when generating reminder:' ) traceback.print_exception(type(error), error, error.__traceback__, file=sys.stderr)
async def showreminders(self, ctx): logger.info( "[Reminders showreminders()] remindme command detected from user " + str(ctx.message.author)) if self.curs is not None: try: reminders = '' sqlCommand = "SELECT * FROM Reminders WHERE author_id = '" + str( ctx.author.id) + "';" self.curs.execute(sqlCommand) logger.info( "[Reminders showreminders()] retrieved all reminders belonging to user " + str(ctx.message.author)) for row in self.curs.fetchall(): logger.info( "[Reminders showreminders()] dealing with reminder [" + str(row) + "]") reminders += str(row[5]) + "\t\t\t" + str(row[2]) + "\n" author = ctx.author.nick or ctx.author.name if reminders != '': logger.info( "[Reminders showreminders()] sent off the list of reminders to " + str(ctx.message.author)) eObj = embed(title="Here are you reminders " + author, author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, content=[[ "MessageID\t\t\t\t\t\t\tReminder", reminders ]]) await ctx.send(embed=eObj) else: logger.info("[Reminders showreminders()] " + str(ctx.message.author) + " didnt seem to have any reminders.") eObj = embed( author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description="You don't seem to have any reminders " + author) await ctx.send(embed=eObj) except Exception as error: eObj = embed( author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description= "Something screwy seems to have happened, look at the logs for more info." ) await ctx.send(embed=eObj) logger.error( '[Reminders.py showreminders()] Ignoring exception when generating reminder:' ) traceback.print_exception(type(error), error, error.__traceback__, file=sys.stderr)
async def urban(self, ctx, *arg): logger.info("[Misc urban()] urban command detected from user " + str(ctx.message.author) + " with argument =\"" + str(arg) + "\"") logger.info("[Misc urban()] query string being contructed") queryString = '' for x in arg: queryString += x + '%20' queryString = queryString[:len(queryString) - 3] url = 'http://api.urbandictionary.com/v0/define?term=%s' % queryString logger.info( "[Misc urban()] following url constructed for get request =\"" + str(url) + "\"") async with self.session.get(url) as res: data = '' if res.status == 200: logger.info("[Misc urban()] Get request successful") data = await res.json() else: logger.info("[Misc urban()] Get request failed resulted in " + str(res.status)) data = data['list'] if not data: logger.info( "[Misc urban()] sending message indicating 404 result") eObj = embed( title="Urban Results", author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, colour=0xfd6a02, description= ":thonk:404:thonk:You searched something dumb didn't you?") await ctx.send(embed=eObj) return else: logger.info( "[Misc urban()] constructing embed object with definition of \"" + queryString + "\"") urbanUrl = 'https://www.urbandictionary.com/define.php?term=%s' % queryString # truncate to fit in embed, field values must be 1024 or fewer in length definition = data[0]['definition'][:1021] + '...' if len( data[0]['definition']) > 1024 else data[0]['definition'] content = [['Definition', definition], ['Link', '[here](%s)' % urbanUrl]] eObj = embed(title='Results from Urban Dictionary', author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, colour=0xfd6a02, content=content) await ctx.send(embed=eObj)
async def urban(self, ctx, *arg): logger.info("[Misc urban()] urban command detected from user " + str(ctx.message.author) + " with argument =\"" + str(arg) + "\"") logger.info("[Misc urban()] query string being contructed") queryString = '' for x in arg: queryString += x + '%20' queryString = queryString[:len(queryString) - 3] url = 'http://api.urbandictionary.com/v0/define?term=%s' % queryString logger.info( "[Misc urban()] following url constructed for get request =\"" + str(url) + "\"") res = req.get(url) logger.info("[Misc urban()] Get request made =\"" + str(res) + "\"") if (res.status_code != 404): logger.info("[Misc urban()] Get request successful") data = res.json() else: logger.info("[Misc urban()] Get request failed, 404 resulted") data = '' data = data['list'] if not data: logger.info("[Misc urban()] sending message indicating 404 result") eObj = embed( title="Urban Results", author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, colour=0xfd6a02, description= ":thonk:404:thonk:You searched something dumb didn't you?") await ctx.send(embed=eObj) return else: logger.info( "[Misc urban()] constructing embed object with definition of \"" + queryString + "\"") urbanUrl = 'https://www.urbandictionary.com/define.php?term=%s' % queryString content = [['Definition', data[1]['definition']], ['Link', '[here](%s)' % urbanUrl]] eObj = embed(title='Results from Urban Dictionary', author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, colour=0xfd6a02, content=content) await ctx.send(embed=eObj)
async def ping(self, ctx): logger.info("[HealthChecks ping()] ping command detected from " + str(ctx.message.author)) eObj = embed(description='Pong!', author=settings.BOT_NAME, avatar=settings.BOT_AVATAR) await ctx.send(embed=eObj)
async def get_messages(self): await self.bot.wait_until_ready() while True: message = self.message_subscriber.get_message() if message is not None and message['type'] == 'message': try: cid_mid_dct = json.loads(message['data']) chan = self.bot.get_channel(cid_mid_dct['cid']) if chan is not None: msg = await chan.get_message(cid_mid_dct['mid']) ctx = await self.bot.get_context(msg) if ctx.valid and helper_files.testenv.TestCog.check_test_environment( ctx): fmt = '<@{0}>\n {1}' logger.info( '[Misc.py get_message()] sent off reminder to ' + str(ctx.message.author) + " about \"" + ctx.message.content + "\"") eObj = embed(author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description=fmt.format( ctx.message.author.id, ctx.message.content), footer='Reminder') await ctx.send(embed=eObj) except Exception as error: logger.error( '[Reminders.py get_message()] Ignoring exception when generating reminder:' ) traceback.print_exception(type(error), error, error.__traceback__, file=sys.stderr) await asyncio.sleep(2)
async def iamn(self, ctx, roleToRemove): logger.info("[RoleCommands iamn()] " + str(ctx.message.author) + " called iamn with role " + str(roleToRemove)) roleToRemove = roleToRemove.lower() role = discord.utils.get(ctx.guild.roles, name=roleToRemove) if role == None: logger.info("[RoleCommands iam()] role doesnt exist.") eObj = embed(author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description="Role **`" + roleToRemove + "`** doesn't exist.") await ctx.send(embed=eObj) return membersOfRole = role.members user = ctx.message.author if user in membersOfRole: await user.remove_roles(role) eObj = embed( author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description="You have successfully been removed from role **`" + roleToRemove + "`**.") await ctx.send(embed=eObj) logger.info("[RoleCommands iamn()] " + str(user) + " has been removed from role " + str(roleToRemove)) # delete role if last person membersOfRole = role.members if not membersOfRole: deleteRole = await role.delete() logger.info( "[RoleCommands deleterole()] no members were detected, role has been deleted." ) eObj = embed(author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description="Role **`" + role.name + "`** deleted.") await ctx.send(embed=eObj) else: eObj = embed( author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description= "Boop Beep??\n You don't have the role, so how am I gonna remove it????" ) await ctx.send(embed=eObj) logger.info("[RoleCommands iamn()] " + str(user) + " wasnt in the role " + str(roleToRemove))
async def echo(self, ctx, *args): user = ctx.author.display_name arg='' for argument in args: arg+=argument+' ' logger.info("[HealthChecks echo()] echo command detected from "+str(ctx.message.author)+" with argument "+str(arg)) avatar = ctx.author.avatar_url eObj = embed(author=user, avatar=avatar, description=arg) await ctx.send(embed=eObj)
async def iam(self, ctx, roleToAdd): logger.info("[RoleCommands iam()] " + str(ctx.message.author) + " called iam with role " + str(roleToAdd)) roleToAdd = roleToAdd.lower() role = discord.utils.get(ctx.guild.roles, name=roleToAdd) if role == None: logger.info("[RoleCommands iam()] role doesnt exist.") eObj = embed(author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description="Role **`" + roleToAdd + "**` doesn't exist.\nCalling .newrole " + roleToAdd) await ctx.send(embed=eObj) return user = ctx.message.author membersOfRole = role.members if user in membersOfRole: logger.info("[RoleCommands iam()] " + str(user) + " was already in the role " + str(roleToAdd) + ".") eObj = embed( author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description= "Beep Boop\n You've already got the role dude STAAAHP!!") await ctx.send(embed=eObj) else: await user.add_roles(role) logger.info("[RoleCommands iam()] user " + str(user) + " added to role " + str(roleToAdd) + ".") if (roleToAdd == 'froshee'): eObj = embed( author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description= "**WELCOME TO SFU!!!!**\nYou have successfully been added to role **`" + roleToAdd + "`**.") else: eObj = embed( author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description="You have successfully been added to role **`" + roleToAdd + "`**.") await ctx.send(embed=eObj)
async def wolfram(self, ctx, *arg): arg = " ".join(arg) logger.info("[Misc wolfram()] wolfram command detected from user " + str(ctx.message.author) + " with argument =\"" + str(arg) + "\"") logger.info("[Misc wolfram()] URL being contructed") commandURL = arg.replace("+", "%2B") commandURL = commandURL.replace("(", "%28") commandURL = commandURL.replace(")", "%29") commandURL = commandURL.replace("[", "%5B") commandURL = commandURL.replace("]", "%5D") commandURL = commandURL.replace(" ", "+") wolframURL = 'https://www.wolframalpha.com/input/?i=%s' % commandURL logger.info("[Misc wolfram()] querying WolframAlpha for %s" % arg) res = wolframClient.query(arg) try: content = [[ 'Results from Wolfram Alpha', "`" + next(res.results).text + "`" + "\n\n[Link](%s)" % wolframURL ]] eObj = embed(author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, colour=0xdd1100, content=content) await ctx.send(embed=eObj) logger.info("[Misc wolfram()] result found for %s" % arg) except (AttributeError, StopIteration): content = [ [ 'Results from Wolfram Alpha', "No results found. :thinking: \n\n[Link](%s)" % wolframURL ], ] eObj = embed(author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, colour=0xdd1100, content=content) await ctx.send(embed=eObj) logger.error("[Misc wolfram()] result NOT found for %s" % arg)
async def whois(self, ctx, roleToCheck): logger.info("[RoleCommands whois()] " + str(ctx.message.author) + " called whois with role " + str(roleToCheck)) memberString = "" logString = "" role = discord.utils.get(ctx.guild.roles, name=roleToCheck) if role == None: eObj = embed(author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description="**`" + roleToCheck + "`** does not exist.") await ctx.send(embed=eObj) logger.info("[RoleCommands whois()] role " + str(roleToCheck) + " doesnt exist") return membersOfRole = role.members if not membersOfRole: logger.info( "[RoleCommands whois()] there are no members in the role " + str(roleToCheck)) eObj = embed(author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description="No members in role **`" + roleToCheck + "`**.") await ctx.send(embed=eObj) return for members in membersOfRole: name = members.display_name memberString += name + "\n" logString += name + '\t' logger.info( "[RoleCommands whois()] following members were found in the role: " + str(logString)) eObj = embed(title="Members belonging to role: `" + roleToCheck + '`', author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description=memberString) await ctx.send(embed=eObj)
async def on_command_error(ctx, error): if helper_files.testenv.TestCog.check_test_environment(ctx): if isinstance(error, commands.MissingRequiredArgument): fmt = 'Missing argument: {0}' logger.error('[main.py on_command_error()] ' + fmt.format(error.param)) eObj = embed(author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description=fmt.format(error.param)) await ctx.send(embed=eObj) else: #only prints out an error to the log if the string that was entered doesnt contain just "." pattern = r'[^\.]' if re.search(pattern, str(error)[9:-14]): author = ctx.author.nick or ctx.author.name #await ctx.send('Error:\n```Sorry '+author+', seems like the command \"'+str(error)[9:-14]+'\"" doesn\'t exist :(```') traceback.print_exception(type(error), error, error.__traceback__, file=sys.stderr) return
async def get_messages(self): await self.bot.wait_until_ready() REMINDER_CHANNEL_ID = None ##determines the channel to send the reminder on try: if settings.ENVIRONMENT == 'PRODUCTION': logger.info("[Reminders get_messages()] environment is =[" + settings.ENVIRONMENT + "]") reminder_chan = discord.utils.get(self.bot.guilds[0].channels, name='bot_commands_and_misc') if reminder_chan is None: logger.info( "[Reminders get_messages()] reminder channel does not exist in PRODUCTION." ) reminder_chan = await self.bot.guilds[ 0].create_text_channel('bot_commands_and_misc') REMINDER_CHANNEL_ID = reminder_chan.id if REMINDER_CHANNEL_ID is None: logger.info( "[Reminders get_messages()] the channel designated for reminders [bot_commands_and_misc] in PRODUCTION does not exist and I was unable to create it, exiting now...." ) exit(1) logger.info( "[Reminders get_messages()] variable \"REMINDER_CHANNEL_ID\" is set to \"" + str(REMINDER_CHANNEL_ID) + "\"") else: logger.info( "[Reminders get_messages()] reminder channel exists in PRODUCTION and was detected." ) REMINDER_CHANNEL_ID = reminder_chan.id elif settings.ENVIRONMENT == 'TEST': logger.info("[Reminders get_messages()] branch is =[" + settings.BRANCH_NAME + "]") reminder_chan = discord.utils.get( self.bot.guilds[0].channels, name=settings.BRANCH_NAME.lower() + '_reminders') if reminder_chan is None: reminder_chan = await self.bot.guilds[ 0].create_text_channel(settings.BRANCH_NAME + '_reminders') REMINDER_CHANNEL_ID = reminder_chan.id if REMINDER_CHANNEL_ID is None: logger.info( "[Reminders get_messages()] the channel designated for reminders [" + settings.BRANCH_NAME + "_reminders] in " + str(settings.BRANCH_NAME) + " does not exist and I was unable to create it, exiting now...." ) exit(1) logger.info( "[Reminders get_messages()] variable \"REMINDER_CHANNEL_ID\" is set to \"" + str(REMINDER_CHANNEL_ID) + "\"") else: logger.info( "[Reminders get_messages()] reminder channel exists in " + str(settings.BRANCH_NAME) + " and was detected.") REMINDER_CHANNEL_ID = reminder_chan.id else: reminder_chan = discord.utils.get( self.bot.guilds[0].channels, name=settings.ENVIRONMENT.lower() + '_reminders') if reminder_chan is None: reminder_chan = await self.bot.guilds[ 0].create_text_channel('localhost_reminders') REMINDER_CHANNEL_ID = reminder_chan.id if REMINDER_CHANNEL_ID is None: logger.info( "[Reminders get_messages()] the channel designated for reminders [localhost_reminders] does not exist and I was unable to create it, exiting now...." ) exit(1) logger.info( "[Reminders get_messages()] variable \"REMINDER_CHANNEL_ID\" is set to \"" + str(REMINDER_CHANNEL_ID) + "\"") else: logger.info( "[Reminders get_messages()] reminder channel exists and was detected." ) REMINDER_CHANNEL_ID = reminder_chan.id except Exception as e: logger.error( "[Reminders get_messages()] enountered following exception when connecting to reminder channel\n{}" .format(e)) REMINDER_CHANNEL = self.bot.get_channel( REMINDER_CHANNEL_ID) # channel ID goes here while True: dt = datetime.datetime.now() try: self.curs.execute( "SELECT * FROM Reminders where reminder_date <= TIMESTAMP '" + str(dt) + "';") for row in self.curs.fetchall(): print(row) #fmt = '<@{0}>\n {1}' fmt = '{0}' reminder_message = row[2] author_id = row[3] logger.info( '[Misc.py get_message()] obtained the message of [' + str(reminder_message) + '] for author with id [' + str(author_id) + '] for REMINDER_CHANNEL [' + str(REMINDER_CHANNEL_ID) + ']') reminder_channel = self.bot.get_channel( int(REMINDER_CHANNEL_ID)) logger.info( '[Misc.py get_message()] sent off reminder to ' + str(author_id) + " about \"" + reminder_message + "\"") eObj = embed(author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description="This is your reminder to " + reminder_message, footer='Reminder') self.curs.execute( "DELETE FROM Reminders WHERE reminder_id = " + str(row[0]) + ";") await reminder_channel.send('<@' + author_id + '>', embed=eObj) except Exception as error: logger.error( '[Reminders.py get_message()] Ignoring exception when generating reminder:' ) traceback.print_exception(type(error), error, error.__traceback__, file=sys.stderr) await asyncio.sleep(2)
async def remindmein(self, ctx, *args): logger.info( "[Reminders remindme()] remindme command detected from user " + str(ctx.message.author)) parsedTime = '' message = '' parseTime = True for index, value in enumerate(args): if parseTime == True: if value == 'to': parseTime = False else: parsedTime += str(value) + " " else: message += str(value) + " " how_to_call_command = "\nPlease call command like so:\nremindmein <time|minutes|hours|days> to <what to remind you about>\nExample: \".remindmein 10 minutes to turn in my assignment\"" if parsedTime == '': logger.info("[Reminders remindme()] was unable to extract a time") eObj = embed(title='RemindMeIn Error', author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description="unable to extract a time" + str(how_to_call_command)) await ctx.send(embed=eObj) return if message == '': logger.info( "[Reminders remindme()] was unable to extract a message") eObj = embed(title='RemindMeIn Error', author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description="unable to extract a string" + str(how_to_call_command)) await ctx.send(embed=eObj) return timeUntil = str(parsedTime) logger.info("[Reminders remindme()] extracted time is " + str(timeUntil)) logger.info("[Reminders remindme()] extracted message is " + str(message)) time_struct, parse_status = parsedatetime.Calendar().parse(timeUntil) if parse_status == 0: logger.info("[Reminders remindme()] couldn't parse the time") eObj = embed(title='RemindMeIn Error', author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description="Could not parse time!" + how_to_call_command) await ctx.send(embed=eObj) return expire_seconds = int(mktime(time_struct) - time.time()) json_string = json.dumps({ 'cid': ctx.channel.id, 'mid': ctx.message.id }) r = self.r r.set(json_string, '', expire_seconds) fmt = 'Reminder set for {0} seconds from now' eObj = embed(author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description=fmt.format(expire_seconds)) await ctx.send(embed=eObj) logger.info( "[Reminders remindme()] reminder has been contructed and sent.")
async def poll(self, ctx, *questions): logger.info("[Misc poll()] poll command detected from user " + str(ctx.message.author)) name = ctx.author.display_name ava = ctx.author.avatar_url if len(questions) > 12: logger.info("[Misc poll()] was called with too many options.") eObj = embed( title='Poll Error', author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description= 'Please only submit a maximum of 11 options for a multi-option question.' ) await ctx.send(embed=eObj) return elif len(questions) == 1: logger.info("[Misc poll()] yes/no poll being constructed.") eObj = embed(title='Poll', author=name, avatar=ava, description=questions[0]) post = await ctx.send(embed=eObj) await post.add_reaction(u"\U0001F44D") await post.add_reaction(u"\U0001F44E") logger.info( "[Misc poll()] yes/no poll constructed and sent to server.") return if len(questions) == 2: logger.info("[Misc poll()] poll with only 2 arguments detected.") eObj = embed( title='Poll Error', author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description= 'Please submit at least 2 options for a multi-option question.' ) await ctx.send(embed=eObj) return elif len(questions) == 0: logger.info("[Misc poll()] poll with no arguments detected.") eObj = embed( title='Usage', author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description='.poll <Question> [Option A] [Option B] ...') await ctx.send(embed=eObj) return else: logger.info("[Misc poll()] multi-option poll being constructed.") questions = list(questions) optionString = "\n" numbersEmoji = [ ":zero:", ":one:", ":two:", ":three:", ":four:", ":five:", ":six:", ":seven:", ":eight:", ":nine:", ":keycap_ten:" ] numbersUnicode = [ u"0\u20e3", u"1\u20e3", u"2\u20e3", u"3\u20e3", u"4\u20e3", u"5\u20e3", u"6\u20e3", u"7\u20e3", u"8\u20e3", u"9\u20e3", u"\U0001F51F" ] question = questions.pop(0) options = 0 for m, n in zip(numbersEmoji, questions): optionString += m + ": " + n + "\n" options += 1 content = [['Options:', optionString]] eObj = embed(title='Poll:', author=name, avatar=ava, description=question, content=content) pollPost = await ctx.send(embed=eObj) logger.info( "[Misc poll()] multi-option poll message contructed and sent.") for i in range(0, options): await pollPost.add_reaction(numbersUnicode[i]) logger.info( "[Misc poll()] reactions added to multi-option poll message.")
async def deletereminder(self, ctx, messageId): logger.info( "[Reminders deletereminder()] deletereminder command detected from user " + str(ctx.message.author)) if self.r is not None: reminderExists = False try: reminder = '' logger.info( "[Reminders deletereminder()] iterating through all the keys in the database" ) for key in self.r.scan_iter("*"): keyValue = json.loads(key) logger.info("[Reminders deletereminder()] acquired key " + str(keyValue)) if keyValue['mid'] == int(messageId): reminderExists = True logger.info( "[Reminders deletereminder()] determined that it was the key the user wants to delete" ) chan = self.bot.get_channel(keyValue['cid']) if chan is not None: logger.info( "[Reminders deletereminder()] acquired valid channel " + str(chan)) msg = await chan.get_message(keyValue['mid']) logger.info( "[Reminders deletereminder()] acquired the messsage " + str(msg)) reminderCtx = await self.bot.get_context(msg) if reminderCtx.valid and helper_files.testenv.TestCog.check_test_environment( reminderCtx): if reminderCtx.message.author == ctx.message.author: logger.info( "[Reminders deletereminder()] determined that message did originate with " + str(ctx.message.author) + ", adding to list of reminders") reminder = reminderCtx.message.content logger.info( "[Reminders deletereminder()] following reminder was deleted = " + reminderCtx.message.content) eObj = embed( title='Delete Reminder', author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description= "Following reminder has been deleted:\n" + reminder) await ctx.send(embed=eObj) self.r.delete(key) else: eObj = embed( title='Delete Reminder', author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description= "ERROR\nYou are trying to delete a reminder that is not yours" ) await ctx.send(embed=eObj) logger.info( "[Reminders deletereminder()] It seems that " + str(ctx.message.author) + " was trying to delete " + str(reminderCtx.message.author) + "'s reminder.") if not reminderExists: eObj = embed( title='Delete Reminder', author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description= "ERROR\nSpecified reminder could not be found") await ctx.send(embed=eObj) logger.info( "[Reminders deletereminder()] Specified reminder could not be found " ) except Exception as error: logger.error( '[Reminders.py showreminders()] Ignoring exception when generating reminder:' ) traceback.print_exception(type(error), error, error.__traceback__, file=sys.stderr)
async def showreminders(self, ctx): logger.info( "[Reminders showreminders()] remindme command detected from user " + str(ctx.message.author)) if self.r is not None: try: reminders = '' logger.info( "[Reminders showreminders()] iterating through all the keys in the database" ) for key in self.r.scan_iter("*"): keyValue = json.loads(key) logger.info("[Reminders showreminders()] acquired key " + str(keyValue)) chan = self.bot.get_channel(keyValue['cid']) if chan is not None: logger.info( "[Reminders showreminders()] acquired valid channel " + str(chan)) msg = await chan.get_message(keyValue['mid']) logger.info( "[Reminders showreminders()] acquired the messsage " + str(msg)) reminderCtx = await self.bot.get_context(msg) if reminderCtx.valid and helper_files.testenv.TestCog.check_test_environment( reminderCtx): if reminderCtx.message.author == ctx.message.author: logger.info( "[Reminders showreminders()] determined that message did originate with " + str(ctx.message.author) + ", adding to list of reminders") reminders += str( keyValue['mid'] ) + "\t\t\t" + reminderCtx.message.content + "\n" author = ctx.author.nick or ctx.author.name if reminders != '': logger.info( "[Reminders showreminders()] sent off the list of reminders to " + str(ctx.message.author)) eObj = embed(title="Here are you reminders " + author, author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, content=[[ "MessageID\t\t\t\t\t\t\tReminder", reminders ]]) await ctx.send(embed=eObj) else: logger.info("[Reminders showreminders()] " + str(ctx.message.author) + " didnt seem to have any reminders.") eObj = embed( author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description="You don't seem to have any reminders " + author) await ctx.send(embed=eObj) except Exception as error: eObj = embed( author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description= "Something screwy seems to have happened, look at the logs for more info." ) await ctx.send(embed=eObj) logger.error( '[Reminders.py showreminders()] Ignoring exception when generating reminder:' ) traceback.print_exception(type(error), error, error.__traceback__, file=sys.stderr)
async def sfu(self, ctx, *course): logger.info('[SFU sfu()] sfu command detected from user ' + str(ctx.message.author)) logger.info('[SFU sfu()] arguments given: ' + str(course)) if (not course): eObj = embed(title='Missing Arguments', author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, colour=sfuRed, content=[['Usage', '`.sfu <arg>`'], ['Example', '`.sfu cmpt300`']], footer='SFU Error') await ctx.send(embed=eObj) logger.info('[SFU sfu()] missing arguments, command ended') return year = time.localtime()[0] term = time.localtime()[1] if (term <= 4): term = 'spring' elif (term >= 5 and term <= 8): term = 'summer' else: term = 'fall' # Check if arg needs to be manually split if (len(course) == 1): #split crs = re.findall('(\d*\D+)', course[0]) if (len(crs) < 2): crs = re.split('(\d+)', course[0]) if (len(crs) < 2): # Bad args eObj = embed(title='Bad Arguments', author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, colour=sfuRed, content=[['Usage', '`.sfu <arg>`'], ['Example', '`.sfu cmpt300`']], footer='SFU Error') await ctx.send(embed=eObj) logger.info('[SFU outline()] bad arguments, command ended') return courseCode = crs[0].lower() courseNum = crs[1] else: courseCode = course[0].lower() courseNum = course[1] url = 'http://www.sfu.ca/bin/wcm/academic-calendar?%s/%s/courses/%s/%s' % ( year, term, courseCode, courseNum) logger.info('[SFU sfu()] url for get request constructed: %s' % url) async with aiohttp.ClientSession() as req: res = await req.get(url) if (res.status == 200): logger.info('[SFU sfu()] get request successful') data = '' while True: chunk = await res.content.read(10) if not chunk: break data += str(chunk.decode()) data = json.loads(data) else: logger.info('[SFU sfu()] get resulted in ' + str(res.status)) eObj = embed( title='Results from SFU', author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, colour=sfuRed, description= 'Couldn\'t find anything for:\n%s/%s/%s/%s/\nMake sure you entered all the arguments correctly' % (year, term.upper(), courseCode.upper(), courseNum), footer='SFU Error') await ctx.send(embed=eObj) return logger.info('[SFU sfu()] parsing json data returned from get request') sfuUrl = 'http://www.sfu.ca/students/calendar/%s/%s/courses/%s/%s.html' % ( year, term, courseCode, courseNum) link = '[here](%s)' % sfuUrl footer = 'Written by VJ' fields = [[data['title'], data['description']], ["URL", link]] embedObj = embed(title='Results from SFU', author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, content=fields, colour=sfuRed, footer=footer) await ctx.send(embed=embedObj) logger.info('[SFU sfu()] out sent to server')
async def remindmein(self, ctx, *args): logger.info( "[Reminders remindmein()] remindme command detected from user " + str(ctx.message.author)) parsedTime = '' message = '' parseTime = True for index, value in enumerate(args): if parseTime == True: if value == 'to': parseTime = False else: parsedTime += str(value) + " " else: message += str(value) + " " how_to_call_command = "\nPlease call command like so:\nremindmein <time|minutes|hours|days> to <what to remind you about>\nExample: \".remindmein 10 minutes to turn in my assignment\"" if parsedTime == '': logger.info( "[Reminders remindmein()] was unable to extract a time") eObj = embed(title='RemindMeIn Error', author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description="unable to extract a time" + str(how_to_call_command)) await ctx.send(embed=eObj) return if message == '': logger.info( "[Reminders remindmein()] was unable to extract a message") eObj = embed(title='RemindMeIn Error', author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description="unable to extract a string" + str(how_to_call_command)) await ctx.send(embed=eObj) return timeUntil = str(parsedTime) logger.info("[Reminders remindmein()] extracted time is " + str(timeUntil)) logger.info("[Reminders remindmein()] extracted message is " + str(message)) time_struct, parse_status = parsedatetime.Calendar().parse(timeUntil) if parse_status == 0: logger.info("[Reminders remindmein()] couldn't parse the time") eObj = embed(title='RemindMeIn Error', author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description="Could not parse time!" + how_to_call_command) await ctx.send(embed=eObj) return expire_seconds = int(mktime(time_struct) - time.time()) dt = datetime.datetime.now() b = dt + datetime.timedelta( seconds=expire_seconds) # days, seconds, then other fields. sqlCommand = "INSERT INTO Reminders ( reminder_date, message, author_id, author_name, message_id) VALUES (TIMESTAMP '" + str( b) + "', '" + message + "', '" + str(ctx.author.id) + "', '" + str( ctx.message.author) + "', '" + str(ctx.message.id) + "');" logger.info("[Reminders remindme()] sqlCommand=[" + sqlCommand + "]") self.curs.execute(sqlCommand) fmt = 'Reminder set for {0} seconds from now' eObj = embed(author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description=fmt.format(expire_seconds)) await ctx.send(embed=eObj) logger.info( "[Reminders remindmein()] reminder has been contructed and sent.")
async def paginateEmbed(bot, ctx, descriptionToEmbed, title=" "): numOfPages = len(descriptionToEmbed) logger.info( "[Paginate paginateEmbed()] called with following argument: title=" + title + "\n\ndescriptionToEmbed=" + str(descriptionToEmbed) + "\n\n") currentPage = 0 firstRun = True msg = None while True: logger.info("[Paginate paginateEmbed()] loading page " + str(currentPage)) logger.info("[Paginate paginateEmbed()] loading roles " + str(descriptionToEmbed[currentPage])) embedObj = None embedObj = embed(title=title, author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, description=descriptionToEmbed[currentPage], footer='{}/{}'.format(str(currentPage + 1), str(numOfPages))) logger.info( "[Paginate paginateEmbed()] embed succesfully created and populated for page " + str(currentPage)) # determining which reactions are needed if numOfPages == 1: toReact = ['✅'] else: toReact = ['⏪', '⏩', '✅'] # setting the content if it was the first run through or not. if firstRun == True: firstRun = False msg = await ctx.send(content=None, embed=embedObj) logger.info("[Paginate paginateEmbed()] sent message") else: await msg.edit( embed=None ) #this is only here cause there seems to be a bug with editing embeds where it will still ##retain some traces of the former embed await msg.edit(embed=embedObj) await msg.clear_reactions() logger.info("[Paginate paginateEmbed()] edited message") # adding reactions deemed necessary to page for reaction in toReact: await msg.add_reaction(reaction) logger.info( "[Paginate paginateEmbed()] added all reactions to message") def checkReaction(reaction, user): if not user.bot: ##just making sure the bot doesnt take its own reactions ##into consideration e = str(reaction.emoji) logger.info("[Paginate paginateEmbed()] reaction " + e + " detected from " + str(user)) return e.startswith(('⏪', '⏩', '✅')) userReacted = False while userReacted == False: try: userReacted = await bot.wait_for('reaction_add', timeout=20, check=checkReaction) except asyncio.TimeoutError: logger.info( "[Paginate paginateEmbed()] timed out waiting for the user's reaction." ) if userReacted != False: if '⏪' == userReacted[0].emoji: prevPage = currentPage currentPage = currentPage - 1 if currentPage < 0: currentPage = numOfPages - 1 logger.info( "[Paginate paginateEmbed()] user indicates they want to go back a page from " + str(prevPage) + " to " + str(currentPage)) elif '⏩' == userReacted[0].emoji: prevPage = currentPage currentPage = currentPage + 1 if currentPage == numOfPages: currentPage = 0 logger.info( "[Paginate paginateEmbed()] user indicates they want to go forward a page from " + str(prevPage) + " to " + str(currentPage)) elif '✅' == userReacted[0].emoji: logger.info( "[Paginate paginateEmbed()] user indicates they are done with the roles command, deleting roles message" ) await msg.delete() return else: logger.info("[Paginate paginateEmbed()] deleting message") await msg.delete() return
async def outline(self, ctx, *course): logger.info('[SFU outline()] outline command detected from user ' + str(ctx.message.author)) logger.info('[SFU outline()] arguments given: ' + str(course)) usage = [ [ 'Usage', '`.outline <course> [<term> <section> next]`\n*<term>, <section>, and next are optional arguments*\nInclude the keyword `next` to look at the next semester\'s outline. Note: `next` is used for course registration purposes and if the next semester info isn\'t available it\'ll return an error.' ], [ 'Example', '`.outline cmpt300\n .outline cmpt300 fall\n .outline cmpt300 d200\n .outline cmpt300 spring d200\n .outline cmpt300 next`' ] ] if (not course): eObj = embed(title='Missing Arguments', author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, colour=sfuRed, content=usage, footer='SFU Outline Error') await ctx.send(embed=eObj) logger.info('[SFU outline()] missing arguments, command ended') return course = list(course) if 'next' in course: year = 'registration' term = 'registration' course.remove('next') else: year = 'current' term = 'current' courseCode = '' courseNum = '' section = '' logger.info('[SFU outline()] parsing args') argNum = len(course) if (argNum > 1 and course[1][:len(course[1]) - 1].isdigit()): # User gave course in two parts courseCode = course[0].lower() courseNum = course[1].lower() course = course[:1] + course[2:] argNum = len(course) else: # Split course[0] into parts crs = re.findall('(\d*\D+)', course[0]) if (len(crs) < 2): crs = re.split( '(\d+)', course[0] ) # this incase the course num doesnt end in a letter, need to split with different regex if (len(crs) < 2): # Bad args eObj = embed(title='Bad Arguments', author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, colour=sfuRed, content=usage, footer='SFU Outline Error') await ctx.send(embed=eObj) logger.info('[SFU outline()] bad arguments, command ended') return courseCode = crs[0].lower() courseNum = crs[1] # Course and term or section is specified if (argNum == 2): # Figure out if section or term was given temp = course[1].lower() if temp[3].isdigit(): section = temp elif term != 'registration': if (temp == 'fall'): term = temp elif (temp == 'summer'): term = temp elif (temp == 'spring'): term = temp # Course, term, and section is specified elif (argNum == 3): # Check if last arg is section if course[2][3].isdigit(): section = course[2].lower() if term != 'registration': if course[1] == 'fall' or course[1] == 'spring' or course[ 1] == 'summer': term = course[1].lower() else: # Send something saying be in this order logger.info('[SFU outline] args out of order or wrong') eObj = embed( title='Bad Arguments', author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, colour=sfuRed, description= 'Make sure your arguments are in the following order:\n<course> <term> <section>\nexample: `.outline cmpt300 fall d200`\n term and section are optional args', footer='SFU Outline Error') await ctx.send(embed=eObj) return # Set up url for get if section == '': # get req the section logger.info('[SFU outline()] getting section') res = await self.req.get( 'http://www.sfu.ca/bin/wcm/course-outlines?%s/%s/%s/%s' % (year, term, courseCode, courseNum)) if (res.status == 200): data = '' while not res.content.at_eof(): chunk = await res.content.readchunk() data += str(chunk[0].decode()) res = json.loads(data) logger.info('[SFU outline()] parsing section data') for x in res: if x['sectionCode'] in ['LEC', 'LAB', 'TUT', 'SEM']: section = x['value'] break else: logger.info('[SFU outline()] section get resulted in ' + str(res.status)) eObj = embed( title='SFU Course Outlines', author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, colour=sfuRed, description='Couldn\'t find anything for `' + courseCode.upper() + ' ' + str(courseNum).upper() + '`\n Maybe the course doesn\'t exist? Or isn\'t offerend right now.', footer='SFU Outline Error') await ctx.send(embed=eObj) return url = 'http://www.sfu.ca/bin/wcm/course-outlines?%s/%s/%s/%s/%s' % ( year, term, courseCode, courseNum, section) logger.info('[SFU outline()] url for get constructed: ' + url) res = await self.req.get(url) if (res.status == 200): logger.info('[SFU outline()] get request successful') data = '' while not res.content.at_eof(): chunk = await res.content.readchunk() data += str(chunk[0].decode()) data = json.loads(data) else: logger.info('[SFU outline()] full outline get resulted in ' + str(res.status)) eObj = embed( title='SFU Course Outlines', author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, colour=sfuRed, description='Couldn\'t find anything for `' + courseCode.upper() + ' ' + str(courseNum).upper() + '`\n Maybe the course doesn\'t exist? Or isn\'t offerend right now.', footer='SFU Outline Error') await ctx.send(embed=eObj) return logger.info('[SFU outline()] parsing data from get request') try: # Main course information info = data['info'] # Course schedule information schedule = data['courseSchedule'] except Exception: logger.info('[SFU outline()] info keys didn\'t exist') eObj = embed( title='SFU Course Outlines', author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, colour=sfuRed, description='Couldn\'t find anything for `' + courseCode.upper() + ' ' + str(courseNum).upper() + '`\n Maybe the course doesn\'t exist? Or isn\'t offerend right now.', footer='SFU Outline Error') await ctx.send(embed=eObj) return outline = info['outlinePath'].upper() title = info['title'] try: #instructor = data['instructor'][0]['name'] + '\n[' + data['instructor'][0]['email'] + ']' instructor = '' instructors = data['instructor'] for prof in instructors: instructor += prof['name'] instructor += ' [%s]\n' % prof['email'] except Exception: instructor = 'TBA' # Course schedule info parsing crs = '' for x in schedule: # [LEC] days time, room, campus secCode = '[' + x['sectionCode'] + ']' days = x['days'] tme = x['startTime'] + '-' + x['endTime'] room = x['buildingCode'] + ' ' + x['roomNumber'] campus = x['campus'] crs = crs + secCode + ' ' + days + ' ' + tme + ', ' + room + ', ' + campus + '\n' classTimes = crs # Exam info examTimes = 'TBA' roomInfo = '' tim = '' date = '' try: # Course might not have an exam tim = data['examSchedule'][0]['startTime'] + '-' + data[ 'examSchedule'][0]['endTime'] date = data['examSchedule'][0]['startDate'].split() date = date[0] + ' ' + date[1] + ' ' + date[2] examTimes = tim + ' ' + date # Room info much later roomInfo = data['examSchedule'][0]['buildingCode'] + ' ' + data[ 'schedule']['roomNumber'] + ', ' + data['examSchedule'][0][ 'campus'] examTimes += '\n' + roomInfo except Exception: pass # Other details # need to cap len for details description = data['info']['description'] try: details = html.unescape(data['info']['courseDetails']) details = re.sub('<[^<]+?>', '', details) if (len(details) > 200): details = details[:200] + '\n(...)' except Exception: details = 'None' try: prerequisites = data['info']['prerequisites'] or 'None' except Exception: prerequisites = 'None' try: corequisites = data['info']['corequisites'] except Exception: corequisites = '' url = 'http://www.sfu.ca/outlines.html?%s' % data['info']['outlinePath'] logger.info('[SFU outline()] finished parsing data for: %s' % data['info']['outlinePath']) # Make tuple of the data for the fields fields = [['Outline', outline], ['Title', title], ['Instructor', instructor], ['Class Times', classTimes], ['Exam Times', examTimes], ['Description', description], ['Details', details], ['Prerequisites', prerequisites]] if corequisites: fields.append(['Corequisites', corequisites]) fields.append(['URL', '[here](%s)' % url]) img = 'http://www.sfu.ca/content/sfu/clf/jcr:content/main_content/image_0.img.1280.high.jpg/1468454298527.jpg' eObj = embed(title='SFU Outline Results', author=settings.BOT_NAME, avatar=settings.BOT_AVATAR, colour=sfuRed, thumbnail=img, content=fields, footer='Written by VJ') await ctx.send(embed=eObj)