示例#1
0
def command_msg_count_rank(chat, msgs_count, count_mode):
    print("mode of !rank: ", count_mode)
    contacts = msgs_count[chat['contact']]
    count_sorted = sorted(
        [participant['id'] for participant in chat['participants']],
        key=lambda x: reset_count(contacts[x], count_mode),
        reverse=True)
    reset_day = 0
    ghost = '👻'
    total_count = 0
    rank_str = ''
    for i, contact_id in enumerate(count_sorted, 1):
        contact_info = contacts[contact_id]
        count = reset_count(contact_info, count_mode)
        rank_str += f'\t*{i}. {contact_info["contact"]} [{count}]*'
        if count < 100:
            rank_str += f' {ghost}'
            rank_str += f'\n  - Número: ({contact_id})'
            if count > 0:
                first_msg_date = contact_info['messages'][0]['time']
                rank_str += f'\n  - 1ª msg: {first_msg_date}'
        rank_str += '\n'
        total_count += count

    rank_str = f'Rank de mensagens (Total: ' \
               f'{total_count})\n{read_more()}{rank_str}'
    send_message(chat['id'], rank_str)
def command_anime_release(driver, chat, anime):
    # Starting searching using MyAnimeList because the searching engine is
    # way better, only get the 10 first results
    search_url = f'https://api.jikan.moe/v3/search/anime?page=1&q={anime}'
    search_results = requests.get(search_url).json()['results'][:10]
    mal_ids = []
    for mal_anime in search_results:
        mal_ids.append(mal_anime['mal_id'])

    # Querying with the mal_ids from the MAL search
    q = get_release_from_anime_q()
    variables = {'idMal_in': mal_ids, 'page': 1, 'perPage': 50}
    result = requests.post(get_anilist_api_url(),
                           json={
                               'query': q,
                               'variables': variables
                           }).json()
    s = ''
    for anime_r in result['data']['Page']['media']:
        anime_title = anime_r["title"]["romaji"]
        airing_data = anime_r['nextAiringEpisode']
        # If doesn't have a airing schedule, show release start date
        if airing_data is None:
            st_date = anime_r['startDate']
            d = st_date['day'] if st_date['day'] is not None else '?'
            m = st_date['month'] if st_date['month'] is not None else '?'
            y = st_date['year'] if st_date['year'] is not None else '?'
            dv = '28' if d == '?' else d
            mv = '12' if m == '?' else m
            yv = '3000' if y == '?' else y
            if datetime.strptime(f'{dv}{mv}{yv}',
                                 '%d%m%Y') >= datetime.today():
                s += f'O anime *"{anime_title}"* ' \
                     f'não tem uma data de lançamento específica.\n' \
                     f'*Data mais próxima:* {d}/{m}/{y}\n\n'
            continue

        tua = get_date_from_sec(airing_data['timeUntilAiring'])
        air_datetime = datetime.fromtimestamp(airing_data['airingAt'])
        release_weekday_i = air_datetime.weekday()
        release_weekday = dias_da_semana[release_weekday_i]
        episodes = anime_r['episodes']
        s += f'*{anime_title}*\n'

        episode = airing_data["episode"]
        if 60 * 60 * 24 <= airing_data['timeUntilAiring'] <= 60 * 60 * 24 * 7 \
                and release_weekday_i == datetime.today().weekday():
            s += f'O episódio lança hoje! ep: {episode - 1}\n'
        s += f'*Próximo episódio: {episode}* / ' \
             f'{"?" if episodes is None else episodes}\n' \
             f'O próximo episódio será lançado daqui a ' \
             f'{tua}' \
             f' *({release_weekday})*\n\n'
    if s == '':
        send_message(
            chat['id'], f'O anime "{anime}" não foi encontrado '
            f'ou já foi finalizado.')
    else:
        send_message(chat['id'], s)
示例#3
0
def command_search_studio(driver, chat, wpp_message):
    studio_pattern = re.compile('!(estúdio|estudio)\\s+(.+)')
    studio_name = studio_pattern.match(wpp_message['message']).groups()[1]
    q = get_studio_search_q()
    variables = {
        'search': studio_name,
        'page': 1,
        'perPage': 50
    }
    results = requests.post(get_anilist_api_url(),
                            json={'query': q, 'variables': variables}).json()
    studio_results = results['data']['Page']['studios']
    total_results = len(studio_results)
    studio = None
    if total_results == 0:  # No results, send warning and that's it
        send_message(chat['id'],
                     f'Estúdio {studio_name} não encontrado.')
        return
    elif total_results == 1:  # Don't need to choose, only one option
        studio = studio_results[0]
    else:  # send a list to choose a studio
        choose_list_str = ''
        time_limit = 30
        i = 1
        for studio_result in studio_results[:20]:
            choose_list_str += f'*[{i:02}] {studio_result["name"]}*\n'
            i += 1
        choose_msg = send_choose_list(chat_id=chat['id'],
                                      q_type='estúdio',
                                      choose_list_str=choose_list_str,
                                      time_limit=time_limit)
        for cur_chat, cur_message in wait_for_response_generator(time_limit):
            msg = cur_message['message']
            if can_make_element_choice(wpp_message, cur_message, max_value=i):
                studio = studio_results[int(msg) - 1]
                delete_message(driver, chat['id'], choose_msg)
                break
            elif msg == '0':  # cancel sentinel
                delete_message(driver, chat['id'], choose_msg)
                return

        if studio is None:  # Did not send any value
            send_message(chat['id'], 'Tempo terminado.')
            delete_message(driver, chat['id'], msg=choose_msg)
            return

    animes = []
    for anime in studio['media']['nodes'][:25]:
        anime_info = f'Ano: {anime["startDate"]["year"]}\n' \
                     f'Tipo: {anime["format"]}'
        animes.append(BotImageElement(title=anime['title']['romaji'],
                                      image_info=anime_info,
                                      image_url=anime['coverImage']['large']))
    studio_image_result = get_list_image(animes, studio['name'])
    send_media(chat['id'], msg=f'*Estúdio {studio["name"]}*',
               img_base64=studio_image_result, msg_id=wpp_message['msg_id'],
               image_url=None)
示例#4
0
def command_spoiler(chat, wpp_message):
    spoiler_pattern = re.compile('!spoiler\s+([^/|]+)[/|](.+)')
    command = wpp_message['message']
    if 'contact' not in wpp_message.keys():
        wpp_message['contact'] = 'Eu'
    if spoiler_pattern.match(command):
        spoiler_data = spoiler_pattern.match(command).groups()
        spoiler_warning = spoiler_data[0].strip()
        spoiler_content = spoiler_data[1].strip()
        send_message(
            chat['id'],
            f'*[SPOILER {spoiler_warning}]* ({wpp_message["contact"]})'
            f'{read_more()}\n\n\n{spoiler_content}')
def command_anime_manga_list(driver, chat, user, q, q_type, wpp_message):
    response = requests.get(
        f'https://api.jikan.moe/v3/user/{user}/{q_type}list/{q}')
    if response.status_code == 400:
        send_message(
            chat['id'], f'Ocorreu um erro ao pesquisar a lista do usuário '
            f'*"{user}"* verifique se o nome está correto')
    results = response.json()[q_type]
    results = sorted(results, key=lambda k: k['score'], reverse=True)
    i = 1
    head = f"Continuação da lista de {q_type} {q} de *'{user}'*:\n"
    s = ''
    elements = []
    for e in results:
        title = e["title"]
        e_str = ''
        e_str += f'*{e["title"]}* '
        if q_type == 'manga':
            e_info = f'c.{e["read_chapters"]} v.{e["read_volumes"]}'
            e_str += f'*c.{e["read_chapters"]} v.{e["read_volumes"]}*'
        else:
            total_episodes = e['total_episodes']
            total_episodes = '?' if total_episodes == 0 else total_episodes
            e_info = f'Episodes: {e["watched_episodes"]}/{total_episodes}'
            e_str += f'_{e["watched_episodes"]} eps_'
        e_info += f'\nScore: {e["score"]}'
        elements.append(
            BotImageElement(title=title,
                            image_info=e_info,
                            image_url=e['image_url']))
        e_str += f' [ {e["score"]} ] \n'
        if i == 16:
            s += read_more()
        if i > 16:
            s += e_str
        i += 1
    # send_message(driver, chat['id'], s)
    if len(elements) > 0:
        header_text = f"lista de {q_type} {q} de '{user}':"
        list_image = get_list_image(elements[:16], header_text)
        send_media(chat['id'],
                   image_url=None,
                   msg=head + s,
                   msg_id=wpp_message['msg_id'],
                   img_base64=list_image)
    else:
        send_message(chat['id'],
                     f"Não há nada na lista de {q_type} {q} de *'{user}'*:\n")
def command_user_manager(driver, chat, wpp_message):
    command = wpp_message['message']
    user_profile_pattern = re.compile('!user\\s+(perfil\\s+)?(.+)')
    user_history_pattern = re.compile('!user\\s+(historico|histórico)\\s+(.+)')
    if user_history_pattern.match(command):
        user = user_history_pattern.match(command).groups()[1]
        send_message(chat['id'], command_user_history(user))
    elif user_profile_pattern.match(command):
        user = user_profile_pattern.match(command).groups()[1]
        user_profile = command_user_profile(user)
        # If the user does not have a photo
        if user_profile[1] is not None:
            send_media(chat['id'], user_profile[0], user_profile[1],
                       wpp_message['msg_id'])
        else:
            send_message(chat['id'], user_profile[0])
    else:  # if command if incorrect, send explanation
        # send_message(driver, chat['id'], help_user())
        get_help(driver, chat, '!user', wpp_message)
示例#7
0
def command_help(driver, chat, wpp_message):
    """Return all the commands and their descriptions"""
    # get_help(driver, chat, '!help', wpp_message)
    send_message(chat['id'],
        'MyAnimeList bot help\n' +
        '-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n' + read_more() + '\n' +
        bot_help() + help_anime() + help_manga() + help_personagem() +
        help_studio() + help_monogatari() +
        '-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n'
        '*[ !contador* _help_ *]* – Mostra todos os comandos relacionados ao '
        'contador de mensagens e ranks.\n'
        '*[ !user ]* - Mostra comandos relacionados ao perfil do usuário'
        '\n*[ !favorite ]* - Mostra os comandos que mostra os favoritos de um '
        'usuário no MAL\n'
        '*[ !list ]* - Mostra comandos relacionados às listas de usuários do '
       'MAL\n'
        '*[ !semanal ]* - Mostra todos os comandos relacionados a '
       'lançamentos de animes na semana\n'
       '*[ !top ]* - Mostra todos os comandos que mostram os tops do '
        'MyAnimeList, inclusive os top animes da temporada\n')
示例#8
0
def command_msg_count(chat, driver, wpp_message, msgs_count):
    command = wpp_message['message']
    contacts = msgs_count[chat['contact']]
    number_choose_pat = re.compile(
        '!contador\\s+(\\d+)\\s*(all|mes|mês|mensal|hoje|dia|diário|diario|semana|semanal)?$'
    )
    person_pattern = re.compile(
        '!contador\\s+@(\\d+)\\s*(all|mes|mês|hoje|dia|mensal|diário|diario|semana|semanal)?'
    )
    default_pattern = re.compile(
        '!contador\\s*(all|mes|mês|mensal|hoje|dia|diário|diario|semana|semanal)?'
    )

    if number_choose_pat.match(command):
        mode = number_choose_pat.match(command).groups()[1]
    elif person_pattern.match(command):
        mode = person_pattern.match(command).groups()[1]
    elif default_pattern.match(command):
        mode = default_pattern.match(command).groups()[0]
    count_sorted = sorted(
        [participant['id'] for participant in chat['participants']],
        key=lambda x: reset_count(contacts[x], mode),
        reverse=True)

    if person_pattern.match(command):
        m_id = person_pattern.match(command).groups()[0]
        try:
            contact = contacts[m_id]
        except KeyError:
            send_message(chat['id'], f'Número "{m_id}" não encontrado')
            return
    elif number_choose_pat.match(command):
        n = int(number_choose_pat.match(command).groups()[0])
        try:
            if n - 1 < 0:
                raise IndexError('Go f**k yourself you f*****g c**t')
            m_id = count_sorted[n - 1]
            contact = contacts[m_id]
        except IndexError:
            send_message(chat['id'], f'Número {n} fora de alcance')
            return
    elif default_pattern.match(command):
        contact = contacts[wpp_message['id']]
        m_id = wpp_message['id']
    contagem = f"{contact['contact']}, enquanto o bot esteve ligado," \
               f" escreveu {reset_count(contact, mode)} mensagens. " \
               f"({count_sorted.index(m_id) + 1}º lugar)" \
               f" "
    send_message(chat['id'], contagem)
示例#9
0
def command_user_favorites(driver, chat, wpp_message):
    command = wpp_message['message']
    favorite_pattern = re.compile(
        '!favorit(e|o)\\s+(anime|manga|personagem)\\s+(.+)')
    if favorite_pattern.match(command):
        user = favorite_pattern.match(command).groups()[2]
        q_type = favorite_pattern.match(command).groups()[1]
        q_type = q_type.replace('personagem', 'characters')

        # If user is not found, send a warning
        response = requests.get("https://api.jikan.moe/v3/user/" + user)
        if response.status_code == 404:
            send_message(chat['id'],
                         f'O usuário "{user}" não foi encontrado.')
            return
        elif 'error' in response.json().keys():
            send_message(chat['id'],
                         f'Ocorreu um erro ao analisar'
                         f' *"{user}"*, verifique se o '
                         f'usuário está correto, ou sua conta está vazia.')
        elements = []
        favorites = response.json()['favorites']
        user = response.json()['username']

        s = f"{user}'s favorite {q_type}:"
        for i, anime in enumerate(favorites[q_type], 1):
            elements.append(BotImageElement(title=anime['name'],
                                            image_info=f'{i}',
                                            image_url=anime['image_url']))

        if len(elements) > 0:
            list_image = get_list_image(elements, s)
            send_media(chat['id'], s, None, wpp_message['msg_id'],
                       list_image)
        else:
            send_message(chat['id'], s)
    else:
        get_help(driver, chat, '!favorite', wpp_message)
def command_day_releases(driver, chat, week_day, wpp_message):
    send_message(chat['id'], 'Pesquisando lançamentos...')
    q = get_release_from_anime_q()
    variables = {
        'page': 1,
        'perPage': 50,
        'startDate_greater': 19000000,
        'format_in': ['TV', 'TV_SHORT', 'ONA']
    }
    result = requests.post(get_anilist_api_url(),
                           json={
                               'query': q,
                               'variables': variables
                           }).json()
    pages = result['data']['Page']['pageInfo']['lastPage']
    results = [result['data']['Page']['media'][0]]
    threads = [
        threading.Thread(target=get_day_results, args=[page, results])
        for page in range(2, pages)
    ]
    [thread.start() for thread in threads]
    [thread.join() for thread in threads]

    elements = []

    i = 1

    for anime_r in results:
        anime_title = anime_r["title"]["romaji"]
        airing_data = anime_r['nextAiringEpisode']
        image_url = anime_r['coverImage']['large']
        anime_info = ''
        if airing_data is None:
            continue
        # if will release
        air_at = airing_data['airingAt']
        air_remain = airing_data['timeUntilAiring']
        air_date = datetime.fromtimestamp(air_at)
        # if is the requested day and is less than a week needed
        if air_date.weekday() == week_day \
                and air_remain <= 7 * 24 * 60 * 60:
            episodes = anime_r['episodes']
            episode = airing_data["episode"]

            if air_remain < 60 * 60 * 24 \
                    or air_date.weekday() != datetime.today().weekday():
                anime_info += f'EP: {episode} / ' \
                              f'{"?" if episodes is None else episodes}\n'
            elif episode - 1 > 0:
                anime_info += f'Ep: {episode - 1} / ' \
                              f'{"?" if episodes is None else episodes}' \
                              f' (Lançado)\n'
            i += 1

            anime_info += f'Próximo Ep: {get_date_from_sec(air_remain)}'
            elements.append(
                BotImageElement(title=anime_title,
                                image_info=anime_info,
                                image_url=image_url))

    if len(elements) == 0:
        send_message(chat['id'], 'Nada encontrado')
    else:
        header_text = f'Episódios que lançam {dias_da_semana[week_day]}:'
        list_image = get_list_image(elements, header_text)
        send_media(chat['id'], f"*{header_text}*", None, wpp_message['msg_id'],
                   list_image)
示例#11
0
def make_call(driver, chat, wpp_message, msgs_count):
    """Sends the response message to a command, if there is one

         :Args:
         - driver: The webdriver to execute the JS scrips
         - chat: the chat to send the message
         - message: the message send by the user

         :Usage:
             chat = Output.output[0]
             message = chat['messages'][0]
             threading.Thread(
                 target=make_call, args=[driver, chat, message]).start()
    """

    wpp_message['message'] = wpp_message['message'].strip().lower()

    # stripping spaces after !
    wpp_message['message'] = \
        re.sub('!\\s+(.+)', r'!\1', wpp_message['message'])

    command = wpp_message['message']
    if command == '!help':
        command_help(driver, chat, wpp_message)
    elif command.startswith('!anime'):
        command_anime_search(driver, chat, wpp_message)
    elif command.startswith('!manga') or command.startswith('!mangá'):
        command_manga_search(driver, chat, wpp_message)
    elif command.startswith('!personagem'):
        command_character_search(driver, chat, wpp_message)
    elif command.startswith('!estúdio') or command.startswith('estúdio'):
        command_search_studio(driver, chat, wpp_message)
    elif command.startswith('!user'):
        command_user_manager(driver, chat, wpp_message)
    elif command.startswith('!favorit'):
        command_user_favorites(driver, chat, wpp_message)
    elif command.startswith('!semana') or command.startswith('!lançamento'):
        command_release_manager(driver, chat, wpp_message)
    elif command.startswith('!top'):
        command_top_manager(driver, chat, wpp_message)
    elif command == '!monogatari':
        command_monogatari_order(driver, chat, wpp_message)
    elif command.startswith('!list'):
        command_list_manager(driver, chat, wpp_message)
    elif command.startswith('!spoiler'):
        command_spoiler(chat, wpp_message)
    elif command == '!temp':
        command_measure_temp(chat)
    elif command.startswith('!rank') or command.startswith("!contador rank"):
        print(Last.last)
        if chat['id'] in Last.last.keys() and command not in Last.last[
                chat['id']]:
            print('iffffffff')
            Last.last[chat['id']][command] = time() - wait_rank - 1
        elif chat['id'] not in Last.last:
            print('elseeeeee')
            Last.last[chat['id']] = {}
            Last.last[chat['id']][command] = time() - wait_rank - 1

        time_passed = time() - Last.last[chat['id']][command]

        if time_passed > wait_rank:
            command_msg_count_manager(chat, driver, wpp_message, msgs_count)
            Last.last[chat['id']][command] = time()
        else:
            remain = wait_rank - time_passed
            mn = remain // 60
            sec = remain % 60
            send_message(
                chat['id'], f'Espere *{mn:.0f} min* e *{sec:.0f}s* para'
                f' usar !rank novamente nesse chat (15 em 15 min)')
    elif command.startswith('!contador'):
        command_msg_count_manager(chat, driver, wpp_message, msgs_count)
示例#12
0
def command_words_count(chat, wpp_message, msgs_count):
    command = wpp_message['message']
    person_pattern = re.compile('!contador\\s+palavras\\s+@(\d+)')
    if person_pattern.match(command):
        contact_number = person_pattern.match(command).groups()[0]
    else:
        contact_number = wpp_message['id']
    messages = msgs_count[chat['contact']][contact_number]['messages']
    contact = msgs_count[chat['contact']][contact_number]['contact']

    word_counter = {}
    types_counter = {}
    times_counter = {}
    excluded_words = [
        'eles', 'elas', 'comigo', 'contigo', 'conosco', 'convosco', 'lhes',
        'você', 'voce', 'minha', 'mais', 'meus', 'minhas', 'teus', 'tuas',
        'seus', 'suas', 'nosso', 'nossa', 'nossos', 'nossas', 'vosso', 'vossa',
        'vossos', 'vossas', 'seus', 'suas', 'mesmo', 'mesma', 'mesmos',
        'mesmas', 'tais', 'quem', 'qual', 'quais', 'quanto', 'quanta',
        'quantos', 'quantas', 'assim', 'então', 'logo', 'pois', 'portanto',
        'porque', 'pois', 'porquanto', 'como', 'embora', 'conquanto', 'caso',
        'quando'
        'esses', 'essas', 'esse', 'essa', 'isso', 'isto'
    ]
    total_words = 0
    for message in messages:
        # counting types
        msg_type = '!comandos' if message['message'].startswith(
            '!') else message['type']
        if msg_type in types_counter:
            types_counter[msg_type] += 1
        else:
            types_counter[msg_type] = 1

        msg_txt = message['message']
        if msg_txt == '(Sem mensagem)': continue

        # gets all words and count them, includes pitch accents
        words = re.findall('[a-zA-ZáéíóúâêîôûãõüÁÉÍÓÚÂÊÎÔÛÃÕÜ]+', msg_txt)
        total_words += len(words)
        for word in words:
            word = word.lower()
            word = 'kkkk (e variantes)' if word == 'k' * len(word) else word
            if len(word) < 4 or (word in excluded_words): continue
            if word in word_counter:
                word_counter[word] += 1
            else:
                word_counter[word] = 1

        # couting hours
        date = datetime.strptime(message['time'], '%d/%m/%Y (%H:%M)')
        if date.hour in times_counter:
            times_counter[date.hour] += 1
        else:
            times_counter[date.hour] = 1
    ordered_words = sorted(word_counter.keys(),
                           key=lambda x: word_counter[x],
                           reverse=True)
    s = f'*Palavras mais usadas de {contact}:*'
    s += f'{read_more()}\n*Total:* {len(messages)}\n'
    chat_count = 1 if 'chat' not in types_counter else types_counter['chat']
    s += f'*Média de palavras {(total_words / chat_count):.2f} por mensagem*\n'
    for i, word in enumerate(ordered_words[:10], 1):
        s += f'*{i}. {word}* [{word_counter[word]}]\n'

    s += '\n*Tipos de mensagens e contagem:*\n'
    ordered_types = sorted(types_counter.keys(),
                           key=lambda x: types_counter[x],
                           reverse=True)
    for i, msg_type in enumerate(ordered_types, 1):
        s += f'*{i}. {msg_type}* [{types_counter[msg_type]}]\n'

    s += '\n*Horários e contagem:*\n'
    ordered_times = sorted(times_counter.keys(),
                           key=lambda x: times_counter[x],
                           reverse=True)
    for msg_time in ordered_times:
        s += (f'*{msg_time:02}:00~{((msg_time + 1) % 24):02}:00-* '
              f'{times_counter[msg_time]}\n')
    send_message(chat['id'], s)
    pass
def command_measure_temp(chat):
    temp = os.popen('vcgencmd measure_temp').readline()
    temp = temp.replace('temp=', '')
    temp = temp.replace("'", "º")
    send_message(chat['id'], f'A temperatura do bot no momento é {temp}')