Esempio n. 1
0
 async def _clear(self, ctx, messages=None):
     if messages is not None:
         if is_number(messages):
             try:
                 messages = int(messages)
             except ValueError:
                 return await ctx.reply(f'Eu só aceito números inteiros!')
         else:
             return await ctx.reply(f'Digite um número válido!')
         if 200 >= messages >= 1:
             try:
                 deleted = await ctx.channel.purge(
                     limit=messages + 1, check=lambda m: not m.pinned)
             except:
                 return await ctx.send(
                     f'{ctx.author.mention} não consegui deletar as mensagens. Tente novamente.'
                 )
             else:
                 if (len(deleted) - 1) >= messages:
                     return await ctx.send(
                         f'{ctx.author.mention} deletou {len(deleted) - 1} mensagens!',
                         delete_after=5)
                 else:
                     return await ctx.send(
                         f'{ctx.author.mention} não foi(ram) deletada(s) '
                         f'{abs(messages - len(deleted) - 1)} mensagem(ns), pois estava(m) '
                         f'fixada(s).',
                         delete_after=5)
         else:
             return await ctx.reply(f'Informe um número entre 1 e 200!')
     else:
         return await self.bot.send_help(ctx)
Esempio n. 2
0
 async def _say(self, ctx, *, frase=''):
     if len(frase) == 0:
         await self.bot.send_help(ctx)
         return
     channel = ctx
     # se a pessoa tiver perm de gerenciar mensagens, vai ver se ela passou um chat
     # para o bot enviar a mensagem
     # se não entrar nesse if, o chat para enviar a mensagem vai ser o mesmo que o comando foi usado
     # e também vai ser adicionado quem mandou o bot falar aquilo, caso a pessoa não tenha permissão
     if await check_permissions(ctx, {'manage_messages': True}):
         channel_id = frase.split(' ')[0].replace('<#', '').replace('>', '')
         if is_number(channel_id) and (ctx.guild is not None):
             try:
                 channel = ctx.guild.get_channel(int(channel_id))
             except:
                 channel = ctx
             if channel is None:
                 return await ctx.send(
                     f'{ctx.author.mention} Não consegui achar o chat que você me informou.'
                     ' <a:sad:755774681008832623>')
         else:
             channel = ctx
         if channel != ctx:
             frase = frase.replace(f'<#{channel_id}> ', '')
     else:
         frase += f'\n\n- {ctx.author}'
     # se a pessoa não tiver perm de marca everyone
     if await check_permissions(ctx, {'mention_everyone': False}):
         # vai tirar todas as menções da mensagem
         allowed_mentions = discord.AllowedMentions().none()
     else:
         # se a pessoa tiver perm, vai deixar marcar qualquer coisa
         allowed_mentions = discord.AllowedMentions().all()
     if len(frase) == 0:  # se após os filtros, a mensagem ficou vazia
         frase = '.'
     try:
         await channel.send(content=frase,
                            allowed_mentions=allowed_mentions)
     except discord.Forbidden:
         return await ctx.send(
             f'{ctx.author.mention} eu não tenho permissão para enviar mensagem no chat {channel.mention}.'
             ' <a:sad:755774681008832623>')
     if channel != ctx:
         await ctx.send(
             f'{ctx.author.mention} Mensagem enviada no chat {channel.mention} com sucesso!'
         )
     else:  # se o channel for igual ao ctx
         # se o bot tiver perm de apagar mensagens:
         if await bot_check_permissions(ctx, manage_messages=True):
             await ctx.message.delete()
Esempio n. 3
0
    async def _money(self, ctx, *args):
        """
        possibilidades de uso do comando:
        money → vai responder 1 dólar em reais
        money 10 → vai responder 10 dólares em reais
        money eur → vai responder 1 euro em reais
        money aud 5 → vai responder 5 dólares australianos em reais
        money eur aud 1 → vai responder 1 euro em dólares australianos
        """
        m_from = 'USD'
        m_to = 'BRL'
        m_qtd = 1
        # se a pessoa não passou nada, vai continuar com esses valores padrões
        if args:  # se a pessoa passou pelo menos 1 argumento:
            # se a pessoa digitou "money 2" ou "mon 10.57"
            if is_number(args[0]):
                m_qtd = float(args[0])
            else:  # se o primeiro valor não for número

                def is_valid(value):
                    # todas as moedas que aceita
                    currencies = [
                        c.split(' - ')[0]
                        for c in currency_exchange.currencies()
                    ]
                    for currency in currencies:
                        if value == currency:
                            return True
                    return False

                # se a pessoa usar o comando assim: "money eur"
                if len(args) == 1:
                    if is_valid(args[0].upper()):
                        m_from = args[0].upper()
                    else:
                        # se não achou o que a pessoa passou:
                        return await self.bot.send_help(ctx)
                # se a pessoa usou o comando assim: "money aud 5"
                elif len(args) == 2:
                    if is_valid(args[0].upper()):
                        m_from = args[0].upper()
                        if is_number(args[-1]):
                            m_qtd = float(args[-1])
                        else:
                            return await self.bot.send_help(ctx)
                    else:
                        return await self.bot.send_help(ctx)
                # se a pessoa usou o comando assim: "money eur aud 1"
                elif len(args) == 3:
                    if is_valid(args[0].upper()):
                        m_from = args[0].upper()
                        if is_valid((args[1].upper())):
                            m_to = args[1].upper()
                            if is_number(args[-1]):
                                m_qtd = float(args[-1])
                            else:
                                return await self.bot.send_help(ctx)
                        else:
                            return await self.bot.send_help(ctx)
                    else:
                        return await self.bot.send_help(ctx)
                else:
                    # se a pessoa passou mais de 3 parâmetros:
                    return await self.bot.send_help(ctx)
        result, _ = currency_exchange.exchange(m_from, m_to, m_qtd,
                                               False)[0].split(' ')
        um_valor, _ = currency_exchange.exchange(m_from, m_to, 1,
                                                 False)[0].split(' ')
        result = float(f'{float(result.replace(",", "")):.2f}')
        um_valor = float(f'{float(um_valor):.2f}')
        embed = discord.Embed(
            title=
            f'🪙 {m_qtd:.2f} {m_from.lower()} = {result:.2f} {m_to.lower()}',
            colour=discord.Colour(random_color()),
            description='** **',
            timestamp=datetime.utcnow())
        embed.set_footer(text=f'{ctx.author}', icon_url=ctx.author.avatar_url)
        conexao = Conexao()
        info = InformacoesRepository()
        # se ainda não tiver essa conversão no banco:
        if info.get_dado(conexao,
                         f'{m_from.upper()} to {m_to.upper()}') is None:
            # vai criar
            info.create(conexao, f'{m_from.upper()} to {m_to.upper()}',
                        f'{um_valor:.2f}')
            ultimo_valor = um_valor
        else:
            ultimo_valor = float(
                info.get_dado(conexao, f'{m_from.upper()} to {m_to.upper()}'))
            info.update(conexao, f'{m_from.upper()} to {m_to.upper()}',
                        f'{um_valor:.2f}')
        if ultimo_valor > um_valor:
            msg = f'O valor diminuiu {(ultimo_valor - result):.2f}! <:diminuiu:730088971077681162>'
        elif ultimo_valor < um_valor:
            msg = f'O valor aumentou {(result - ultimo_valor):.2f}! <:aumentou:730088970779623524>'
        else:
            msg = 'Não teve alteração no valor.'
        embed.add_field(
            name=f'Com base na última vez que esse comando foi usado:\n{msg}',
            value=
            f'Fonte: [x-rates](https://www.x-rates.com/calculator/?from={m_from}&to='
            f'{m_to}&amount={m_qtd})',
            inline=True)
        await ctx.send(embed=embed)
Esempio n. 4
0
    async def _regra_de_tres(self, ctx):
        # TODO
        await ctx.reply(
            f'Olá {ctx.author.mention}!\nPrimeiro, qual regra de três você quer que eu faça? '
            '(``inversamente``/``diretamente``)')

        def check(message):
            return message.author == ctx.author

        try:
            msg = await self.bot.wait_for('message', check=check, timeout=30)
        except asyncio.TimeoutError:
            return await ctx.send('Tempo esgotado!')
        modo = None
        path = ''
        if 'inversamente'.startswith(msg.content.lower()):
            modo = 'i'
        elif 'diretamente'.startswith(msg.content.lower()):
            modo = 'd'
        if modo:
            if exists('discord_bot/'):
                path = 'discord_bot/'
            else:
                path = './'
            if modo == 'd':
                await ctx.send(
                    'Modo selecionado: ``diretamente proporcional``!')
                valores = [['primeiro', 'v1'], ['segundo', 'v2'],
                           ['terceiro', 'v3']]
                pos_text_list = [[(115, 210), 'v1'], [(352, 210), 'v2'],
                                 [(115, 406), 'v3'], [(363, 406), 'x']]
                valores_user = []
                for valor in valores:
                    img = Image.open(f'{path}images/regra_de_tres_direta.png')
                    draw = ImageDraw.Draw(img)
                    font = ImageFont.truetype(
                        f'{path}fonts/helvetica-normal.ttf', 25)
                    black = (0, 0, 0)  # rgb
                    red = (255, 0, 0)  # rgb
                    for pos_text in pos_text_list:
                        if pos_text[-1] == valor[-1]:
                            draw.text(pos_text[0],
                                      pos_text[-1],
                                      red,
                                      font=font)
                        else:
                            draw.text(pos_text[0],
                                      pos_text[-1],
                                      black,
                                      font=font)
                    img.save(f'{path}images/regra_de_tres_direta-edited.png')
                    img.close()
                    await ctx.send(
                        f'Agora, eu preciso que você me fale o {valor[0]} valor (**{valor[-1]} na foto**).',
                        file=discord.File(
                            f'{path}images/regra_de_tres_direta-edited.png'))
                    try:
                        value = await self.bot.wait_for('message',
                                                        check=check,
                                                        timeout=30)
                        if not is_number(value.content):
                            return await ctx.send(
                                f'O valor ``{value.content}`` não é um número válido!'
                            )
                        try:
                            value = int(value.content)
                        except ValueError:
                            try:
                                value = float(value.content.replace(',', '.'))
                            except ValueError:
                                return await ctx.send(
                                    f'O valor ``{value.content}`` não é um número válido!'
                                )
                    except asyncio.TimeoutError:
                        return await ctx.send('Tempo esgotado!')
                    if value >= 5000:
                        return await ctx.send(
                            f'{ctx.author.mention} você não acha que ``{value}`` não é muito grande não?!'
                        )
                    for c in range(0, len(pos_text_list)):
                        if pos_text_list[c][-1] == valor[-1]:
                            pos_text_list[c][-1] = f'{value}'
                    valores_user.append(value)
                mult = valores_user[-1] * valores_user[1]
                resp = mult / valores_user[0]
                embed = discord.Embed(
                    title=f'Regra de 3!',
                    colour=discord.Colour.random(),
                    description='Passo a passo da resolução:\n' +
                    f'**{valores_user[0]}x = {valores_user[-1]}×{valores_user[1]}**\n'
                    + f'**{valores_user[0]}x = {mult}**\n' +
                    f'**x = {mult}/{valores_user[0]}**\n' +
                    f'**x = {prettify_number(resp)}**',
                    timestamp=datetime.utcnow())
                embed.set_author(name=self.bot.user.name,
                                 icon_url=self.bot.user.avatar_url)
                embed.set_footer(text=f'{ctx.author}',
                                 icon_url=ctx.author.avatar_url)
                img = Image.open(f'{path}images/regra_de_tres_direta.png')
                draw = ImageDraw.Draw(img)
                font = ImageFont.truetype(f'{path}fonts/helvetica-normal.ttf',
                                          25)
                black = (0, 0, 0)  # rgb
                red = (255, 0, 0)  # rgb
                pos1 = (115, 210)  # x e y
                pos2 = (352, 210)  # x e y
                pos3 = (115, 406)  # x e y
                posx = (363, 406)  # x e y
                text1 = str(valores_user[0])
                text2 = str(valores_user[1])
                text3 = str(valores_user[2])
                x = f'{resp:.2f}'
                draw.text(pos1, text1, black, font=font)
                draw.text(pos2, text2, black, font=font)
                draw.text(pos3, text3, black, font=font)
                draw.text(posx, x, red, font=font)
                img.save(f'{path}images/regra_de_tres_direta-edited.png')
                img.close()
                await ctx.send(
                    embed=embed,
                    file=discord.File(
                        f'{path}images/regra_de_tres_direta-edited.png'))
                remove(f'{path}images/regra_de_tres_direta-edited.png')
            else:
                await ctx.send(
                    'Modo selecionado: ``inversamente proporcional``!')
                valores = [['primeiro', 'v1'], ['segundo', 'v2'],
                           ['terceiro', 'v3']]
                pos_text_list = [[(60, 280), 'v1'], [(400, 280), 'v2'],
                                 [(60, 370), 'v3'], [(400, 370), 'x']]
                valores_user = []
                for valor in valores:
                    img = Image.open(f'{path}images/regra_de_tres_inversa.png')
                    draw = ImageDraw.Draw(img)
                    font = ImageFont.truetype(
                        f'{path}fonts/helvetica-normal.ttf', 25)
                    black = (0, 0, 0)  # rgb
                    red = (255, 0, 0)  # rgb
                    for pos_text in pos_text_list:
                        if pos_text[-1] == valor[-1]:
                            draw.text(pos_text[0],
                                      pos_text[-1],
                                      red,
                                      font=font)
                        else:
                            draw.text(pos_text[0],
                                      pos_text[-1],
                                      black,
                                      font=font)
                    img.save(f'{path}images/regra_de_tres_inversa-edited.png')
                    img.close()
                    await ctx.send(
                        f'Agora, eu preciso que você me fale o {valor[0]} valor (**{valor[-1]} na foto**).',
                        file=discord.File(
                            f'{path}images/regra_de_tres_inversa-edited.png'))
                    try:
                        value = await self.bot.wait_for('message',
                                                        check=check,
                                                        timeout=30)
                        if not is_number(value.content):
                            return await ctx.send(
                                f'O valor ``{value.content}`` não é um número válido!'
                            )
                        try:
                            value = int(value.content)
                        except ValueError:
                            try:
                                value = float(value.content.replace(',', '.'))
                            except ValueError:
                                return await ctx.send(
                                    f'O valor ``{value.content}`` não é um número válido!'
                                )
                    except asyncio.TimeoutError:
                        return await ctx.send('Tempo esgotado!')
                    if value >= 5000:
                        return await ctx.send(
                            f'{ctx.author.mention} você não acha que ``{value}`` não é muito grande não?!'
                        )
                    for c in range(0, len(pos_text_list)):
                        if pos_text_list[c][-1] == valor[-1]:
                            pos_text_list[c][-1] = f'{value}'
                    valores_user.append(value)
                mult = valores_user[0] * valores_user[1]
                resp = mult / valores_user[-1]
                embed = discord.Embed(
                    title=f'Regra de 3!',
                    colour=discord.Colour.random(),
                    description='Passo a passo da resolução:\n' +
                    f'**{valores_user[-1]}x = {valores_user[0]}×{valores_user[1]}**\n'
                    + f'**{valores_user[-1]}x = {mult}**\n' +
                    f'**x = {mult}/{valores_user[-1]}**\n' +
                    f'**x = {prettify_number(resp)}**',
                    timestamp=datetime.utcnow())
                embed.set_author(name=self.bot.user.name,
                                 icon_url=self.bot.user.avatar_url)
                embed.set_footer(text=f'{ctx.author}',
                                 icon_url=ctx.author.avatar_url)
                img = Image.open(f'{path}images/regra_de_tres_inversa.png')
                draw = ImageDraw.Draw(img)
                font = ImageFont.truetype(f'{path}fonts/helvetica-normal.ttf',
                                          25)
                black = (0, 0, 0)  # rgb
                red = (255, 0, 0)  # rgb
                pos1 = (60, 280)  # x e y
                pos2 = (400, 280)  # x e y
                pos3 = (60, 370)  # x e y
                posx = (400, 370)  # x e y
                text1 = str(valores_user[0])
                text2 = str(valores_user[1])
                text3 = str(valores_user[2])
                x = f'{resp:.2f}'
                draw.text(pos1, text1, black, font=font)
                draw.text(pos2, text2, black, font=font)
                draw.text(pos3, text3, black, font=font)
                draw.text(posx, x, red, font=font)
                img.save(f'{path}images/regra_de_tres_inversa-edited.png')
                img.close()
                await ctx.send(
                    embed=embed,
                    file=discord.File(
                        f'{path}images/regra_de_tres_inversa-edited.png'))
                remove(f'{path}images/regra_de_tres_inversa-edited.png')
        else:
            await ctx.send(
                f'{ctx.author.mention} eu não sei o que é ' +
                f'``{msg.content}``! Eu aceito apenas ``inversamente`` ou ``diretamente``'
            )
Esempio n. 5
0
    async def _eval(self, ctx, *, cmd):
        emojis = {
            'ids': get_emojis_json()['ids'],
            'check_verde': self.bot.get_emoji('check_verde'),
            'atencao': self.bot.get_emoji('atencao'),
            'warning_flag': self.bot.get_emoji('warning_flag')
        }
        emojis['cadeado'] = self.bot.get_emoji(emojis['ids']['cadeado'])
        emojis['desativado'] = self.bot.get_emoji(emojis['ids']['desativado'])
        emojis['ativado'] = self.bot.get_emoji(emojis['ids']['ativado'])
        send_file = False
        msg_file = None

        def check(reaction_, user_):
            author = user_.id == ctx.author.id
            reactions = (str(reaction_.emoji) == str(
                emojis['cadeado'])) or (str(reaction_.emoji) == str(
                    emojis['desativado'])) or (str(reaction_.emoji) == str(
                        emojis['ativado']))
            message_check = reaction_.message == msg_bot
            return author and reactions and message_check

        closed = discord.Embed(title=f'Eval fechada {emojis["check_verde"]}',
                               colour=discord.Colour(0xff6961),
                               timestamp=datetime.utcnow())
        closed.set_footer(text=f'{ctx.author}',
                          icon_url=f'{ctx.author.avatar_url}')
        execute_cmd = ''
        try:
            fn_name = '_eval_function'
            if cmd.startswith('```py'):
                cmd = cmd[5:]
            elif cmd.startswith('```'):
                cmd = cmd[3:]
            if cmd.endswith('```'):
                cmd = cmd[:-3]
            if cmd.startswith('\n'):
                cmd = cmd[1:]
            # add a layer of indentation
            cmd = '\n'.join(f'    {i}' for i in cmd.splitlines())
            # wrap in async def body
            body = f'async def {fn_name}():\n{cmd}'
            # se o comando começar com #s, vai emitir a mensagem do retorno do comando
            retornar_algo = not cmd.splitlines()[0].replace(
                ' ', '').startswith('#s')
            execute_cmd = body
            if len(execute_cmd) > 1000:
                execute_cmd = f'{execute_cmd[:1000]}\n...'
            parsed = ast.parse(body)
            body = parsed.body[0].body

            self.__insert_returns(body)

            env = {
                'self': self,
                'discord': discord,
                'asyncpg': asyncpg,
                'asyncio': asyncio,
                'commands': commands,
                'datetime': datetime,
                'BlacklistRepository': BlacklistRepository,
                'ComandoDesativadoRepository': ComandoDesativadoRepository,
                'ComandoPersonalizadoRepository':
                ComandoPersonalizadoRepository,
                'InformacoesRepository': InformacoesRepository,
                'ServidorRepository': ServidorRepository,
                'ComandoDesativado': ComandoDesativado,
                'ComandoPersonalizado': ComandoPersonalizado,
                'Servidor': Servidor,
                'permissions': permissions,
                'Stopwatch': Stopwatch,
                'ctx': ctx,
                'bot': self.bot,
                'author': ctx.author,
                'message': ctx.message,
                'msg': ctx.message,
                'channel': ctx.channel,
                'guild': ctx.guild,
                '_find': discord.utils.find,
                '_get': discord.utils.get,
                '__import__': __import__
            }
            utils_module = getmodule(get_emoji_dance)
            for attr_name in dir(utils_module):
                try:
                    attr = getattr(utils_module, attr_name)
                except AttributeError:
                    continue
                if getmodule(attr) == utils_module:
                    env[attr_name] = attr
            exec(compile(parsed, filename='<ast>', mode='exec'), env)
            execution_time = Stopwatch()
            result = await eval(f'{fn_name}()', env)
            execution_time.stop()
        except:
            erro_embed = discord.Embed(
                title=f'{emojis["atencao"]} Erro no comando eval',
                colour=discord.Colour(0xff6961),
                timestamp=datetime.utcnow())
            erro_embed.set_footer(text=f'{ctx.author}',
                                  icon_url=f'{ctx.author.avatar_url}')
            erro_embed.add_field(name='📥 Input',
                                 value=f'```py\n{execute_cmd}```',
                                 inline=False)
            erro_msg = '\n'.join(f'- {line}'
                                 for line in format_exc().splitlines())
            if len(erro_msg) <= 1500:
                erro_embed.add_field(name=f'{emojis["warning_flag"]} Erro',
                                     value=f'```diff\n{erro_msg}```',
                                     inline=False)
            else:
                send_file = True
                erro_embed.add_field(
                    name='** **',
                    value='😅 infelizmente o erro foi muito grande, então enviei '
                    'o erro completo num arquivo.',
                    inline=False)
            msg_bot = await ctx.send(embed=erro_embed)
            if send_file:
                msg_file = await ctx.send(
                    file=discord.File(filename='erro.log',
                                      fp=BytesIO(format_exc().encode('utf-8')))
                )
            await msg_bot.add_reaction(emojis['ativado'])
            try:
                await self.bot.wait_for('reaction_add',
                                        timeout=120.0,
                                        check=check)
            except asyncio.TimeoutError:
                pass
            await msg_bot.remove_reaction(emojis['ativado'], ctx.me)
            await msg_bot.edit(
                embed=closed,
                allowed_mentions=discord.AllowedMentions(replied_user=False))
            if send_file and msg_file is not None:
                await msg_file.delete()
        else:
            if retornar_algo:
                e = discord.Embed(title=f'Comando eval executado com sucesso!',
                                  colour=discord.Colour(0xbdecb6),
                                  timestamp=datetime.utcnow())
                e.set_footer(text=f'{ctx.author}',
                             icon_url=f'{ctx.author.avatar_url}')
                e.add_field(name='📥 Input',
                            value=f'```py\n{execute_cmd}```',
                            inline=False)
                result_type = type(result)
                if is_number(str(result)):
                    result_str = prettify_number(str(result))
                else:
                    result_str = pretty_i(result)
                if len(result_str) <= 1_000:
                    e.add_field(name='📤 Output',
                                value=f'```py\n{result_str}```',
                                inline=False)
                else:
                    send_file = True
                    e.add_field(
                        name='** **',
                        value=
                        '😅 infelizmente o resultado ficou muito grande, então '
                        'enviei o erro completo num arquivo.',
                        inline=False)
                e.add_field(name='🤔 Tipo do return',
                            value=f'```py\n{result_type}```',
                            inline=False)
                e.add_field(name='⌚ Tempo de execução',
                            value=f'```md\n{str(execution_time)}\n====```',
                            inline=False)
                e.add_field(name='** **',
                            value=f'Essa mensagem será fechada em 2 minutos 🙂',
                            inline=False)
                msg_bot = await ctx.send(embed=e)
                if send_file:
                    msg_file = await ctx.send(file=discord.File(
                        filename='result.py',
                        fp=BytesIO(result_str.encode('utf-8'))))
                await msg_bot.add_reaction(emojis['desativado'])
                await msg_bot.add_reaction(emojis['cadeado'])
                try:
                    reaction, _ = await self.bot.wait_for('reaction_add',
                                                          timeout=120.0,
                                                          check=check)
                    if str(reaction.emoji) == str(emojis['desativado']):
                        await msg_bot.edit(
                            embed=closed,
                            allowed_mentions=discord.AllowedMentions(
                                replied_user=False))
                        if send_file and msg_file is not None:
                            await msg_file.delete()
                    elif str(reaction.emoji) == str(emojis['cadeado']):
                        e.remove_field(-1)
                        await msg_bot.edit(
                            embed=e,
                            allowed_mentions=discord.AllowedMentions(
                                replied_user=False))
                except asyncio.TimeoutError:
                    await msg_bot.edit(
                        embed=closed,
                        allowed_mentions=discord.AllowedMentions(
                            replied_user=False))
                    if send_file and msg_file is not None:
                        await msg_file.delete()
                await msg_bot.remove_reaction(emojis['desativado'], ctx.me)
                await msg_bot.remove_reaction(emojis['cadeado'], ctx.me)
            else:
                await ctx.message.add_reaction(emojis['ativado'])