Esempio n. 1
0
 async def deletelink(self, ctx, *, args=None):
     # check to see if private channel exists, if not makes one
     if args is None:
         await ctx.send("Please use the syntax '!deletelink [COURSE/TOPIC]'"
                        )
         return
     # clean the args to prevent sql injection
     args = dbcon.sanitize(args)
     coursename = args
     c.execute(
         f"SELECT course, url, description FROM links WHERE course='{coursename}' COLLATE NOCASE;"
     )
     info = c.fetchall()
     if info is None:
         await ctx.send(f"No links for {coursename} found")
         return
     counter = 0
     embed = discord.Embed(title=coursename, color=0xf03413)
     for i in info:
         embed.add_field(name=f"{i[2]}", value=f"{i[1]}", inline=False)
         counter += 1
     embed.set_footer(text=f"Total links: {counter}")
     # there is a 6000 char limit to embeds
     if len(embed) > 5999:
         print(f'its over 6000! {coursename}')
     await ctx.send(embed=embed, content=None)
     await ctx.send("Please tell me the title of the link to delete:"
                    "\n**WARNING: CANNOT BE UNDONE**")
     link = await self.bot.wait_for(
         'message',
         check=lambda message: message.author == ctx.author,
         timeout=60.0)
     link = dbcon.sanitize(link.content)
     c.execute(
         f"SELECT description, course FROM links WHERE description='{link}' AND course='{coursename}' COLLATE NOCASE;"
     )
     verify = c.fetchone()
     if verify is None:
         await ctx.send("Link not found")
         return
     try:
         c.execute(
             f"DELETE FROM links WHERE course='{coursename}' COLLATE NOCASE AND description='{link}' COLLATE NOCASE;"
         )
         conn.commit()
     except sqlite3.Error as e:
         print(type(e).__name__)
     except:
         await ctx.send("Hmmm.... something went wrong")
         return
     print(f'{ctx.author} Deleted {link} from {coursename}')
     await ctx.author.dm_channel.send(f'"{link}" deleted')
     return
Esempio n. 2
0
 async def prof_quote(self, ctx, *, args=None):
     if args is None:
         c.execute('SELECT quote, prof FROM profquotes')
     else:
         dbcon.sanitize(args)
         c.execute(
             f"SELECT quote, prof FROM profquotes WHERE prof='{args}' COLLATE NOCASE;"
         )
     pq = c.fetchall()
     if len(pq) == 0:
         await ctx.send(f"No quote from {args} found :man_shrugging:")
     response = random.choice(pq)
     await ctx.send(str(response[0]) + " - " + str(response[1]))
Esempio n. 3
0
 async def makequiz(self, ctx, *, arg=None):
     # check to see if private channel exists, if not makes one
     if ctx.author.dm_channel is None:
         await ctx.author.create_dm()
     if arg is None:
         await ctx.send(
             "Please enter a name of the quiz\nEg: !makequiz Ken Trivia")
         return
     # clean the arg to prevent SQL injection
     arg = dbcon.sanitize(arg)
     quizname = str(arg)
     c.execute("SELECT name FROM quiz WHERE name='" + quizname + "';")
     q = c.fetchone()
     if q is not None:
         await ctx.send("A quiz by that name already exists")
         return
     try:
         sql = "INSERT INTO quiz (name, questions, madeby, score) VALUES (?, ?, ?, ?)"
         c.execute(sql, (quizname, 0, str(ctx.author), 100))
         conn.commit()
     except sqlite3.Error as e:
         print(type(e).__name__)
     except:
         await ctx.author.dm_channel.send(
             "Something went wrong adding the quiz\nQuizname: " + quizname +
             "\nauthor: " + str(ctx.author))
         return
     else:
         await ctx.author.dm_channel.send("Quiz created. Type '!addq " +
                                          quizname +
                                          "' to add questions to this quiz")
     return
Esempio n. 4
0
    async def define(self, ctx, arg=None):
        if arg is None:
            await ctx.send("What **word** would you like the definition of?")
            word = await self.bot.wait_for(
                'message',
                check=lambda message: message.author == ctx.author,
                timeout=60.0)
            arg = word.content

        app_id = os.getenv('DEFINE_ID')
        app_key = os.getenv('DEFINE_KEY')

        endpoint = "entries"
        language_code = "en-us"
        word_id = sanitize(arg)
        url = "https://od-api.oxforddictionaries.com/api/v2/" + endpoint + "/" + language_code + "/" + word_id.lower(
        )
        async with ctx.typing():
            r = requests.get(url,
                             headers={
                                 "app_id": app_id,
                                 "app_key": app_key
                             })
            p = r.json()

        # print("code {}\n".format(r.status_code))
        # print("text \n" + r.text)
        # print("json \n" + json.dumps(r.json()))

        await ctx.send(
            f'**{p["word"]}** *{p["results"][0]["lexicalEntries"][0]["lexicalCategory"]["text"]}*: '
            f'{p["results"][0]["lexicalEntries"][0]["entries"][0]["senses"][0]["definitions"][0]}'
        )
Esempio n. 5
0
    async def quiz(self, ctx, *, args=None):
        # If there is no course specified
        info = None
        name = None
        channelname = ctx.channel.name.split('_')
        name = channelname[0]
        print(name)
        c.execute(
            f"SELECT name, questions, madeby, score FROM quiz WHERE name='{str.lower(name)}';"
        )
        info = c.fetchone()
        if args is None:
            # If there is no course specified but you are in a course channel (ie 'cosc111_computer-programming')
            if info is not None:
                author = str(info[2]).split('#')
                quizname = name
                desc = ""
                desc += "\nNumber of Questions: " + info[1]
                desc += "\nMade by: " + author[0]
                embed = discord.Embed(title=quizname,
                                      description=desc,
                                      color=0x206694)
                await ctx.send(
                    "I found a quiz for this channel: \n(Type '!quiz run' to start the quiz)"
                )
                await ctx.send(embed=embed, content=None)
                return
            # no quiz specified and not a course channel

            await ctx.send("'!quiz [NAME]' to run a quiz\n"
                           "'!quizlist' to see list of quizzes\n"
                           "'!addquiz [NAME]' to add a quiz\n"
                           "'!delquiz [NAME]' to delete a quiz\n"
                           "'!addq [QUIZNAME]' to add a question to a quiz")
            return
        # run quiz for current channel
        if args == 'run':
            if info is None:
                await ctx.send(
                    "No quiz found for this channel\nType '!quizlist' to see a list of all quizzes"
                )
                return
            await run(self, ctx, name)
            return
        # clean the args to prevent SQL injection
        args = dbcon.sanitize(args)
        c.execute(f"SELECT name FROM quiz WHERE name='{args}';")
        quizinfo = c.fetchone()
        if quizinfo is None:
            await ctx.send(
                "Quiz not found\nType '!quizlist' to see a list of all quizzes"
            )
            return
        else:
            await ctx.send('Starting quiz... Type !end to stop')
            await run(self, ctx, args)
            return
Esempio n. 6
0
 async def links(self, ctx):
     userinput = ctx.message.content.split(' ')
     # If there is no course specified
     if len(userinput) < 2:
         channelname = ctx.channel.name.split('_')
         name = channelname[0]
         c.execute(
             f"SELECT course, url, description FROM links WHERE course='{name}' COLLATE NOCASE;"
         )
         info = c.fetchall()
         # If there is no course specified but you are in a course channel (ie 'cosc111_computer-programming')
         if len(info) >= 1:
             await ctx.send("*Warning: Follow links at your own risk!*")
             coursename = str.upper(name)
             counter = 0
             embed = discord.Embed(title=coursename, color=0xf03413)
             for i in info:
                 embed.add_field(name=f"{i[2]}",
                                 value=f"{i[1]}",
                                 inline=False)
                 counter += 1
             embed.set_footer(text=f'Total links = {counter}')
             await ctx.send(embed=embed, content=None)
             return
         # no course specified and not a course channel
         else:
             await ctx.send(
                 "Please enter '!links' followed by a course code\nEg: !links COSC111"
             )
         return
     # returns the specific course/topic (even if you are in course channel)
     coursename = dbcon.sanitize(userinput[1])
     c.execute(
         f"SELECT course, url, description FROM links WHERE course='{coursename}' COLLATE NOCASE;"
     )
     info = c.fetchall()
     if info is None:
         await ctx.send(f"No links for {coursename} found")
         return
     await ctx.send("*Warning: Follow links at your own risk!*")
     counter = 0
     embed = discord.Embed(title=coursename, color=0xf03413)
     for i in info:
         embed.add_field(name=f"{i[2]}", value=f"{i[1]}", inline=False)
         counter += 1
     embed.set_footer(text=f"Total links: {counter}")
     # there is a 6000 char limit to embeds
     if len(embed) > 5999:
         print(f'its over 6000! {coursename}')
     await ctx.send(embed=embed, content=None)
     return
Esempio n. 7
0
    async def courseinfo(self, ctx):
        userinput = ctx.message.content.split(' ')
        # If there is no course specified
        if len(userinput) < 2:
            channelname = ctx.channel.name.split('_')
            name = channelname[0]
            info = c.execute(
                f"SELECT desc, pre_req, core_req FROM course_info WHERE course_id='{str.lower(name)}';"
            )
            info = info.fetchone()
            if info is None:
                await ctx.send(
                    "Please enter '!courseinfo' followed by a course code\nEg: !courseinfo COSC111"
                )
                return
            # If there is no course specified but you are in a course channel (ie 'cosc111_computer-programming')
            else:
                coursename = str.upper(name)
                desc = info.desc
                if len(info.pre_req) > 0:
                    desc += "\nPre-reqs: " + info.pre_req
                if len(info.core_req) > 0:
                    desc += "\nCo-reqs: " + info.core_req

                embed = discord.Embed(title=coursename,
                                      description=desc,
                                      color=0x206694)
                await ctx.send(embed=embed, content=None)
                return
        # returns the specific course (even if you are in course channel)
        coursename = dbcon.sanitize(userinput[1])
        info = c.execute(
            f"SELECT desc, pre_req, core_req FROM course_info WHERE course_id='{str.lower(coursename)}';"
        )
        info = info.fetchone()
        if info is None:
            await ctx.send("Class not found")
            return
        coursename = str.upper(coursename)
        desc = info.desc
        if len(info.pre_req) > 0:
            desc += "\nPre-reqs: " + info.pre_req
        if len(info.core_req) > 0:
            desc += "\nCo-reqs: " + info.core_req

        embed = discord.Embed(title=coursename,
                              description=desc,
                              color=0x206694)
        await ctx.send(embed=embed, content=None)
        return
Esempio n. 8
0
async def on_message(message):
    if message.author.bot:
        # Stops it from replying to bots
        return

    userinput = message.content.split(' ')
    if len(userinput) > 0:
        name = userinput[0]
        if name[0] == '!':
            # log the command and who called it for debugging purposes
            print(
                f'Command "{userinput[0]}" called by user "{message.author}" in channel "{message.channel}"'
            )

            # Removes '!' from beginning of command
            name = dbcon.sanitize(name[1:])

            # Checks for a match in the custom commands table
            c.execute(
                f"SELECT * FROM customcommands WHERE name='{name}' COLLATE NOCASE;"
            )
            row = c.fetchone()

            if row is None:
                # No matching commands were found in database, stops
                return
            # if context is multiVal
            if row[1] == 'multiVal':
                c.execute(
                    f"SELECT * from multival WHERE name='{name}' COLLATE NOCASE;"
                )
                vals = c.fetchall()
                response = random.choice(vals)
                await message.channel.send(response[1])
                return

            if row[1] != 'onMessage':
                # Commands 'trigger' is not onMessage, stops
                return

            if len(userinput) > 1 and userinput[1] == 'help':
                # Outputs help text if 1st arg is 'help'
                await message.channel.send('Help for ' + name + ':\n' + row[3])

            else:
                # Outputs content of command
                await message.channel.send(row[2])
Esempio n. 9
0
 async def delquiz(self, ctx, *, arg=None):
     if arg is None:
         await ctx.send(
             "Please enter a name of the quiz to delete.\nEg: !delquiz Ken Trivia"
         )
         return
     # clean the arg to prevent SQL injection
     arg = dbcon.sanitize(arg)
     quizname = str(arg)
     c.execute(
         "SELECT name, questions, madeby, score FROM quiz WHERE name='" +
         quizname + "';")
     q = c.fetchone()
     quizauthor = str(q[2]).split("#")
     desc = f"Quiz Name: {q[0]}\nNo of Questions: {q[1]}\nMade by: {quizauthor[0]}"
     embed = discord.Embed(title=q[0], description=desc, color=0x206694)
     await ctx.send(
         "Please review the quiz and type 'y' to delete or 'n' to cancel:")
     await ctx.send(embed=embed, content=None)
     confirm = await self.bot.wait_for(
         'message',
         check=lambda message: message.author == ctx.author,
         timeout=60.0)
     if confirm.content.startswith('n') or confirm.content.startswith('N'):
         await ctx.send("Cancelled")
         return
     author = str(ctx.author).split("#")
     # check to see if the quiz author is the same as the message author
     if author[0] != quizauthor[0]:
         print(f'{ctx.author} failed to delete command {quizname}')
         await ctx.send("Quizzes can only be deleted by their author")
         return
     try:
         c.execute("DELETE FROM quiz WHERE name='" + quizname + "';")
         conn.commit()
     except sqlite3.Error as e:
         print(type(e).__name__)
     except:
         await ctx.send("Hmmm.... something went wrong")
         return
     c.execute("DELETE FROM questions WHERE quizname='" + quizname + "';")
     await ctx.send(f"{quizname} deleted")
     print(f"{quizname} deleted by {ctx.author}")
     return
Esempio n. 10
0
    async def customcommand(self, ctx, *, args=None):
        if args is not None:
            args = dbcon.sanitize(args)
        # add command
        if args == 'add' or args == 'a':
            await ctx.send(
                "What will the name of the command be:\n*(one word only please)*"
            )
            cmdname = await self.bot.wait_for(
                'message',
                check=lambda message: message.author == ctx.author,
                timeout=60.0)
            if " " in cmdname.content:
                await ctx.send("No spaces please... cc add cancelled")
                return
            if cmdname.content in nouse:
                await ctx.send(
                    f"{cmdname.content} is a restricted word... cc add cancelled"
                )
                return
            # check to see if cmd already exists
            c.execute(
                f"SELECT name FROM customcommands WHERE name='{str(cmdname.content)}';"
            )
            name = c.fetchone()
            if name is not None:
                await ctx.send(
                    "A command by that name already exists.\n"
                    "Type '!customcommand list' to see the list of custom commands"
                )
                return
            await ctx.send(
                "What context will it be called on:\n"
                "**1. onMessage** - will activate when called by user (eg '!pizza')\n"
                "**2. onJoin** - will notify user upon joining server\n"
                "**3. multiVal** - an onMessage that returns a random response from a list of values\n"
                "(other types coming in future)")
            cmdcontext = await self.bot.wait_for(
                'message',
                check=lambda message: message.author == ctx.author,
                timeout=60.0)
            # check to see what the context will be (default is set as 'onMessage')
            # this should really be a unnamed function
            context = "onMessage"
            if cmdcontext.content.startswith(
                    "1") or cmdcontext.content.startswith(
                        "onM") or cmdcontext.content.startswith("onm"):
                context = "onMessage"
            if cmdcontext.content.startswith(
                    "2") or cmdcontext.content.startswith(
                        "onJ") or cmdcontext.content.startswith("onj"):
                context = "onJoin"
            if cmdcontext.content.startswith(
                    "3") or cmdcontext.content.startswith("mu"):
                context = "multiVal"
            # the value the bot returns when the command is called
            cmdval = ""
            if context == 'onMessage' or context == 'onJoin':
                await ctx.send(
                    "What will the return value be:\n*(Discord markdown will apply in the return)*"
                )
                cmdreturn = await self.bot.wait_for(
                    'message',
                    check=lambda message: message.author == ctx.author,
                    timeout=60.0)
                cmdval = cmdreturn.content
            if context == 'multiVal':
                addval = []
                while (1):
                    await ctx.send("Enter a return:\n*(enter !stop to stop)*")
                    val = await self.bot.wait_for(
                        'message',
                        check=lambda message: message.author == ctx.author,
                        timeout=60.0)

                    if val.content == '!stop':
                        break
                    else:
                        addval += [val.content]
                        continue
                cmdval = "multival"
            # the help value
            await ctx.send(
                f"What will the help value be:\n(what will '!help {cmdname.content}' return?)"
            )
            cmdhelp = await self.bot.wait_for(
                'message',
                check=lambda message: message.author == ctx.author,
                timeout=60.0)
            await ctx.send(
                "Please review the command and type 'y' to accept or 'n' to cancel:"
            )
            desc = ""
            desc += "\nName: " + cmdname.content
            desc += "\nContext: " + context
            desc += "\nReturn: " + cmdval
            desc += "\nHelp: " + cmdhelp.content
            embed = discord.Embed(title=cmdname.content,
                                  description=desc,
                                  color=0x206694)
            await ctx.send(embed=embed, content=None)
            confirm = await self.bot.wait_for(
                'message',
                check=lambda message: message.author == ctx.author,
                timeout=60.0)
            if confirm.content.startswith('n') or confirm.content.startswith(
                    'N'):
                await ctx.send("Cancelled")
                return
            else:
                try:
                    sql = "INSERT INTO customcommands (name, context, value, help, author) VALUES (?, ?, ?, ?, ?)"
                    c.execute(sql, (cmdname.content, context, cmdval,
                                    cmdhelp.content, str(ctx.author)))
                    conn.commit()
                    if context == 'multiVal':
                        for add in addval:
                            sql = "INSERT INTO multival (name, value) VALUES (?,?)"
                            c.execute(sql, (cmdname.content, add))
                            conn.commit()
                    await ctx.send("Command added")
                except sqlite3.Error as e:
                    print(type(e).__name__)
                except:
                    await ctx.send("Hmmm.... something went wrong")
                    return
            return
        # delete command
        if args == 'del' or args == 'd':
            await ctx.send(
                "What is the name of the custom command you would like to delete?"
                "\n(please do not include the '!')")
            cmdname = await self.bot.wait_for(
                'message',
                check=lambda message: message.author == ctx.author,
                timeout=60.0)
            if cmdname.content.startswith("!"):
                await ctx.send("Cancelled cc d")
                return
            try:
                c.execute(
                    "SELECT name, value, context, help, author FROM customcommands WHERE name='"
                    + str(cmdname.content) + "';")
            except sqlite3.Error as e:
                print(type(e).__name__)
            except:
                await ctx.send("Hmmm.... something went wrong")
                return
            cmd = c.fetchone()
            if cmd is None:
                await ctx.send(
                    "No command by that name exists.\n"
                    "Type '!customcommand list' to see the list of custom commands"
                )
                return
            cmdauthor = str(cmd[4]).split("#")
            desc = f"Value: {cmd[1]}\nContext: {cmd[2]}\nHelp: {cmd[3]}\nMade by: {cmdauthor[0]}"
            embed = discord.Embed(title=cmdname.content,
                                  description=desc,
                                  color=0x206694)
            await ctx.send(
                "Please review the command and type 'y' to delete or 'n' to cancel:"
            )
            await ctx.send(embed=embed, content=None)

            confirm = await self.bot.wait_for(
                'message',
                check=lambda message: message.author == ctx.author,
                timeout=60.0)
            if confirm.content.startswith('n') or confirm.content.startswith(
                    'N'):
                await ctx.send("Cancelled")
                return
            author = str(ctx.author).split("#")
            # if caller is admin, they can delete any command
            if ctx.message.author.top_role.permissions.administrator:
                print(f'user is admin')
                c.execute(
                    f"DELETE FROM customcommands WHERE name='{cmdname.content}';"
                )
                await ctx.send(f"{cmdname.content} deleted")
                print(f"{cmdname.content} deleted by {ctx.author}")
            else:
                if author[0] != cmdauthor[0]:
                    print(
                        f'{ctx.author} failed to delete command {cmdname.content}'
                    )
                    await ctx.send(
                        "Commands can only be deleted by their author")
                else:
                    c.execute("DELETE FROM customcommands WHERE name='" +
                              cmdname.content + "';")
                    await ctx.send(f"{cmdname.content} deleted")
                    print(f"{cmdname.content} deleted by {ctx.author}")
            conn.commit()
            return
        # modify command
        if args == 'mod' or args == 'm':
            await ctx.send("you have chosen modify\nComing soon")
            return
        # list commands
        if args == 'list' or args == 'l':
            try:
                c.execute('SELECT * FROM customcommands')
            except sqlite3.Error as e:
                print(type(e).__name__)
            rows = c.fetchall()
            customcmds = ""
            for row in rows:
                if row[1] == 'onMessage':
                    customcmds += "!" + row[0] + '\n'
                if row[1] == 'onJoin':
                    customcmds += row[0] + " *(onJoin)*\n"
            embed = discord.Embed(title="Custom Command List",
                                  description=customcmds,
                                  color=0x206694)
            await ctx.send(embed=embed, content=None)
            return
        await ctx.send(
            "'!customcommand add' to add command\n'!customcommand mod' to modify command"
            "\n'!customcommand del' to delete command\n'!customcommand list' to list custom commands"
        )
        return
Esempio n. 11
0
    async def help(self, ctx):
        message = ctx.message.content
        message = message.split(' ')
        if len(message) <= 1:

            # If no arguments are provided it will put out a list of all commands
            desc = "List of all commands for this bot:\n"
            embed = discord.Embed(title="Help",
                                  description=desc,
                                  color=0x206694)
            hardcoded = ""
            for command in self.bot.commands:
                if not command.hidden:
                    hardcoded += f"!{command}\n"
            embed.add_field(name="Hardcoded Commands:",
                            value=hardcoded,
                            inline=False)

            # Custom commands
            c.execute('SELECT name, context FROM customcommands ORDER BY name')
            rows = c.fetchall()
            customcmds = ""
            for row in rows:
                if row[1] == 'onMessage' or row[1] == 'multiVal':
                    customcmds += f'!{row[0]}\n'
                if row[1] == 'onJoin':
                    customcmds += row[0] + " *(onJoin)*\n"
            embed.add_field(name="Custom Commands:",
                            value=customcmds,
                            inline=False)

            # if caller is admin, they get to see all commands
            HiddenCommands = discord.Embed(title="Help",
                                           description=None,
                                           color=0x206694)
            hide = ""
            for command in self.bot.commands:
                if command.hidden:
                    hide += f"!{command}\n"
            HiddenCommands.add_field(name="Admin-only Commands:",
                                     value=hide,
                                     inline=False)

            if ctx.message.author.top_role.permissions.administrator:
                if ctx.author.dm_channel is None:
                    await ctx.author.create_dm()
                await ctx.author.dm_channel.send(embed=HiddenCommands,
                                                 content=None)

            # Outputs to channel

            await ctx.send(embed=embed, content=None)
            await ctx.send(
                "Type '!help [COMMAND]' for additional information about that specific command"
            )
            return
        else:
            arg = dbcon.sanitize(message[1])
            argtitle = "!" + arg
            embed = discord.Embed(title=argtitle, color=0x206694)
            cmdhelp = ""
            cmdname = arg
            # Checks for custom commands
            c.execute("SELECT * FROM customcommands WHERE name='" + arg +
                      "' COLLATE NOCASE;")
            row = c.fetchone()

            if row is not None:
                # Sets the output to the help message of that command
                cmdhelp += row[3]

            # find the hardcoded cmd
            else:
                cmd = self.bot.get_command(arg)
                if cmd is None:
                    await ctx.send(
                        "Command not found. Use '!help' to see a list of all commands."
                    )
                    return
                cmdhelp = cmd.help
                cmdname = f"!{cmd.name}"
                cmdaliases = cmd.aliases
                if len(cmdaliases) > 0:
                    cmdhelp += '\nAliases: ' + str(cmdaliases)

            embed.add_field(name=cmdname, value=cmdhelp, inline=False)
            await ctx.send(embed=embed, content=None)
            return