コード例 #1
0
    async def getprofilemeta(self, ctx: Context, profile: Profile,
                             target_user: Member):
        """Gets a profile for a given member"""

        # See if there's a set profile
        user_profile = profile.get_profile_for_member(target_user
                                                      or ctx.author)
        if user_profile is None:
            if target_user:
                await ctx.send(
                    f"{target_user.mention} doesn't have a profile for `{profile.name}`."
                )
            else:
                await ctx.send(
                    f"You don't have a profile for `{profile.name}`.")
            return

        # See if verified
        if user_profile.verified or member_is_moderator(ctx.bot, ctx.author):
            await ctx.send(embed=user_profile.build_embed())
            return

        # Not verified
        if target_user:
            await ctx.send(
                f"{target_user.mention}'s profile hasn't been verified yet.")
        else:
            await ctx.send(f"Your profile hasn't been verified yet.")
        return
コード例 #2
0
    async def deleteprofilemeta(self, ctx: Context, profile: Profile,
                                target_user: Member):
        """Handles deleting a profile"""

        # Handle permissions
        if ctx.author != target_user and not member_is_moderator(
                self.bot, ctx.author):
            await ctx.send(
                f"You're missing the `manage_roles` permission required to do this."
            )
            return

        # Check it exists
        if profile.get_profile_for_member(target_user or ctx.author) is None:
            if target_user:
                await ctx.send(
                    f"{target_user.mention} doesn't have a profile set for `{profile.name}`."
                )
            else:
                await ctx.send(
                    f"You don't have a profile set for `{profile.name}`.")
            return

        # Database it babey
        async with self.bot.database() as db:
            await db(
                'DELETE FROM filled_field WHERE user_id=$1 AND field_id in (SELECT field_id FROM field WHERE profile_id=$2)',
                target_user.id, profile.profile_id)
            await db(
                'DELETE FROM created_profile WHERE user_id=$1 AND profile_id=$2',
                target_user.id, profile.profile_id)
        del UserProfile.all_profiles[(target_user.id, ctx.guild.id,
                                      profile.name)]
        await ctx.send("Profile deleted.")
コード例 #3
0
    async def verification_emoji_check(self, payload: RawReactionActionEvent):
        '''Triggered when a reaction is added or removed, check for profile verification'''

        # Firstly we wanna check the message being reacted to, make sure its ours
        channel_id = payload.channel_id
        channel: TextChannel = self.bot.get_channel(channel_id)
        if channel is None:
            channel: TextChannel = await self.bot.fetch_channel(channel_id)

        # Get the message from the channel
        message: Message = await channel.fetch_message(payload.message_id)

        # Check if we're the author
        if message.author.id != self.bot.user.id:
            return

        # Check if there's an embed
        if not message.embeds:
            return

        # Make sure it's the right kind of embed
        embed: Embed = message.embeds[0]
        if 'Verification Check' not in embed.footer.text:
            return
        # profile_name = embed.footer.text.split('//')[0].strip().lower()
        profile_name = embed.title.split(' ')[0].strip().lower()

        # It's a verification message! Now we wanna check the author to make sure they're approved
        # Get guild
        guild_id = payload.guild_id
        guild: Guild = self.bot.get_guild(guild_id)
        if guild is None:
            guild: Guild = await self.bot.fetch_guild(guild_id)

        # Get the member from the guild
        member: Member = guild.get_member(payload.user_id)

        # Make sure they aren't a bot
        if member.bot:
            return

        # Check their permissions
        if not member_is_moderator(self.bot, member):
            return

        # And FINALLY we can check their emoji
        if payload.emoji.id and payload.emoji.id not in [
                self.TICK_EMOJI_ID, self.CROSS_EMOJI_ID
        ]:
            return

        # Check what they reacted with
        verify = payload.emoji.id == self.TICK_EMOJI_ID

        # Check whom and what we're updating
        profile_user_id, profile_id = message.content.split('\n')[-1].split(
            '/')
        profile_user_id = int(profile_user_id)

        # Decide whether to verify or to delete
        async with self.bot.database() as db:
            if verify:
                await db(
                    'UPDATE created_profile SET verified=true WHERE user_id=$1 AND profile_id=$2',
                    profile_user_id, profile_id)
            else:
                await db(
                    'DELETE FROM filled_field WHERE user_id=$1 AND field_id IN (SELECT field_id FROM field WHERE profile_id=$2)',
                    profile_user_id, profile_id)
                await db(
                    'DELETE FROM created_profile WHERE user_id=$1 AND profile_id=$2',
                    profile_user_id, profile_id)

        # Delete the verify message
        await message.delete()

        # Get the profile
        profile = UserProfile.all_profiles.get(
            (profile_user_id, guild.id, profile_name))
        if profile is None:
            # Silently fail I guess
            return

        # Remove them if necessary
        if verify is False:
            del UserProfile.all_profiles[(profile_user_id, guild.id,
                                          profile_name)]
        else:
            profile.verified = verify

        # Tell the user about the decision
        user: User = self.bot.get_user(profile_user_id)
        if user is None:
            user: User = await self.bot.fetch_user(profile_user_id)
        try:
            if verify:
                await user.send(
                    f"Your profile for `{profile.profile.name}` on `{guild.name}` has been verified.",
                    embed=profile.build_embed())
            else:
                await user.send(
                    f"Your profile for `{profile.profile.name}` on `{guild.name}` has been denied.",
                    embed=profile.build_embed())
        except Exception:
            # Issues sending info to the user, just fail silently
            # raise e
            pass
コード例 #4
0
    async def setprofilemeta(self, ctx: Context, profile: Profile,
                             target_user: Member):
        """Talks a user through setting up a profile on a given server"""

        # Set up some variaballlales
        user = ctx.author
        target_user = target_user or user
        fields = profile.fields

        # Check if they're setting someone else's profile and they're not a mod
        if target_user != ctx.author and not member_is_moderator(
                ctx.bot, ctx.author):
            await ctx.send(
                f"You're missing the `manage_roles` permission required to do this."
            )
            return

        # Check if they already have a profile set
        user_profile = profile.get_profile_for_member(target_user)
        if user_profile is not None:
            await ctx.send(
                f"{'You' if target_user == user else target_user.mention} already {'have' if target_user == user else 'has'} a profile set for `{profile.name}`."
            )
            return

        # See if you we can send them the PM
        try:
            await user.send(
                f"Now talking you through setting up a `{profile.name}` profile{' for ' + target_user.mention if target_user != user else ''}."
            )
            await ctx.send("Sent you a PM!")
        except Exception:
            await ctx.send(
                "I'm unable to send you PMs to set up the profile :/")
            return

        # Talk the user through each field
        filled_fields = []
        for field in fields:
            await user.send(field.prompt)

            # User text input
            if isinstance(field.field_type, (TextField, NumberField)):
                check = lambda m: m.author == user and isinstance(
                    m.channel, DMChannel)
                while True:
                    try:
                        m = await self.bot.wait_for('message',
                                                    check=check,
                                                    timeout=field.timeout)
                    except AsyncTimeoutError:
                        await user.send(
                            f"Your input for this field has timed out. Please try running `set{profile.name}` on your server again."
                        )
                        return
                    try:
                        field.field_type.check(m.content)
                        field_content = m.content
                        break
                    except FieldCheckFailure as e:
                        await user.send(e.message)

            # Image input
            elif isinstance(field.field_type, ImageField):
                check = lambda m: m.author == user and isinstance(
                    m.channel, DMChannel)
                while True:
                    try:
                        m = await self.bot.wait_for('message',
                                                    check=check,
                                                    timeout=field.timeout)
                    except AsyncTimeoutError:
                        await user.send(
                            f"Your input for this field has timed out. Please try running `set{profile.name}` on your server again."
                        )
                        return
                    try:
                        if m.attachments:
                            content = m.attachments[0].url
                        else:
                            content = m.content
                        field.field_type.check(content)
                        field_content = content
                        break
                    except FieldCheckFailure as e:
                        await user.send(e.message)

            # Invalid field type apparently
            else:
                raise Exception(
                    f"Field type {field.field_type} is not catered for")

            # Add field to list
            filled_fields.append(
                FilledField(target_user.id, field.field_id, field_content))

        # Make the UserProfile object
        up = UserProfile(target_user.id, profile.profile_id,
                         profile.verification_channel_id == None)

        # Make sure the bot can send the embed at all
        try:
            await user.send(embed=up.build_embed())
        except Exception as e:
            await user.send(
                f"Your profile couldn't be sent to you - `{e}`.\nPlease try again later."
            )
            return

        # Make sure the bot can send the embed to the channel
        if profile.verification_channel_id:
            try:
                channel = await self.bot.fetch_channel(
                    profile.verification_channel_id)
                embed = up.build_embed()
                embed.set_footer(
                    text=f'{profile.name.upper()} // Verification Check')
                v = await channel.send(
                    f"New **{profile.name}** submission from {target_user.mention}\n{target_user.id}/{profile.profile_id}",
                    embed=embed)
                await v.add_reaction(self.TICK_EMOJI)
                await v.add_reaction(self.CROSS_EMOJI)
            except Exception as e:
                await user.send(
                    f"Your profile couldn't be send to the verification channel? - `{e}`."
                )
                return

        # Database me up daddy
        async with self.bot.database() as db:
            try:
                await db(
                    'INSERT INTO created_profile (user_id, profile_id, verified) VALUES ($1, $2, $3)',
                    up.user_id, up.profile.profile_id, up.verified)
            except UniqueViolationError:
                await db(
                    'UPDATE created_profile SET verified=$3 WHERE user_id=$1 AND profile_id=$2',
                    up.user_id, up.profile.profile_id, up.verified)
                await db(
                    'DELETE FROM filled_field WHERE user_id=$1 AND field_id in (SELECT field_id FROM field WHERE profile_id=$2)',
                    up.user_id, up.profile.profile_id)
                self.log_handler.warn(
                    f"Deleted profile for {up.user_id} on UniqueViolationError"
                )
            for field in filled_fields:
                await db(
                    'INSERT INTO filled_field (user_id, field_id, value) VALUES ($1, $2, $3)',
                    field.user_id, field.field_id, field.value)

        # Respond to user
        await user.send("Your profile has been created and saved.")