Ejemplo n.º 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)
Ejemplo n.º 2
0
def get_wiki(text):
    """
    Return a list of explanations for a each term inputed.
    """
    error_response = ['N-não..', 'Não sei...']
    data = Query.get_pos(text)

    wiki = wikipedia
    wiki.set_lang('pt')

    if not data:
        return error_response

    tokens = [
        token['token'] for token in data['data']['partOfSpeech']
        if token['description'] == 'substantivo'
        or token['description'] == 'nome próprio'
    ]

    if len(tokens) > 3:
        return [get_random_blahblahblah()]

    try:
        response = [wiki.summary(token, sentences=2) for token in tokens]
    except (wiki.exceptions.DisambiguationError, wiki.exceptions.PageError):
        response = error_response

    return response
Ejemplo n.º 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}')
Ejemplo n.º 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)
Ejemplo n.º 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')
Ejemplo 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)
Ejemplo n.º 7
0
def cli_ranking():
    top10 = Query.get_top_10().get('data')
    print('Showing top 10\n')
    print('-------------------------')
    print('NAME PERFORMANCE ROUNDS DATE')
    for score in top10.get('wumpusScores', []):
        name = score.get('playerName')
        performance = score.get('performance')
        rounds = score.get('rounds')
        date = score.get('gameDatetime')
        print(f'{name} {performance} {rounds} {date}')
    print('-------------------------\n')
Ejemplo n.º 8
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)
Ejemplo 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)
Ejemplo n.º 10
0
async def on_member_join(member):
    """
    Greets the new member.
    """
    # Gets an hello
    message = ResponseGenerator.get_greeting_response()
    server_reference = make_hash('id', int(member.guild.id))
    query = Query.get_custom_config(server_reference)
    try:
        response = gql_client.execute(query)
    except:
        log.error(f'Cant get server {server_reference} config. Skipping!')
        return None

    server_config = response.get('custom_config')
    channel = client.get_channel(int(server_config.get('main_channel')))
    if channel:
        await channel.send(f'{message} {member.mention}')
Ejemplo n.º 11
0
async def guess(ctx, *args):
    """
    Luci tenta adivinhar quem disse a frase.
    """
    text = ' '.join(char for char in args)
    query = Query.somal_guess(text)
    url = 'http://somal.brunolcarli.repl.co/graphql/'

    response = requests.post(url, json={'query': query}).json()
    target = response['data'].get('guess')

    if target:
        if target == 'bruno':
            return await ctx.send('Eu acho que quem disse isso foi o Bruno.')

        return await ctx.send(
            f'Acho que quem disse isso foi o tio {target.capitalize()}')

    return await ctx.send('Acho que não sei quem disse isso, sei la...')
Ejemplo n.º 12
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)
Ejemplo n.º 13
0
async def on_member_join(member):
    """
    Greets the new member.
    """
    # Gets an hello
    message = ResponseGenerator.get_greeting_response()
    server_reference = make_hash('id', int(member.guild.id))
    query = Query.get_custom_config(server_reference)
    try:
        response = gql_client.execute(query)
    except:
        log.error(f'Cant get server {server_reference} config. Skipping!')
        return None

    server_config = response.get('custom_config')
    channel = client.get_channel(int(server_config.get('main_channel')))
    if channel:
        await channel.send(
            'https://media.discordapp.net/attachments/590678517407285251/865606198341926912/jerry.gif?width=979&height=466'
        )
        await channel.send(f'{message} bem vinde.')
Ejemplo n.º 14
0
def extract_sentiment(text):
    """
    Extracts sentiment polarity from text, returning a integer value
    between -1 and 1. In any failure case, consider it neutral (0).

    param : text : <str>
    return : <int>
    """
    request_sentiment = Query.get_text_sentiment(text)

    if not request_sentiment:
        return 0

    try:
        polarity = request_sentiment['data']['sentimentExtraction']
    except KeyError:
        return 0
    else:
        return polarity if polarity else 0

    return 0
Ejemplo n.º 15
0
def validate_text_offense(text):
    """
    Verify if an text message is offensive or not. Returns Tru if it is
    offensive text. Returns False if its not offensive.

    param : text : <str> : Text input;
    return: : <bool>
    """
    request_offenssivnes = Query.get_text_offense(text)
    if not request_offenssivnes:
        return False

    try:
        is_offensive = request_offenssivnes['data']['textOffenseLevel'][
            'isOffensive']
    except KeyError:
        # In case of failure, like an naive child, take as False
        return False
    else:
        # Otherwise return the value calculated by LISA
        return is_offensive
Ejemplo n.º 16
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)}')