Files
Travel-Agent/app/callbacks/profile.py
T

293 lines
8.3 KiB
Python

# type: ignore
__all__ = ()
from aiogram import F, Router
from aiogram.exceptions import TelegramBadRequest
from aiogram.filters import StateFilter
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.keyboards.profile import get
from app.models.user import User
from app.utils.states import delete_message_from_state, UserAltering
router = Router(name="profile_callback")
@router.callback_query(
F.data.startswith("profile_change_"),
StateFilter(None),
RegisteredCallback(),
)
async def profile_change_callback(
callback: CallbackQuery,
state: FSMContext,
) -> None:
if callback.data is None or callback.message is None:
return
column = callback.data.replace("profile_change_", "")
if column == "username":
message = await callback.message.answer(
f"{messages.EDIT_USERNAME}\n{messages.CANCEL_CHANGE}",
)
elif column == "age":
message = await callback.message.answer(
f"{messages.INPUT_AGE}\n{messages.CANCEL_CHANGE}",
)
elif column == "bio":
message = await callback.message.answer(
f"{messages.EDIT_BIO}\n{messages.CANCEL_CHANGE}",
)
elif column == "sex":
message = await callback.message.answer(
f"{messages.INPUT_SEX}\n{messages.CANCEL_CHANGE}",
reply_markup=profile(["Male", "Female"]),
)
elif column == "location":
message = await callback.message.answer(
f"{messages.INPUT_LOCATION}\n{messages.CANCEL_CHANGE}",
)
await state.update_data(
column=column,
message_id=callback.message.message_id,
input_message_id=message.message_id,
)
await state.set_state(UserAltering.value)
await callback.answer()
@router.message(UserAltering.value, F.text, Registered())
async def profile_change_entered(message: Message, state: FSMContext) -> None:
column = (await state.get_data()).get("column")
value = message.text.strip()
if value == "/cancel":
await message.answer(
messages.CHANGE_CANCELED,
reply_markup=ReplyKeyboardRemove(),
)
await state.update_data(successfully=True)
await message.delete()
await delete_message_from_state(
state,
message.chat.id,
message.bot,
)
await state.clear()
return
if column == "username":
try:
validated_value = User().validate_username(
key="username",
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,
)
return
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.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,
)
return
await state.update_data(value=validated_age, successfully=True)
elif column == "bio":
if value == "/skip":
await state.update_data(value=None, successfully=True)
await delete_message_from_state(
state,
message.chat.id,
message.bot,
)
else:
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,
)
return
await state.update_data(value=validated_bio, successfully=True)
elif column == "sex":
value = value.lower()
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,
)
return
await state.update_data(value=validated_sex, successfully=True)
elif column == "location":
location = value.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,
)
return
country, city = location
try:
validated_country = User().validate_country(
key="country",
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,
)
return
try:
validated_city = User().validate_city(
city=city,
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,
)
return
await delete_message_from_state(state, message.chat.id, message.bot)
await state.update_data(
value=[validated_country, validated_city],
successfully=True,
)
await delete_message_from_state(state, message.chat.id, message.bot)
state_data = await state.get_data()
user = User.get_user_queryset_by_telegram_id(message.from_user.id)
if isinstance(state_data["value"], list):
user.update(
{
"country": state_data["value"][0],
"city": state_data["value"][1],
},
)
else:
data = {state_data["column"]: state_data["value"]}
user.update(data)
session.commit()
user = user.first()
session.refresh(user)
try:
await message.bot.edit_message_text(
messages.PROFILE.format(
username=user.username,
age=user.age,
bio=user.bio if user.bio else messages.NOT_SET,
sex=user.sex.capitalize(),
country=user.country,
city=user.city,
),
message.chat.id,
state_data["message_id"],
reply_markup=get(),
)
except TelegramBadRequest:
pass
await message.delete()
await message.answer(
messages.PROFILE_UPDATED,
reply_markup=ReplyKeyboardRemove(),
)
await state.clear()