示例#1
0
async def custom_config(ctx):
    """
    Verifica as configurações customizaveis para este server.
    """
    server = make_hash('id', ctx.message.guild.id).decode('utf-8')
    payload = Query.get_custom_config(server)
    gql_client = get_gql_client(BACKEND_URL)

    try:
        response = gql_client.execute(payload)
    except Exception as err:
        log.error(f'Erro: {str(err)}\n\n')
        return await ctx.send('D-desculpa, não consegui...')

    data = response.get('custom_config')
    embed = discord.Embed(color=0x1E1E1E, type='rich')
    embed.add_field(name='Server', value=data.get('server_name'), inline=True)
    embed.add_field(name='Sys Channel',
                    value=data.get('main_channel'),
                    inline=True)
    embed.add_field(name='Allow auto send message',
                    value=data.get('allow_auto_send_messages'),
                    inline=False)
    embed.add_field(name='Allow chat learning',
                    value=data.get('allow_learning_from_chat'),
                    inline=False)
    embed.add_field(name='Filter offensive messages',
                    value=data.get('filter_offensive_messages'),
                    inline=False)

    return await ctx.send('Configurações do servidor:', embed=embed)
示例#2
0
async def quote(ctx, *args):
    """
    Ensina um novo quote à Luci
    """
    message = ' '.join(word for word in args)
    author = ctx.author.name

    if not message:
        return await ctx.send(
            'Por favor insira uma mensagem.\nExemplo:\n'\
            '``` !quote my name is bond, vagabond ```'
        )

    if '@' in message:
        return await ctx.send(
            'Eu não posso aprender esse tipo de coisa. Vou contar pro meu pai.'
        )

    server = make_hash('id', ctx.guild.id)
    payload = Mutation.create_quote(message, server.decode('utf-8'), author)
    client = get_gql_client(BACKEND_URL)

    try:
        response = client.execute(payload)
    except Exception as err:
        print(f'Erro: {str(err)}\n\n')
        return await ctx.send('Buguei')

    quote = response['create_quote'].get('quote')
    embed = discord.Embed(color=0x1E1E1E, type="rich")
    embed.add_field(name='Entendi:', value=quote.get('quote'), inline=True)
    return await ctx.send('Ok:', embed=embed)
示例#3
0
async def source(ctx, *args):
    """
    Pergunta quem foi que ensinou a mensagem.
    """
    text = ' '.join(char for char in args)
    if not text.strip():
        return await ctx.send('Ué você não disse nada ...')

    query = Query.get_message_authors(text)
    gql_client = get_gql_client(BACKEND_URL)
    try:
        response = gql_client.execute(query)
    except Exception as err:
        log.error(f'Erro: {str(err)}\n\n')
        return

    authors = set()
    messages = response.get('messages', [])
    if not messages:
        return await ctx.send('Não conhecia essa ainda, até agora...')

    for message in messages:
        authors.add(message.get('author'))

    if len(authors) > 9:
        return await ctx.send(
            f'Ja vi tipo umas {len(authors)} pessoas dizerem isso :rolling_eyes:'
        )

    authors = ';'.join(author for author in list(authors))

    return await ctx.send(f'Aprendi isso com {authors}')
示例#4
0
async def user_status(ctx):
    """
    Verifica o relatório de afeição que Luci possui de um determinado membro.

    Uso:
        !user @Username
    """
    mentions = ctx.message.mentions
    if not mentions:
        return await tx.send(
            'Não sei de quem vc está falando. Marca ele tipo @Fulano.')

    # consulta os membros no backend
    server = make_hash('id', ctx.message.guild.id).decode('utf-8')
    user_id = make_hash(server, mentions[0].id).decode('utf-8')
    payload = Query.get_user(user_id)
    gql_client = get_gql_client(BACKEND_URL)

    try:
        response = gql_client.execute(payload)
    except Exception as err:
        log.error(f'Erro: {str(err)}\n\n')
        return

    data = response.get('users', [])
    if not data:
        return await ctx.send('Acho que não c-conheço... Desculpa.')

    # monta a resposta
    embed = discord.Embed(color=0x1E1E1E, type='rich')
    name = data[0].get('name')
    friendshipness = data[0].get('friendshipness', 0)
    emotions = data[0].get('emotion_resume', {})
    user_id = extract_user_id(data[0]['reference'])

    pleasantness_status = EmotionHourglass.get_pleasantness(
        emotions["pleasantness"])
    pleasantness = f':heart_decoration: {emotions["pleasantness"]:.2f} '\
                    f'| status: {pleasantness_status}'

    attention_status = EmotionHourglass.get_attention(emotions["attention"])
    attention = f':yin_yang: {emotions["attention"]:.2f} | status: {attention_status}'

    sensitivity_status = EmotionHourglass.get_sensitivity(
        emotions["sensitivity"])
    sensitivity = f':place_of_worship: {emotions["sensitivity"]:.2f} | ' \
                    f'status: {sensitivity_status}'

    aptitude_status = EmotionHourglass.get_aptitude(emotions["aptitude"])
    aptitude = f':atom: {emotions["aptitude"]:.2f} | status: {aptitude_status}'

    embed.add_field(name='Username', value=name, inline=True)
    embed.add_field(name='Affection', value=friendshipness, inline=True)
    embed.add_field(name='Pleasantness', value=pleasantness, inline=False)
    embed.add_field(name='Attention', value=attention, inline=False)
    embed.add_field(name='Sensitivity', value=sensitivity, inline=False)
    embed.add_field(name='Aptitude', value=aptitude, inline=False)

    return await ctx.send('', embed=embed)
示例#5
0
    async def track(self):
        """ Tracking task """
        log.info('tracking...')
        gql_client = get_gql_client(BACKEND_URL)

        for guild in self.guilds:
            log.info(guild.name)

            server = make_hash('id', guild.id).decode('utf-8')
            # recupera a configuração do server
            query = Query.get_custom_config(server)
            try:
                response = gql_client.execute(query)
            except:
                log.error(f'Cant get server {guild.name} config. Skipping!')
                continue

            server_config = response.get('custom_config')
            main_channel = server_config.get('main_channel')

            if not main_channel:
                continue

            channel = client.get_channel(int(main_channel))

            # data da última mensagem enviada no server
            try:
                last_message_dt = parser.parse(self.short_memory.get(guild.id))
            except:
                last_message_dt = None

            if last_message_dt:
                now = datetime.now().astimezone(tz=timezone.utc)
                elapsed_time = now.replace(
                    tzinfo=None) - last_message_dt.replace(tzinfo=None)

                log.info('elapsed time: ')
                log.info(elapsed_time)
                log.info('total: ')
                log.info(elapsed_time.total_seconds() / 60 / 60)

                if (elapsed_time.total_seconds() / 60 / 60) > self.window:
                    if server_config.get('allow_auto_send_messages'):
                        # envia mensagem no canal principal se autorizado
                        log.info('Notifying channel %s', channel)
                        await channel.send(choice(bored_messages))

                    # Renova a data de última mensagem para a data atual
                    self.short_memory.set(guild.id,
                                          str(now.astimezone(tz=timezone.utc)))
                    log.info('Renewed datetime to %s', str(now))
                    payload = Mutation.update_emotion(server=server,
                                                      aptitude=-0.1)
                    try:
                        response = gql_client.execute(payload)
                        log.info('Updated aptitude')
                    except Exception as err:
                        log.error(f'Erro: {str(err)}\n\n')
示例#6
0
async def friendship(ctx, opt=None):
    """
    Lista os membros com maior afinidade com a Luci.
    O parâmetro `-` solicita que sejam listados os membros com menor afinidade.

    Exemplos:

        - `!fs`
        - `!friendship -`
    """
    embed = discord.Embed(color=0x1E1E1E, type="rich")

    # consulta os membros no backend
    server = make_hash('id', ctx.message.guild.id).decode('utf-8')
    payload = Query.get_users(server)
    gql_client = get_gql_client(BACKEND_URL)
    try:
        response = gql_client.execute(payload)
    except Exception as err:
        print(f'Erro: {str(err)}\n\n')
        return

    members = response.get('users')

    if not members:
        return await ctx.send('Acho que ainda não gosto muito de ninguém')

    if opt and opt == '-':
        members = [m for m in members if m['friendshipness'] < 0]

        if not members:
            return await ctx.send('Acho que não tenho muitos amigos aqui ainda'
                                  )

        members = sorted(members, key=lambda k: k['friendshipness'])[:10]

        for member in members:
            body = f'{member["name"]} | :heartpulse: : {member["friendshipness"]}'
            embed.add_field(name='Membro', value=body, inline=False)

        return await ctx.send('Membros que eu menos curto :rolling_eyes:',
                              embed=embed)

    members = [m for m in members if m['friendshipness'] >= 0]
    if not members:
        return await ctx.send('Acho que gosto de todo mundo por aqui')

    members = sorted(members, key=lambda k: k['friendshipness'],
                     reverse=True)[:10]
    for member in members:
        body = f'{member["name"]} | :heartpulse: : {member["friendshipness"]}'
        embed.add_field(name='Membro', value=body, inline=False)

    return await ctx.send('Membros que eu mais curto :blush:', embed=embed)
示例#7
0
async def random_quote(bot):
    """
    Retorna um quote aleatório.
    """
    server = make_hash('id', bot.guild.id)
    payload = Query.get_quotes(server.decode('utf-8'))
    client = get_gql_client(BACKEND_URL)

    try:
        response = client.execute(payload)
    except Exception as err:
        print(f'Erro: {str(err)}\n\n')
        return await bot.send('Buguei')

    quotes = response.get('quotes')
    if not quotes:
        return await bot.send('Ainda não aprendi quotes neste servidor')

    # sorteia um quote vindo da memória de longo rpazo
    chosen_quote = choice([quote['quote'] for quote in quotes])
    # recupera os últimos quotes ditos nesse server da memória de curto prazo
    server_memory = get_short_memory_value(server)

    # se o quote sorteado não for um quote repetido
    if chosen_quote not in server_memory.get('last_quotes', []):
        # atualiza memória de curto prazo e retorna o quote sorteado
        server_memory['last_quotes'].append(chosen_quote)
        if len(server_memory['last_quotes']) > 10:
            server_memory['last_quotes'].pop(0)
        set_short_memory_value(server, server_memory)
        return await bot.send(chosen_quote)

    # se ela souber menos que 10 quotes nesse server pode retornar o quote repetido mesmo
    if len(quotes) < 10:
        return await bot.send(chosen_quote)

    # Se não tem que ir sorteando quotes até não ser repetido
    while chosen_quote in server_memory['last_quotes']:
        chosen_quote = choice([quote['quote'] for quote in quotes])

    # Atualiza a memória de curto rpazo ao selecionar o quote
    server_memory['last_quotes'].append(chosen_quote)
    if len(server_memory['last_quotes']) > 10:
        server_memory['last_quotes'].pop(0)
    set_short_memory_value(server, server_memory)

    return await bot.send(chosen_quote)
示例#8
0
    async def track(self):
        """ Tracking task """
        log.info('tracking...')
        for guild in self.guilds:
            log.info(guild.name)
            # data da última mensagem enviada no server
            try:
                last_message_dt = parser.parse(self.short_memory.get(guild.id))
            except:
                last_message_dt = None

            if last_message_dt:
                now = datetime.now().astimezone(tz=timezone.utc)
                elapsed_time = now.replace(tzinfo=None) - last_message_dt.replace(tzinfo=None)

                log.info('elapsed time: ')
                log.info(elapsed_time)
                log.info('total: ')
                log.info(elapsed_time.total_seconds() / 60 / 60)

                if (elapsed_time.total_seconds() / 60 / 60) > self.window:
                    # envia mensagem no canal principal
                    log.info('Notifying channel %s', guild.system_channel.name)
                    await guild.system_channel.send(choice(bored_messages))

                    # Renova a data de última mensagem para a data atual
                    self.short_memory.set(
                        guild.id,
                        str(now.astimezone(tz=timezone.utc))
                    )
                    log.info('Renewed datetime to %s', str(now))

                    # O humor poderia ser localmente em um mongo
                    # Atualiza o humor da Luci no backend
                    server = make_hash('id', guild.id).decode('utf-8')
                    gql_client = get_gql_client(BACKEND_URL)

                    payload = Mutation.update_emotion(
                        server=server,
                        aptitude=-0.1
                    )
                    try:
                        response = gql_client.execute(payload)
                        log.info('Updated aptitude')
                    except Exception as err:
                        log.error(f'Erro: {str(err)}\n\n')
示例#9
0
async def status(bot):
    """
    Verifica o estado emocional da Luci.
    """
    server = make_hash('id', bot.guild.id)
    payload = Query.get_emotions(server.decode('utf-8'))
    client = get_gql_client(BACKEND_URL)

    try:
        response = client.execute(payload)
    except Exception as err:
        print(f'Erro: {str(err)}\n\n')
        return await bot.send('Buguei')

    humor = response.get('emotions')
    if humor:
        luci_humor = humor[0]

        embed = discord.Embed(color=0x1E1E1E, type='rich')

        pleasantness_status = EmotionHourglass.get_pleasantness(
            luci_humor["pleasantness"]
        )
        pleasantness = f':heart_decoration: {luci_humor["pleasantness"]:.2f} '\
                       f'| status: {pleasantness_status}'

        attention_status = EmotionHourglass.get_attention(
            luci_humor["attention"]
        )
        attention = f':yin_yang: {luci_humor["attention"]:.2f} | status: {attention_status}'

        sensitivity_status = EmotionHourglass.get_sensitivity(
            luci_humor["sensitivity"]
        )
        sensitivity = f':place_of_worship: {luci_humor["sensitivity"]:.2f} | ' \
                      f'status: {sensitivity_status}'

        aptitude_status = EmotionHourglass.get_aptitude(luci_humor["aptitude"])
        aptitude = f':atom: {luci_humor["aptitude"]:.2f} | status: {aptitude_status}'

        embed.add_field(name='Pleasantness', value=pleasantness, inline=False)
        embed.add_field(name='Attention', value=attention, inline=False)
        embed.add_field(name='Sensitivity', value=sensitivity, inline=False)
        embed.add_field(name='Aptitude', value=aptitude, inline=False)

        return await bot.send('', embed=embed)
示例#10
0
async def random_quote(bot):
    """
    Retorna um quote aleatório.
    """
    server = make_hash('id', bot.guild.id)
    payload = Query.get_quotes(server.decode('utf-8'))
    client = get_gql_client(BACKEND_URL)

    try:
        response = client.execute(payload)
    except Exception as err:
        print(f'Erro: {str(err)}\n\n')
        return await bot.send('Buguei')

    quotes = response.get('quotes')
    if not quotes:
        return await bot.send('Ainda não aprendi quotes neste servidor')

    chosen_quote = choice([quote['quote'] for quote in quotes])

    return await bot.send(chosen_quote)
示例#11
0
async def on_message(message):
    """
    Handler para mensagens do chat.
    """
    channel = message.channel
    if message.author.bot:
        return

    await client.process_commands(message)

    server = make_hash('id', message.guild.id).decode('utf-8')

    # guarda a data da mensagem como valor para o id da guilda
    short_memory = redis.Redis(REDIS_HOST, REDIS_PORT)
    short_memory.set(message.guild.id, str(message.created_at))

    text = message.content

    global_intention, specific_intention = get_intentions(text)
    is_offensive = validate_text_offense(text)
    text_pol = extract_sentiment(text)
    user_name = message.author.name
    new_humor = change_humor_values(text_pol, is_offensive)
    friendshipness = -0.5 + text_pol if is_offensive else text_pol
    msg = {
        'global_intention': global_intention,
        'specific_intention': specific_intention,
        'text': text
    }

    user_id = make_hash(server, message.author.id).decode('utf-8')
    gql_client = get_gql_client(BACKEND_URL)

    # Atualiza o humor da Luci
    payload = Mutation.update_emotion(server=server, **new_humor)
    try:
        gql_client.execute(payload)
    except Exception as err:
        log.error(f'Erro: {str(err)}\n\n')

    # Atualiza o humor status do usuario
    payload = Mutation.update_user(user_id, user_name, friendshipness,
                                   new_humor, msg)

    try:
        gql_client.execute(payload)
    except Exception as err:
        log.error(f'Erro: {str(err)}\n\n')

    # get server configuration
    query = Query.get_custom_config(server)
    try:
        response = gql_client.execute(query)
    except Exception as error:
        log.error(str(error))
        response = {}

    server_config = response.get('custom_config')

    # Atualiza reconhecimento de respostas, se for resposta à outra mensagem
    if message.reference:
        payload = Mutation.assign_response(
            text=message.reference.resolved.content, possible_response=msg)

        try:
            response = gql_client.execute(payload)
        except Exception as err:
            log.error(f'Erro: {str(err)}\n\n')

    # process @Luci mentions
    if str(channel.guild.me.id) in text:
        # busca possíveis respostas na memória de longo prazo
        payload = Query.get_possible_responses(text=remove_id(text))

        try:
            response = gql_client.execute(payload)
        except Exception as err:
            log.error(f'Erro: {str(err)}\n\n')
            response = {'messages': []}

        if response.get('messages'):
            possible_responses = []
            for msg in response['messages']:
                for possible_response in msg.get('possible_responses'):
                    possible_responses.append(possible_response.get('text'))

            if possible_responses:
                return await channel.send(choice(possible_responses))

        # Caso não conheça nenhuma resposta, use o classificador inocente
        return await channel.send(
            naive_response(remove_id(text), reference=server))

    # 10% chance to not answer if is offensive and lucis not mentioned
    is_allowed = server_config.get('allow_auto_send_messages')
    if not is_allowed:
        return

    if is_offensive and choice([1, 0]) and choice([1, 0]):
        return await channel.send(
            f'{message.author.mention} {choice(offended)}')
示例#12
0
async def on_message(message):
    """
    Handler para mensagens do chat.
    """
    channel = message.channel
    if message.author.bot:
        return

    await client.process_commands(message)

    # guarda a data da mensagem como valor para o id da guilda
    short_memory = redis.Redis(REDIS_HOST, REDIS_PORT)
    short_memory.set(message.guild.id, str(message.created_at))

    text = message.content
    
    global_intention, specific_intention = get_intentions(text)
    is_offensive = validate_text_offense(text)
    text_pol = extract_sentiment(text)
    user_name = message.author.name
    new_humor = change_humor_values(text_pol, is_offensive)
    friendshipness = -0.5 + text_pol if is_offensive else text_pol
    msg = {
        'global_intention': global_intention,
        'specific_intention': specific_intention,
        'text': text
    }

    server = make_hash('id', message.guild.id).decode('utf-8')
    user_id = make_hash(server, message.author.id).decode('utf-8')
    gql_client = get_gql_client(BACKEND_URL)

    # Atualiza o humor da Luci
    payload = Mutation.update_emotion(server=server, **new_humor)
    try:
        response = gql_client.execute(payload)
    except Exception as err:
        log.error(f'Erro: {str(err)}\n\n')

    # Atualiza o humor status do usuario
    payload = Mutation.update_user(
        user_id,
        user_name,
        friendshipness,
        new_humor,
        msg
    )

    try:
        response = gql_client.execute(payload)
    except Exception as err:
        log.error(f'Erro: {str(err)}\n\n')

    # Atualiza reconhecimento de respostas, se for resposta à outra mensagem
    if message.reference:
        payload = Mutation.assign_response(
            text=message.reference.resolved.content,
            possible_response=msg
        )

        try:
            response = gql_client.execute(payload)
        except Exception as err:
            log.error(f'Erro: {str(err)}\n\n')

    # process @Luci mentions
    if str(channel.guild.me.id) in text:
        return await channel.send(naive_response(remove_id(text)))

    # 10% chance to not answer if is offensive and lucis not mentioned
    if is_offensive and choice([1, 0]) and choice([1, 0]):
        return await channel.send(f'{message.author.mention} {choice(offended)}')