Beispiel #1
0
def create_poll(session, poll, user, chat, message=None):
    """Finish the poll creation."""
    poll.created = True
    user.expected_input = None
    user.current_poll = None

    text = get_poll_text(session, poll)

    if len(text) > 4000:
        error_message = i18n.t("misc.over_4000", locale=user.locale)
        message = chat.send_message(error_message, parse_mode="markdown")
        session.delete(poll)
        return

    if message:
        message = message.edit_text(
            text,
            parse_mode="markdown",
            reply_markup=get_management_keyboard(poll),
            disable_web_page_preview=True,
        )
    else:
        message = chat.send_message(
            text,
            parse_mode="markdown",
            reply_markup=get_management_keyboard(poll),
            disable_web_page_preview=True,
        )

    if len(text) > 3000:
        error_message = i18n.t("misc.over_3000", locale=user.locale)
        message = chat.send_message(error_message, parse_mode="markdown")

    reference = Reference(poll,
                          ReferenceType.admin.name,
                          user=user,
                          message_id=message.message_id)
    session.add(reference)
    session.flush()

    increase_stat(session, "created_polls")
    increase_user_stat(session, user, "created_polls")
Beispiel #2
0
def clone_poll(session, context, poll):
    """Clone this poll."""
    new_poll = clone_poll_internal(session, poll)
    session.commit()

    context.tg_chat.send_message(
        get_poll_text(session, new_poll),
        parse_mode="markdown",
        reply_markup=get_management_keyboard(new_poll),
        disable_web_page_preview=True,
    )

    return i18n.t("callback.cloned", locale=poll.user.locale)
Beispiel #3
0
def show_menu(session, context, poll):
    """Replace the current message with the main poll menu."""
    message = context.query.message
    message.edit_text(
        get_poll_text(session, poll),
        parse_mode="markdown",
        reply_markup=get_management_keyboard(poll),
        disable_web_page_preview=True,
    )
    remove_old_references(session, context.bot, poll, context.user)

    reference = Reference(
        poll, ReferenceType.admin.name, user=context.user, message_id=message.message_id
    )
    session.add(reference)
    session.commit()
Beispiel #4
0
def go_back(session, context, poll):
    """Go back to the original step."""
    if context.callback_result == CallbackResult.main_menu:
        text = get_poll_text(session, poll)
        keyboard = get_management_keyboard(poll)
        poll.in_settings = False

    elif context.callback_result == CallbackResult.settings:
        text = get_settings_text(poll)
        keyboard = get_settings_keyboard(poll)

    context.query.message.edit_text(
        text,
        parse_mode="markdown",
        reply_markup=keyboard,
        disable_web_page_preview=True,
    )

    # Reset the expected input from the previous option
    context.user.expected_input = None
Beispiel #5
0
def update_reference(
    session, bot, poll, reference, show_warning=False, first_try=False
):
    try:
        # Admin poll management interface
        if reference.type == ReferenceType.admin.name and not poll.in_settings:
            text, keyboard = get_poll_text_and_vote_keyboard(
                session, poll, user=poll.user, show_warning=show_warning, show_back=True
            )

            if poll.user.expected_input != ExpectedInput.votes.name:
                keyboard = get_management_keyboard(poll)

            bot.edit_message_text(
                text,
                chat_id=reference.user.id,
                message_id=reference.message_id,
                reply_markup=keyboard,
                parse_mode="markdown",
                disable_web_page_preview=True,
            )

        # User that votes in private chat (priority vote)
        elif reference.type == ReferenceType.private_vote.name:
            text, keyboard = get_poll_text_and_vote_keyboard(
                session,
                poll,
                user=reference.user,
                show_warning=show_warning,
            )

            bot.edit_message_text(
                text,
                chat_id=reference.user.id,
                message_id=reference.message_id,
                reply_markup=keyboard,
                parse_mode="markdown",
                disable_web_page_preview=True,
            )

        # Edit message created via inline query
        elif reference.type == ReferenceType.inline.name:
            # Create text and keyboard
            text, keyboard = get_poll_text_and_vote_keyboard(
                session, poll, show_warning=show_warning
            )

            bot.edit_message_text(
                text,
                inline_message_id=reference.bot_inline_message_id,
                reply_markup=keyboard,
                parse_mode="markdown",
                disable_web_page_preview=True,
            )

    except BadRequest as e:
        if (
            e.message.startswith("Message_id_invalid")
            or e.message.startswith("Message can't be edited")
            or e.message.startswith("Message to edit not found")
            or e.message.startswith("Chat not found")
            or e.message.startswith("Can't access the chat")
        ):
            # This is just a hunch
            # It feels like we're too fast and the message isn't synced between Telegram's servers yet.
            # If this happens, allow the first try to fail and schedule an update
            # If it happens again, we'll fail on the second try
            if first_try:
                update = Update(poll, datetime.now() + timedelta(seconds=2))
                session.add(update)
                sentry.capture_exception(
                    extra={
                        "context": "update_reference",
                    },
                )

                return

            session.delete(reference)
            session.commit()
        elif e.message.startswith("Message is not modified"):
            pass
        else:
            raise e

    except Unauthorized:
        session.delete(reference)
        session.commit()
    except TimedOut:
        # Ignore timeouts during updates for now
        pass
Beispiel #6
0
def update_reference(session, bot, poll, reference, show_warning=False):
    try:
        # Admin poll management interface
        if reference.type == ReferenceType.admin.name and not poll.in_settings:
            text, keyboard = get_poll_text_and_vote_keyboard(
                session, poll, user=poll.user, show_warning=show_warning, show_back=True
            )

            if poll.user.expected_input != ExpectedInput.votes.name:
                keyboard = get_management_keyboard(poll)

            bot.edit_message_text(
                text,
                chat_id=reference.user.id,
                message_id=reference.message_id,
                reply_markup=keyboard,
                parse_mode="markdown",
                disable_web_page_preview=True,
            )

        # User that votes in private chat (priority vote)
        elif reference.type == ReferenceType.private_vote.name:
            text, keyboard = get_poll_text_and_vote_keyboard(
                session, poll, user=reference.user, show_warning=show_warning,
            )

            bot.edit_message_text(
                text,
                chat_id=reference.user.id,
                message_id=reference.message_id,
                reply_markup=keyboard,
                parse_mode="markdown",
                disable_web_page_preview=True,
            )

        # Edit message created via inline query
        elif reference.type == ReferenceType.inline.name:
            # Create text and keyboard
            text, keyboard = get_poll_text_and_vote_keyboard(
                session, poll, show_warning=show_warning
            )

            bot.edit_message_text(
                text,
                inline_message_id=reference.bot_inline_message_id,
                reply_markup=keyboard,
                parse_mode="markdown",
                disable_web_page_preview=True,
            )

    except BadRequest as e:
        if (
            e.message.startswith("Message_id_invalid")
            or e.message.startswith("Message can't be edited")
            or e.message.startswith("Message to edit not found")
            or e.message.startswith("Chat not found")
            or e.message.startswith("Can't access the chat")
        ):
            session.delete(reference)
            session.commit()
        elif e.message.startswith("Message is not modified"):
            pass
        else:
            raise

    except Unauthorized:
        session.delete(reference)
        session.commit()
    except TimedOut:
        # Ignore timeouts during updates for now
        pass