예제 #1
0
    async def _limited_disable(self, ctx):
        '''Disables limited role requests for the guild'''
        doc = utils.getGuildDoc(ctx.bot, ctx.guild)

        if doc['requests_opts']['channel'] == None:
            return await utils.cmdFail(
                ctx, f'Requests are already disabled for this guild.')

        utils.guildKeySet(ctx.bot, ctx.guild, 'requests_opts.channel', None)
        return await utils.cmdSuccess(
            ctx, f'Requests are now disabled for this guild.')
예제 #2
0
    async def _limited_channel(self, ctx, channel: discord.TextChannel):
        '''Sets the channel that limited role requests will be posted in'''
        doc = utils.getGuildDoc(ctx.bot, ctx.guild)

        if doc['requests_opts']['channel'] == channel.id:
            return await utils.cmdFail(
                ctx, f'The requests channel is already {channel}.')

        utils.guildKeySet(ctx.bot, ctx.guild, 'requests_opts.channel',
                          channel.id)
        return await utils.cmdSuccess(
            ctx, f'The requests channel is now {channel}.')
예제 #3
0
    async def _limited_option_toggle(self, ctx, user_setting, setting_key,
                                     setting_string):
        doc = utils.getGuildDoc(ctx.bot, ctx.guild)
        current = doc['requests_opts'][setting_key]

        if user_setting is None:
            user_setting = not current

        human = 'enabled' if user_setting else 'disabled'

        if user_setting == current:
            return await utils.cmdFail(
                ctx,
                f'Limited role join command {setting_string} is already **{human}**.'
            )

        utils.guildKeySet(ctx.bot, ctx.guild, f'requests_opts.{setting_key}',
                          user_setting)
        return await utils.cmdSuccess(
            ctx,
            f'Limited role join command {setting_string} is now **{human}**.')
예제 #4
0
    async def _role(self, ctx, role: discord.Role,
                    option: typing.Optional[str]):
        '''Adds, modifies, or removes a requestable role
        
        Adds or removes a role from the server's requestable roles or modifies an existing requestable roles type.'''
        doc = utils.getGuildDoc(ctx.bot, ctx.guild)

        options = {
            'open': ['open', 'o'],
            'limited': ['limited', 'limit', 'l'],
            'remove': ['delete', 'del', 'd', 'remove', 'rem', 'r'],
            'add': ['add',
                    'a']  # Option resolves to 'open' but only for new roles.
        }

        resolved_option = None
        for key, val in options.items():
            if option in val:
                resolved_option = key

        if option and not resolved_option:
            return await utils.cmdFail(ctx,
                                       f'"{option}" is not a valid option.')

        # @everyone role or managed
        if role.is_default() or role.managed:
            return await utils.cmdFail(ctx,
                                       f'"{role.name}" is not a valid role.')

        role_request_type = None if not (doc and str(
            role.id) in doc['roles']) else doc['roles'][str(role.id)]['type']

        # Role info
        if resolved_option is None:
            embed = discord.Embed(
                title='Role Info',
                description=f'<@&{role.id}> (`{role.id}`)\n' +
                f'**Color:** {"None" if role.color == discord.Colour.default() else role.color}\n'
                + f'**Hoisted:** {"Yes" if role.hoist else "No"}\n' +
                f'**Mentionable:** {"Yes" if role.mentionable else "No"}\n' +
                '**Requestable:** ' + ('No' if not role_request_type else
                                       f'Yes, {role_request_type.title()}'),
                color=discord.Embed.Empty
                if role.color == discord.Colour.default() else role.colour)

            if commands.has_permissions(manage_roles=True)(ctx):
                embed.set_footer(
                    text=f'See "{ctx.prefix}help role" for valid subcommands.')

            return await ctx.send(embed=embed)

        # Remove role
        if resolved_option == 'remove':
            if not role_request_type:
                return await utils.cmdFail(
                    ctx, f'"{role.name}" is not a requestable role.')

            utils.guildKeyDel(ctx.bot, ctx.guild, f'roles.{role.id}')
            return await utils.cmdSuccess(
                ctx, f'"{role.name}" has been removed as a requestable role.')

        # Modify role type
        if role_request_type:
            if resolved_option == 'add':
                return await utils.cmdFail(
                    ctx, f'"{role.name}" is already a requestable role.')

            if role_request_type == resolved_option:
                return await utils.cmdFail(
                    ctx,
                    f'"{role.name}" is already a {resolved_option} requestable role.'
                )

            utils.guildKeySet(ctx.bot, ctx.guild, f'roles.{role.id}.type',
                              resolved_option)
            return await utils.cmdSuccess(
                ctx,
                f'"{role.name}" is now a {resolved_option} requestable role.')

        # Add role
        else:
            if resolved_option == 'add':
                resolved_option = 'open'

            utils.guildKeySet(ctx.bot, ctx.guild, f'roles.{role.id}',
                              {'type': resolved_option})
            return await utils.cmdSuccess(
                ctx,
                f'"{role.name}" has been added as a requestable {resolved_option} role.'
            )
예제 #5
0
    async def request_create(self, ctx, role):
        doc = utils.getGuildDoc(ctx.bot, ctx.guild)

        channel = doc['requests_opts']['channel']
        users_requests = list(
            filter(lambda e: e['user'] == ctx.author.id,
                   doc['requests'].values()))

        if doc['requests_opts']['hidejoins']:
            try:
                await ctx.message.delete(delay=5)
            except:
                pass
            delete = 15
        else:
            delete = None

        if not channel:
            return await utils.cmdFail(
                ctx,
                f'Limited role requests are currently disabled for this guild.',
                delete_after=delete)

        existing_request = list(
            filter(lambda e: e['role'] == role.id, users_requests))
        if existing_request and existing_request[-1]['status'] == 'pending':
            return await utils.cmdFail(
                ctx,
                f'You already have a request pending for the role "{role.name}".',
                delete_after=delete)

        # Ratelimit if enabled & ratelimit score above maximum; score calculated from status of requests in last 24h
        if doc['requests_opts']['ratelimit']:
            rl_score = 0
            for r in users_requests:
                rl_score += 0 if not r[
                    "status"] in LIMITED_RATELIMIT_SCORES else LIMITED_RATELIMIT_SCORES[
                        r["status"]]

            if rl_score > LIMITED_RATELIMIT_SCORE_MAX:
                return await utils.cmdFail(
                    ctx,
                    'You have too many recent requests. Please try again later.',
                    delete_after=delete)

        embed = discord.Embed(
            title='Limited Role Request',
            description=
            f'<@{ctx.message.author.id}> requested the <@&{role.id}> role.',
            color=discord.Colour.blurple(),
            timestamp=datetime.datetime.utcnow() +
            datetime.timedelta(hours=24))
        embed.set_author(
            name=f'{ctx.message.author} ({ctx.message.author.id})',
            icon_url=ctx.message.author.avatar_url)
        embed.add_field(name='Status',
                        value='Pending. React to approve or deny the request.')
        embed.set_footer(text='Request expires')

        embed_message = await ctx.guild.get_channel(channel).send(embed=embed)
        await embed_message.add_reaction(config.greenTick)
        await embed_message.add_reaction(config.redTick)

        utils.guildKeySet(
            ctx.bot, ctx.guild, f'requests.{embed_message.id}', {
                'channel': embed_message.channel.id,
                'created': datetime.datetime.utcnow().timestamp(),
                'role': role.id,
                'status': 'pending',
                'user': ctx.author.id,
            })

        return await utils.cmdSuccess(
            ctx,
            f'Your request for "{role.name}" has been submitted.',
            delete_after=delete)
예제 #6
0
    async def request_update(self,
                             guild,
                             message_id,
                             request,
                             status,
                             mod=None):
        statuses = {
            'cancelled': {
                'colour': discord.Colour.darker_grey(),
                'footer': 'Request cancelled',
                'status': 'Cancelled by user.'
            },
            'approved': {
                'colour': discord.Colour.dark_green(),
                'dm': 'been approved.',
                'footer': 'Request approved',
                'status': f'Approved by {mod}.'
            },
            'denied': {
                'colour': discord.Colour.dark_red(),
                'dm': 'been denied.',
                'footer': 'Request denied',
                'status': f'Denied by {mod}.'
            },
            'expired': {
                'colour': discord.Colour.greyple(),
                'dm': 'expired due to lack of moderator response.',
                'footer': 'Request expired',
                'status': f'Request expired due to lack of moderator response.'
            }
        }

        member = await guild.fetch_member(request['user'])
        role = guild.get_role(request['role'])
        layout = statuses[status]

        if status == 'approved':
            await member.add_roles(role, reason='User role request approved')

        if status == 'expired':
            utils.guildKeyDel(self.bot, guild, f'requests.{message_id}')
        else:
            utils.guildKeySet(self.bot, guild, f'requests.{message_id}.status',
                              status)

        if request['status'] == 'pending':
            channel = await self.bot.fetch_channel(request['channel'])

            try:
                embed_message = await channel.fetch_message(message_id)

                embed = embed_message.embeds[0]
                embed.colour = layout['colour']
                embed.timestamp = datetime.datetime.utcnow()
                embed.set_footer(text=layout['footer'])
                embed.remove_field(0)
                embed.add_field(name='Status', value=layout['status'])

                await embed_message.edit(embed=embed)
                await embed_message.clear_reactions()
            except:
                pass

            if status != 'cancelled':
                try:
                    await member.send(
                        f'Your request for "{role}" in "{guild}" has {layout["dm"]}'
                    )
                except:
                    pass
        return