Beispiel #1
0
    async def jumbo(self, ctx, emoji):
        """Send the full-size image of an emoji."""
        await send_warning(
            ctx,
            "This command is still in development; you might encounter some bugs."
        )

        # convert to emoji
        try:
            conv = commands.PartialEmojiConverter()
            emoji = await conv.convert(ctx=ctx, argument=emoji)
        except:
            raise CustomCommandError(
                "This command requires that you submit a custom emoji. Use the emoji itself, "
                "not just its name.")

        emoji_int = emoji.id
        emoji_int = int(emoji_int)

        if emoji.animated:  # animated; get gif
            url = f"https://cdn.discordapp.com/emojis/{emoji_int}.gif"
        else:  # static; get png
            url = f"https://cdn.discordapp.com/emojis/{emoji_int}.png"

        jumbo_embed = discord.Embed(colour=Colours.success)
        jumbo_embed.set_image(url=url)

        # send
        await ctx.message.channel.send(embed=jumbo_embed)
 async def _add_emoji_to_react_list(self, ctx, name, emoji):
     """
             Do '!add_emoji_to_react_list <name> <emoji>'
             For example: `!add_emoji_to_react_list blaseball, :ballclark:`
             (don't include the <> or [] when running the command)
             (don't use a comma in this command!)
             Also works with '!aerl'
             """
     if not self.has_role(ctx, self.allowed_role):
         return await ctx.message.delete()
     rl_name = f"{ctx.guild.id}_{name.strip()}"
     if rl_name not in self.word_reacts.keys():
         await ctx.send(f"No react list named {name} found.",
                        delete_after=10)
         return await ctx.message.add_reaction(self.bot.failed_react)
     converter = commands.PartialEmojiConverter()
     done = False
     try:
         emoji_to_add = await converter.convert(ctx, emoji)
         await ctx.message.add_reaction(emoji_to_add)
         self.word_reacts[rl_name]["emoji_list"].append(emoji_to_add)
         done = True
     except:
         try:
             await ctx.message.add_reaction(emoji)
             emoji_to_add = emoji
             self.word_reacts[rl_name]["emoji_list"].append(emoji_to_add)
             done = True
         except:
             pass
     self.save_word_reacts()
     if not done:
         await ctx.message.add_reaction(self.bot.failed_react)
         return await ctx.send(f"Could not find emoji {emoji}.",
                               delete_after=10)
Beispiel #3
0
    async def add_react_list(self, ctx, *, info):
        """
        Do '!add_react_list <name>, <emoji>, <channel_id>, <word1>[,<word2>, <word3>]'
        For example: `!add_react_list snivy, :snivy:, 103110311031103110, snivy`
        Use 'none' instead of a channel id to apply this react list to all channels.
        (don't include the <> or [] when running the command)
        Also works with '!arl'
        """
        info = re.split(r',\s+', info)
        if len(info) < 4:
            await ctx.message.add_reaction(self.bot.failed_react)
            return await ctx.send(
                "Must provide at least a name for the list, a reaction emoji, channel, and a list of at least 1 listen word.",
                delete_after=10)
        name, emoji, channel_raw, words = info[0], info[1], info[2], info[3:]
        rl_name = f"{ctx.guild.id}_{name}"
        if rl_name in self.react_lists.keys():
            await ctx.message.add_reaction(self.bot.failed_react)
            return await ctx.send(
                f"A reaction list already exists for {name}. To add a word to its list, use the "
                f"`!add_word_to_react_list/!awrl` command",
                delete_after=20)
        utilities_cog = self.bot.cogs.get('Utilities')
        channel_id = "none"
        if channel_raw != "none":
            channel = await utilities_cog.get_channel_by_name_or_id(
                ctx, channel_raw)
            if not channel:
                await ctx.message.add_reaction(self.bot.failed_react)
                return await ctx.send(f"Could not find channel {channel_raw}",
                                      delete_after=10)
            channel_id = channel.id
        converter = commands.PartialEmojiConverter()
        badge_emoji = None
        try:
            badge_emoji = await converter.convert(ctx, info[1].strip())
            emoji = badge_emoji
            await ctx.message.add_reaction(emoji)
        except:
            pass
        try:
            await ctx.message.add_reaction(info[1].strip())
            badge_emoji = info[1].strip()
            emoji = badge_emoji
        except:
            pass
        if not badge_emoji:
            await ctx.message.add_reaction(self.bot.failed_react)
            return await ctx.send("Could not find that emoji.",
                                  delete_after=10)

        self.react_lists[rl_name] = {
            "name": name,
            "emoji": emoji,
            "channel_id": channel_id,
            "guild_id": ctx.guild.id,
            "words": words
        }
        await ctx.message.add_reaction(self.bot.success_react)
    async def _add_word_react(self, ctx, *, info):
        """
        Do '!add_react_list <name>, <emoji>, <channel_id>, <word1>[,<word2>, <word3>]'
        For example: `!add_react_list snivy, :snivy:, 103110311031103110, snivy`
        Use 'none' instead of a channel id to apply this react list to all channels.
        (don't include the <> or [] when running the command)
        Also works with '!arl'
        """
        if not self.has_role(ctx, self.allowed_role):
            return await ctx.message.delete()
        info = re.split(r',\s+', info)
        if len(info) < 2:
            await ctx.message.add_reaction(self.bot.failed_react)
            return await ctx.send(
                "Must provide at least a word and 1 reaction emoji.",
                delete_after=10)
        name = info[0]
        rl_name = f"{ctx.guild.id}_{name}"
        if rl_name in self.word_reacts.keys():
            await ctx.message.add_reaction(self.bot.failed_react)
            return await ctx.send(
                f"A reaction already exists for {name}. To add an emoji to its reaction list, use the "
                f"`!add_emoji_to_react_list/!aerl` command",
                delete_after=20)
        converter = commands.PartialEmojiConverter()
        emoji_list = []
        for i in info[1:]:
            emoji_to_add = None
            emoji = i.strip()
            try:
                emoji_to_add = await converter.convert(ctx, emoji)
                await ctx.message.add_reaction(emoji_to_add)
                emoji_list.append(emoji_to_add)
            except:
                pass
            try:
                await ctx.message.add_reaction(emoji)
                emoji_to_add = emoji
                emoji_list.append(emoji_to_add)
            except:
                pass
            if not emoji_to_add:
                await ctx.message.add_reaction(self.bot.failed_react)
                return await ctx.send(f"Could not find emoji {i}.",
                                      delete_after=10)

        self.word_reacts[rl_name] = {
            "name": name,
            "emoji_list": emoji_list,
            "guild_id": ctx.guild.id
        }
        self.save_word_reacts()
        await ctx.message.add_reaction(self.bot.success_react)
Beispiel #5
0
 async def get_count(self, ctx, emoji):
     converter = commands.PartialEmojiConverter()
     try:
         react_emoji = await converter.convert(ctx, emoji.strip())
     except:
         await ctx.message.add_reaction(self.bot.failed_react)
         return await ctx.send("Could not find that emoji.", delete_after=10)
     if str(react_emoji.id) not in self.counts:
         await ctx.message.add_reaction(self.bot.failed_react)
         return await ctx.send("No react counter found with that emoji.", delete_after=10)
     react_count = self.counts[str(react_emoji.id)]
     await ctx.send(f"I have counted {react_count['count']} {react_count['message']}")
Beispiel #6
0
 async def _add(self, ctx, *, info):
     """**Usage**: `!badge add <emoji>, <badge name>, [<badge description], [create in pokenav]`
     **Aliases**: `create, cr, new`
     Emoji and name are required with a comma between each. Description is optional
     Optionally can provide "false/no" to prevent badge from being created in Pokenav as well.
     By default, badge will be created on both bots
     """
     info = re.split(r',\s+', info)
     if len(info) < 2:
         await ctx.message.add_reaction(self.bot.failed_react)
         self.bot.help_logger.info(f"User: {ctx.author.name}, channel: {ctx.channel}, error: Insufficient badge info: {info}.")
         return await ctx.send("Must provide at least an emoji and badge name, and optionally badge description.",
                               delete_after=10)
     converter = commands.PartialEmojiConverter()
     try:
         badge_emoji = await converter.convert(ctx, info[0].strip())
     except:
         badge_emoji = None
     if not badge_emoji:
         await ctx.message.add_reaction(self.bot.failed_react)
         self.bot.help_logger.info(f"User: {ctx.author.name}, channel: {ctx.channel}, error: No emoji found: {info[0]}.")
         return await ctx.send("Could not find that emoji.", delete_after=10)
     badge_name = info[1]
     badge_desc = ''
     create_in_pokenav = True
     if len(info) > 2:
         badge_desc = info[2]
         if len(info) > 3:
             if info[3].lower() == 'false' or info[3].lower() == 'no':
                 create_in_pokenav = False
     try:
         new_badge, __ = BadgeTable.get_or_create(name=badge_name, description=badge_desc,
                                                  emoji=badge_emoji.id, active=True)
         if new_badge:
             send_emoji = self.bot.get_emoji(badge_emoji.id)
             message = f"{send_emoji} {badge_name} (#{new_badge.id}) successfully created!"
             colour = discord.Colour.green()
             reaction = self.bot.success_react
             quick_badge_config = self.bot.guild_dict[ctx.guild.id]['configure_dict'].get('quick_badge', None)
             if create_in_pokenav and quick_badge_config is not None:
                 pokenav_channel_id = quick_badge_config['pokenav_channel']
                 pokenav_channel = self.bot.get_channel(pokenav_channel_id)
                 await pokenav_channel.send(f'$create badge {badge_emoji} "{badge_name}" "{badge_desc}"')
         else:
             message = "Failed to create badge. Please try again."
             colour = discord.Colour.red()
             reaction = self.bot.failed_react
     except peewee.IntegrityError:
         message = f"""A badge already exists with the same name, description, and emoji."""
         colour = discord.Colour.red()
         reaction = self.bot.failed_react
     await ctx.message.add_reaction(reaction)
     await ctx.channel.send(embed=discord.Embed(colour=colour, description=message))
Beispiel #7
0
 async def _add(self, ctx, *, info):
     info = re.split(r',\s+', info)
     if len(info) < 2:
         await ctx.message.add_reaction(self.bot.failed_react)
         self.bot.help_logger(
             f"User: {ctx.author.name}, channel: {ctx.channel}, error: Insufficient badge info: {info}."
         )
         return await ctx.send(
             "Must provide at least an emoji and badge name, and optionally badge description.",
             delete_after=10)
     converter = commands.PartialEmojiConverter()
     try:
         badge_emoji = await converter.convert(ctx, info[0])
     except:
         badge_emoji = None
     if not badge_emoji:
         await ctx.message.add_reaction(self.bot.failed_react)
         self.bot.help_logger(
             f"User: {ctx.author.name}, channel: {ctx.channel}, error: No emoji found: {info[0]}."
         )
         return await ctx.send("Could not find that emoji.",
                               delete_after=10)
     badge_name = info[1]
     badge_desc = ''
     if len(info) > 2:
         badge_desc = info[2]
     try:
         new_badge, __ = BadgeTable.get_or_create(name=badge_name,
                                                  description=badge_desc,
                                                  emoji=badge_emoji.id,
                                                  active=True)
         if new_badge:
             send_emoji = self.bot.get_emoji(badge_emoji.id)
             message = f"{send_emoji} {badge_name} (#{new_badge.id}) successfully created!"
             colour = discord.Colour.green()
             reaction = self.bot.success_react
         else:
             message = "Failed to create badge. Please try again."
             colour = discord.Colour.red()
             reaction = self.bot.failed_react
     except peewee.IntegrityError:
         message = f"""A badge already exists with the same name, description, and emoji."""
         colour = discord.Colour.red()
         reaction = self.bot.failed_react
     await ctx.message.add_reaction(reaction)
     response = await ctx.channel.send(embed=discord.Embed(
         colour=colour, description=message),
                                       delete_after=12)
Beispiel #8
0
async def emojibig(ctx, *, emote):
    emoji_converter = commands.PartialEmojiConverter()
    emoji = await emoji_converter.convert(ctx, emote)
    emotestring = str(emote)
    colon1 = emotestring.find(':')
    colon2 = emotestring.rfind(':')
    filename = emotestring[colon1 + 1:colon2]
    filepath = 'assets/Emotes/' + filename
    if emotestring[1] == "a":
        filepath += ".gif"
    else:
        filepath += ".jpg"
    with open(os.path.join(filepath), "wb+") as f:
        await emoji.url.save(filepath)
        await ctx.send(file=discord.File(filepath))
    os.remove(filepath)
Beispiel #9
0
 async def zipemojis(self, ctx: commands.Context,
                     *messages: discord.Message):
     async with ctx.typing():
         regex = r"<(a?):([a-zA-Z0-9\_]+):([0-9]+)>"
         emojis = []
         for m in messages:
             for em in re.finditer(regex, m.content):
                 try:
                     pec = commands.PartialEmojiConverter()
                     em = await pec.convert(ctx=ctx, argument=em.group(0))
                     emojis.append(em)
                 except PartialEmojiConversionFailure:
                     pass
         if len(emojis) == 0:
             await ctx.reply("No emojis found.")
             return
         await self.partial_emoji_list_to_uploaded_zip(ctx, emojis)
Beispiel #10
0
    async def add_react_counter(self, ctx, *, info):
        info = re.split(r',\s+', info)
        if len(info) < 4:
            await ctx.message.add_reaction(self.bot.failed_react)
            return await ctx.send("Must provide at least an emoji, counter name, target user, counter message,  optionally channel id(s).",
                                  delete_after=10)
        converter = commands.PartialEmojiConverter()
        try:
            badge_emoji = await converter.convert(ctx, info[0].strip())
        except:
            await ctx.message.add_reaction(self.bot.failed_react)
            return await ctx.send("Could not find that emoji.", delete_after=10)
        if str(badge_emoji.id) in self.counts.keys():
            await ctx.message.add_reaction(self.bot.failed_react)
            return await ctx.send("React counter already exists with that emoji.", delete_after=10)
        converter = commands.MemberConverter()
        try:
            member = await converter.convert(ctx, info[2])
        except:
            await ctx.message.add_reaction(self.bot.failed_react)
            return await ctx.send(f"Could not find user {info[2]}.", delete_after=10)
        counter_name = info[1]
        channel_ids = []
        counter_message = info[3]
        if len(info) > 4:
            channel_ids_raw = info[4:]

            for c_id in channel_ids_raw:
                utilities_cog = self.bot.cogs.get('Utilities')
                channel = await utilities_cog.get_channel_by_name_or_id(ctx, c_id)
                if channel:
                    channel_ids.append(channel.id)
        self.counts[badge_emoji.id] = {
            "name": counter_name,
            "emoji_id": badge_emoji.id,
            "channel_ids": channel_ids,
            "user": member.id,
            "message": counter_message,
            "count": 0
        }
        await ctx.message.add_reaction(self.bot.success_react)
        success_msg = f"Counter '**{counter_name}**' added with emoji {badge_emoji}."
        if len(channel_ids) > 0:
            success_msg += f" Active in {len(channel_ids)} channels."
        self.save_react_counts()
        return await ctx.send(success_msg, delete_after=10)
Beispiel #11
0
    async def convert(self, ctx: utils.CustomContext, argument: str):

        converters = {
            commands.TextChannelConverter(): "Text Channel",
            commands.VoiceChannelConverter(): "Voice Channel",
            commands.MemberConverter(): "Server Member",
            commands.UserConverter(): "Discord User",
            commands.PartialEmojiConverter(): "Emoji",
            utils.RoleConverter(): "Server Role",
        }

        for converter, title in converters.items():
            try:
                convert = await converter.convert(ctx, argument)
                return convert.id, title
            except Exception as e:
                continue

        raise commands.BadArgument("Couldn't find anything that matches that.")
    async def convert(self, ctx: utils.CustomContext, argument: str):
        try:
            member_converter = commands.MemberConverter()
            member = await member_converter.convert(ctx, argument)

            asset = member.avatar_url_as(static_format="png",
                                         format="png",
                                         size=512)
            image = await asset.read()

            return image

        except (commands.MemberNotFound, TypeError):

            url_regex = r"http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*(),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+"
            try:
                emoji_regex = r"<(?P<animated>a?):(?P<name>[a-zA-Z0-9_]{2,32}):(?P<id>[0-9]{18,22})>"

                url = await twemoji_parser.emoji_to_url(argument,
                                                        include_check=True)
                if re.match(url_regex, url):
                    async with ctx.bot.session.get(url) as response:
                        image_bytes = await response.read()
                        return image_bytes

                if re.match(url_regex, argument):
                    async with ctx.bot.session.get(argument) as response:
                        image = await response.read()
                        return image

                elif re.match(emoji_regex, argument):
                    emoji_converter = commands.PartialEmojiConverter()
                    emoji = await emoji_converter.convert(ctx, argument)

                    asset = emoji.url
                    image = await asset.read()

                    return image
            except TypeError:
                return None

        return None
Beispiel #13
0
    async def convert(self, ctx, argument):
        if self.check_embed and url_regex.fullmatch(argument) is not None:
            if ctx.message.embeds:
                embed = ctx.message.embeds[0]
            else:

                def check(_, message):
                    return message.id == ctx.message.id and message.embeds

                try:
                    _, message = await ctx.bot.wait_for('message_edit',
                                                        timeout=2,
                                                        check=check)
                except asyncio.TimeoutError:
                    raise commands.BadArgument

                embed = message.embeds[0]
            if embed.type != 'image':
                raise commands.CheckFailure

            return embed.thumbnail.proxy_url

        if self.check_member:
            converter = commands.MemberConverter()
            try:
                member = await converter.convert(ctx, argument)
            except commands.BadArgument:
                pass
            else:
                return member.avatar_url

        if self.check_emoji:
            converter = commands.PartialEmojiConverter()
            try:
                emoji = await converter.convert(ctx, argument)
            except commands.BadArgument:
                pass
            else:
                return emoji.url

        raise commands.BadArgument
Beispiel #14
0
    async def convert(self, ctx, argument):
        find_member = lambda s: self.re_member.findall(s)
        find_emoji = lambda s: self.re_emoji.findall(s)

        converters = (
            (find_member, commands.MemberConverter(), 0),
            (find_emoji, commands.PartialEmojiConverter(), 1),
        )

        args = argument.replace(", ", ",").replace(" ,", ",").split(",")
        if not isinstance(args, list):
            args = [args]

        args = args[:self.n]
        if self.require and len(args) != self.n:
            raise commands.UserInputError()

        parsed = []
        for arg in args:
            added = 0
            for pack in converters:
                search, converter, i = pack
                found = search(arg)
                if found and (arg.strip() == found[0]):
                    obj = await converter.convert(ctx=ctx, argument=found[0])
                    if obj:
                        parsed.append(obj)
                        added = 1
                        break

            if not added:
                parsed.append(await
                              commands.clean_content(
                                  use_nicknames=True,
                                  fix_channel_mentions=True).convert(ctx, arg))

        return parsed[:self.n]
    def __init__(self, bot):
        self.bot = bot
        self.client = bot.client

        self.table = self.client['Giveaways']
        self.codes = self.table['codes']

        self.channel_converter = commands.TextChannelConverter()
        self.emoji_converter = commands.PartialEmojiConverter()
        ## Using partial so i can accept default emoji's as well

        self.giveaways = {}
        self.questions = (
            'Which channel would you like to set this giveaway up in?',
            'How many winners would you like for this giveaway',
            'How long will this giveaway last for? Please use the format of `<TIME>[s/m/h/d/w]`, default is set to seconds.',
            'Are there any requirements? (y/n)',
            'What is the prize for this giveaway?',
            'Would you like a custom emoji in place of the default option "🎉", if not simply respond with `no`. Else send the emoji below. Warning: If using a discord custom emoji, please ensure the bot is in the server that has the emoji.'
        )

        self.scopes = {
            ## 'message': 2,
            ## 'invite': 3,

            ## Adding the message and invite option later when I get them done.
            'guild': {
                'scope': 1,
                'aliases': ['guilds']
            },
            'server': {
                'scope': 1,
                'aliases': ['servers']
            },
            ## This is for the reverse search.
            'role': {
                'scope': 2,
                'aliases': ['roles']
            },
            'creation-date': {
                'scope': 3,
                'aliases': ['creation']
            },
            'join-date': {
                'scope': 4,
                'aliases': ['join']
            },
            'exit': {
                'scope': 5,
                'aliases': []
            },
        }

        self.aliase_to_scope = {}

        for key, value in self.scopes.items():
            for aliase in value['aliases']:
                self.aliase_to_scope.update({aliase: key})

        self.scales = {
            's': 1,
            'm': 60,
            'h': (60 * 60),
            'd': ((60 * 60) * 24),
            'w': (((60 * 60) * 24) * 7)
        }

        self.marks = {
            's': 'second(s)',
            'm': 'minutes(s)',
            'h': 'hour(s)',
            'd': 'day(s)',
            'w': 'week(s)'
        }

        self.listed_scopes = ''

        for scope in self.scopes:
            self.listed_scopes += '%s|' % scope

            for aliase in self.scopes[scope]['aliases']:
                self.listed_scopes += '%s|' % aliase

        self.listed_scopes = self.listed_scopes[:-1].split('|')

        for guild in bot.guilds:
            self.giveaways[guild.id] = {}

        bot.loop.create_task(self.load_giveaways())
Beispiel #16
0
    async def init(self, ctx):
        """
        Initialize role message for current channel

        :param ctx: Context
        :return:
        """
        async with session_lock:
            with Session() as session:
                db_server = get_create_ctx(ctx, session, server_crud)

                embed = Embed()
                embed.title = f"Assignable roles for **{ctx.guild.name}**"
                embed.description = "Use reactions inorder to get " \
                                    "roles assigned to you, or use " \
                                    "`!role add roleName`"

                converter = commands.EmojiConverter()
                pconverter = commands.PartialEmojiConverter()

                # Get all roles on the server
                roles = role_crud.get_multi_by_server_uuid(
                    session, get_create_ctx(ctx, session, server_crud).uuid
                )

                # Gather all used emojis for future reactions
                emojis = []

                for r in roles:

                    emoji = emoji_crud.get_by_role(
                        session, r.uuid
                    )

                    if emoji is not None:

                        try:
                            # Convert into actual emoji
                            e = await converter.convert(
                                ctx, emoji.identifier
                            )
                        except commands.EmojiNotFound:
                            # Try partial emoji instead
                            try:
                                e = await pconverter.convert(
                                    ctx, emoji.identifier
                                )
                            except commands.PartialEmojiConversionFailure:
                                # Assume that it is an unicode emoji
                                e = emoji.identifier

                        # Add to message
                        embed.add_field(
                            name=f"{str(e)}  ==  {r.name}",
                            value=r.description,
                            inline=False
                        )

                        emojis.append(e)

                # Send message
                role_message = await ctx.send(embed=embed)

                # Add reaction to message with all used emojis
                for e in emojis:
                    await role_message.add_reaction(e)

                # Update server object to include role message data
                server_update = UpdateServer(**{
                    "role_message": str(role_message.id),
                    "role_channel": str(ctx.channel.id)
                })

                server_crud.update(
                    session, db_obj=db_server, obj_in=server_update
                )
Beispiel #17
0
    async def create(
            self, ctx, discord_id: int, description: str, emoji: str = None
    ):
        """
        Create assignable role

        :param ctx: Context
        :param discord_id: Role Discord ID
        :param description: Description of role usage
        :param emoji: Emoji for assignment via reactions
        :return:
        """
        embed = Embed()
        embed.set_author(name=self.__bot.user.name,
                         url=settings.URL,
                         icon_url=self.__bot.user.avatar_url)
        async with session_lock:
            with Session() as session:
                d_role = ctx.guild.get_role(discord_id)
                db_role = role_crud.get_by_discord(session, discord_id)

                # TODO Add emoji parsing

                if d_role is None:
                    embed.title = "Role not found."
                    embed.colour = Colors.error
                elif db_role is not None:
                    embed.title = "Role already exists!"
                    embed.colour = Colors.other
                else:
                    role = CreateRole(**{
                        "discord_id": discord_id,
                        "name": d_role.name,
                        "description": description,
                        "server_uuid": get_create_ctx(
                            ctx, session, server_crud
                        ).uuid
                    })

                    db_role = role_crud.create(session, obj_in=role)

                    if emoji is not None:
                        converter = commands.EmojiConverter()
                        pconverter = commands.PartialEmojiConverter()

                        try:
                            # Convert into actual emoji
                            e = await converter.convert(
                                ctx, emoji
                            )
                        except commands.EmojiNotFound:
                            # Try partial emoji instead
                            try:
                                e = await pconverter.convert(
                                    ctx, emoji
                                )
                            except commands.PartialEmojiConversionFailure:
                                # Assume that it is an unicode emoji
                                e = emoji
                    else:
                        e = None

                    if e is not None and not isinstance(e, discord.partial_emoji.PartialEmoji):

                        if hasattr(e, 'name'):
                            e = e.name

                        db_e = CreateRoleEmoji(**{
                            "identifier": e,
                            "role_uuid": db_role.uuid
                        })
                        emoji_crud.create(session, obj_in=db_e)
                    elif isinstance(emoji, discord.partial_emoji.PartialEmoji):
                        embed.description = "**Note**: Role was created" \
                                            " without an emoji, because the bot " \
                                            "cannot use provided emoji..."
                    else:
                        embed.description = "**Note**: Role was created" \
                                            " without an emoji, so it " \
                                            "cannot be assigned with " \
                                            "reactions!"

                    embed.title = f"Role *{db_role.name}* created."
                    embed.colour = Colors.success
        embed.timestamp = datetime.utcnow()
        await ctx.send(embed=embed)
Beispiel #18
0
    async def role_update(self):
        """
        Update roles stored every 30 minutes
        :return:
        """
        await self.__bot.wait_until_ready()
        logger.info("Updating role messages...")

        async with session_lock:
            with Session() as session:

                # Go through all visible guilds
                for guild in self.__bot.guilds:

                    server = server_crud.get_by_discord(session, guild.id)

                    # Skip if server is not found
                    if server is None:
                        continue

                    # Get all roles for server
                    roles = role_crud.get_multi_by_server_uuid(
                        session, server.uuid
                    )

                    temp_roles = {}

                    for r in roles:
                        temp_roles[r.discord_id] = r

                    # Go through all roles of a guild
                    for r in guild.roles:

                        # Skip roles that are default or premium
                        if r.is_default or r.is_premium_subscriber:
                            continue

                        # Check that role is registered, otherwise skip
                        if r.id not in temp_roles:
                            continue

                        # If the name is the same, then skip
                        if r.name == temp_roles[r.id].name:
                            continue

                        role_update = UpdateRole(**{
                            "name": r.name
                        })

                        # Update role
                        role_crud.update(
                            session, temp_roles[r.id], role_update
                        )

                    # Update role message if it exists
                    if server.role_message is not None and \
                            server.role_channel is not None:
                        channel = self.__bot.get_channel(
                            int(server.role_channel)
                        )

                        # Continue if channel wasn't found
                        if channel is None:
                            logger.info(f"No channel found for {server.name}.")
                            continue

                        # Channel must not be bloated with messages
                        message = utils.find(
                            lambda m: (m.id == int(server.role_message)),
                            await channel.history(limit=10).flatten()
                        )

                        # Continue if message wasn't found
                        if message is None:
                            logger.info(f"No message found for {server.name}.")
                            continue

                        # Get context
                        ctx = await self.__bot.get_context(message)

                        embed = Embed()
                        embed.title = f"Assignable roles for " \
                                      f"**{message.guild.name}**"
                        embed.description = "Use reactions inorder to get " \
                                            "roles assigned to you, or use " \
                                            "`!role add roleName`"

                        converter = commands.EmojiConverter()
                        pconverter = commands.PartialEmojiConverter()

                        # Get all roles of a server
                        roles = role_crud.get_multi_by_server_uuid(
                            session, server.uuid
                        )

                        # Gather all used emojis for future reactions
                        emojis = []

                        for ro in roles:

                            emoji = emoji_crud.get_by_role(session, ro.uuid)

                            try:
                                # Convert into actual emoji
                                e = await converter.convert(
                                    ctx, emoji.identifier
                                )
                            except commands.EmojiNotFound:
                                # Try partial emoji instead
                                try:
                                    e = await pconverter.convert(
                                        ctx, emoji.identifier
                                    )
                                except commands.PartialEmojiConversionFailure:
                                    # Assume that it is an unicode emoji
                                    e = emoji.identifier

                            # Add to message
                            embed.add_field(
                                name=f"{str(e)}  ==  {ro.name}",
                                value=ro.description,
                                inline=False
                            )

                            emojis.append(e)

                        await message.edit(embed=embed)

                        # Check old reactions
                        old_emojis = []
                        for r in message.reactions:
                            old_emojis.append(r.emoji)

                        # Add new reactions to message
                        for e in emojis:
                            if isinstance(e, discord.partial_emoji.PartialEmoji):
                                logger.error(f"Emoji not cannot be used! Emoji: {e}")
                            elif e not in old_emojis:
                                await message.add_reaction(e)

                        logger.info(f"Message updated for {server.name}.")
Beispiel #19
0
# API stuff
BOTS_GG_TOKEN: str = ""


# Colors used in the Bot
class Colours:
    base: Color = Color(16562199)
    success: Color = Color(3066993)
    fail: Color = Color(15742004)
    warn: Color = Color(16707936)


# Custom logging class (can be modified to send Discord alerts etc.)
class DiscordLogger(logging.Logger):
    channel: TextChannel

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    def log(self, *args, **kwargs):
        # TODO: add Discord alerts
        super().log(*args, **kwargs)


# Logger
LOGGER = DiscordLogger(__name__)

# Converters
EMOJI_CONVERTER = commands.EmojiConverter()
PARTIAL_EMOJI_CONVERTER = commands.PartialEmojiConverter()
Beispiel #20
0

type_to_converter = {
    # Builtins
    bool: commands.core._convert_to_bool,
    int: built_in_converter(int),
    str: str,
    # Discord objects
    Role: commands.RoleConverter(),
    User: commands.UserConverter(),
    Member: commands.MemberConverter(),
    Color: commands.ColorConverter(),
    Invite: commands.InviteConverter(),
    Emoji: commands.EmojiConverter(),
    Message: commands.MessageConverter(),
    PartialEmoji: commands.PartialEmojiConverter(),
    TextChannel: commands.TextChannelConverter(),
    VoiceChannel: commands.VoiceChannelConverter(),
    CategoryChannel: commands.CategoryChannelConverter(),
}

_to_str = {
    Message: lambda m: f"Message with id {m.id} in {m.channel.mention}",
}


def to_str(argument: UserInputable) -> str:
    _type = type(argument)
    if issubclass(_type, Enum):
        return argument.name.capitalize().replace("_", " ")
    if _type is Reaction: