예제 #1
0
 def on_enter(self, request_container: RequestContainer) -> None:
     if self.chosen_language is None:
         request_container.add_template_reply(
             templates.choose_language,
             {'list': self.languages_registry.get_languages_list()})
     else:
         request_container.add_template_reply(templates.upload_solution, {})
예제 #2
0
    def handle(self, state_changer: StateChanger,
               request_container: RequestContainer) -> None:
        req = request_container.request

        if req.has_text(buttons.button_cancel):
            # Cancel: move back
            state_changer.change(GameChosenState(self.game, self.components),
                                 request_container)
        elif req.match_text(self.solution_name_regex):
            # New name -> rename
            with self.database.tx():
                solution = self.solutions_dao.find_solution(
                    req.effective_user_id, self.game.name)
                if solution is None:
                    raise NoSolutionException(self.game)
                solution.name = req.text

            request_container.add_template_reply(templates.rename_solution_ok,
                                                 {})
            state_changer.change(GameChosenState(self.game, self.components),
                                 request_container)
        else:
            # Anything else -> show message
            self.on_enter(request_container)

        request_container.stop_handling()
 def handle(self, container: RequestContainer) -> None:
     try:
         self.wrapped.handle(container)
     except BotException as ex:
         container.stop_handling()
         self.__handle_bot_exception(container, ex)
     except Exception:
         self.__handle_exception(container)
예제 #4
0
 def on_enter(self, request_container: RequestContainer) -> None:
     req = request_container.request
     solution = self.solutions_dao.find_solution(req.effective_user_id,
                                                 self.game.name)
     request_container.add_template_reply(
         templates.solution_info, {
             'solution': solution,
             'game': self.game,
             'top': self.solutions_dao.solutions_top(self.game.name, 5)
         })
    def handle(self, state_changer: StateChanger,
               request_container: RequestContainer):
        update = request_container.request.update
        message_text = update.message.text if update.message else None

        self.counter += 1
        request_container.add_template_reply(
            Template.constant(MessageContent('StateA handled this request')),
            {'counter': self.counter})

        if message_text == 'SwitchB':
            state_changer.change(StateB(), request_container)
        elif message_text == 'SwitchDefault':
            state_changer.change(None, request_container)
    def handle_and_get_counter(self, user_id, message):
        request = RequestFaker.message(message, user_id=user_id)
        request_container = RequestContainer(request)
        self.handler.handle(request_container)

        self.assertEqual(1, len(request_container.responses))
        response = request_container.responses[0]

        self.assertIsInstance(response, ResponseReplyTemplate)
        return response.args['counter']
    def assert_has_answer(self, message_text: str, template: Template,
                          args: dict):
        request = RequestFaker.message(message_text)
        container = RequestContainer(request)

        self.rh.handle(container)

        self.assertEqual(1, len(container.responses))
        response = container.responses[0]
        self.assertIsInstance(response, ResponseReplyTemplate)
        self.assertEqual(template, response.template)
        self.assertEqual(args, response.args)
    def handle_update(self, update: Update, dispatcher: Dispatcher) -> None:
        request_container = RequestContainer(Request(update))
        try:
            self.request_handler.handle(request_container)
        except Exception:
            logger.exception('Exception while handling request with RequestHandler')

        for response in request_container.responses:
            try:
                response.send(self.bot, request_container.request)
            except Exception:
                logger.exception('Exception while sending response')
예제 #9
0
    def handle(self, state_changer: StateChanger,
               request_container: RequestContainer) -> None:
        req = request_container.request
        request_container.stop_handling()  # Stop handling by default

        if req.has_text(buttons.button_upload):
            # 'Upload Solution' -> change to upload state
            state_changer.change(
                GameSolutionUploadState(self.game, self.components),
                request_container)
        elif req.has_text(buttons.button_rename):
            # 'Rename Solution' -> change to rename state
            state_changer.change(
                GameSolutionChangeNameState(self.game, self.components),
                request_container)
        elif req.has_text(buttons.button_challenge):
            # 'Challenge' -> show challenge link
            solution = self.solutions_dao.find_solution(
                req.effective_user_id, self.game.name)
            if solution is None:
                raise NoSolutionException(self.game)
            request_container.add_template_reply(
                templates.challenge_link,
                {'link': solution.create_link().to_command()})
        else:
            # Unknown action: continue handling
            request_container.continue_handling()
    def assert_has_answer(self, message_content: Union[FileHandle, str], template: Template, user_id: int = 42) -> dict:
        request = RequestFaker.message(message_content, user_id=user_id)
        container = RequestContainer(request)

        self.rh.handle(container)

        self.assertEqual(1, len(container.responses))
        response = container.responses[0]
        self.assertIsInstance(response, ResponseReplyTemplate)
        self.assertEqual(template, response.template)

        # Test that message can be constructed without errors
        response.get_content()

        return response.args
    def assert_has_answers(self, message_content: Union[FileHandle, str], template_1: Template, template_2: Template) -> dict:
        request = RequestFaker.message(message_content)
        container = RequestContainer(request)

        self.rh.handle(container)

        self.assertEqual(2, len(container.responses))
        response1 = container.responses[0]
        self.assertIsInstance(response1, ResponseReplyTemplate)
        self.assertEqual(template_1, response1.template)
        response1.get_content()
        response2 = container.responses[1]
        self.assertIsInstance(response2, ResponseReplyTemplate)
        self.assertEqual(template_2, response2.template)
        response2.get_content()

        return container.responses[1].args
예제 #12
0
    def handle(self, state_changer: StateChanger,
               request_container: RequestContainer) -> None:
        req = request_container.request

        if req.has_text(buttons.button_cancel):
            # Cancel -> jump to GameChosenState
            state_changer.change(GameChosenState(self.game, self.components),
                                 request_container)
            return

        if self.chosen_language and req.get_file_handle():
            # File -> upload file
            max_file_size = 2**20  # 1 MiB
            file_handle = req.get_file_handle()

            if file_handle.size() > max_file_size:
                request_container.add_template_reply(
                    templates.upload_solution_too_big, {})
                return

            name = file_handle.name()
            content = file_handle.content()

            self.solutions_dao.create_solution(
                req.effective_user_id, self.game.name,
                SourceCode(name, content, self.chosen_language.name))
            request_container.add_template_reply(templates.upload_solution_ok)
            state_changer.change(GameChosenState(self.game, self.components),
                                 request_container)
        elif not self.chosen_language and req.text and self.languages_registry.get_by_display_name(
                req.text):
            language = self.languages_registry.get_by_display_name(req.text)
            self.chosen_language = language
            self.on_enter(request_container)
        else:
            # Anything else -> show message
            self.on_enter(request_container)

        request_container.stop_handling()
    def handle(self, request_container: RequestContainer):
        req = request_container.request
        match_info_cmd = req.match_text(re_info_cmd)
        solution_link = SolutionLink.from_command(
            req.text) if req.text else None

        if req.is_command('start'):
            request_container.add_template_reply(templates.start_message)
        elif req.has_text(buttons.button_about):
            request_container.add_template_reply(templates.about_bot)
        elif req.has_text(buttons.button_games):
            games = self.games_registry.get_games_list()
            solutions = self.solutions_dao.find_solutions_by_creator(
                req.effective_user_id)

            request_container.add_template_reply(templates.solutions_list, {
                'solutions': solutions,
                'games': games
            })
        elif match_info_cmd:
            game_name = match_info_cmd.group(1)
            game = self.games_registry.get_by_name(game_name)
            self.state_based_handler.change_state(
                GameChosenState(game, self.components), request_container)
        elif solution_link:
            solution_2 = self.solutions_dao.find_solution(
                solution_link.creator_id, solution_link.game_name)
            if solution_2 is None:
                raise BotException(templates.duel_failed_bad_link, {})
            game = self.components.games_registry.get_by_name(
                solution_link.game_name)
            solution_1 = self.solutions_dao.find_solution(
                req.effective_user_id, solution_link.game_name)
            if solution_1 is None:
                raise NoSolutionException(game)

            request_container.add_template_reply(templates.duel_started, {})
            verdict_future: Future = self.components.checking_system.async_evaluate(
                game, solution_1.id_with_version, solution_1.source_code,
                solution_2.id_with_version, solution_2.source_code)

            def on_duel_finished(_):
                try:
                    v: GameVerdict = verdict_future.result()
                    old_rating = (solution_1.rating, solution_2.rating)
                    new_rating = old_rating

                    if solution_1.creator_id != solution_2.creator_id:
                        # Update rating
                        with self.components.database.tx():
                            s1 = self.components.solutions_dao.find_by_id(
                                solution_1.id)
                            s2 = self.components.solutions_dao.find_by_id(
                                solution_2.id)
                            old_rating = (s1.rating, s2.rating)
                            new_rating1, new_rating2 = self.components.rating_system.update_rating(
                                s1.rating, s2.rating, v.outcome)
                            s1.rating = new_rating1
                            s2.rating = new_rating2
                            new_rating = (new_rating1, new_rating2)

                    args = {
                        'verdict': v,
                        'sol1': solution_1,
                        'sol2': solution_2,
                        'old_rating': old_rating,
                        'new_rating': new_rating
                    }

                    self.components.notification_service.notify_user(
                        solution_1.creator_id,
                        templates.duel_result_notification, {
                            **args, 'user_id': solution_1.creator_id
                        })

                    if solution_1.creator_id != solution_2.creator_id:
                        self.components.notification_service.notify_user(
                            solution_2.creator_id,
                            templates.duel_result_notification, {
                                **args, 'user_id': solution_2.creator_id
                            })
                except:
                    logger.exception('Error handling finished duel')

            verdict_future.add_done_callback(on_duel_finished)
        else:
            # If still is not handled...
            request_container.add_template_reply(templates.main_message, {})

        request_container.stop_handling()
 def assert_no_answer(self, message_text: str):
     request = RequestFaker.message(message_text)
     container = RequestContainer(request)
     self.rh.handle(container)
     self.assertEqual(0, len(container.responses))
예제 #15
0
 def on_enter(self, request_container: RequestContainer) -> None:
     request_container.add_template_reply(templates.rename_solution, {})