def create_poll(session, poll, user, chat, message=None): """Finish the poll creation.""" poll.created = True user.expected_input = None user.current_poll = None if message: message = message.edit_text( get_poll_text(session, poll), parse_mode='markdown', reply_markup=get_management_keyboard(poll), disable_web_page_preview=True, ) else: message = chat.send_message( get_poll_text(session, poll), parse_mode='markdown', reply_markup=get_management_keyboard(poll), disable_web_page_preview=True, ) reference = Reference(poll, admin_chat_id=chat.id, admin_message_id=message.message_id) session.add(reference) session.commit()
def handle_chosen_inline_result(bot, update, session, user): """Save the chosen inline result.""" result = update.chosen_inline_result poll_id = result.result_id try: poll = session.query(Poll).get(poll_id) except DataError: # Possile if the poll has been shared too often and # the inline result is picked despite saying otherwise. return if result.inline_message_id is None: return try: reference = Reference( poll, ReferenceType.inline.name, inline_message_id=result.inline_message_id, ) session.add(reference) session.commit() except (UniqueViolation, IntegrityError): # I don't know how this can happen, but it happens. # It seems that user can spam click inline query, which then leads to # multiple chosen_inline_result queries being sent to the bot. session.rollback() return update_reference(session, bot, poll, reference) increase_user_stat(session, user, "inline_shares")
def handle_chosen_inline_result(bot, update, session, user): """Save the chosen inline result.""" result = update.chosen_inline_result poll_id = result.result_id try: poll = session.query(Poll).get(poll_id) except DataError: # Possile if the poll has been shared too often and # the inline result is picked despite saying otherwise. return try: reference = Reference( poll, ReferenceType.inline.name, inline_message_id=result.inline_message_id, ) session.add(reference) session.commit() except UniqueViolation: # I don't know how this can happen, but it happens. return update_reference(session, bot, poll, reference) increase_user_stat(session, user, "inline_shares")
def handle_chosen_inline_result(bot, update, session, user): """Save the chosen inline result.""" result = update.chosen_inline_result poll_id = result.result_id poll = session.query(Poll).get(poll_id) reference = Reference(poll, inline_message_id=result.inline_message_id) session.add(reference) session.commit()
def show_menu(session, context, poll): """Replace the current message with the main poll menu.""" message = context.query.message message.edit_text( get_poll_management_text(session, poll), parse_mode='markdown', reply_markup=get_management_keyboard(poll), ) reference = Reference(poll, admin_chat_id=message.chat.id, admin_message_id=message.message_id) session.add(reference) session.commit()
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 handle_new_option(bot, update, session, user, text, poll, chat): """Add a new option after poll creation.""" added_options = add_options(poll, text) if len(added_options) > 0: text = i18n.t('creation.option.multiple_added', locale=user.locale) + '\n' for option in added_options: text += f'\n*{option}*' chat.send_message(text, parse_mode='markdown') poll.init_votes_for_new_options(session) else: chat.send_message(i18n.t('creation.option.no_new', locale=user.locale)) # Reset expected input user.current_poll = None user.expected_input = None text = get_settings_text(poll) keyboard = get_settings_keyboard(poll) message = chat.send_message( text, parse_mode='markdown', reply_markup=keyboard, ) # Delete old references references = session.query(Reference) \ .filter(Reference.poll == poll) \ .filter(Reference.admin_user_id == chat.id) \ .all() for reference in references: try: bot.delete_message(chat.id, reference.admin_message_id) except: pass session.delete(reference) # Create new reference reference = Reference(poll, admin_user=user, admin_message_id=message.message_id) session.add(reference) session.commit() update_poll_messages(session, bot, poll)
def update_shared(session, context, poll): """All options are entered the poll is created.""" message_id = context.query.inline_message_id reference = (session.query(Reference).filter( Reference.bot_inline_message_id == message_id).filter( Reference.poll == poll).one_or_none()) if reference is None: reference = Reference( poll, ReferenceType.inline.name, inline_message_id=message_id, ) session.add(reference) session.commit() try_update_reference(session, context.bot, poll, reference)
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 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, admin_chat_id=chat.id, admin_message_id=message.message_id) session.add(reference) session.commit() increase_stat(session, 'created_polls')
def handle_new_option(bot, update, session, user, text, poll, chat): """Add a new option after poll creation.""" added_options = add_options(session, poll, text) if len(added_options) > 0: text = i18n.t("creation.option.multiple_added", locale=user.locale) + "\n" for option in added_options: text += f"\n*{option}*" chat.send_message(text, parse_mode="markdown") poll.init_votes_for_new_options(session) else: chat.send_message(i18n.t("creation.option.no_new", locale=user.locale)) # Reset expected input user.current_poll = None user.expected_input = None text = get_settings_text(poll) keyboard = get_settings_keyboard(poll) message = chat.send_message( text, parse_mode="markdown", reply_markup=keyboard, ) remove_old_references(session, bot, poll, user) # Create new reference reference = Reference(poll, ReferenceType.admin.name, user=user, message_id=message.message_id) session.add(reference) session.commit() update_poll_messages(session, bot, poll, message.message_id, user)
def start(bot, update, session, user): """Send a start text.""" # Truncate the /start command text = update.message.text[6:].strip() user.started = True poll = None action = None try: poll_uuid = UUID(text.split("-")[0]) action = StartAction(int(text.split("-")[1])) poll = session.query(Poll).filter(Poll.uuid == poll_uuid).one() except: text = "" # We got an empty text, just send the start message if text == "": update.message.chat.send_message( i18n.t("misc.start", locale=user.locale), parse_mode="markdown", reply_markup=get_main_keyboard(user), disable_web_page_preview=True, ) return if poll is None: return "This poll no longer exists." if action == StartAction.new_option and poll.allow_new_options: # Update the expected input and set the current poll user.expected_input = ExpectedInput.new_user_option.name user.current_poll = poll session.commit() update.message.chat.send_message( i18n.t("creation.option.first", locale=poll.locale), parse_mode="markdown", reply_markup=get_external_add_option_keyboard(poll), ) elif action == StartAction.show_results: # Get all lines of the poll lines = compile_poll_text(session, poll) # Now split the text into chunks of max 4000 characters chunks = split_text(lines) for chunk in chunks: message = "\n".join(chunk) try: update.message.chat.send_message( message, parse_mode="markdown", disable_web_page_preview=True, ) # Retry for Timeout error (happens quite often when sending large messages) except TimeoutError: time.sleep(2) update.message.chat.send_message( message, parse_mode="markdown", disable_web_page_preview=True, ) time.sleep(1) update.message.chat.send_message( i18n.t("misc.start_after_results", locale=poll.locale), parse_mode="markdown", reply_markup=get_main_keyboard(user), ) increase_stat(session, "show_results") elif action == StartAction.share_poll and poll.allow_sharing: update.message.chat.send_message( i18n.t("external.share_poll", locale=poll.locale), reply_markup=get_external_share_keyboard(poll), ) increase_stat(session, "externally_shared") elif action == StartAction.vote: if not config["telegram"][ "allow_private_vote"] and not poll.is_priority(): return if poll.is_priority(): init_votes(session, poll, user) session.commit() text, keyboard = get_poll_text_and_vote_keyboard( session, poll, user=user, ) sent_message = update.message.chat.send_message( text, reply_markup=keyboard, parse_mode="markdown", disable_web_page_preview=True, ) reference = Reference( poll, ReferenceType.private_vote.name, user=user, message_id=sent_message.message_id, ) session.add(reference) session.commit()
def start(bot, update, session, user): """Send a start text.""" # Truncate the /start command text = "" if update.message is not None: text = update.message.text[6:].strip() user.started = True try: poll_uuid = UUID(text.split('-')[0]) action = StartAction(int(text.split('-')[1])) poll = session.query(Poll).filter(Poll.uuid == poll_uuid).one() except: text = '' # We got an empty text, just send the start message if text == '': update.message.chat.send_message( i18n.t('misc.start', locale=user.locale), parse_mode='markdown', reply_markup=get_main_keyboard(user), disable_web_page_preview=True, ) return if poll is None: return 'This poll no longer exists.' if action == StartAction.new_option: # Update the expected input and set the current poll user.expected_input = ExpectedInput.new_user_option.name user.current_poll = poll session.commit() update.message.chat.send_message( i18n.t('creation.option.first', locale=poll.locale), parse_mode='markdown', reply_markup=get_external_add_option_keyboard(poll)) elif action == StartAction.show_results: # Get all lines of the poll lines = compile_poll_text(session, poll) # Now split the text into chunks of max 4000 characters chunks = split_text(lines) for chunk in chunks: message = '\n'.join(chunk) try: update.message.chat.send_message( message, parse_mode='markdown', disable_web_page_preview=True, ) # Retry for Timeout error (happens quite often when sending large messages) except TimeoutError: time.sleep(2) update.message.chat.send_message( message, parse_mode='markdown', disable_web_page_preview=True, ) time.sleep(1) update.message.chat.send_message( i18n.t('misc.start_after_results', locale=poll.locale), parse_mode='markdown', reply_markup=get_main_keyboard(user), ) increase_stat(session, 'show_results') elif action == StartAction.share_poll: update.message.chat.send_message( i18n.t('external.share_poll', locale=poll.locale), reply_markup=get_external_share_keyboard(poll)) increase_stat(session, 'externally_shared') elif action == StartAction.vote: if poll.is_priority(): poll.init_votes(session, user) session.commit() text, keyboard = get_poll_text_and_vote_keyboard( session, poll, user=user, ) sent_message = update.message.chat.send_message( text, reply_markup=keyboard, parse_mode='markdown', disable_web_page_preview=True, ) reference = Reference( poll, vote_user=user, vote_message_id=sent_message.message_id, ) session.add(reference) session.commit()