def _main():
    persistence = YamlPersistence(directory=config.persist_dir)
    updater = Updater(config.token, persistence=persistence)

    dispatcher = updater.dispatcher
    logger.info('Dispatcher is created.')

    # Create bot data if missing
    try:
        bot_data = BotData.from_dict(dispatcher.bot_data)
    except MissingDataError:
        bot_data = BotData()
        bot_data.update_dict(dispatcher.bot_data)

    # Generate deep-linked URL to link owner to the bot; printed via logs
    uname = dispatcher.bot.getMe().username
    url = utils.helpers.create_deep_linked_url(uname, bot_data.uuid, False)
    logger.info(f'User link: {url}')
    url = utils.helpers.create_deep_linked_url(uname, bot_data.uuid, True)
    logger.info(f'Group link: {url}')

    # Update persistence data
    Data.update_bot(dispatcher.bot)

    # Register bot handlers, e.g. converstaion/command handlers
    polydating_bot.handlers.add_handlers(dispatcher)

    # Start bot  polling mode
    updater.start_polling()

    # Push updater to another thread
    updater.idle()
    def __call__(self, parser, namespace, values, option_string = None):
        bot_data = BotData.from_context(self._context)

        try:
            bot_data.dating_channel = values
        except IncorrectIdError as exc:
            raise CommandError(str(exc)) from exc
    def __call__(self, parser, namespace, values, option_string = None):
        bot_data = BotData.from_context(self._context)

        for admin in values:
            try:
                admin = int(admin)
                bot_data.admins.remove(admin)
            except ValueError as exc:
                raise CommandError('Несуществующий ID.') from exc
    def __call__(self, parser, namespace, values, option_string = None):
        bot_data = BotData.from_context(self._context)
        bot = Dispatcher.get_instance().bot

        text = []
        for var_id in bot_data.pending_forms:
            user_data = UserData.by_id(var_id)
            text.append(f'{var_id} ({user_data.mention()})')
        text = 'Список анкет: ' + ', '.join(text)
        bot.sendMessage(self._update.effective_chat.id, text)
def _withdraw_form(update: Update, context: CallbackContext):
    user_data = UserData.from_context(context)
    bot_data = BotData.from_context(context)

    # Anyway change form status
    user_data.status = FormStatus.BLOCKING
    bot_data.pending_forms.remove(user_data.id)

    update.callback_query.answer('Отправка анкеты отменена.')
    return _manage_form(update, context)
    def __call__(self, parser, namespace, values, option_string = None):
        user_data = UserData.by_id(int(vars(namespace)['id'][0]))
        bot_data = BotData.from_context(self._context)

        logger.debug('Trying to reject form..')
        user_data.status = FormStatus.RETURNED
        bot_data.pending_forms.remove(user_data.id)
        user_data.note = ' '.join(values)

        new_conv_status(user_data.id)
        logger.info(f'Form was rejected: {str(user_data)}')
def _delete_form(update: Update, context: CallbackContext):
    bot_data = BotData.from_context(context)
    user_data = UserData.from_context(context)
    try:
        user_data.status = FormStatus.BLOCKING
        channel = ChatData.by_id(bot_data.dating_channel)
    except MissingDataError:
        pass
    else:
        channel.delete_form(user_data.id)

    logger.info(f'Form has been deleted: {str(user_data)}')
    update.callback_query.answer('Анкета успешно удалена.')
    return _manage_form(update, context)
def _start(update: Update, context: CallbackContext) -> None:
    bot_data = BotData.from_context(context)
    try:
        ChatData.from_context(context)
    except MissingDataError:
        ChatData(update.effective_chat).update_context(context)

    try:
        if bot_data.uuid == context.args[0]:
            logger.info('Adding chat to admin chat list.')
            bot_data.admins.append(update.effective_chat.id)
        else:
            logger.warning(f'Incorrect deep-link token: {update}')
    except IndexError:
        pass
def _start(update: Update, context: CallbackContext) -> None:
    logger.debug(f'{update.message.text}')

    try:
        UserData.from_context(context)
    except MissingDataError:
        UserData(update.message.chat).update_context(context)
        ChatData(update.message.chat).update_context(context)
        logger.debug(f'Created new user data: {update.message.chat.id}')
        update.message.reply_text(text=HELP, parse_mode=ParseMode.MARKDOWN_V2)

    try:
        bot_data = BotData.from_context(context)
        bot_data.owner = (context.args[0], update.message.chat.id)
    except (IndexError, MissingDataError):
        pass

    return _select_level(update, context)
    def __call__(self, parser, namespace, values, option_string = None):
        user_data = UserData.by_id(int(values[0]))
        bot_data = BotData.from_context(self._context)
        bot = Dispatcher.get_instance().bot

        if not bot_data.dating_channel:
            raise CommandError('Не указан канал для публикации!')

        logger.debug('Trying to post form..')
        try:
            channel = ChatData.by_id(bot_data.dating_channel)
        except MissingDataError:
            channel = ChatData(bot.getChat(bot_data.dating_channel))
        finally:
            channel.send_form(user_data)

        bot_data.pending_forms.remove(user_data.id)
        user_data.status = FormStatus.PUBLISHED

        new_conv_status(user_data.id)
        logger.info(f'Form was posted: {str(user_data)}')
    def __call__(self, parser, namespace, values, option_string = None):
        bot_data = BotData.from_context(self._context)

        # Try to add admin by reply (seems to be the easiest way to get user ID)
        if self._update.message.reply_to_message:
            reply = self._update.message.reply_to_message
            bot_data.admins.append(reply.from_user.id)
            return
        elif not values:
            raise CommandError('Укажите ID пльзователя или сделайте реплай на его сообщение.')

        try:
            var_id = int(values)
        except TypeError:
            try:
                var_id = UserData.by_username(values)
            except MissingDataError as exc:
                raise CommandError('Этот username мне не знаком. :(') from exc
        try:
            bot_data.admins.append(var_id)
        except IncorrectIdError as exc:
            raise CommandError(f'Некорректный ID: {var_id}') from exc
def _send_form(update: Update, context: CallbackContext):
    user_data = UserData.from_context(context)
    bot_data = BotData.from_context(context)
    bot = Dispatcher.get_instance().bot

    # Send message to all admins chats (chats have negative ID)
    for chat in [c for c in bot_data.admins if c < 0]:
        text = utils.helpers.escape_markdown(
            f'Новая анкета: {user_data.id} \({user_data.mention()}\)'
        )
        keyboard = InlineKeyboardMarkup.from_button(InlineKeyboardButton(
            text='Показать', callback_data=f'{str(SHOW)}{user_data.id}'
        ))
        bot.sendMessage(chat, text=text, reply_markup=keyboard, parse_mode='MarkdownV2')

    # Update form status
    bot_data.pending_forms.append(user_data.id)
    user_data.status = FormStatus.PENDING

    logger.info('New form has been sent: {str(user_data)}')
    update.callback_query.answer('Анкета успешно отправлена!')
    return _manage_form(update, context)
    def __call__(self, parser, namespace, values, option_string = None):
        bot_data = BotData.from_context(self._context)

        text = [list(), list()]
        for admin in bot_data.admins:
            try:
                if admin > 0:
                    data = UserData.by_id(admin)
                else:
                    data = ChatData.by_id(admin)
            except MissingDataError:
                logger.warning(f'Unknown ID: {admin}')
                bot_data.admins.remove(admin)
                continue

            item = f'{admin} ({data.mention()})'
            if admin > 0:
                text[0].append(item)
            else:
                text[1].append(item)

        text[0] = 'Список админов: ' + ', '.join(text[0])
        text[1] = 'Список админских чатов: ' + ', '.join(text[1])
        bot_data._bot.send_message(self._update.effective_chat.id, '\n'.join(text))
    def __call__(self, parser, namespace, values, option_string = None):
        bot_data = BotData.from_context(self._context)
        bot = Dispatcher.get_instance().bot

        text = 'Канал для публикаций: '

        try:
            if bot_data.dating_channel:
                channel = ChatData.by_id(bot_data.dating_channel)
            else:
                channel = None
        except MissingDataError:
            try:
                channel = ChatData(bot.getChat(bot_data.dating_channel))
            except TelegramError:
                logger.warning(f'Channel seems to be outdated: {bot_data.dating_channel}')
                bot_data.dating_channel = None
                channel = None
        finally:
            if channel:
                text += channel.mention()
            else:
                text += 'отсутствует'
            bot.send_message(self._update.effective_chat.id, text)