Esempio n. 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

    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")
Esempio n. 3
0
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")
Esempio n. 4
0
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()
Esempio n. 5
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_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()
Esempio n. 6
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()
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)
Esempio n. 8
0
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)
Esempio n. 9
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")
Esempio n. 10
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,
                          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)
Esempio n. 12
0
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()
Esempio n. 13
0
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()