From 3226e090f5beee1d698590337b19ec937d3ffb01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=ADITQ?= Date: Thu, 21 Mar 2024 18:33:14 +0300 Subject: [PATCH] chore: Added message deletions and small code refactoring --- app/callbacks/profile.py | 87 +++++++++++++++++++++++++++-------- app/handlers/start_command.py | 71 ++++++++++++++++++++++++---- app/messages.py | 3 +- app/utils/states.py | 31 +++++++++++++ 4 files changed, 161 insertions(+), 31 deletions(-) diff --git a/app/callbacks/profile.py b/app/callbacks/profile.py index 4b0d969..8a7d4d1 100644 --- a/app/callbacks/profile.py +++ b/app/callbacks/profile.py @@ -12,7 +12,7 @@ from app.filters.user_filter import Registered, RegisteredCallback from app.keyboards.builders import profile from app.keyboards.profile import get from app.models.user import User -from app.utils.states import UserAltering +from app.utils.states import delete_message_from_state, UserAltering router = Router(name="profile_callback") @@ -33,22 +33,23 @@ async def profile_change_callback( column = callback.data.replace("profile_change_", "") if column == "username": - await callback.message.answer(messages.EDIT_USERNAME) + message = await callback.message.answer(messages.EDIT_USERNAME) elif column == "age": - await callback.message.answer(messages.INPUT_AGE) + message = await callback.message.answer(messages.INPUT_AGE) elif column == "bio": - await callback.message.answer(messages.EDIT_BIO) + message = await callback.message.answer(messages.EDIT_BIO) elif column == "sex": - await callback.message.answer( + message = await callback.message.answer( messages.INPUT_SEX, reply_markup=profile(["Male", "Female"]), ) elif column == "location": - await callback.message.answer(messages.INPUT_LOCATION) + message = await callback.message.answer(messages.INPUT_LOCATION) await state.update_data( column=column, message_id=callback.message.message_id, + input_message=message, ) await state.set_state(UserAltering.value) @@ -67,41 +68,72 @@ async def profile_change_entered(message: Message, state: FSMContext) -> None: value=value, ) except AssertionError as e: - await message.answer(str(e)) + await message.delete() + await delete_message_from_state(state) + + error_message = await message.answer(str(e)) + await state.update_data(previous_message=error_message) + return - await state.update_data(value=validated_value) + await state.update_data(value=validated_value, successfully=True) elif column == "age": try: validated_age = User().validate_age(key="age", value=value) except AssertionError as e: - await message.answer(str(e)) + await message.delete() + await delete_message_from_state(state) + + error_message = await message.answer(str(e)) + await state.update_data(previous_message=error_message) + return - await state.update_data(value=validated_age) + await state.update_data(value=validated_age, successfully=True) elif column == "bio": if value == "/skip": - await state.update_data(value=None) + await state.update_data(value=None, successfully=True) + await delete_message_from_state(state) else: try: validated_bio = User().validate_bio(key="bio", value=value) except AssertionError as e: - await message.answer(str(e)) + await message.delete() + await delete_message_from_state(state) + + error_message = await message.answer(str(e)) + await state.update_data(previous_message=error_message) + return - await state.update_data(value=validated_bio) + await state.update_data(value=validated_bio, successfully=True) elif column == "sex": value = value.lower() - if value not in ["male", "female"]: - await message.answer(messages.VALIDATION_ERROR_MESSAGE) + try: + validated_sex = User().validate_sex(key="sex", value=value) + except AssertionError as e: + await message.delete() + await delete_message_from_state(state) + + error_message = await message.answer(str(e)) + await state.update_data(previous_message=error_message) + return - await state.update_data(value=value) + await state.update_data(value=validated_sex, successfully=True) elif column == "location": location = value.split(", ") + if len(location) != 2: - await message.answer(messages.VALIDATION_ERROR_MESSAGE) + await message.delete() + await delete_message_from_state(state) + + error_message = await message.answer( + messages.VALIDATION_ERROR_MESSAGE, + ) + await state.update_data(previous_message=error_message) + return country, city = location @@ -112,7 +144,12 @@ async def profile_change_entered(message: Message, state: FSMContext) -> None: value=country, ) except AssertionError as e: - await message.answer(str(e)) + await message.delete() + await delete_message_from_state(state) + + error_message = await message.answer(str(e)) + await state.update_data(previous_message=error_message) + return try: @@ -121,11 +158,20 @@ async def profile_change_entered(message: Message, state: FSMContext) -> None: country=validated_country, ) except AssertionError as e: - await message.answer(str(e)) + await message.delete() + await delete_message_from_state(state) + + error_message = await message.answer(str(e)) + await state.update_data(previous_message=error_message) + return + await delete_message_from_state(state) + await state.update_data(value=[validated_country, validated_city]) + await delete_message_from_state(state) + state_data = await state.get_data() user = User.get_user_queryset_by_telegram_id(message.from_user.id) @@ -163,8 +209,9 @@ async def profile_change_entered(message: Message, state: FSMContext) -> None: except TelegramBadRequest: pass + await message.delete() await message.answer( - "✅ Profile updated", + messages.PROFILE_UPDATED, reply_markup=ReplyKeyboardRemove(), ) diff --git a/app/handlers/start_command.py b/app/handlers/start_command.py index 5d73201..e58a903 100644 --- a/app/handlers/start_command.py +++ b/app/handlers/start_command.py @@ -8,7 +8,7 @@ from aiogram.types import Message, ReplyKeyboardRemove from app import messages, session from app.keyboards.builders import profile from app.models.user import User -from app.utils.states import RegistrationForm +from app.utils.states import delete_message_from_state, RegistrationForm router = Router(name="start_command") @@ -51,9 +51,16 @@ async def username_handler(message: Message, state: FSMContext) -> None: value=username, ) except AssertionError as e: - await message.answer(str(e)) + await message.delete() + await delete_message_from_state(state) + + error_message = await message.answer(str(e)) + await state.update_data(previous_message=error_message) + return + await delete_message_from_state(state) + await state.update_data(username=validated_username) await state.set_state(RegistrationForm.age) @@ -76,9 +83,16 @@ 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.answer(str(e)) + await message.delete() + await delete_message_from_state(state) + + error_message = await message.answer(str(e)) + await state.update_data(previous_message=error_message) + return + await delete_message_from_state(state) + await state.update_data(age=validated_age) await state.set_state(RegistrationForm.sex) @@ -98,11 +112,20 @@ async def sex_handler(message: Message, state: FSMContext) -> None: sex = message.text.strip().lower() - if sex not in ["male", "female"]: - await message.answer(messages.VALIDATION_ERROR_MESSAGE) + try: + validated_sex = User().validate_sex(key="sex", value=sex) + except AssertionError as e: + await message.delete() + await delete_message_from_state(state) + + error_message = await message.answer(str(e)) + await state.update_data(previous_message=error_message) + return - await state.update_data(sex=sex) + await delete_message_from_state(state) + + await state.update_data(sex=validated_sex) await state.set_state(RegistrationForm.bio) await message.answer( @@ -123,15 +146,24 @@ async def bio_handler(message: Message, state: FSMContext) -> None: await state.update_data(bio=None) await state.set_state(RegistrationForm.location) + await delete_message_from_state(state) + await message.answer(messages.INPUT_BIO_SKIPPED) await message.answer(messages.INPUT_LOCATION) else: try: validated_bio = User().validate_bio(key="bio", value=bio) except AssertionError as e: - await message.answer(str(e)) + await message.delete() + await delete_message_from_state(state) + + error_message = await message.answer(str(e)) + await state.update_data(previous_message=error_message) + return + await delete_message_from_state(state) + await state.update_data(bio=validated_bio) await state.set_state(RegistrationForm.location) @@ -149,7 +181,12 @@ async def location_handler(message: Message, state: FSMContext) -> None: location = message.text.strip().split(", ") if len(location) != 2: - await message.answer(messages.VALIDATION_ERROR_MESSAGE) + await message.delete() + await delete_message_from_state(state) + + error_message = await message.answer(messages.VALIDATION_ERROR_MESSAGE) + await state.update_data(previous_message=error_message) + return country, city = location @@ -160,7 +197,12 @@ async def location_handler(message: Message, state: FSMContext) -> None: value=country, ) except AssertionError as e: - await message.answer(str(e)) + await message.delete() + await delete_message_from_state(state) + + error_message = await message.answer(str(e)) + await state.update_data(previous_message=error_message) + return try: @@ -169,9 +211,16 @@ async def location_handler(message: Message, state: FSMContext) -> None: country=validated_country, ) except AssertionError as e: - await message.answer(str(e)) + await message.delete() + await delete_message_from_state(state) + + error_message = await message.answer(str(e)) + await state.update_data(previous_message=error_message) + return + await delete_message_from_state(state) + await state.update_data(location=[validated_country, validated_city]) data = await state.get_data() await state.clear() @@ -187,6 +236,8 @@ async def location_handler(message: Message, state: FSMContext) -> None: data["country"] = data["location"][0] data["city"] = data["location"][1] del data["location"] + del data["previous_message"] + session.add(User(**data)) session.commit() diff --git a/app/messages.py b/app/messages.py index 0419dd8..db287d0 100644 --- a/app/messages.py +++ b/app/messages.py @@ -21,10 +21,11 @@ PROFILE = ( "\tUsername: {username}\n" "\tAge: {age}\n" "\tSex: {sex}\n" - "\tBio: {bio}\n" "\tCountry: {country}\n" "\tCity: {city}" + "\tBio: {bio}\n" ) NOT_SET = "Not set" EDIT_USERNAME = "Enter your username:\nAllowed characters: a-z, A-Z, 0-9, _\nLength: 5-20 characters" EDIT_BIO = "Enter your bio (enter /skip if you want to set it to None):\nMaximum length: 100 characters" +PROFILE_UPDATED = "✅ Profile updated" diff --git a/app/utils/states.py b/app/utils/states.py index 65dd129..6aee704 100644 --- a/app/utils/states.py +++ b/app/utils/states.py @@ -1,9 +1,12 @@ __all__ = ("RegistrationForm",) +from aiogram.exceptions import TelegramBadRequest from aiogram.fsm.state import State, StatesGroup +from aiogram.fsm.context import FSMContext class RegistrationForm(StatesGroup): + previous_message = State() username = State() age = State() bio = State() @@ -12,6 +15,34 @@ class RegistrationForm(StatesGroup): class UserAltering(StatesGroup): + successfully = State() message_id = State() + input_message = State() + previous_message = State() column = State() value = State() + + +async def delete_message_from_state(state: FSMContext) -> None: + data = await state.get_data() + + if "previous_message" in data and data["previous_message"] is not None: + try: + await data["previous_message"].delete() + except TelegramBadRequest: + pass + + await state.update_data(previous_message=None) + + if ( + "input_message" in data + and data["input_message"] is not None + and "successfully" in data + and data["successfully"] + ): + try: + await data["input_message"].delete() + except TelegramBadRequest: + pass + + await state.update_data(info_message=None)