def notification_service():
        telegram_bot = TelegramBot()

        while True:
            matches_for_notify = TinderDb.get_new_from_notification_queue()

            for match in matches_for_notify:
                telegram_bot.notify_telegram(match)
                time.sleep(2)

                TinderDb.push_notification_status(match)

            time.sleep(2)
    def delete_match(self, update: Update, context: CallbackContext):
        callback_data = context.match.group().split('/')
        match_id = callback_data[1]
        photos_count = callback_data[2]

        chat_id = update.callback_query.message.chat_id
        buttons_message_id = update.callback_query.message.message_id

        self.telegram_bot_instance.bot_actions.cleanup_chat(
            photos_count, buttons_message_id, chat_id)

        TinderDb.delete_match(match_id)
        self.tinder_handler.client.delete_match(match_id)
    def continue_chat(self, update: Update, context: CallbackContext):
        _, match_id, photos_count = context.match.group().split('/')

        chat_id = update.callback_query.message.chat_id
        buttons_message_id = update.callback_query.message.message_id

        self.telegram_bot_instance.bot_actions.cleanup_chat(
            photos_count, buttons_message_id, chat_id)

        ConversationHandler.continue_chat(
            tinder_client=self.tinder_handler.client, match_id=match_id)

        StatisticsDb.derease_contacts_recieved()

        TinderDb.delete_match(match_id)
    def write_telegram(self, match: Match, offset: int):
        telegram = json.loads(
            TinderDb.get_match_tgs(match_id=match.match_id))[offset]
        asyncio.set_event_loop(self.loop)

        messages = MessageProvider.messages_for_telegram()

        if TextAnalyzer.try_parse_login(strings=[telegram]):
            receiver = f"@{telegram}"

            for message in messages:
                try:
                    self.client.send_message(receiver, message)
                    time.sleep(2)
                except ValueError as e:
                    print(e.args)

        elif TextAnalyzer.try_parse_phone(telegram):
            contact = InputPhoneContact(
                client_id=0,  # For new contacts use client_id = 0
                phone=f"+7{telegram}",
                first_name=f"{match.name} {match.age}",
                last_name='Tinder')

            c = self.client(ImportContactsRequest([contact]))
            if c.users:
                for message in messages:
                    self.client.send_message(c.users[0], message)
        def extend_conversations(conversations_collection, data, only_new=False):
            if only_new:
                only_new_filter = lambda x: not TinderDb.match_exists(x['id'])

                conversations_collection.extend([{'id': m['id'], 'name': m['person']['name']}
                                                 for m in data['data']['matches'] if only_new_filter(m)])
            else:
                conversations_collection.extend([{'id': m['id'], 'name': m['person']['name']}
                                                 for m in data['data']['matches']])
    def try_add(tinder_client, match_id, girl_responses, whole_conversation):

        try:
            user_info = tinder_client.get_user_info(match_id)
        except AssertionError as e:
            return False

        search_strings = []
        search_strings.append(user_info['bio'])
        search_strings.extend(girl_responses)
        contacts = ContactsRecognizer.get_contacts_from_strings(search_strings)

        if len(contacts['ig'] + contacts['tg'] + contacts['wa']) == 0:
            return False

        pretty_conversation = ConversationFormatter.format(
            tinder_client.my_id, user_info['name'], whole_conversation)

        dbdata = {
            'match_id': user_info['tinder_match_id'],
            'user_id': user_info['id'],
            'name': user_info['name'],
            'birth_date': user_info['birth_date'],
            'bio': user_info['bio'],
            'age': user_info['age'],
            'photos': '\n\n'.join(user_info['photos']),
            'photos_orig': '\n\n'.join(user_info['photos_orig']),
            'photos_count': len(user_info['photos']),
            'pretty_conversation': pretty_conversation,
            'instagram': json.dumps(contacts['ig'], ensure_ascii=False),
            'telegram': json.dumps(contacts['tg'], ensure_ascii=False),
            'whatsapp': json.dumps(contacts['wa'], ensure_ascii=False),
            'notification_status': 'new'
        }

        TinderDb.add_to_notification_queue(**dbdata)

        StatisticsDb.increase_contacts_recieved()
        return True
    def view_original_photos(self, update: Update, context: CallbackContext):
        match_id = context.match.group().split('/')[1]
        match = TinderDb.get_match(match_id)
        ph_orig = match.photos_orig

        chat_id = update.callback_query.message.chat_id
        self.telegram_bot_instance.bot.send_message(
            chat_id=chat_id,
            text=ph_orig,
            reply_markup=InlineKeyboardMarkup([[
                InlineKeyboardButton('Delete this message',
                                     callback_data='delete_message/')
            ]]))
    def get_info(self, update: Update, context: CallbackContext):
        query = update.message.text
        match = TinderDb.search_match(query)

        if query == '/start':
            self.telegram_bot_instance.bot.send_message(
                chat_id=update.message.chat_id,
                text='started',
                parse_mode='HTML',
                disable_web_page_preview=True,
                reply_markup=InlineKeyboardMarkup([[
                    InlineKeyboardButton('Delete this message',
                                         callback_data='delete_message/')
                ]]))

            self.telegram_bot_instance.bot.delete_message(
                chat_id=update.message.chat_id,
                message_id=update.message.message_id)

            return

        if match is not None:
            self.telegram_bot_instance.chat_writer.send_mediagroup(match)
            self.telegram_bot_instance.chat_writer.send_message(match)

        else:
            self.telegram_bot_instance.bot.send_message(
                chat_id=update.message.chat_id,
                text=f"<b>Not found for query: {query}</b>",
                parse_mode='HTML',
                disable_web_page_preview=True,
                reply_markup=InlineKeyboardMarkup([[
                    InlineKeyboardButton('Delete this message',
                                         callback_data='delete_message/')
                ]]))

        # remove search query
        self.telegram_bot_instance.bot.delete_message(
            chat_id=update.message.chat_id,
            message_id=update.message.message_id)
    def handle(tinder_client, match_id):

        if TinderDb.match_exists(match_id=match_id):
            return

        replicas_for_tinder = MessageProvider.messages_for_tinder()

        girl_responses, my_requests, whole_conversation = tinder_client.get_messages(
            match_id)
        match_id = whole_conversation[0]['match_id']

        replicas_sent_quantity = ConversationHandler._count_my_replicas_sent(
            whole_conversation, tinder_client)

        if replicas_sent_quantity == 0:
            tinder_client.send_message(match_id, replicas_for_tinder[0])
            StatisticsDb.increase_new_matches(
            )  # i did not send anything but conversation exists, so she was first
            return

        my_last_replica_replied = ConversationHandler._replica_was_replied(
            whole_conversation, tinder_client, replicas_sent_quantity)
        if my_last_replica_replied:

            if replicas_sent_quantity >= MessageProvider.notification_threshold(
            ):

                if NotificationQueue.try_add(tinder_client, match_id,
                                             girl_responses,
                                             whole_conversation):

                    return

            if (replicas_sent_quantity + 1) <= len(replicas_for_tinder):
                '''replica indexes starts from 0 and if we already sent one replica,
                    then we should send second replica, which index will be 1'''

                tinder_client.send_message(
                    match_id, replicas_for_tinder[replicas_sent_quantity])
    def switch_instagram(self, update: Update, context: CallbackContext):
        callback_data = update.callback_query.data
        direction, _, tinder_match_id = callback_data.split('/')

        ig_write_button_row_index = -1
        ig_switch_buttons_row_index = -1

        for i, row_of_buttons in enumerate(
                update.callback_query.message.reply_markup.inline_keyboard):
            if 'instagram' in row_of_buttons[0].callback_data:
                ig_write_button_row_index = i
                ig_switch_buttons_row_index = i + 1
                position = int(update.callback_query.message.reply_markup.inline_keyboard[i] \
                                   [0].callback_data.split('/')[2])
                break

        instagrams = json.loads(
            TinderDb.get_match_igs(match_id=tinder_match_id))

        if direction == 'next':
            position += 1

            if position > len(instagrams) - 1:
                return

        elif direction == 'prev':
            position -= 1

            if position < 0:
                return

        new_instagram_login = instagrams[position]['login']

        new_reply_markup = update.callback_query.message.reply_markup
        open_instagram = 'open' if instagrams[position]["open"] else 'private'
        new_reply_markup.inline_keyboard[ig_write_button_row_index][0].text = f'iG: {new_instagram_login} ' \
                                                                              f'({open_instagram})'
        new_reply_markup.inline_keyboard[ig_write_button_row_index][
            0].callback_data = f'instagram/{tinder_match_id}/{position}'

        if position == 0:

            new_reply_markup.inline_keyboard[ig_switch_buttons_row_index] = [
                InlineKeyboardButton(
                    f'<<', callback_data=f'prev/ig/{tinder_match_id}'),
                InlineKeyboardButton(
                    f'>> {instagrams[position + 1]["login"]}',
                    callback_data=f'next/ig/{tinder_match_id}')
            ]

        elif position == len(instagrams) - 1:

            new_reply_markup.inline_keyboard[ig_switch_buttons_row_index] = [
                InlineKeyboardButton(
                    f'<< {instagrams[position - 1]["login"]}',
                    callback_data=f'prev/ig/{tinder_match_id}'),
                InlineKeyboardButton(
                    f'>>', callback_data=f'next/ig/{tinder_match_id}')
            ]

        else:

            new_reply_markup.inline_keyboard[ig_switch_buttons_row_index] = [
                InlineKeyboardButton(
                    f'<< {instagrams[position - 1]["login"]}',
                    callback_data=f'prev/ig/{tinder_match_id}'),
                InlineKeyboardButton(
                    f'>> {instagrams[position + 1]["login"]}',
                    callback_data=f'next/ig/{tinder_match_id}')
            ]

        self.telegram_bot_instance.bot.edit_message_reply_markup(
            chat_id=update.callback_query.message.chat_id,
            message_id=update.callback_query.message.message_id,
            reply_markup=new_reply_markup)
    def switch_whatsapp(self, update: Update, context: CallbackContext):
        callback_data = update.callback_query.data
        direction, _, tinder_match_id = callback_data.split('/')

        wa_write_button_row_index = -1
        wa_switch_buttons_row_index = -1

        for i, row_of_buttons in enumerate(
                update.callback_query.message.reply_markup.inline_keyboard):
            if 'whatsapp' in row_of_buttons[0].callback_data:
                wa_write_button_row_index = i
                wa_switch_buttons_row_index = i + 1
                position = int(update.callback_query.message.reply_markup.inline_keyboard[i] \
                    [0].callback_data.split('/')[2])
                break

        whatsapps = json.loads(
            TinderDb.get_match_was(match_id=tinder_match_id))

        if direction == 'next':
            position += 1

            if position > len(whatsapps) - 1:
                return

        elif direction == 'prev':
            position -= 1

            if position < 0:
                return

        new_whatsapp_login = whatsapps[position]

        new_reply_markup = update.callback_query.message.reply_markup
        new_reply_markup.inline_keyboard[wa_write_button_row_index][
            0].text = f'Wa: {new_whatsapp_login}'
        new_reply_markup.inline_keyboard[wa_write_button_row_index][
            0].callback_data = f'whatsapp/{tinder_match_id}/{position}'

        if position == 0:

            new_reply_markup.inline_keyboard[wa_switch_buttons_row_index] = [
                InlineKeyboardButton(
                    f'<<', callback_data=f'prev/wa/{tinder_match_id}'),
                InlineKeyboardButton(
                    f'>> {whatsapps[position + 1]}',
                    callback_data=f'next/wa/{tinder_match_id}')
            ]

        elif position == len(whatsapps) - 1:

            new_reply_markup.inline_keyboard[wa_switch_buttons_row_index] = [
                InlineKeyboardButton(
                    f'<< {whatsapps[position - 1]}',
                    callback_data=f'prev/wa/{tinder_match_id}'),
                InlineKeyboardButton(
                    f'>>', callback_data=f'next/wa/{tinder_match_id}')
            ]

        else:

            new_reply_markup.inline_keyboard[wa_switch_buttons_row_index] = [
                InlineKeyboardButton(
                    f'<< {whatsapps[position - 1]}',
                    callback_data=f'prev/wa/{tinder_match_id}'),
                InlineKeyboardButton(
                    f'>> {whatsapps[position + 1]}',
                    callback_data=f'next/wa/{tinder_match_id}')
            ]

        self.telegram_bot_instance.bot.edit_message_reply_markup(
            chat_id=update.callback_query.message.chat_id,
            message_id=update.callback_query.message.message_id,
            reply_markup=new_reply_markup)