예제 #1
0
 async def on_message(self, msg):
     if msg.author.bot:
         return
     if globals.conf.list_contains(globals.conf.keys.CHANNELS, msg.channel.id):
         if globals.bot.user.mentioned_in(msg):
             if '@everyone' not in msg.content and '@here' not in msg.content:
                 member = msg.channel.guild.get_member(globals.bot.user.id) or \
                          await msg.channel.guild.fetch_member(globals.bot.user.id)
                 seed = msg.clean_content.replace(f'@{member.display_name}', '')
                 n = np.random.geometric(0.5)
                 for text in globals.bot.markov.generate_multiple_from_least_common(seed, n):
                     async with msg.channel.typing():
                         await asyncio.sleep(0.04 * len(text))
                         await msg.channel.send(escape_mentions(text))
     if globals.conf.list_contains(globals.conf.keys.CHANNELS, msg.channel.id):
         if (random.random() * 1000) < globals.conf.get(globals.conf.keys.MARKOV_CHANCE):
             member = msg.channel.guild.get_member(globals.bot.user.id) or \
                      await msg.channel.guild.fetch_member(globals.bot.user.id)
             seed = msg.clean_content.replace(f'@{member.display_name}', '')
             for text in globals.bot.markov.generate_multiple_from_least_common(seed):
                 async with msg.channel.typing():
                     await asyncio.sleep(0.04 * len(text))
                     await msg.reply(escape_mentions(text))
     if globals.conf.list_contains(globals.conf.keys.MARKOV_CHANNELS, msg.channel.id):
         globals.bot.markov.insert_text(msg.clean_content, tag=str(msg.author.id))
예제 #2
0
    async def eval(self, ctx, *, code=None) -> None:
        code = code.replace('```python', '')
        code = code.replace('```py', '')
        code = code.replace('`', '')
        code = utils.escape_mentions(code)

        feedback_mes = await ctx.send('Code execution started')
        log.info(
            f'Code: {code} sent for evaluation by author: {ctx.author.id} in guild: {ctx.guild.id}'
        )

        output = await self._post_eval(code)
        stdout = output['stdout']
        stdout = stdout.strip('`')
        stdout = utils.escape_mentions(stdout)

        await feedback_mes.delete()

        if len(stdout) > MAX_CONTENT_LENGTH:
            await ctx.send(
                f'{ctx.author.mention} Attempted output length exceeds 2000 characters, Please try again'
            )
            return

        result_emoji = ':white_check_mark:' if output[
            'returncode'] == 0 else ':warning:'
        out = f'{ctx.author.mention}  {result_emoji} Eval Completed with response code: {output["returncode"]}'
        if stdout:
            await ctx.send(f'{out}\n\n```{self._format(stdout)}```')
        else:
            await ctx.send(f'{out}\n\n```[No Output]```')
예제 #3
0
    async def on_mod_logging_messages(self,
                                      payload: Union[RawMessageUpdateEvent,
                                                     RawMessageDeleteEvent],
                                      message_log_type: MessageLogType):
        if message_log_type is MessageLogType.deleted_message:
            destinations = await self.get_destinations(payload.guild_id,
                                                       ModLoggingType.messages)
            guild_tz = self.bot.cache.guilds.get(payload.guild_id).timezone

            time_fmt = datetime.now().astimezone(
                timezone(guild_tz)).strftime("%H:%M:%S")

            if (cached_message := payload.cached_message) is None:
                message = await self.bot.db.fetchrow(
                    "SELECT * FROM bot.messages WHERE guild_id = $1 AND message_id = $2",
                    payload.guild_id, payload.message_id)

                if message is not None:
                    content = self.bot.cryptor.decrypt(message['content'])
                    content_fmt = utils.escape_mentions(
                        utils.escape_markdown(
                            content.decode(encoding='utf-8')))
                    author = self.bot.get_user(message['author_id'])
                    c = self.bot.get_channel(message['channel_id'])

                    for channel in destinations:
                        await channel.send(
                            Translator.translate('MOD_LOGS_MESSAGE_DELETED',
                                                 payload.guild_id,
                                                 user=str(author),
                                                 time=time_fmt,
                                                 user_id=str(
                                                     message['author_id']),
                                                 content=content_fmt,
                                                 channel=c.mention))

            elif cached_message is not None:
                content_fmt = utils.escape_mentions(
                    utils.escape_markdown(cached_message.content))

                for channel in destinations:
                    await channel.send(
                        Translator.translate(
                            'MOD_LOGS_MESSAGE_DELETED',
                            cached_message.guild.id,
                            user=str(cached_message.author),
                            time=time_fmt,
                            user_id=str(cached_message.author.id),
                            content=content_fmt,
                            channel=cached_message.channel.mention))
예제 #4
0
    async def beers(
        self,
        ctx: commands.Context,
        members: commands.Greedy[Member],
        *,
        reason: commands.clean_content = None,
    ):
        """Invite a bunch of people to have beer"""
        if not members:
            return await ctx.send("You can't have beer with no other person!")
        for member in members:
            if member.bot:
                return await ctx.send("Beer with bots isn't exactly a thing...")

        message = (
            ", ".join(m.display_name for m in members)
            + "\nYou have been invited for beer \U0001f37b by "
            + ctx.author.display_name
            + ((" Reason: " + reason) if reason else "")
        )

        msg = await ctx.send(message)
        await msg.add_reaction("\U0001f37b")

        def check(r, m):
            return m in members and r.message == msg and str(r.emoji) == "\U0001f37b"

        while True:
            try:
                r, _ = await self.bot.wait_for("reaction_add", check=check, timeout=60)
            except asyncio.TimeoutError:
                return await msg.edit(
                    content="Ouch, looks like not everyone wants beer now..."
                )
            else:
                if set(
                    m.id for m in await r.message.reactions[0].users().flatten()
                ).issuperset(m.id for m in members):
                    content = (
                        ", ".join(
                            utils.escape_mentions(m.display_name) for m in members
                        )
                        + ", "
                        + utils.escape_mentions(ctx.author.display_name)
                        + " enjoy a lovely beer together \U0001f37b"
                    )

                    return await msg.edit(content=content)
예제 #5
0
    async def archive_messages(bot, messages: List[Message]):
        # Preparing text file heading
        guild_timezone = bot.cache.guilds.get(messages[0].guild.id).timezone
        server_format = f"{messages[0].guild.name} ({messages[0].guild.id})"
        channel_format = f"{messages[0].channel.name} ({messages[0].channel.id})"
        timezone_format = f"{guild_timezone.title()}"

        output = f"Server: {server_format}\nChannel: {channel_format}\nLogs timezone: {timezone_format}\n\n\n"
        for msg in messages:
            # Preparing format
            created_at_format = msg.created_at.astimezone(
                timezone(guild_timezone)).strftime("%d-%m-%Y %H:%M:%S")
            content_format = utils.escape_markdown(
                utils.escape_mentions(msg.content))
            prefix = f"{created_at_format} | {msg.author} ({msg.author.id})"

            # Adding the message content to output string
            output += f"{prefix}: {content_format}\n"

            # Check if the message has any attachments
            if len(msg.attachments) > 0:
                # Add all the links from message attachments
                for attachment in msg.attachments:
                    output += f"{prefix}: {attachment.proxy_url}\n"

        # Return BytesIO object so it can be used in discord.File
        bdata = io.BytesIO()
        bdata.write(output.encode(encoding='utf-8'))
        bdata.seek(0)
        return bdata
예제 #6
0
    async def prefix(self, ctx: MyContext, new_prefix: Optional[str] = None):
        """
        Change/view the server prefix.

        Note that some prefixes are global and can't be edited.
        """
        db_guild = await get_from_db(ctx.guild)
        _ = await ctx.get_translate_function()

        if new_prefix is not None:
            db_guild.prefix = new_prefix

            await db_guild.save()

        if db_guild.prefix:
            await ctx.send(
                _("The server prefix is set to `{prefix}`.",
                  prefix=escape_mentions(escape_markdown(db_guild.prefix))))
        else:
            language_code = await ctx.get_language_code()

            global_prefixes = self.bot.config['bot']['prefixes']
            global_prefixes_list = babel.lists.format_list(
                global_prefixes, locale=language_code)

            await ctx.send(
                _("There is no specific prefix set for this guild.") + " " +
                _("You can call me with any of the global prefixes : {global_prefixes_list}",
                  global_prefixes_list=global_prefixes_list))
예제 #7
0
    async def language(self,
                       ctx: MyContext,
                       language_code: Optional[str] = None):
        """
        Change/view the server language.

        Specify the server language as a 2/5 letters code. For example, if you live in France, you'd use fr or fr_FR.
        In Québec, you could use fr_QC.
        """
        db_guild = await get_from_db(ctx.guild)
        if language_code:
            db_guild.language = language_code
        await db_guild.save()

        _ = await ctx.get_translate_function()
        if db_guild.language:
            await ctx.send(
                _("The server language is set to `{language}`.",
                  language=escape_mentions(escape_markdown(db_guild.language)))
            )

            # Do not translate
            await ctx.send(
                f"If you wish to go back to the default, english language, use `{ctx.prefix}{ctx.command.qualified_name} en`"
            )
        else:
            await ctx.send(
                _("There is no specific language set for this guild."))
예제 #8
0
    async def _basic_search(self, ctx, query: str, category: str) -> None:
        """Basic search formatting."""
        is_nsfw = ctx.channel.is_nsfw() if hasattr(ctx.channel, "is_nsfw") else False

        async with ctx.typing():
            try:
                results = await self._search_logic(query, is_nsfw, category)
            except SafesearchFail:
                await ctx.send(
                    f":x: Sorry {ctx.author.mention}, your message contains filtered words, I've removed this message."
                )
                return await ctx.message.delete()
            count = len(results)

            # Ignore markdown when displaying
            query_display = utils.escape_mentions(query)
            query_display = utils.escape_markdown(query_display)

            # Return if no results
            if not count:
                return await ctx.send(f"No results found for `{query_display}`.")

            # Gets the first entry's data
            first_title = self.tomd.handle(
                results[0]["title"]).rstrip("\n").strip("<>")
            first_url = results[0]["url"]
            first_desc = self.tomd.handle(results[0]["desc"]).rstrip("\n")

            # Builds the substring for each of the other result.
            other_results: List[str] = []

            for result in results[1:count]:
                title = self.tomd.handle(result["title"]).rstrip("\n")
                url = result["url"]
                other_results.append(f"**{title}**\n{url}")

            other_msg = "\n\n".join(other_results).strip()

            # Builds message
            msg = textwrap.dedent(
                f"""
                [{first_title.strip("<>")}]({first_url.strip("<>")})\n
                {first_desc}\n
                {other_msg}
                """
            )

            msg = re.sub(
                r"(https?://(?:www\.)?[-a-zA-Z0-9@:%._+~#=]+\."
                r"[a-zA-Z0-9()]+\b[-a-zA-Z0-9()@:%_+.~#?&/=]*)",
                r"<\1>",
                msg,
            )

            embed = Embed(title="Search Results",
                          description=msg, color=Color.blue())
            embed.set_footer(
                text=f"Showing {count} results for {query_display}.")

            await ctx.send(embed=embed)
예제 #9
0
    async def color(self,
                    ctx,
                    embed_name: str = None,
                    hex_color: str = None) -> None:
        """ Sets the color for the given saved embed.
        :param embed_name: The name of the embed to insert.
        :param hex_color: The embed color.
        """

        embed_name = escape_mentions(embed_name)

        member = ctx.author

        if not embed_name:
            return await ctx.send(
                f"**Please, inform an `embed_name` to put the values in, {member.mention}!**"
            )

        if len(embed_name) > 30:
            return await ctx.send(
                f"**Please, inform a `embed_name` witihin 1-30 characters, {member.mention}!**"
            )

        if not hex_color:
            return await ctx.send(
                f"**Please, inform a `hex_color` for the author field, {member.mention}!**"
            )

        if len(hex_color) > 7:
            return await ctx.send(
                f"**Please, inform a `hex_color` witihin 1-7 characters, {member.mention}!**"
            )

        if not await self.embed_exists(embed_name):
            return await ctx.send(
                f"**Embed `{embed_name}` doesn't exist, {member.mention}!**")

        confirmation = await self.reaction_confirmation(ctx, member, hex_color)
        if not confirmation:
            return

        mycursor, db = await the_database()
        await mycursor.execute(
            "SELECT embed_name from EmbedColor WHERE embed_name = %s",
            (embed_name, ))
        exists = await mycursor.fetchall()
        if exists:
            await mycursor.execute(
                "UPDATE EmbedColor SET hex_color = %s WHERE embed_name = %s",
                (hex_color, embed_name))
            await db.commit()
            await mycursor.close()
            await ctx.send(f"**Updated `color` for {embed_name}!**")
        else:
            await mycursor.execute(
                "INSERT INTO EmbedColor (embed_name, hex_color) VALUES (%s, %s)",
                (embed_name, hex_color))
            await db.commit()
            await mycursor.close()
            await ctx.send(f"**Inserted `color` for {embed_name}!**")
예제 #10
0
    async def remove_member_item(self,
                                 ctx,
                                 member: discord.Member = None,
                                 *,
                                 item_name: str = None) -> None:
        """ (ADM) Removes an item from the member.
        :param member: The member to remove the item.
        :param item_name: The name of the item. """

        item_name = escape_mentions(item_name)

        if not member:
            return await ctx.send("**Inform a member!**", delete_after=3)

        if not item_name:
            return await ctx.send("**Inform an item to remove!**",
                                  delete_after=3)

        user_has_item = await self.get_user_specific_item(member.id, item_name)
        if len(user_has_item) != 0:
            await self.remove_user_item(member.id, item_name)
            return await ctx.send(
                f"**{item_name.title()} taken from {member.name}!**",
                delete_after=3)
        else:
            return await ctx.send(f"**{member.name} doesn't have that item!**",
                                  delete_after=3)
예제 #11
0
def remove_mentions(message_content):
    message_content = escape_mentions(message_content)
    return re.sub(
        r'(@([A-Za-z0-9`~!@#$%^&*()_|+\-=?;:\'",.<>\{\}\[\]\\\/]{2,32}))',
        "",
        message_content,
    ).strip()
예제 #12
0
    async def add_member(self,
                         ctx,
                         member: discord.Member = None,
                         *,
                         item_name: str = None) -> None:
        """ (ADM) Gives a member an item.
        :param member: The member to give the item.
        :param item_name: The name of the item. """

        item_name = escape_mentions(item_name)

        if not member:
            return await ctx.send("**Inform a member!**", delete_after=3)

        if not item_name:
            return await ctx.send("**Inform an item to add!**", delete_after=3)

        user_has_item = await self.get_user_specific_item(
            member.id, item_name.title())
        if not user_has_item:
            if (shop_item := await self.get_shop_item(item_name)):
                await self.insert_user_item(
                    member.id, item_name, 'unequipped', shop_item[5],
                    str(shop_item[3]).replace('registered_items/', ''))
                return await ctx.send(
                    f"**{item_name.title()} given to {member.name}!**",
                    delete_after=3)
            else:
                return await ctx.send(
                    f"**This item doesn't exist, {ctx.author.mention}!**")
예제 #13
0
    async def unequip(self, ctx, *, item_name: str = None) -> None:
        """ Unequips an item.
        :param item_name: The item to unequip """

        item_name = escape_mentions(item_name)

        await ctx.message.delete()
        if not item_name:
            return await ctx.send("**Inform an item to unequip!**",
                                  delete_after=3)

        user_items = await self.get_user_items(ctx.author.id)
        for item in user_items:
            if item[1] == item_name.title():
                if await self.check_user_can_unequip(ctx.author.id,
                                                     item_name.lower()):
                    await self.update_user_item_info(ctx.author.id,
                                                     item_name.title(),
                                                     'unequipped')
                    return await ctx.send(
                        f"**{ctx.author.mention} unequipped __{item_name.title()}__!**",
                        delete_after=3)
                else:
                    return await ctx.send(
                        f"**The item __{item_name}__ is already unequipped!**",
                        delete_after=3)
        else:
            return await ctx.send(
                f"**You don't have an item named __{item_name.title()}__!**",
                delete_after=3)
예제 #14
0
 async def pplocate(self, ctx, *, content):
     """Locates a players pearl"""
     with open('resources/pearl locations.txt', 'r') as file:
         locations = json.load(file)
     if content.lower() in locations:
         await ctx.channel.send(locations[content])
     else:
         await ctx.channel.send("**" + escape_mentions(content) + "**'s pearl could not be located")
예제 #15
0
    async def _basic_search(self, ctx, query: str, category: str) -> None:
        """Basic search formatting."""
        is_nsfw = ctx.channel.is_nsfw() if hasattr(ctx.channel,
                                                   "is_nsfw") else False

        async with ctx.typing():
            # Searches
            try:
                results = await self._search_logic(query, is_nsfw, category)
            except SafesearchFail:
                await ctx.send(
                    f":x: Sorry {ctx.author.mention}, your message contains filtered words, I've removed this message."
                )
                await ctx.message.delete()
                return
            count = len(results)

            # Ignore markdown when displaying
            query_display = utils.escape_mentions(query)
            query_display = utils.escape_markdown(query_display)

            # Return if no results
            if count == 0:
                await ctx.send(f"No results found for `{query_display}`.")
                return

            # Gets the first entry's data
            first_title = self.tomd.handle(results[0]["title"]).rstrip("\n")
            first_url = results[0]["url"]
            first_desc = self.tomd.handle(results[0]["desc"]).rstrip("\n")

            # Builds the substring for each of the other result.
            other_results: List[str] = []
            for r in results[1:count]:
                title = self.tomd.handle(r["title"]).rstrip("\n")
                url = r["url"]
                other_results.append(f"**{title}** {url}")
            other_msg: str = "\n".join(other_results)

            # Builds message
            msg = (textwrap.dedent(f"""
                Showing **{count}** results for `{query_display}`.


                **{first_title}** {first_url}
                {first_desc}

                {other_msg}

                _Powered by HotWired._
                """))

            msg = re.sub(
                r"(https?://(?:www\.)?[-a-zA-Z0-9@:%._+~#=]+\."
                r"[a-zA-Z0-9()]+\b[-a-zA-Z0-9()@:%_+.~#?&/=]*)", r"<\1>", msg)

            await ctx.send(msg)
예제 #16
0
 async def unbanusr(self,
                    ctx,
                    user: discord.User,
                    reason: str = "No reason provided"):
     clean_user = escape_markdown(
         text=escape_mentions(f"{user.name}#{user.discriminator}"))
     await ctx.message.guild.unban(
         user, reason=f"{ctx.author} (Unban) - {reason}")
     await ctx.send(f":eyes: {str(clean_user)} has been unbanned. ")
예제 #17
0
 async def snippet_raw(self, ctx, *, name: str.lower):
     """
     View the raw content of a snippet.
     """
     val = self.bot.snippets.get(name)
     if val is None:
         embed = create_not_found_embed(name, self.bot.snippets.keys(), "Snippet")
         return await ctx.send(embed=embed)
     return await ctx.send(escape_markdown(escape_mentions(val)).replace("<", "\\<"))
예제 #18
0
 async def ppfree(self, ctx, *, content):
     """`ppfree <playername>`"""
     with open('resources/pearl locations.txt', 'r') as file:
         locations = json.load(file)
     if content.lower() in locations:
         await ctx.channel.send("You freed **" + escape_mentions(content) + "**")
         del locations[content.lower()]
         with open('resources/pearl locations.txt', 'w') as file:
             json.dump(locations, file)
예제 #19
0
    async def binarytotext(self, ctx, *, binary: str):
        binary = binary.replace(' ', '')
        binary = binary.replace('\n', '')
        bytes_list = [binary[i:i + 8] for i in range(0, len(binary), 8)]

        output = ''
        for byte in bytes_list:
            output += chr(int(byte, 2))

        await ctx.send(escape_markdown(escape_mentions(output)))
예제 #20
0
def clean_message(message: str, modules=None):
    if modules is None:
        modules = [filter_spoiler, filter_nsfw]

    ret = escape_mentions(message)

    for module in modules:
        ret = module(ret)

    return ret
예제 #21
0
    async def get_praise(self, ctx: Context, after: str = None):
        await ctx.send(f'Fetching all Praise from {ctx.guild.name}...')

        if after:
            dates = [int(char) for char in after.split('-')]
            after = datetime(dates[2], dates[1], dates[0])
        else:
            # praise from 20 days ago from now
            after = datetime.now() - timedelta(days=20)

        clean_msgs = [[
            "To", "From", "Reason for Dishing", "Date", "Server", "Room"
        ]]
        for channel in ctx.guild.text_channels:
            await sleep(5)
            try:
                await ctx.send(
                    f"Attempting to get praise from - {channel.name}")
                msgs = await channel.history(after=after, limit=None).flatten()
                for msg in msgs:
                    if msg.content.startswith('!praise'):
                        for person in msg.mentions:
                            clean_msgs.append([
                                person.name + "#" + person.discriminator,
                                msg.author.name + "#" +
                                msg.author.discriminator,
                                re.sub(r'(<@).*?>', '',
                                       utils.escape_mentions(
                                           msg.content)[8:]).strip().replace(
                                               '\n', ' '),
                                msg.created_at.strftime("%b-%d-%Y"),
                                msg.guild.name, msg.channel.name
                            ])
                            log.info(f'Adding praise for: {person.name}')
            except Forbidden:
                await ctx.send(
                    f"Missing perms... Skipping channel - {channel.name}")
                continue
            else:
                continue

        with open(f"praise_{ctx.guild.id}.csv", 'w') as f:
            try:
                writer = csv.writer(f)
                log.info('Writing Praise...')
                writer.writerows(clean_msgs)
            except Exception as e:
                log.error(f"Error in writing Praise: {e}")

            log.info("Praise successfully written!")
        await ctx.send("Praise written!")
        await ctx.send(
            f"Praise written! Here's all of the Praise since {(datetime.now() - after).days} days ago",
            file=File(f'praise_{ctx.guild.id}.csv',
                      f'{ctx.guild.name} praise.csv'))
예제 #22
0
async def help(ctx, *, cmd: str =  None):
    """ Shows some information about commands and categories. 
    :param cmd: The command/category. """


    if not cmd:
        embed = discord.Embed(
            title="All commands and categories",
            description=f"```ini\nUse {client.command_prefix}help command or {client.command_prefix}help category to know more about a specific command or category\n\n[Examples]\n[1] Category: {client.command_prefix}help SlothCurrency\n[2] Command : {client.command_prefix}help rep```",
            timestamp=ctx.message.created_at,
            color=ctx.author.color
            )

        for cog in client.cogs:
            cog = client.get_cog(cog)
            cog_commands = [c for c in cog.__cog_commands__ if hasattr(c, 'parent') and c.parent is None]
            commands = [f"{client.command_prefix}{c.name}" for c in cog_commands if not c.hidden]
            if commands:
                embed.add_field(
                    name=f"__{cog.qualified_name}__",
                    value=f"`Commands:` {', '.join(commands)}",
                    inline=False
                    )

        cmds = []
        for y in client.walk_commands():
            if not y.cog_name and not y.hidden:
                cmds.append(f"{client.command_prefix}{y.name}")

        embed.add_field(
            name='__Uncategorized Commands__',
            value=f"`Commands:` {', '.join(cmds)}",
            inline=False)
        await ctx.send(embed=embed)

    else:  
        cmd = escape_mentions(cmd)
        if command := client.get_command(cmd.lower()):
            command_embed = discord.Embed(title=f"__Command:__ {client.command_prefix}{command.qualified_name}", description=f"__**Description:**__\n```{command.help}```", color=ctx.author.color, timestamp=ctx.message.created_at)
            return await ctx.send(embed=command_embed)

        # Checks if it's a cog
        for cog in client.cogs:
            if str(cog).lower() == str(cmd).lower():
                cog = client.get_cog(cog)
                cog_embed = discord.Embed(title=f"__Cog:__ {cog.qualified_name}", description=f"__**Description:**__\n```{cog.description}```", color=ctx.author.color, timestamp=ctx.message.created_at)
                cog_commands = [c for c in cog.__cog_commands__ if hasattr(c, 'parent') and c.parent is None]
                for c in cog_commands:
                    if not c.hidden:
                        cog_embed.add_field(name=c.qualified_name, value=c.help, inline=False)

                return await ctx.send(embed=cog_embed)
        # Otherwise, it's an invalid parameter (Not found)
        else:
            await ctx.send(f"**Invalid parameter! It is neither a command nor a cog!**")
예제 #23
0
    async def snippet(self, ctx, *, name: str.lower = None):
        """
        Create pre-defined messages for use in threads.

        When `{prefix}snippet` is used by itself, this will retrieve
        a list of snippets that are currently set. `{prefix}snippet-name` will show what the
        snippet point to.

        To create a snippet:
        - `{prefix}snippet add snippet-name A pre-defined text.`

        You can use your snippet in a thread channel
        with `{prefix}snippet-name`, the message "A pre-defined text."
        will be sent to the recipient.

        Currently, there is not a built-in anonymous snippet command; however, a workaround
        is available using `{prefix}alias`. Here is how:
        - `{prefix}alias add snippet-name anonreply A pre-defined anonymous text.`

        See also `{prefix}alias`.
        """

        if name is not None:
            val = self.bot.snippets.get(name)
            if val is None:
                embed = create_not_found_embed(
                    name, self.bot.snippets.keys(), "Snippet"
                )
                return await ctx.send(embed=embed)
            return await ctx.send(escape_mentions(val))

        if not self.bot.snippets:
            embed = discord.Embed(
                color=discord.Color.red(),
                description="You dont have any snippets at the moment.",
            )
            embed.set_footer(
                text=f"Do {self.bot.prefix}help snippet for more commands."
            )
            embed.set_author(name="Snippets", icon_url=ctx.guild.icon_url)
            return await ctx.send(embed=embed)

        embeds = []

        for i, names in enumerate(
            zip_longest(*(iter(sorted(self.bot.snippets)),) * 15)
        ):
            description = format_description(i, names)
            embed = discord.Embed(color=self.bot.main_color, description=description)
            embed.set_author(name="Snippets", icon_url=ctx.guild.icon_url)
            embeds.append(embed)

        session = EmbedPaginatorSession(ctx, *embeds)
        await session.run()
예제 #24
0
 async def pickle(self, ctx, content):
     """Pickles a player with a food related adjective"""
     with open('resources/TextMeme/Food adjectives.txt') as f:
         lines = f.read().splitlines()
     adjs = []
     for a in lines:
         if a[0].casefold() == content[0].casefold():
             adjs.append(a)
     if content.casefold() == "pirater":
         adjs = ["pickled"]
     if len(adjs) > 0:
         await ctx.channel.send(random.choice(adjs).capitalize() + " " + escape_mentions(content))
예제 #25
0
def _clean(
    bot: TravusBotBase,
    guild: Optional[discord.Guild],
    text: str,
    escape_markdown: bool = True,
    replace_backticks: bool = False,
) -> str:
    """Underlying function used by clean and clean_no_ctx functions."""
    transformations: dict[str, str] = {}

    def resolve_member(_id):
        """Resolves user mentions."""
        member = bot.get_user(_id)
        return "@" + member.name if member else "@deleted-user"

    transformations.update(
        (f"<@{member_id}>", resolve_member(member_id))
        for member_id in [int(x) for x in findall(r"<@!?(\d+)>", text)])
    transformations.update(
        (f"<@!{member_id}>", resolve_member(member_id))
        for member_id in [int(x) for x in findall(r"<@!?(\d+)>", text)])

    if guild:

        def resolve_channel(_id):
            """Resolves channel mentions."""
            ch = guild.get_channel(_id)
            return f"<#{_id}>", ("#" + ch.name if ch else "#deleted-channel")

        def resolve_role(_id):
            """Resolves role mentions."""
            role = guild.get_role(_id)
            return "@" + role.name if role else "@deleted-role"

        transformations.update(
            resolve_channel(channel)
            for channel in [int(x) for x in findall(r"<#(\d+)>", text)])
        transformations.update(
            (f"<@&{role_id}>", resolve_role(role_id))
            for role_id in [int(x) for x in findall(r"<@&(\d+)>", text)])

    def repl(obj):
        """Function used in regex substitution."""
        return transformations.get(obj.group(0), "")

    pattern = re_cmp("|".join(transformations.keys()))
    result = pattern.sub(repl, text)
    if escape_markdown:
        result = utils.escape_markdown(result)
    if replace_backticks:
        result = result.replace("`", "ˋ")
    return utils.escape_mentions(result)
예제 #26
0
 async def execute(self, args, msg):
     if len(msg.mentions) != 1:
         raise Exception('Mention a user with this command.')
     elif msg.mentions[0].bot:
         raise Exception('Cannot imitate bot users.')
     for n in range(np.random.geometric(0.5)):
         text = globals.bot.markov.generate_forwards(tag=str(msg.mentions[0].id))
         if text is None:
             await msg.reply(f'I don\' know {msg.mentions[0].display_name} well enough.')
             return
         async with msg.channel.typing():
             await asyncio.sleep(0.04 * len(text))
             await msg.channel.send(escape_mentions(text))
예제 #27
0
async def echo(_cmd, pld):
    """
    :param _cmd: The command object referenced in the command.
    :type _cmd: sigma.core.mechanics.command.SigmaCommand
    :param pld: The payload with execution data and details.
    :type pld: sigma.core.mechanics.payload.CommandPayload
    """
    if pld.args:
        content = f'👄 {" ".join(pld.args)[:1995]}'
        await pld.msg.channel.send(escape_mentions(content))
    else:
        no_args = GenericResponse('Nothing inputted.').error()
        await pld.msg.channel.send(embed=no_args)
예제 #28
0
파일: vote.py 프로젝트: sinus-x/Amadeus
    async def loop(self, vote_msg, edit_msg, date):
        votes = await self.find_emotes(vote_msg)

        while True:
            if date < datetime.now():
                break
            timeout = (date - datetime.now()).seconds
            pending_tasks = [
                self.bot.wait_for("raw_reaction_add"),
                self.bot.wait_for("raw_reaction_remove"),
            ]

            done_tasks, pending_tasks = await asyncio.wait(
                pending_tasks,
                return_when=asyncio.FIRST_COMPLETED,
                timeout=timeout)
            for task in done_tasks:
                raw_reaction = await task

            await self.check_reactions(raw_reaction, vote_msg, votes, edit_msg,
                                       date)

        if vote_msg not in self.bot.cached_messages:
            vote_msg = await vote_msg.channel.fetch_message(vote_msg.id)

        for reaction in vote_msg.reactions:
            for option in votes:
                if reaction.emoji == option["emote"]:
                    option["num_votes"] = reaction.count

        lines = vote_msg.content.split("\n")

        content = text.fill("vote",
                            "ended",
                            now=datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
        content += lines[0] + "\n"
        votes = sorted(votes, key=lambda i: (i["num_votes"]), reverse=True)
        for option in votes:
            content += text.fill(
                "vote",
                "option",
                option=option["option"],
                num=option["num_votes"] - 1,
            )
        content = escape_mentions(escape_markdown(content))

        await edit_msg.channel.send(content=content)
        repository.del_vote(channel_id=vote_msg.channel.id,
                            message_id=vote_msg.id)
        return
예제 #29
0
    async def plot(self,
                   ctx,
                   xmin: Optional[float] = -10,
                   xmax: Optional[float] = 10,
                   *,
                   inp: str):
        """
            !plot from_range to_range equation1; equation2; equation3; ...

            example:
                !plot -10 10 x^2; x^3; x^4
        """
        # Escape mentions and markdown
        equations = escape_mentions(escape_markdown(inp)).split(";")

        fig = plt.figure(dpi=300)
        ax = fig.add_subplot(1, 1, 1)

        if xmin < 0 < xmax:
            ax.spines["left"].set_position("zero")

        # Eliminate upper and right axes
        ax.spines["right"].set_color("none")
        ax.spines["top"].set_color("none")

        # Show ticks in the left and lower axes only
        ax.xaxis.set_tick_params("bottom", direction="inout")
        ax.yaxis.set_tick_params("left", direction="inout")

        successful_eq = 0
        msg = "Couldn't plot these functions:"
        numpy.seterr(divide="ignore", invalid="ignore")
        for eq in equations:
            try:
                func = self.string2func(eq)
                x = numpy.linspace(xmin, xmax, 1000)
                plt.plot(x, func(x))
                plt.xlim(xmin, xmax)
                successful_eq += 1
            except Exception as e:
                msg += "\n" + eq + " - " + str(e)

        if msg != "Couldn't plot these functions:":
            await ctx.send(msg)

        if successful_eq > 0:
            plt.savefig("assets/plot.png", bbox_inches="tight", dpi=100)
            plt.clf()
            await ctx.send(file=discord.File("assets/plot.png"))
            os.remove("assets/plot.png")
예제 #30
0
    async def rick(self, ctx: MyContext, value: Optional[int] = 0):
        """
        Changes/views the rick roll response
        """
        db_guild = await get_from_db(ctx.guild)
        if value != 0:
            db_guild.rickpref = int(value)
        await db_guild.save()

        _ = await ctx.get_translate_function()
        if db_guild.rickpref:
            await ctx.send(_('The server Rick-Roll preference is `{value}`', value=escape_mentions(escape_markdown(str(db_guild.rickpref)))))
        else:
            await ctx.send(_('There is no specific preference set for this guild.'))