You've already forked Travel-Agent
337 lines
8.5 KiB
Python
337 lines
8.5 KiB
Python
__all__ = ("router",)
|
|
|
|
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
|
|
|
|
from app import messages, session
|
|
from app.config import Config
|
|
from app.filters.user import Registered, RegisteredCallback
|
|
from app.keyboards.builders import travels_keyboard
|
|
from app.keyboards.travel import get as travel_get
|
|
from app.keyboards.routes import get as routes_get
|
|
from app.models.travel import Travel
|
|
from app.models.user import User
|
|
from app.states.travel import (
|
|
TravelAlteringState,
|
|
)
|
|
from app.utils.states import delete_message_from_state, handle_validation_error
|
|
|
|
|
|
router = Router(name="travel_callback")
|
|
|
|
|
|
@router.callback_query(
|
|
F.data == "travels",
|
|
RegisteredCallback(),
|
|
StateFilter(None),
|
|
)
|
|
async def travels_index_callback(callback: CallbackQuery) -> None:
|
|
page = 0
|
|
|
|
if callback.from_user is None or not isinstance(callback.message, Message):
|
|
return
|
|
|
|
user = User().get_user_by_telegram_id(callback.from_user.id)
|
|
|
|
travels = user.get_user_travels()
|
|
|
|
if not travels or travels == []:
|
|
try:
|
|
await callback.message.edit_text(messages.NO_TRAVELS)
|
|
except TelegramBadRequest:
|
|
pass
|
|
else:
|
|
pages = (len(travels) + Config.PAGE_SIZE - 1) // Config.PAGE_SIZE
|
|
|
|
try:
|
|
await callback.message.edit_text(
|
|
messages.TRAVELS,
|
|
reply_markup=travels_keyboard(
|
|
travels,
|
|
page,
|
|
pages,
|
|
user.telegram_id,
|
|
),
|
|
)
|
|
except TelegramBadRequest:
|
|
pass
|
|
|
|
|
|
@router.callback_query(
|
|
F.data.startswith("travels_page"),
|
|
RegisteredCallback(),
|
|
StateFilter(None),
|
|
)
|
|
async def travels_callback(callback: CallbackQuery) -> None:
|
|
if callback.data is None or not isinstance(callback.message, Message):
|
|
return
|
|
|
|
page = int(callback.data.replace("travels_page_", ""))
|
|
|
|
user = User().get_user_by_telegram_id(callback.from_user.id)
|
|
|
|
travels = user.get_user_travels()
|
|
|
|
if not travels or travels == []:
|
|
try:
|
|
await callback.message.edit_text(messages.NO_TRAVELS)
|
|
except TelegramBadRequest:
|
|
pass
|
|
else:
|
|
pages = (len(travels) + Config.PAGE_SIZE - 1) // Config.PAGE_SIZE
|
|
|
|
try:
|
|
await callback.message.edit_text(
|
|
messages.TRAVELS,
|
|
reply_markup=travels_keyboard(
|
|
travels,
|
|
page,
|
|
pages,
|
|
user.telegram_id,
|
|
),
|
|
)
|
|
except TelegramBadRequest:
|
|
pass
|
|
|
|
|
|
@router.callback_query(
|
|
F.data.startswith("travel_detail"),
|
|
RegisteredCallback(),
|
|
StateFilter(None),
|
|
)
|
|
async def travel_detail_callback(callback: CallbackQuery) -> None:
|
|
if callback.data is None or not isinstance(callback.message, Message):
|
|
return
|
|
|
|
travel_id = int(callback.data.replace("travel_detail_", ""))
|
|
|
|
travel = Travel().get_travel_by_id(travel_id)
|
|
|
|
if not travel:
|
|
return
|
|
|
|
try:
|
|
await callback.message.edit_text(
|
|
travel.get_travel_text(),
|
|
reply_markup=travel_get(travel),
|
|
)
|
|
except TelegramBadRequest:
|
|
pass
|
|
|
|
|
|
@router.callback_query(
|
|
F.data.startswith("travel_change"),
|
|
RegisteredCallback(),
|
|
StateFilter(None),
|
|
)
|
|
async def travel_change_callback(
|
|
callback: CallbackQuery,
|
|
state: FSMContext,
|
|
) -> None:
|
|
if (
|
|
callback.data is None
|
|
or callback.message is None
|
|
or not isinstance(callback.message, Message)
|
|
):
|
|
return
|
|
|
|
travel_id, column = callback.data.replace("travel_change_", "").split("_")
|
|
|
|
travel = Travel().get_travel_by_id(travel_id)
|
|
|
|
if not travel:
|
|
return
|
|
|
|
if column == "title":
|
|
message = await callback.message.answer(
|
|
f"{messages.INPUT_TRAVEL_TITLE}\n{messages.CANCEL_CHANGE}",
|
|
)
|
|
elif column == "description":
|
|
message = await callback.message.answer(
|
|
f"{messages.EDIT_TRAVEL_DESCRIPTION}\n{messages.CANCEL_CHANGE}",
|
|
)
|
|
|
|
await state.update_data(
|
|
column=column,
|
|
travel_message_id=callback.message.message_id,
|
|
input_message_id=message.message_id,
|
|
travel_id=travel_id,
|
|
)
|
|
await state.set_state(TravelAlteringState.value)
|
|
|
|
await callback.answer()
|
|
|
|
|
|
@router.message(TravelAlteringState.value, F.text, Registered())
|
|
async def travel_change_entered(message: Message, state: FSMContext) -> None:
|
|
if (
|
|
message.text is None
|
|
or message.from_user is None
|
|
or message.bot is None
|
|
):
|
|
return
|
|
|
|
data = await state.get_data()
|
|
|
|
column = data["column"]
|
|
travel_id = data["travel_id"]
|
|
value = message.text.strip()
|
|
|
|
if value == "/cancel":
|
|
await message.answer(
|
|
messages.CHANGE_CANCELED,
|
|
)
|
|
|
|
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 == "title":
|
|
try:
|
|
validated_title = Travel().validate_title(
|
|
key="title",
|
|
value=value,
|
|
)
|
|
except AssertionError as e:
|
|
await handle_validation_error(message, state, e)
|
|
|
|
return
|
|
|
|
await state.update_data(value=validated_title, successfully=True)
|
|
elif column == "description":
|
|
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_description = Travel().validate_description(
|
|
key="description",
|
|
value=value,
|
|
)
|
|
except AssertionError as e:
|
|
await handle_validation_error(message, state, e)
|
|
|
|
return
|
|
|
|
await state.update_data(
|
|
value=validated_description,
|
|
successfully=True,
|
|
)
|
|
|
|
await message.delete()
|
|
await delete_message_from_state(state, message.chat.id, message.bot)
|
|
|
|
state_data = await state.get_data()
|
|
|
|
travel = Travel().get_travel_queryset_by_id(travel_id)
|
|
|
|
data = {state_data["column"]: state_data["value"]}
|
|
travel.update(data)
|
|
|
|
session.commit()
|
|
|
|
travel = travel.first()
|
|
session.refresh(travel)
|
|
|
|
try:
|
|
await message.bot.edit_message_text(
|
|
travel.get_travel_text(),
|
|
message.chat.id,
|
|
state_data["travel_message_id"],
|
|
reply_markup=travel_get(travel),
|
|
)
|
|
except TelegramBadRequest:
|
|
pass
|
|
|
|
await message.answer(
|
|
messages.TRAVEL_UPDATED,
|
|
)
|
|
|
|
await state.clear()
|
|
|
|
|
|
@router.callback_query(
|
|
F.data.startswith("travel_delete"),
|
|
RegisteredCallback(),
|
|
StateFilter(None),
|
|
)
|
|
async def delete_travel_callback(
|
|
callback: CallbackQuery,
|
|
):
|
|
if callback.data is None or not isinstance(callback.message, Message):
|
|
return
|
|
|
|
travel_id = int(callback.data.replace("travel_delete_", ""))
|
|
|
|
user = User().get_user_by_telegram_id(callback.from_user.id)
|
|
|
|
travel = Travel.get_travel_queryset_by_id(travel_id)
|
|
|
|
travel.delete()
|
|
|
|
session.commit()
|
|
|
|
travels = user.get_user_travels()
|
|
|
|
pages = (len(travels) + Config.PAGE_SIZE - 1) // Config.PAGE_SIZE
|
|
|
|
await callback.message.answer(messages.DELETED_TRAVEL)
|
|
|
|
await callback.message.edit_text(
|
|
messages.TRAVELS,
|
|
reply_markup=travels_keyboard(
|
|
travels,
|
|
0,
|
|
pages,
|
|
callback.from_user.id,
|
|
),
|
|
)
|
|
|
|
await callback.answer()
|
|
|
|
|
|
@router.callback_query(
|
|
F.data.startswith("travel_routes"),
|
|
RegisteredCallback(),
|
|
StateFilter(None),
|
|
)
|
|
async def travel_routes_callback(
|
|
callback: CallbackQuery,
|
|
):
|
|
if (
|
|
callback.message is None
|
|
or callback.data is None
|
|
or not isinstance(callback.message, Message)
|
|
):
|
|
return
|
|
|
|
travel_id = int(callback.data.replace("travel_routes_", ""))
|
|
|
|
travel = Travel().get_travel_by_id(travel_id)
|
|
|
|
if not travel:
|
|
await callback.answer()
|
|
|
|
return
|
|
|
|
await callback.message.edit_text(
|
|
travel.get_travel_text(),
|
|
reply_markup=routes_get(travel),
|
|
)
|
|
|
|
await callback.answer()
|