diff --git a/Makefile b/Makefile index 7b3b3fc..62446d1 100644 --- a/Makefile +++ b/Makefile @@ -57,9 +57,9 @@ cover: # Lint format: - ruff check . --fix black . isort . + ruff check . --fix check-ruff: ruff check . diff --git a/app/bot/handlers/__init__.py b/app/bot/handlers/__init__.py index ca448fb..e69de29 100644 --- a/app/bot/handlers/__init__.py +++ b/app/bot/handlers/__init__.py @@ -1,17 +0,0 @@ -from .base import EventHandler # noqa -from .config_difficulty import ConfigDifficultyHandler # noqa -from .config_language import ConfigLanguageHandler # noqa -from .config_model import ConfigModelHandler # noqa -from .config_solvers import ConfigSolverHandler # noqa -from .continue_get_id import ContinueGetIdHandler # noqa -from .continue_handler import ContinueHandler # noqa -from .custom import CustomHandler # noqa -from .error import ErrorHandler # noqa -from .fallback import FallbackHandler # noqa -from .get_session import GetSessionsHandler # noqa -from .help import HelpMessageHandler # noqa -from .warmup import WarmupHandler # noqa -from .next_move import NextMoveHandler # noqa -from .process_message import ProcessMessageHandler # noqa -from .start import StartEventHandler # noqa -from .testing import TestingHandler # noqa diff --git a/app/bot/handlers/continue_get_id.py b/app/bot/handlers/continue_get_id.py deleted file mode 100644 index c4ad69c..0000000 --- a/app/bot/handlers/continue_get_id.py +++ /dev/null @@ -1,6 +0,0 @@ -from bot.handlers.base import EventHandler - - -class ContinueGetIdHandler(EventHandler): - def handle(self): - pass diff --git a/app/bot/handlers/continue_handler.py b/app/bot/handlers/continue_handler.py deleted file mode 100644 index bb7a362..0000000 --- a/app/bot/handlers/continue_handler.py +++ /dev/null @@ -1,6 +0,0 @@ -from bot.handlers.base import EventHandler - - -class ContinueHandler(EventHandler): - def handle(self): - self.send_text("This is not implemented yet 😢") diff --git a/app/bot/handlers/custom/__init__.py b/app/bot/handlers/custom/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/bot/handlers/config_difficulty.py b/app/bot/handlers/custom/config_difficulty.py similarity index 95% rename from app/bot/handlers/config_difficulty.py rename to app/bot/handlers/custom/config_difficulty.py index 2bf4c3d..921b6c7 100644 --- a/app/bot/handlers/config_difficulty.py +++ b/app/bot/handlers/custom/config_difficulty.py @@ -1,4 +1,4 @@ -from bot.handlers.base import EventHandler +from bot.handlers.other.event_handler import EventHandler from bot.models import AVAILABLE_MODELS, BadMessageError, BotState from telegram import ReplyKeyboardMarkup from the_spymaster_solvers_api.structs import Difficulty diff --git a/app/bot/handlers/config_language.py b/app/bot/handlers/custom/config_language.py similarity index 88% rename from app/bot/handlers/config_language.py rename to app/bot/handlers/custom/config_language.py index cfc9226..4fe5a2c 100644 --- a/app/bot/handlers/config_language.py +++ b/app/bot/handlers/custom/config_language.py @@ -1,5 +1,5 @@ -from bot.handlers.base import EventHandler -from bot.handlers.common import SUPPORTED_LANGUAGES +from bot.handlers.other.common import SUPPORTED_LANGUAGES +from bot.handlers.other.event_handler import EventHandler from bot.models import BadMessageError, BotState from telegram import ReplyKeyboardMarkup from the_spymaster_util.logger import get_logger diff --git a/app/bot/handlers/config_model.py b/app/bot/handlers/custom/config_model.py similarity index 88% rename from app/bot/handlers/config_model.py rename to app/bot/handlers/custom/config_model.py index 5724dd0..4dbffa1 100644 --- a/app/bot/handlers/config_model.py +++ b/app/bot/handlers/custom/config_model.py @@ -1,5 +1,5 @@ -from bot.handlers.base import EventHandler -from bot.handlers.start import StartEventHandler +from bot.handlers.gameplay.start import StartEventHandler +from bot.handlers.other.event_handler import EventHandler from bot.models import AVAILABLE_MODELS, BadMessageError from the_spymaster_solvers_api.structs import ModelIdentifier from the_spymaster_util.logger import get_logger diff --git a/app/bot/handlers/config_solvers.py b/app/bot/handlers/custom/config_solvers.py similarity index 86% rename from app/bot/handlers/config_solvers.py rename to app/bot/handlers/custom/config_solvers.py index c23edb0..0ea7475 100644 --- a/app/bot/handlers/config_solvers.py +++ b/app/bot/handlers/custom/config_solvers.py @@ -1,6 +1,6 @@ -from bot.handlers.base import EventHandler -from bot.handlers.common import title_list -from bot.handlers.start import StartEventHandler +from bot.handlers.gameplay.start import StartEventHandler +from bot.handlers.other.common import title_list +from bot.handlers.other.event_handler import EventHandler from bot.models import BadMessageError, BotState from telegram import ReplyKeyboardMarkup from the_spymaster_solvers_api.structs import Difficulty, Solver diff --git a/app/bot/handlers/custom.py b/app/bot/handlers/custom/custom.py similarity index 83% rename from app/bot/handlers/custom.py rename to app/bot/handlers/custom/custom.py index 9a2ab63..6b5b336 100644 --- a/app/bot/handlers/custom.py +++ b/app/bot/handlers/custom/custom.py @@ -1,5 +1,5 @@ -from bot.handlers.base import EventHandler -from bot.handlers.common import SUPPORTED_LANGUAGES, title_list +from bot.handlers.other.common import SUPPORTED_LANGUAGES, title_list +from bot.handlers.other.event_handler import EventHandler from bot.models import BotState, GameConfig, Session from telegram import ReplyKeyboardMarkup from the_spymaster_solvers_api.structs import Difficulty diff --git a/app/bot/handlers/gameplay/__init__.py b/app/bot/handlers/gameplay/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/bot/handlers/next_move.py b/app/bot/handlers/gameplay/next_move.py similarity index 79% rename from app/bot/handlers/next_move.py rename to app/bot/handlers/gameplay/next_move.py index f654570..5056be0 100644 --- a/app/bot/handlers/next_move.py +++ b/app/bot/handlers/gameplay/next_move.py @@ -1,4 +1,4 @@ -from bot.handlers.base import EventHandler +from bot.handlers.other.event_handler import EventHandler class NextMoveHandler(EventHandler): diff --git a/app/bot/handlers/process_message.py b/app/bot/handlers/gameplay/process_message.py similarity index 92% rename from app/bot/handlers/process_message.py rename to app/bot/handlers/gameplay/process_message.py index a463d35..d6556fc 100644 --- a/app/bot/handlers/process_message.py +++ b/app/bot/handlers/gameplay/process_message.py @@ -1,9 +1,9 @@ -from bot.handlers import HelpMessageHandler -from bot.handlers.base import EventHandler -from bot.handlers.common import ( +from bot.handlers.other.common import ( get_given_guess_result_message_text, is_blue_guesser_turn, ) +from bot.handlers.other.event_handler import EventHandler +from bot.handlers.other.help import HelpMessageHandler from bot.models import COMMAND_TO_INDEX from codenames.game.board import Board from the_spymaster_api.structs import GuessRequest, GuessResponse diff --git a/app/bot/handlers/start.py b/app/bot/handlers/gameplay/start.py similarity index 94% rename from app/bot/handlers/start.py rename to app/bot/handlers/gameplay/start.py index 508e0fb..56d1bb3 100644 --- a/app/bot/handlers/start.py +++ b/app/bot/handlers/gameplay/start.py @@ -1,4 +1,4 @@ -from bot.handlers.base import EventHandler +from bot.handlers.other.event_handler import EventHandler from bot.models import GameConfig, Session from the_spymaster_api.structs import StartGameRequest from the_spymaster_util.logger import get_logger diff --git a/app/bot/handlers/get_session.py b/app/bot/handlers/get_session.py deleted file mode 100644 index e71923c..0000000 --- a/app/bot/handlers/get_session.py +++ /dev/null @@ -1,15 +0,0 @@ -from bot.handlers.base import EventHandler -from the_spymaster_util.logger import get_logger - -log = get_logger(__name__) - - -class GetSessionsHandler(EventHandler): - def handle(self): - log.info(f"Getting sessions for user {self.user.full_name}") - self.send_text("Not implemented yet") - # sessions_dict = {} - # for session_id, session in self.bot.sessions.items(): - # sessions_dict[session_id.chat_id] = session.clean_dict() - # pretty_json = json.dumps(sessions_dict, indent=2, ensure_ascii=False) - # self.send_text(pretty_json) diff --git a/app/bot/handlers/internal/__init__.py b/app/bot/handlers/internal/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/bot/handlers/testing.py b/app/bot/handlers/internal/testing.py similarity index 92% rename from app/bot/handlers/testing.py rename to app/bot/handlers/internal/testing.py index b665c30..bdc5e46 100644 --- a/app/bot/handlers/testing.py +++ b/app/bot/handlers/internal/testing.py @@ -1,4 +1,4 @@ -from bot.handlers.base import EventHandler +from bot.handlers.other.event_handler import EventHandler from bot.models import BotState from the_spymaster_util.logger import get_logger diff --git a/app/bot/handlers/warmup.py b/app/bot/handlers/internal/warmup.py similarity index 98% rename from app/bot/handlers/warmup.py rename to app/bot/handlers/internal/warmup.py index 536b565..04fbf51 100644 --- a/app/bot/handlers/warmup.py +++ b/app/bot/handlers/internal/warmup.py @@ -7,7 +7,7 @@ import requests from bot.config import get_config -from bot.handlers.base import EventHandler +from bot.handlers.other.event_handler import EventHandler from bot.models import AVAILABLE_MODELS from the_spymaster_solvers_api.structs import LoadModelsRequest, LoadModelsResponse diff --git a/app/bot/handlers/other/__init__.py b/app/bot/handlers/other/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/bot/handlers/common.py b/app/bot/handlers/other/common.py similarity index 100% rename from app/bot/handlers/common.py rename to app/bot/handlers/other/common.py diff --git a/app/bot/handlers/error.py b/app/bot/handlers/other/error.py similarity index 83% rename from app/bot/handlers/error.py rename to app/bot/handlers/other/error.py index 7b5d428..c92cebb 100644 --- a/app/bot/handlers/error.py +++ b/app/bot/handlers/other/error.py @@ -1,4 +1,4 @@ -from bot.handlers.base import EventHandler +from bot.handlers.other.event_handler import EventHandler from the_spymaster_util.logger import get_logger log = get_logger(__name__) diff --git a/app/bot/handlers/base.py b/app/bot/handlers/other/event_handler.py similarity index 95% rename from app/bot/handlers/base.py rename to app/bot/handlers/other/event_handler.py index b1b02da..2247c0f 100644 --- a/app/bot/handlers/base.py +++ b/app/bot/handlers/other/event_handler.py @@ -3,7 +3,7 @@ import sentry_sdk from beautifultable import BeautifulTable -from bot.handlers.common import ( +from bot.handlers.other.common import ( enrich_sentry_context, get_given_guess_result_message_text, is_blue_guesser_turn, @@ -16,6 +16,7 @@ BadMessageError, BotState, GameConfig, + ParsingState, Session, ) from codenames.game.card import Card @@ -100,6 +101,12 @@ def config(self) -> Optional[GameConfig]: return None return self.session.config + @property + def parsing_state(self) -> Optional[ParsingState]: + if not self.session: + return None + return self.session.parsing_state + @classmethod def generate_callback(cls, bot: "TheSpymasterBot") -> Callable[[Update, CallbackContext], Any]: def callback(update: Update, context: CallbackContext) -> Any: @@ -146,6 +153,13 @@ def update_game_config(self, **kwargs) -> Session: new_config = old_config.copy(update=kwargs) return self.update_session(config=new_config) + def update_parsing_state(self, **kwargs) -> Session: + old_parsing_state = self.parsing_state + if not old_parsing_state: + raise NoneValueError("parsing state is not set, cannot update parsing state.") + new_parsing_state = old_parsing_state.copy(update=kwargs) + return self.update_session(parsing_state=new_parsing_state) + def handle(self): raise NotImplementedError @@ -176,7 +190,7 @@ def fast_forward(self, state: GameState): self.send_game_summary(state=state) log.update_context(game_id=None) self.update_session(game_id=None) - from bot.handlers import HelpMessageHandler + from bot.handlers.other.help import HelpMessageHandler self.trigger(HelpMessageHandler) return None diff --git a/app/bot/handlers/fallback.py b/app/bot/handlers/other/fallback.py similarity index 56% rename from app/bot/handlers/fallback.py rename to app/bot/handlers/other/fallback.py index 26424c8..37bc72b 100644 --- a/app/bot/handlers/fallback.py +++ b/app/bot/handlers/other/fallback.py @@ -1,4 +1,4 @@ -from bot.handlers.base import EventHandler +from bot.handlers.other.event_handler import EventHandler class FallbackHandler(EventHandler): diff --git a/app/bot/handlers/help.py b/app/bot/handlers/other/help.py similarity index 85% rename from app/bot/handlers/help.py rename to app/bot/handlers/other/help.py index b76cc45..0d4d2f4 100644 --- a/app/bot/handlers/help.py +++ b/app/bot/handlers/other/help.py @@ -1,4 +1,4 @@ -from bot.handlers.base import EventHandler +from bot.handlers.other.event_handler import EventHandler from the_spymaster_util.logger import get_logger log = get_logger(__name__) @@ -11,9 +11,8 @@ def handle(self): /start - start a new game. /custom - start a new game with custom configurations. /help - show this message. -Under development: 👨🏻‍💻 +In development: 👨🏻‍💻 /parse - get help with your camera. -/continue - continue an old game. How to play: You are the blue guesser. The bot will play all other roles. \ diff --git a/app/bot/models.py b/app/bot/models.py index f21bcf0..12d89d8 100644 --- a/app/bot/models.py +++ b/app/bot/models.py @@ -34,15 +34,19 @@ class BadMessageError(Exception): class BotState(IntEnum): - ENTRY = 0 + PLAYING = 30 + # Config CONFIG_LANGUAGE = 10 CONFIG_SOLVER = 11 CONFIG_DIFFICULTY = 12 CONFIG_MODEL = 13 + # Parsing + PARSE_LANGUAGE = 40 + PARSE_MAP = 41 + PARSE_BOARD = 42 + PARSE_FIXES = 43 + # Other CONTINUE_GET_ID = 20 - PLAYING = 30 - PARSE_MAP = 40 - PARSE_BOARD = 41 class GameConfig(BaseModel): # Move to backend api? diff --git a/app/bot/the_spymaster_bot.py b/app/bot/the_spymaster_bot.py index f483ee4..e931ea2 100644 --- a/app/bot/the_spymaster_bot.py +++ b/app/bot/the_spymaster_bot.py @@ -1,26 +1,23 @@ from typing import Any, Callable, Dict, Optional, Type -from bot.handlers import ( - ConfigDifficultyHandler, - ConfigLanguageHandler, - ConfigModelHandler, - ConfigSolverHandler, - ContinueGetIdHandler, - ContinueHandler, - CustomHandler, - ErrorHandler, - EventHandler, - FallbackHandler, - GetSessionsHandler, - HelpMessageHandler, - NextMoveHandler, - ProcessMessageHandler, - StartEventHandler, - TestingHandler, - WarmupHandler, -) -from bot.handlers.parse_handler import ParseBoardHandler, ParseHandler, ParseMapHandler -from bot.handlers.warmup import handle_warmup +from bot.handlers.custom.config_difficulty import ConfigDifficultyHandler +from bot.handlers.custom.config_language import ConfigLanguageHandler +from bot.handlers.custom.config_model import ConfigModelHandler +from bot.handlers.custom.config_solvers import ConfigSolverHandler +from bot.handlers.custom.custom import CustomHandler +from bot.handlers.gameplay.next_move import NextMoveHandler +from bot.handlers.gameplay.process_message import ProcessMessageHandler +from bot.handlers.gameplay.start import StartEventHandler +from bot.handlers.internal.testing import TestingHandler +from bot.handlers.internal.warmup import WarmupHandler, handle_warmup +from bot.handlers.other.error import ErrorHandler +from bot.handlers.other.event_handler import EventHandler +from bot.handlers.other.fallback import FallbackHandler +from bot.handlers.other.help import HelpMessageHandler +from bot.handlers.parse.parse_board_handler import ParseBoardHandler +from bot.handlers.parse.parse_handler import ParseHandler +from bot.handlers.parse.parse_language_handler import ParseLanguageHandler +from bot.handlers.parse.parse_map_handler import ParseMapHandler from bot.models import BotState from persistence.dynamo_db_persistence import DynamoDbPersistence from telegram import Update @@ -86,6 +83,7 @@ def _construct_updater(self): next_move_handler = CommandHandler("next_move", self.generate_callback(NextMoveHandler)) # Parsing parse_handler = CommandHandler("parse", self.generate_callback(ParseHandler)) + parse_language_handler = MessageHandler(Filters.text, self.generate_callback(ParseLanguageHandler)) parse_map_handler = MessageHandler(Filters.photo, self.generate_callback(ParseMapHandler)) parse_board_handler = MessageHandler(Filters.photo, self.generate_callback(ParseBoardHandler)) # Util @@ -95,10 +93,6 @@ def _construct_updater(self): # Internal load_models_handler = CommandHandler("warmup", self.generate_callback(WarmupHandler)) testing_handler = CommandHandler("test", self.generate_callback(TestingHandler)) - # Not supported - continue_game_handler = CommandHandler("continue", self.generate_callback(ContinueHandler)) - continue_get_id_handler = MessageHandler(Filters.text, self.generate_callback(ContinueGetIdHandler)) - get_sessions_handler = CommandHandler("sessions", self.generate_callback(GetSessionsHandler)) conv_handler = ConversationHandler( name="main", @@ -109,19 +103,20 @@ def _construct_updater(self): next_move_handler, load_models_handler, testing_handler, - get_sessions_handler, - continue_game_handler, parse_handler, ], states={ + # Custom BotState.CONFIG_LANGUAGE: [config_language_handler], - BotState.CONFIG_SOLVER: [config_solver_handler, fallback_handler], - BotState.CONFIG_DIFFICULTY: [config_difficulty_handler, fallback_handler], - BotState.CONFIG_MODEL: [config_model_handler, fallback_handler], - BotState.CONTINUE_GET_ID: [continue_get_id_handler], + BotState.CONFIG_SOLVER: [config_solver_handler], + BotState.CONFIG_DIFFICULTY: [config_difficulty_handler], + BotState.CONFIG_MODEL: [config_model_handler], + # Game BotState.PLAYING: [process_message_handler], - BotState.PARSE_MAP: [parse_map_handler, fallback_handler], - BotState.PARSE_BOARD: [parse_board_handler, fallback_handler], + # Parse + BotState.PARSE_LANGUAGE: [parse_language_handler], + BotState.PARSE_MAP: [parse_map_handler], + BotState.PARSE_BOARD: [parse_board_handler], }, fallbacks=[fallback_handler], allow_reentry=True,