예제 #1
0
    async def on_raw_reaction_add(self, payload):
        """ Checks reactions and deletes tracked messages when necessary. """
        if payload.user_id == self.bot.user.id:
            return
        if payload.emoji.name == CONSTANTS.REACTION_DELETE:
            is_tracked = False
            sender_uid = None
            with SQLCursor(self.db) as cur:
                cur.execute(
                    "SELECT messid, sender_uid FROM tracked_messages WHERE messid=?",
                    (payload.message_id, ))
                row = cur.fetchone()
                if row:
                    is_tracked = True
                    sender_uid = row[1]

            if is_tracked:
                reacting_member = self.bot.get_guild(
                    payload.guild_id).get_member(payload.user_id)
                can_delete = self.bot.get_channel(
                    payload.channel_id).permissions_for(
                        reacting_member).manage_messages
                if payload.user_id == sender_uid or can_delete:
                    relevant_message = await self.bot.get_channel(
                        payload.channel_id).get_message(payload.message_id)
                    await relevant_message.delete()
예제 #2
0
 async def show_occupants(self, ctx, position=''):
     pos = position.title()
     position = position.replace(' ', '_')
     if position.lower() in self.positions:
         with SQLCursor(self.db) as cur:
             cur.execute(
                 'SELECT description, officer FROM govt_info WHERE position = ?;',
                 (position, ))
             row = cur.fetchone()
             if row:
                 plural = False
                 if row[1] is not None and ',' in row[1]:
                     officers = [
                         str(ctx.message.guild.get_member(int(member_id)))
                         for member_id in row[1].split(',')
                     ]
                     officers = ', '.join(officers)
                     plural = True
                 else:
                     officers = (str(
                         ctx.message.guild.get_member(int(row[1])))
                                 if row[1] is not None
                                 and row[1].strip() != '' else 'Vacant')
                 description = row[0]
                 await ctx.message.channel.send(
                     'The current _{}: _{}_'.format(
                         pos + ('s_ are' if plural else '_ is'), officers))
                 if description is not None and description.strip() != '':
                     await ctx.message.channel.send(
                         'Description: \n```{}```'.format(description))
     else:
         await ctx.channel.send(
             'Invalid position. Here is a list of valid positions: ' +
             ', '.join(self.positions).replace('_', ' '))
예제 #3
0
 async def remove(self, ctx, position, user: discord.User):
     member_id = user.id
     if ctx.message.author.top_role.name.lower() == 'officer':
         with SQLCursor(self.db) as cur:
             cur.execute(
                 'SELECT officer FROM govt_info WHERE position = ?;',
                 (position, ))
             row = cur.fetchone()
             if row:
                 officers = ','.join(row) if row[0] is not None else ''
                 if officers.strip() != '':
                     officers = officers.replace(str(member_id) + ',',
                                                 '').replace(
                                                     str(member_id), '')
                     if len(officers.split(',')) == 1:
                         officers = officers.replace(',', '')
                     elif officers[len(officers) - 1:len(officers)] == ',':
                         officers = officers[0:len(officers) - 1]
                     cur.execute(
                         'UPDATE govt_info SET officer = ? WHERE position = ?;',
                         (officers, position))
                     await ctx.message.channel.send(
                         'Successfully removed **{}** from the **{}** position.'
                         .format(str(user), position))
     else:
         await ctx.message.channel.send(
             'Hey! You do not have permission to do that.')
예제 #4
0
    async def set(self, ctx, position, user: discord.User):
        if ctx.message.author.top_role.name.lower() == 'officer':
            member_id = user.id
            if position is None or member_id is None:
                await ctx.message.channel.send(
                    'Invalid command format, try: `eboard admin set <position> <@User#0000>`'
                )
            else:
                with SQLCursor(self.db) as cur:
                    cur.execute(
                        'SELECT officer FROM govt_info WHERE position = ?;',
                        (position, ))
                    row = cur.fetchone()
                    if row:
                        officers = ','.join(row) if row[0] is not None else ''
                        if str(member_id) in officers:
                            return
                        officers += (',' if officers.strip() != '' else
                                     '') + '{0}'.format(str(member_id))
                    else:
                        officers = str(member_id)

                    cur.execute(
                        'UPDATE govt_info SET officer = ? WHERE position = ?;',
                        (officers, position))
                    await ctx.message.channel.send(
                        'Successfully added **{}** to the **{}** position.'.
                        format(str(user), position))
        else:
            await ctx.message.channel.send(
                'Hey! You do not have permission to do that.')
예제 #5
0
 async def tally(self, ctx):
     ''' Get the current goodbot/badbot tally '''
     with SQLCursor(self.db) as cur:
         cur.execute("SELECT vote, tally FROM goodbot_badbot")
         row = cur.fetchone()
         await ctx.send("{0}: {1}".format(str(row[0]), str(row[1])))
         row = cur.fetchone()
         await ctx.send("{0}: {1}".format(str(row[0]), str(row[1])))
예제 #6
0
 def vote(self, good):
     ''' Votes goodbot if good is true, badbot if good is false '''
     vote = "good" if good else "bad"
     with SQLCursor(self.db) as cur:
         cur.execute("SELECT vote, tally FROM goodbot_badbot WHERE vote=?", (vote,))
         row = cur.fetchone()
         new_tally = row[1] + 1
         cur.execute("UPDATE goodbot_badbot SET tally=? WHERE vote=?", (new_tally, vote))
예제 #7
0
 async def query_position(self, position):
     """Return all of the officers for a corresponding position as a string list separated by commas."""
     with SQLCursor(self.db) as cur:
         cur.execute('SELECT officer FROM govt_info WHERE position=?',
                     (position, ))
         row = cur.fetchone()
         if row:
             return row[0] if not None else ''
예제 #8
0
def initialize():
    ''' Initializes the table with non-null 'vote' positions '''
    sql_db = SQLConnection()
    with SQLCursor(sql_db) as cur:
        cur.execute("SELECT vote from goodbot_badbot")
        row = cur.fetchone()
        for vote in Tally.votes:
            if row is None or len(row) != len(Tally.votes):
                cur.execute("INSERT OR IGNORE INTO goodbot_badbot VALUES (?, ?)", (vote, 0))
예제 #9
0
def initialize():
    """Initializes the table with non-null 'position' columns."""
    sql_db = SQLConnection()
    with SQLCursor(sql_db) as cur:
        cur.execute('SELECT position from govt_info')
        row = cur.fetchone()
        for pos in Government.positions:
            if row is None or len(row) != len(Government.positions):
                cur.execute(
                    'INSERT OR IGNORE INTO govt_info (position) VALUES (?);',
                    (pos, ))
예제 #10
0
 async def clear(self, ctx):
     """Clears all officers from their positions in the SQLite table."""
     if ctx.message.author.top_role.name.lower() == 'officer':
         with SQLCursor(self.db) as cur:
             cur.execute('UPDATE govt_info SET officer = Null;')
             await ctx.message.channel.send(
                 'Successfully cleared all officers from all positions in the SQLite table.'
             )
     else:
         await ctx.message.channel.send(
             'Hey! You do not have permission to do that.')
예제 #11
0
async def track(message, author=None):
    """ Marks a message in the database so that it will be automatically
        deleted if the sender or an admin reacts with the 'trash' emoji
    """
    await message.add_reaction(CONSTANTS.REACTION_DELETE)
    sql_db = SQLConnection()
    aid = 0
    if author:
        aid = author.id
    with SQLCursor(sql_db) as cur:
        cur.execute(
            "INSERT INTO tracked_messages (messid, sender_uid, track_time) VALUES (?, ?, ?);",
            (message.id, aid, message.created_at))
예제 #12
0
    async def on_command_error(self, ctx, error):
        if type(error) == discord.ext.commands.MissingPermissions:
            logging.warn(
                f'{ctx.author} denied permission for command {ctx.message.content}'
            )
            await ctx.message.add_reaction(CONSTANTS.REACTION_DENY)
            embed = discord.Embed(
                title='{deny} Insufficient Permissions'.format(
                    deny=CONSTANTS.REACTION_DENY),
                colour=discord.Colour(CONSTANTS.EMBED_COLOR_ERROR),
                description="You are not permitted to run the command ``{0}``".
                format(ctx.message.content))
            embed.add_field(name="Reason:", value=str(error))
            msg = await ctx.send(content='', embed=embed)
            await track(msg, ctx.author)
        else:
            embed = None
            if not ctx.command:
                logging.warn(
                    f'Unknown command {ctx.message.content} by {ctx.author}')
                embed = self._construct_unknown_command_embed(
                    str(error), ctx.message.content)
            else:
                logging.warn(
                    f'Error running the command {ctx.command.name} Error: {type(error)} | {error}'
                )
                embed = self._construct_error_embed(ctx.command.name,
                                                    str(type(error)),
                                                    str(error),
                                                    ctx.message.content)

            await ctx.message.add_reaction(CONSTANTS.REACTION_ERROR)
            msg = await ctx.send(content='', embed=embed)
            await track(msg, ctx.author)
            if not ctx.command:
                return
            await msg.add_reaction(CONSTANTS.REACTION_EXPAND)
            with SQLCursor(self.db) as cur:
                bt_string = ''.join(
                    traceback.format_exception(type(error), error,
                                               error.__traceback__))
                print('{bname} encountered an error:\n{0}'.format(
                    bt_string, bname=CONSTANTS.BOT_NAME))
                cur.execute(
                    'INSERT INTO error_messages (message_id, channel_id, command_name, error_name, error_text, '
                    'full_backtrace, full_command_string) VALUES (?,?,?,?,?,?,?);',
                    (msg.id, msg.channel.id, ctx.command.name, str(
                        type(error)), str(error), bt_string,
                     ctx.message.content))
예제 #13
0
    async def on_raw_reaction_remove(self, payload):
        if payload.user_id == self.bot.user.id:
            return
        if payload.emoji.name == CONSTANTS.REACTION_EXPAND:
            row = None
            with SQLCursor(self.db) as cur:
                cur.execute(
                    'SELECT command_name, error_name, error_text, full_command_string, full_backtrace FROM error_messages WHERE message_id=? AND channel_id=?;',
                    (payload.message_id, payload.channel_id))
                row = cur.fetchone()
            if not row:
                return

            to_edit = await self.bot.get_channel(
                payload.channel_id).get_message(payload.message_id)
            new_embed = self._construct_error_embed(row[0], row[1], row[2],
                                                    row[3])
            await to_edit.edit(content='{err} Command error {err}'.format(
                err=CONSTANTS.REACTION_ERROR),
                               embed=new_embed)
예제 #14
0
 async def query_positions(self):
     """Returns an array of positions and corresponding descriptions."""
     values = [{} for _ in range(len(self.positions))]
     counter = 0
     with SQLCursor(self.db) as cur:
         for pos in self.positions:
             cur.execute(
                 'SELECT position, description, officer FROM govt_info WHERE position=?',
                 (pos, ))
             row = cur.fetchone()
             if row:
                 values[counter] = {
                     'position': row[0] if len(row) >= 1 else 'NULL',
                     'description': row[1] if row[1] is not None else '',
                     'officer': row[2] if row[2] is not None else 'Vacant'
                 }
             else:
                 values[counter] = {}
             counter += 1
     return values
예제 #15
0
 async def description(self, ctx, pos='', desc=''):
     if ctx.message.author.top_role.name.lower() == 'officer':
         if pos.strip() != '':
             with SQLCursor(self.db) as cur:
                 cur.execute(
                     'UPDATE govt_info SET description = ? WHERE position = ?;',
                     (desc, pos))
                 if desc.strip() == '':
                     await ctx.message.channel.send(
                         'Successfully cleared the description for position: **{}**'
                         .format(pos))
                 else:
                     await ctx.message.channel.send(
                         'Successfully set a description for position: **{}**\n\nThe description is as '
                         'follows:\n```{}```'.format(pos, desc))
         else:
             await ctx.message.channel.send(
                 'Invalid format, try: **eboard admin description <position> \"<desc>\"**'
             )
     else:
         await ctx.message.channel.send(
             'Hey! You do not have permission to do that.')