Example #1
0
def _send_png_sticker(
        user_session: UserSession,
        message: Optional[str]) -> Sequence[Union[Answer, CloseSession]]:
    """
    Возвращает финальное сообщение. Опционально возвращает путь к созданному
    стикеру на диске
    """
    alias = _send_png_sticker.alias
    if message in USER_COMMANDS['SERVICE_COMMANDS']:
        if message == 'step_back':
            return (Answer(text=get_message(
                step=alias, message_type='unsupported_command')), )
        else:
            message = 'НЕТ'
    message = message.strip().upper()

    if message not in ('ДА', 'НЕТ'):
        return (Answer(text='Пришлите "Да" либо "Нет"'), )
    else:
        if message == 'ДА':
            document = (Answer(content_type='document',
                               content_path=user_session.file_path), )
        else:
            document = tuple()
        return document + (
            CloseSession(),
            Answer(text=get_message(step=alias, message_type='end_message')),
        )
Example #2
0
 def _handle_admin_commands(self, user_id: int, command: str) -> Answer:
     user_role = get_user_role(user_id)
     if user_role != 'admin':
         return Answer(text=self._get_default_answer('unsupported_command'))
     if command == 'create_deep_link':
         deep_link = create_deep_link(user_id)
         return Answer(text=f'Ссылка успешно создана.\n{deep_link}')
Example #3
0
    def command_handler(self, chat_id: int,
                        command: str) -> Sequence[Union[Answer, CloseSession]]:
        """
        Промежуточный обработчик для команд из бота
        """
        command = command[1:]

        if command in USER_COMMANDS['RESET_COMMANDS']:
            self.close_session(chat_id)
            return self._get_init_message()

        if command in USER_COMMANDS['START_COMMANDS']:
            try:
                user_session = self._create_session(chat_id)
            except NotClosedUserSession as exc:
                return (Answer(text=str(exc)), )
            else:
                return self._user_session_handler.handle_session(user_session)

        if command in USER_COMMANDS['SERVICE_COMMANDS']:
            try:
                user_session = self._get_session(chat_id)
            except NotCreatedUserSession as exc:
                return (Answer(text=str(exc)), )
            else:
                return self._user_session_handler.handle_session(
                    user_session, message=command)
Example #4
0
def _language_test_execution(
    session: UserSession, message: Optional[str]
) -> Union[Answer, Tuple[Answer, Answer], Tuple[Answer, CloseSession]]:
    if message is None:
        current_question = session.language_test.current_question
        question = session.language_test.get_current_question()
        fmt_question, keyboard = _get_formatted_question(
            question, current_question + 1)
        number_questions = len(session.language_test.questions)
        start_message = (f'Давайте начнём!\n'
                         f'Выберите ваш вариант ответа вместо пропусков.\n'
                         f'Тест состоит из {number_questions} вопросов.')
        return (Answer(text=start_message),
                Answer(text=fmt_question, keyboard=keyboard))

    language_test = session.language_test
    if _is_correct_question_answer(message, language_test.number_answers):
        return _process_user_answer(session.user_id, language_test,
                                    int(message))
    else:
        max_number = language_test.number_answers
        keyboard = get_keyboard([i for i in range(1, max_number + 1)],
                                row_width=2)
        return Answer(text=f'Ответ д. б. в диапазоне от 1 до {max_number}',
                      keyboard=keyboard)
Example #5
0
 def _handle_information_commands(self, user_id: int, command: str) -> Answer:
     if get_user_role(user_id) == 'user':
         return Answer(text=self._get_default_answer('unsupported_command'))
     if command == 'languages_list':
         return Answer(text=get_formatted_languages_list())
     if command == 'test_types_list':
         return Answer(text=get_formatted_test_types_list())
Example #6
0
def _set_splitting_numbers(user_session: UserSession,
                           message: Optional[str]) -> Sequence[Answer]:
    """
    Проверяет правильность присланной разбивки текста по строкам, обновляет
    разбивку в экземпляре пользовательской сессии
    """
    alias = _set_splitting_numbers.alias
    if user_session.data_class.splitting_numbers is None:
        user_session.data_class.splitting_numbers = _set_splitting_numbers_helper(
            user_session.data_class.text)

    if message is None and len(user_session.data_class.splitting_numbers) > 1:
        splitting_numbers = _get_str_splitting_numbers(
            user_session.data_class.splitting_numbers)
        split_pattern = _get_split_pattern(
            len(user_session.data_class.splitting_numbers))
        return (Answer(text=get_message(step=alias,
                                        splitting_numbers=splitting_numbers,
                                        split_pattern=split_pattern)), )

    if message in USER_COMMANDS['SERVICE_COMMANDS'] or (
            message is None
            and len(user_session.data_class.splitting_numbers) == 1):
        message = message or 'next_step'
        handler.update_current_step(user_session, command=message)
        return handler.handle_session(user_session)

    try:
        user_session.data_class.splitting_numbers = _get_splitting_numbers(
            message, user_session.data_class.splitting_numbers)
    except NotCorrectSplittingText as exc:
        return (Answer(text=str(exc)), )
    else:
        handler.update_current_step(user_session)
        return handler.handle_session(user_session)
Example #7
0
 def _handle_language_test_creator_commands(
         self, user_id: int, command: str, date: datetime
 ) -> Union[Answer, Tuple[Answer, CloseSession]]:
     handler_alias = 'language_test_creator_session_handler'
     user_role = get_user_role(user_id)
     if user_role == 'user':
         return Answer(text=self._get_default_answer('unsupported_command'))
     handler = self._get_handler(handler_alias)
     handler.alias = handler_alias
     try:
         session = self._create_session(user_id, date, handler)
     except UnclosedSessionError as e:
         return Answer(text=str(e))
     return handler.handle_session(session, command)
Example #8
0
 def _handle_text(
         self, user_id: int, text: str
 ) -> Union[Answer, Tuple[Answer, Answer], Tuple[Answer, CloseSession]]:
     if user_id in self._sessions:
         handler_alias = self._sessions[user_id].handler_alias
         handler = self._get_handler(handler_alias)
         return handler.handle_session(self._sessions[user_id], message=text)
     return Answer(text=self._get_default_answer('invalid_message'))
Example #9
0
 def handle_document(
         self, user_id: int, document: io.BytesIO
 ) -> Union[Answer, Tuple[Answer, CloseSession]]:
     if user_id in self._sessions:
         handler_alias = self._sessions[user_id].handler_alias
         handler = self._get_handler(handler_alias)
         return handler.handle_session(self._sessions[user_id], message=document)
     return Answer(text=self._get_default_answer('invalid_message'))
Example #10
0
 def _handle_user_commands(
         self, user_id: int, date: datetime
 ) -> Answer:
     handler_alias = 'user_session_handler'
     handler = self._get_handler(handler_alias)
     try:
         session = self._create_session(user_id, date, handler)
     except UnclosedSessionError as e:
         return Answer(text=str(e))
     return handler.handle_session(session)
Example #11
0
def _set_background_color(user_session: UserSession,
                          message: Optional[str]) -> Sequence[Answer]:
    """
    Проверяет правильность присланного RGB-кода цвета для заливки фона стикера,
    обновляет RGB-код цвета в экземпляре пользовательской сессии
    """
    alias = _set_background_color.alias
    if message is None:
        return (Answer(text=get_message(step=alias), keyboard=kb_colors), )
    if message in USER_COMMANDS['SERVICE_COMMANDS']:
        handler.update_current_step(user_session, command=message)
        return handler.handle_session(user_session)

    try:
        user_session.data_class.background_color = _set_color_helper(message)
    except NotCorrectRGBCode as exc:
        return (Answer(text=str(exc), keyboard=kb_colors), )
    else:
        handler.update_current_step(user_session)
        return handler.handle_session(user_session)
Example #12
0
def _set_text(user_session: UserSession,
              message: Optional[str]) -> Sequence[Answer]:
    """
    Проверяет правильность присланного текста для стикера, обновляет текст в
    экземпляре пользовательской сессии
    """
    alias = _set_text.alias
    if message is None:
        return (Answer(text=get_message(step=alias)), )
    if message in USER_COMMANDS['SERVICE_COMMANDS']:
        return (Answer(
            text=get_message(step=alias, message_type='unsupported_command')),
                )
    if emoji_count(message) > 0:
        return (Answer(
            text='Текст стикера не может содержать в себе смайлики, '
            'пришлите текст без смайликов'), )

    user_session.data_class.text = message
    handler.update_current_step(user_session)
    return handler.handle_session(user_session)
Example #13
0
def _select_test_type(session: UserSession, message: Optional[str]) -> Answer:
    if message is None or not is_supported_test_type(message):
        test_types_list = get_test_types(session.language_id)
        keyboard = get_keyboard(test_types_list, row_width=1)
        text = 'Выберите один из доступных типов теста.'
        if message is not None:
            text = f'Вы прислали неверный тип теста\n{text}'
        return Answer(text=text, keyboard=keyboard)
    else:
        session.test_type_id = get_test_type_id(message.strip())
        _ush.update_current_step(session)
        return _ush.handle_session(session)
Example #14
0
def _select_language(session: UserSession, message: Optional[str]) -> Answer:
    if message is None or not is_supported_language(message):
        current_languages = get_current_languages()
        keyboard = get_keyboard(current_languages, row_width=1)
        text = 'Выберите один из доступных языков.'
        if message is not None:
            text = f'Вы прислали неподдерживаемый язык.\n{text}'
        return Answer(text=text, keyboard=keyboard)
    else:
        session.language_id = get_language_id(message.strip())
        _ush.update_current_step(session)
        return _ush.handle_session(session)
Example #15
0
 def _get_init_message() -> Sequence[Answer]:
     """
     Возвращает стартовое сообщение
     """
     return (Answer(text='Начните работу с ботом с помощью одной из '
                    'доступных стартовых команд.\n\n'
                    'Стартовые команды:\n'
                    '/create_sticker - начать создание стикера\n\n'
                    'Сервисные команды:\n'
                    '/next_step - пропустить текущий шаг (будет '
                    'установлено значение по умолчанию)\n'
                    '/step_back - вернуться к предыдущему шагу\n'
                    '/reset - начать создание стикера сначала'), )
Example #16
0
def _get_test_result(
        language_test: LanguageTest) -> Tuple[Answer, CloseSession]:
    test_score, wrong_answers = _get_test_score(language_test)
    number_questions = len(language_test.questions)
    percent_test_score = test_score / number_questions * 100
    number_right_answers = _get_fmt_count_right_answers(test_score)
    final_message = (f'Вы ответили верно на {number_right_answers} из '
                     f'{number_questions}. Ваш результат: '
                     f'{percent_test_score:.0f} %')
    if percent_test_score < 100:
        fmt_wrong_answers = _get_fmt_wrong_answers(wrong_answers)
        final_message = f'{final_message}\n{fmt_wrong_answers}'
    return (Answer(text=final_message), CloseSession())
Example #17
0
def _process_user_answer(
        user_id: int, language_test: LanguageTest,
        answer: int) -> Union[Answer, Tuple[Answer, CloseSession]]:
    language_test.register_answer(answer)
    if len(language_test.questions) - 1 > language_test.current_question:
        language_test.current_question += 1
        fmt_question, keyboard = _get_formatted_question(
            language_test.get_current_question(),
            language_test.current_question + 1)
        return Answer(text=fmt_question, keyboard=keyboard)
    else:
        values = generate_answer_values(user_id, language_test)
        insert_user_answers(values)
        return _get_test_result(language_test)
Example #18
0
    def message_handler(self, chat_id: int,
                        message: str) -> Sequence[Union[Answer, CloseSession]]:
        """
        Промежуточный обработчик для сообщений из бота
        """
        if chat_id not in self._sessions:
            return (Answer(
                text='Для начала работы с ботом используйте одну из '
                'доступных стартовых команд.\n\n'
                'Стартовые команды:\n'
                '/create_sticker - начать создание стикера'), )

        user_session = self._sessions[chat_id]
        return self._user_session_handler.handle_session(
            user_session=user_session, message=message)
Example #19
0
def _set_font(user_session: UserSession,
              message: Optional[str]) -> Sequence[Answer]:
    """
    Проверяет правильность присланного номера шрифта, обновляет шрифт в
    экземпляре пользовательской сессии
    """
    alias = _set_font.alias
    if message is None:
        return (Answer(content_type='photo',
                       content_path=EXAMPLE_FONTS_PATH,
                       content_location='telegram_server',
                       text=get_message(step=alias),
                       keyboard=kb_fonts_numbers), )
    if message in USER_COMMANDS['SERVICE_COMMANDS']:
        handler.update_current_step(user_session, command=message)
        return handler.handle_session(user_session)

    try:
        _set_font_helper(message, user_session)
    except NotCorrectFontNumber as exc:
        return (Answer(text=str(exc)), )
    else:
        handler.update_current_step(user_session)
        return handler.handle_session(user_session)
Example #20
0
def _send_sticker(user_session: UserSession,
                  message: Optional[str]) -> Sequence[Answer]:
    """
    Создаёт и сохраняет изображение, возращает путь к изображению
    """
    alias = _send_sticker.alias
    if message is None:
        text = _get_splitting_text(user_session.data_class.text,
                                   user_session.data_class.splitting_numbers)
        sticker = create_sticker(
            text=text,
            background_color=user_session.data_class.background_color,
            font_name=user_session.data_class.font_name,
            font_color=user_session.data_class.font_color,
            picture_width=512,
            picture_height=512)
        file_name = f'{_get_date_formatted(user_session.created)}_{_generate_filename()}.png'
        user_session.file_path = os.path.join(CONTENT_DIR, file_name)
        sticker.save(user_session.file_path)
        handler.update_current_step(user_session)
        return (
            Answer(content_type='photo', content_path=user_session.file_path),
            Answer(text=get_message(step=alias), keyboard=kb_yesno),
        )
Example #21
0
    def _handle_command(
            self, user_id: int, text: str, date: datetime
    ) -> Union[Answer, Tuple[Answer, Answer]]:
        command, deep_link = self._get_bot_command(text)

        if command in COMMANDS['start_commands']:
            return self._handle_start_commands(user_id, command, date, deep_link)

        if command in COMMANDS['user_commands']:
            return self._handle_user_commands(user_id, date)

        if command in COMMANDS['test_creator_commands']:
            return self._handle_language_test_creator_commands(user_id, command, date)

        if command in COMMANDS['information_commands']:
            return self._handle_information_commands(user_id, command)

        if command in COMMANDS['admin_commands']:
            return self._handle_admin_commands(user_id, command)

        return Answer(text=self._get_default_answer('unsupported_command'))
Example #22
0
 def _get_start_message(command: str, role: str) -> Answer:
     start_message = (
         'Привет!\n'
         'С помощью этого бота вы сможете проверить ваши знания грамматики '
         'и лексики иностранного языка.\n\n'
     )
     user_commands = 'Для того, чтобы начать тест, введите /begin_test.\n'
     test_creator_commands = (
         'Для того, чтобы получить список языков, введите /languages_list.\n'
         'Для того, чтобы получить список доступных типов тестов, введите '
         '/test_types_list.\nДля того, чтобы добавить вопросы, введите '
         '/add_questions, чтобы обновить  - /update_questions, чтобы удалить '
         '- /delete_questions.\n'
     )
     admin_commands = 'Для того, чтобы создать deeplink, введите /create_deep_link.'
     if role == 'user':
         text = user_commands
     elif role == 'test_creator':
         text = f'{user_commands}{test_creator_commands}'
     else:
         text = f'{user_commands}{test_creator_commands}{admin_commands}'
     if command == 'start':
         text = f'{start_message}{text}'
     return Answer(text=text)
Example #23
0
def _get_start_message(session: LanguageTestCreatorSession,
                       message: str) -> Answer:
    session.command = message
    text = _get_start_message_text(message)
    _ltcsh.update_current_step(session)
    return Answer(text=text)
Example #24
0
def _handle_language_test(
        session: LanguageTestCreatorSession,
        message: [str, io.BytesIO]) -> Tuple[Answer, CloseSession]:
    answer_text = _handle_test_creator_message(session.command,
                                               session.user_id, message)
    return (Answer(text=answer_text), CloseSession())