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")
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)
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()
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
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
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