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, {})
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)
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')
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
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))
def on_enter(self, request_container: RequestContainer) -> None: request_container.add_template_reply(templates.rename_solution, {})