From 013d04261b90b22804c23ddf96d19e9e0c6d7ddf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=ADITQ?= Date: Fri, 22 Mar 2024 00:16:12 +0300 Subject: [PATCH] chore: Code refactoring and improvements --- app/callbacks/profile.py | 98 +++++-------------------- app/filters/{user_filter.py => user.py} | 0 app/handlers/help_command.py | 2 +- app/handlers/profile_command.py | 2 +- app/handlers/start_command.py | 62 +++++----------- app/keyboards/builders.py | 4 +- app/messages.py | 2 +- app/models/user.py | 2 +- app/states/user.py | 21 ++++++ app/utils/states.py | 40 +++++----- 10 files changed, 82 insertions(+), 151 deletions(-) rename app/filters/{user_filter.py => user.py} (100%) create mode 100644 app/states/user.py diff --git a/app/callbacks/profile.py b/app/callbacks/profile.py index e574033..7b4ff52 100644 --- a/app/callbacks/profile.py +++ b/app/callbacks/profile.py @@ -8,11 +8,15 @@ from aiogram.fsm.context import FSMContext from aiogram.types import CallbackQuery, Message, ReplyKeyboardRemove from app import messages, session -from app.filters.user_filter import Registered, RegisteredCallback -from app.keyboards.builders import profile +from app.filters.user import Registered, RegisteredCallback +from app.keyboards.builders import sex_keyboard from app.keyboards.profile import get from app.models.user import User -from app.utils.states import delete_message_from_state, UserAltering +from app.states.user import UserAltering +from app.utils.states import ( + delete_message_from_state, + handle_validation_error, +) router = Router(name="profile_callback") @@ -47,7 +51,7 @@ async def profile_change_callback( elif column == "sex": message = await callback.message.answer( f"{messages.INPUT_SEX}\n{messages.CANCEL_CHANGE}", - reply_markup=profile(["Male", "Female"]), + reply_markup=sex_keyboard(["Male", "Female"]), ) elif column == "location": message = await callback.message.answer( @@ -93,17 +97,7 @@ async def profile_change_entered(message: Message, state: FSMContext) -> None: value=value, ) except AssertionError as e: - await message.delete() - await delete_message_from_state( - state, - message.chat.id, - message.bot, - ) - - error_message = await message.answer(str(e)) - await state.update_data( - previous_message_id=error_message.message_id, - ) + await handle_validation_error(message, state, e) return @@ -112,17 +106,7 @@ async def profile_change_entered(message: Message, state: FSMContext) -> None: try: validated_age = User().validate_age(key="age", value=value) except AssertionError as e: - await message.delete() - await delete_message_from_state( - state, - message.chat.id, - message.bot, - ) - - error_message = await message.answer(str(e)) - await state.update_data( - previous_message_id=error_message.message_id, - ) + await handle_validation_error(message, state, e) return @@ -139,17 +123,7 @@ async def profile_change_entered(message: Message, state: FSMContext) -> None: try: validated_bio = User().validate_bio(key="bio", value=value) except AssertionError as e: - await message.delete() - await delete_message_from_state( - state, - message.chat.id, - message.bot, - ) - - error_message = await message.answer(str(e)) - await state.update_data( - previous_message_id=error_message.message_id, - ) + await handle_validation_error(message, state, e) return @@ -160,17 +134,7 @@ async def profile_change_entered(message: Message, state: FSMContext) -> None: try: validated_sex = User().validate_sex(key="sex", value=value) except AssertionError as e: - await message.delete() - await delete_message_from_state( - state, - message.chat.id, - message.bot, - ) - - error_message = await message.answer(str(e)) - await state.update_data( - previous_message_id=error_message.message_id, - ) + await handle_validation_error(message, state, e) return @@ -179,18 +143,10 @@ async def profile_change_entered(message: Message, state: FSMContext) -> None: location = value.split(", ") if len(location) != 2: - await message.delete() - await delete_message_from_state( + await handle_validation_error( + message, state, - message.chat.id, - message.bot, - ) - - error_message = await message.answer( - messages.VALIDATION_ERROR_MESSAGE, - ) - await state.update_data( - previous_message_id=error_message.message_id, + messages.VALIDATION_ERROR, ) return @@ -203,17 +159,7 @@ async def profile_change_entered(message: Message, state: FSMContext) -> None: value=country, ) except AssertionError as e: - await message.delete() - await delete_message_from_state( - state, - message.chat.id, - message.bot, - ) - - error_message = await message.answer(str(e)) - await state.update_data( - previous_message_id=error_message.message_id, - ) + await handle_validation_error(message, state, e) return @@ -223,17 +169,7 @@ async def profile_change_entered(message: Message, state: FSMContext) -> None: country=validated_country, ) except AssertionError as e: - await message.delete() - await delete_message_from_state( - state, - message.chat.id, - message.bot, - ) - - error_message = await message.answer(str(e)) - await state.update_data( - previous_message_id=error_message.message_id, - ) + await handle_validation_error(message, state, e) return diff --git a/app/filters/user_filter.py b/app/filters/user.py similarity index 100% rename from app/filters/user_filter.py rename to app/filters/user.py diff --git a/app/handlers/help_command.py b/app/handlers/help_command.py index ab6dff9..2aadb11 100644 --- a/app/handlers/help_command.py +++ b/app/handlers/help_command.py @@ -5,7 +5,7 @@ from aiogram.filters import Command from aiogram.types import Message from app import messages -from app.filters.user_filter import Registered +from app.filters.user import Registered router = Router(name="help_command") diff --git a/app/handlers/profile_command.py b/app/handlers/profile_command.py index 740ac5c..03a76b5 100644 --- a/app/handlers/profile_command.py +++ b/app/handlers/profile_command.py @@ -5,7 +5,7 @@ from aiogram.filters import Command from aiogram.types import Message from app import messages -from app.filters.user_filter import Registered +from app.filters.user import Registered from app.keyboards.profile import get from app.models.user import User diff --git a/app/handlers/start_command.py b/app/handlers/start_command.py index 9248be2..cf6495d 100644 --- a/app/handlers/start_command.py +++ b/app/handlers/start_command.py @@ -6,9 +6,13 @@ from aiogram.fsm.context import FSMContext from aiogram.types import Message, ReplyKeyboardRemove from app import messages, session -from app.keyboards.builders import profile +from app.keyboards.builders import sex_keyboard from app.models.user import User -from app.utils.states import delete_message_from_state, RegistrationForm +from app.states.user import RegistrationForm +from app.utils.states import ( + delete_message_from_state, + handle_validation_error, +) router = Router(name="start_command") @@ -51,11 +55,7 @@ async def username_handler(message: Message, state: FSMContext) -> None: value=username, ) except AssertionError as e: - await message.delete() - await delete_message_from_state(state, message.chat.id, message.bot) - - error_message = await message.answer(str(e)) - await state.update_data(previous_message_id=error_message.message_id) + await handle_validation_error(message, state, e) return @@ -83,11 +83,7 @@ async def age_handler(message: Message, state: FSMContext) -> None: try: validated_age = User().validate_age(key="age", value=age) except AssertionError as e: - await message.delete() - await delete_message_from_state(state, message.chat.id, message.bot) - - error_message = await message.answer(str(e)) - await state.update_data(previous_message_id=error_message.message_id) + await handle_validation_error(message, state, e) return @@ -101,7 +97,7 @@ async def age_handler(message: Message, state: FSMContext) -> None: ) await message.answer( messages.INPUT_SEX, - reply_markup=profile(["Male", "Female"]), + reply_markup=sex_keyboard(["Male", "Female"]), ) @@ -115,11 +111,7 @@ async def sex_handler(message: Message, state: FSMContext) -> None: try: validated_sex = User().validate_sex(key="sex", value=sex) except AssertionError as e: - await message.delete() - await delete_message_from_state(state, message.chat.id, message.bot) - - error_message = await message.answer(str(e)) - await state.update_data(previous_message_id=error_message.message_id) + await handle_validation_error(message, state, e) return @@ -154,17 +146,7 @@ async def bio_handler(message: Message, state: FSMContext) -> None: try: validated_bio = User().validate_bio(key="bio", value=bio) except AssertionError as e: - await message.delete() - await delete_message_from_state( - state, - message.chat.id, - message.bot, - ) - - error_message = await message.answer(str(e)) - await state.update_data( - previous_message_id=error_message.message_id, - ) + await handle_validation_error(message, state, e) return @@ -187,11 +169,11 @@ async def location_handler(message: Message, state: FSMContext) -> None: location = message.text.strip().split(", ") if len(location) != 2: - await message.delete() - await delete_message_from_state(state, message.chat.id, message.bot) - - error_message = await message.answer(messages.VALIDATION_ERROR_MESSAGE) - await state.update_data(previous_message_id=error_message.message_id) + await handle_validation_error( + message, + state, + messages.VALIDATION_ERROR, + ) return @@ -203,11 +185,7 @@ async def location_handler(message: Message, state: FSMContext) -> None: value=country, ) except AssertionError as e: - await message.delete() - await delete_message_from_state(state, message.chat.id, message.bot) - - error_message = await message.answer(str(e)) - await state.update_data(previous_message_id=error_message.message_id) + await handle_validation_error(message, state, e) return @@ -217,11 +195,7 @@ async def location_handler(message: Message, state: FSMContext) -> None: country=validated_country, ) except AssertionError as e: - await message.delete() - await delete_message_from_state(state, message.chat.id, message.bot) - - error_message = await message.answer(str(e)) - await state.update_data(previous_message_id=error_message.message_id) + await handle_validation_error(message, state, e) return diff --git a/app/keyboards/builders.py b/app/keyboards/builders.py index b7538e5..96fe862 100644 --- a/app/keyboards/builders.py +++ b/app/keyboards/builders.py @@ -1,9 +1,9 @@ -__all__ = ("profile",) +__all__ = ("sex_keyboard",) from aiogram.utils.keyboard import ReplyKeyboardBuilder -def profile(text: str | list): +def sex_keyboard(text: str | list): builder = ReplyKeyboardBuilder() if isinstance(text, str): diff --git a/app/messages.py b/app/messages.py index 72d2d0e..8e593dd 100644 --- a/app/messages.py +++ b/app/messages.py @@ -14,7 +14,7 @@ INPUT_BIO = "Enter your bio (enter /skip if you want to skip this step):\nMax INPUT_BIO_SKIPPED = "Sure. You can always fill it later." INPUT_LOCATION = "Enter your location in this format:\nFormat: country, city\nExample: Russia, Moscow" INPUT_CALLBACK = "All right, your {key} is set to: {value}" -VALIDATION_ERROR_MESSAGE = "Invalid input. Please try again." +VALIDATION_ERROR = "Invalid input. Please try again." CANCEL_CHANGE = "Enter /cancel to cancel change." PROFILE = ( diff --git a/app/models/user.py b/app/models/user.py index d9963b1..b57f018 100644 --- a/app/models/user.py +++ b/app/models/user.py @@ -29,7 +29,7 @@ class User(Base): def validate_username(self, key, value): regex_pattern = re.compile(r"^[a-zA-Z0-9_]{5,20}$") - assert len(value) <= 32, "Username must be 20 characters or fewer." + assert len(value) <= 32, "Username must be 32 characters or fewer." assert len(value) >= 5, "Username must be at least 5 characters." assert ( re.match(regex_pattern, value) is not None diff --git a/app/states/user.py b/app/states/user.py new file mode 100644 index 0000000..6941f5c --- /dev/null +++ b/app/states/user.py @@ -0,0 +1,21 @@ +__all__ = ("RegistrationForm", "UserAltering") + +from aiogram.fsm.state import State, StatesGroup + + +class RegistrationForm(StatesGroup): + previous_message_id = State() + username = State() + age = State() + bio = State() + sex = State() + location = State() + + +class UserAltering(StatesGroup): + column = State() + value = State() + message_id = State() + input_message_id = State() + previous_message_id = State() + successfully = State() diff --git a/app/utils/states.py b/app/utils/states.py index 0b3b016..61dcce7 100644 --- a/app/utils/states.py +++ b/app/utils/states.py @@ -1,27 +1,9 @@ -__all__ = ("RegistrationForm",) +__all__ = ("delete_message_from_state", "handle_validation_error") from aiogram import Bot from aiogram.exceptions import TelegramBadRequest from aiogram.fsm.context import FSMContext -from aiogram.fsm.state import State, StatesGroup - - -class RegistrationForm(StatesGroup): - previous_message_id = State() - username = State() - age = State() - bio = State() - sex = State() - location = State() - - -class UserAltering(StatesGroup): - column = State() - value = State() - message_id = State() - input_message_id = State() - previous_message_id = State() - successfully = State() +from aiogram.types import Message async def delete_message_from_state( @@ -63,3 +45,21 @@ async def delete_message_from_state( pass await state.update_data(input_message_id=None) + + +async def handle_validation_error( + message: Message, + state: FSMContext, + e: AssertionError | str, +) -> None: + await message.delete() + await delete_message_from_state( + state, + message.chat.id, + message.bot, + ) + + error_message = await message.answer(str(e)) + await state.update_data( + previous_message_id=error_message.message_id, + )