예제 #1
0
	async def on_raw_reaction_add(self, payload):
		if payload.user_id == self.bot.user.id:
			return
		if payload.emoji.name == '🚮':
			is_tracked = False
			sender_uid = None
			with sql_cur(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()
		elif payload.emoji.name == '\u2733':
			row = None
			with sql_cur(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],row[4])
			await to_edit.edit(content='⚠ Command error ⚠',embed=new_embed)
예제 #2
0
    def _perms_set(self, guild_id, role_id, permissions, mode=None):
        if not mode:
            mode = self._GRANT

        current_perms = 0
        with sql_cur(self.db) as cur:
            cur.execute(
                'SELECT permissions FROM permissions WHERE guild_id=? AND role_id=?;',
                (guild_id, role_id))
            res = cur.fetchone()
            if res:
                current_perms = res[0]

        new_perms = current_perms
        for perm in permissions:
            if mode == self._DENY:
                if _has(new_perms, perm) or not _denied(new_perms, perm):
                    new_perms = _deny_perm(new_perms, perm)

            elif mode == self._GRANT:
                if _denied(new_perms, perm) or not _has(new_perms, perm):
                    new_perms = _grant_perm(new_perms, perm)

            elif mode == self._CLEAR:
                if _has(new_perms, perm) or _denied(new_perms, perm):
                    new_perms = _clear_perm(new_perms, perm)

            else:
                raise commands.CommandError(
                    'Unknown value {0} for permission mode enum.'.format(mode))

        self._perms_write(guild_id, role_id, new_perms)
예제 #3
0
	async def on_raw_reaction_remove(self, payload):
		if payload.user_id == self.bot.user.id:
			return
		if payload.emoji.name == '\u2733':
			row = None
			with sql_cur(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='⚠ Command error ⚠',embed=new_embed)
예제 #4
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('🚮')
    sql_db = sql_con()
    aid = 0
    if author:
        aid = author.id
    with sql_cur(sql_db) as cur:
        cur.execute(
            "INSERT INTO tracked_messages (messid, sender_uid, track_time) VALUES (?, ?, ?);",
            (message.id, aid, message.created_at))
예제 #5
0
    async def _refresh_region_meta(self, region_meta):
        region = self.bot.get_channel(region_meta['channel_id'])
        if not region:
            with sql_cur(self.db) as cur:
                cur.execute('DELETE FROM regions WHERE channel_id=?',
                            (region_meta['channel_id'], ))
                raise commands.CheckFailure(
                    'Channel for region {0} is missing! Removed associated region data.'
                )
        channel_category_id = None
        if region_meta['status'] != 1:
            channel_category_id = region_meta['active_category']
        else:
            with sql_cur(self.db) as cur:
                cur.execute(
                    'SELECT inactive_category FROM guild_settings WHERE guild_id=?',
                    (region.guild.id, ))
                row = cur.fetchone()
                if not row:
                    raise commands.BadArgument(
                        'Please use the {0}rpset inactive command to set up a channel category for inactive channels. {0}help rpset inactive for more information.'
                        .format(self.bot.command_prefix))
                channel_category_id = row[0]
        channel_category = None
        for category in region.guild.categories:
            if category.id == channel_category_id:
                channel_category = category

        await region.edit(name=self._sanitize_channel_name(
            region_meta['name']),
                          position=0,
                          nsfw=region.is_nsfw(),
                          topic=await self._generate_topic(region_meta),
                          sync_permissions=True,
                          category=channel_category,
                          reason='Updating RP region metadata.')
        await self._edit_region(region_meta)
예제 #6
0
    async def unmake_region(self, ctx):
        ''' Removes Hector region status from the channel
		  ' (Note: this does not delete the channel itself)
		'''
        region = await self._get_region(ctx.guild.id, ctx.channel.id)

        if not region:
            raise commands.CheckFailure('Channel #{0} is not a region!'.format(
                ctx.channel.name))

        with sql_cur(self.db) as cur:
            cur.execute('DELETE FROM regions WHERE channel_id=?;',
                        (ctx.channel.id, ))

        await ctx.message.add_reaction('✅')
예제 #7
0
    def _perms_write(self, guild_id, role_id, perms):
        with sql_cur(self.db) as cur:
            cur.execute(
                'SELECT permissions FROM permissions WHERE guild_id=? AND role_id=?;',
                (guild_id, role_id))
            res = cur.fetchone()

            if res:
                cur.execute(
                    'UPDATE permissions SET permissions=? WHERE guild_id=? AND role_id=?',
                    (perms, guild_id, role_id))

            else:
                cur.execute(
                    'INSERT INTO permissions (guild_id, role_id, permissions) VALUES (?,?,?);',
                    (guild_id, role_id, perms))
예제 #8
0
    async def set_inactive(self, ctx):
        ''' Set the category where inactive region channels are stored '''
        with sql_cur(self.db) as cur:
            cur.execute(
                'SELECT inactive_category FROM guild_settings WHERE guild_id=?;',
                (ctx.guild.id, ))
            if cur.fetchone():
                cur.execute(
                    'UPDATE guild_settings SET inactive_category=? WHERE guild_id=?;',
                    (ctx.channel.category_id, ctx.guild.id))
            else:
                cur.execute(
                    'INSERT INTO guild_settings (guild_id, inactive_category) VALUES (?,?);',
                    (ctx.guild.id, ctx.channel.category_id))

        await ctx.message.add_reaction('✅')
예제 #9
0
 async def _edit_region(self, region):
     with sql_cur(self.db) as cur:
         cur.execute(
             'SELECT name FROM regions WHERE channel_id=? AND guild_id=?;',
             (region['channel_id'], region['guild_id']))
         if len(cur.fetchall()) == 0:
             cur.execute(
                 'INSERT INTO regions (channel_id, guild_id, name, description, status, active_category) VALUES (?,?,?,?,?,?);',
                 (region['channel_id'], region['guild_id'], region['name'],
                  region['description'], region['status'],
                  region['active_category']))
         else:
             cur.execute(
                 'UPDATE regions SET name=?,description=?,status=?,active_category=? WHERE channel_id=? AND guild_id=?;',
                 (region['name'], region['description'], region['status'],
                  region['active_category'], region['channel_id'],
                  region['guild_id']))
예제 #10
0
async def get_permissions(member, guild):
    tracked_roles = {}
    with sql_cur(sql_con()) as cur:
        cur.execute(
            'SELECT role_id,permissions FROM permissions WHERE guild_id=?',
            (guild.id, ))
        for role in cur.fetchall():
            tracked_roles[role[0]] = role[1]

    if len(tracked_roles) == 0:
        return 0

    permissions = 0

    for role in member.roles:
        if role.id in tracked_roles.keys():
            role_perms = tracked_roles[role.id]
            permissions = _perms_combine(role_perms, permissions)

    return permissions
예제 #11
0
파일: hector.py 프로젝트: ashuping/hector
    async def on_command_error(self, ctx, error):
        if type(error) == discord.ext.commands.MissingPermissions:
            await ctx.message.add_reaction('⛔')
            embed = discord.Embed(
                title='⛔ Insufficient Permissions',
                colour=discord.Colour(0x913232),
                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:
                embed = self._construct_unknown_command_embed(
                    str(error), ctx.message.content)
            else:
                embed = self._construct_error_embed(ctx.command.name,
                                                    str(type(error)),
                                                    str(error),
                                                    ctx.message.content)

            await ctx.message.add_reaction('⚠')
            msg = await ctx.send(content='', embed=embed)
            await track(msg, ctx.author)
            if not ctx.command:
                return
            await msg.add_reaction('\u2733')
            with sql_cur(self.db) as cur:
                bt_string = ''.join(
                    traceback.format_exception(type(error), error,
                                               error.__traceback__))
                print('Hector encountered an error:\n{0}'.format(bt_string))
                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))
예제 #12
0
    async def _list_regions(self, guild_id=None):
        regions = []
        query = 'SELECT channel_id, guild_id, name, description, status, active_category FROM regions'
        if guild_id:
            query = query + ' WHERE guild_id=?;'
        else:
            query = query + ';'

        with sql_cur(self.db) as cur:
            if guild_id:
                cur.execute(query, (guild_id, ))
            else:
                cur.execute(query)
            for region in cur.fetchall():
                regions.append({
                    'channel_id': region[0],
                    'guild_id': region[1],
                    'name': region[2],
                    'description': region[3],
                    'status': region[4],
                    'active_category': region[5]
                })

        return regions
예제 #13
0
    async def setup_preset(self, ctx, preset_name):
        ''' (Admin-only) Sets up permissions based on a built-in preset.
		  ' WARNING: This will OVERWRITE any existing permissions.
		'''
        if not preset_name:
            raise commands.BadArgument('Please provide a preset name to use.')

        presets = None
        with open('data/default_presets.json') as preset_file:
            presets = json.load(preset_file)

        preset = None
        for possible_preset in presets:
            if possible_preset['name'].lower() == preset_name.lower():
                preset = possible_preset

        if not preset:
            raise commands.BadArgument(
                'Preset {0} not found. Try `{1}perms list` for a list of presets.'
                .format(preset_name, self.bot.command_prefix))

        existing_perms = False
        with sql_cur(self.db) as cur:
            cur.execute('SELECT * FROM permissions WHERE guild_id=?;',
                        (ctx.guild.id, ))
            if cur.fetchone():
                existing_perms = True

        if existing_perms:
            embed = discord.Embed(
                title='\U0001f6a8 WARNING!',
                colour=discord.Colour(0xc7b61a),
                description=
                'Hector already has permission records for this server! Continuing will erase these records and replace them with preset values!'
            )
            embed.add_field(name='If you are sure,',
                            value='Press the \u26a0 button.',
                            inline=False)
            embed.set_footer(
                text=
                'This command will time out in 60 seconds. To cancel, wait until time-out.'
            )
            warn_msg = await ctx.send(content='', embed=embed)
            await warn_msg.add_reaction('\u26a0')

            def check(reaction, user):
                return user == ctx.message.author and str(
                    reaction.emoji
                ) == '\u26a0' and reaction.message.id == warn_msg.id

            try:
                reaction, user = await self.bot.wait_for('reaction_add',
                                                         timeout=60,
                                                         check=check)

            except TimeoutError:
                await warn_msg.clear_reactions()
                await warn_msg.edit(content='Confirmation timed out.')
                await track(warn_msg, ctx.author)
                return

            else:
                await warn_msg.clear_reactions()
                await warn_msg.edit(
                    content='Confirmed. Setting up permissions from preset {0}.'
                    .format(preset['name']))
                with sql_cur(self.db) as cur:
                    cur.execute('DELETE FROM permissions WHERE guild_id=?;',
                                (ctx.guild.id, ))
        for role in preset['roles']:
            perm_val = _construct_from_preset_string(role['permissions'])
            if role['name'] == '*':
                # Handle @everyone separately
                with sql_cur(self.db) as cur:
                    cur.execute(
                        'INSERT INTO permissions (guild_id, role_id, permissions) VALUES (?,?,?);',
                        (ctx.guild.id, ctx.guild.default_role.id, perm_val))
            else:
                if not 'color' in role.keys():
                    role['color'] = 0x419492
                new_role = await ctx.guild.create_role(
                    name=role['name'],
                    colour=discord.Colour(role['color']),
                    mentionable=True,
                    reason=
                    'Setting up permissions from preset (requesting user: {0})'
                    .format(ctx.message.author))
                with sql_cur(self.db) as cur:
                    cur.execute(
                        'INSERT INTO permissions (guild_id, role_id, permissions) VALUES (?,?,?);',
                        (ctx.guild.id, new_role.id, perm_val))
        await ctx.message.add_reaction('✅')