feat: Added notes creation, view and deletion, added route planning, added location list with current weather and nearby locations, code improvements and fixes

This commit is contained in:
ITQ
2024-03-26 07:49:50 +03:00
parent 65719a61ef
commit 88dfe1704d
24 changed files with 1571 additions and 301 deletions
@@ -7,258 +7,25 @@ from aiogram.exceptions import TelegramBadRequest
from aiogram.filters import StateFilter
from aiogram.fsm.context import FSMContext
from aiogram.types import CallbackQuery, Message
import sqlalchemy as sa
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.builders import locations_keyboard, sights_keyboard
from app.keyboards.confirm_location import get as confirm_location_get
from app.keyboards.travel import get as travel_get
from app.keyboards.location import get as location_get
from app.models.travel import Location, Travel
from app.models.user import User
from app.states.travel import CreateLocationState, TravelAlteringState
from app.states.travel import (
CreateLocationState,
)
from app.utils.geo import get_location_by_name
from app.utils.sights import find_trips, get_info_by_xid
from app.utils.states import delete_message_from_state, handle_validation_error
from app.utils.weather import get_current_weather
router = Router(name="menu_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
await callback.message.edit_text(
travel.get_travel_text(),
reply_markup=travel_get(travel_id),
)
@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_id),
)
except TelegramBadRequest:
pass
await message.answer(
messages.TRAVEL_UPDATED,
)
await state.clear()
router = Router(name="location_callback")
@router.callback_query(
@@ -525,8 +292,6 @@ async def location_date_end_entered(
return
await delete_message_from_state(state, message.chat.id, message.bot)
await state.update_data(
date_end=datetime.datetime.strftime(
validated_date_end,
@@ -536,6 +301,35 @@ async def location_date_end_entered(
data = await state.get_data()
overlapping_location = (
session.query(Location)
.filter(
sa.and_(
Location.travel_id == data["travel_id"],
Location.date_start < data["date_end"],
Location.date_end > data["date_start"],
),
)
.first()
)
if overlapping_location:
await handle_validation_error(
message,
state,
messages.OVERLAPPING_LOCATION,
)
return
await message.answer(
messages.INPUT_TRAVEL_CALLBACK.format(
key="end date",
value=date_end,
),
)
await delete_message_from_state(state, message.chat.id, message.bot)
if "temp_location" in data:
del data["temp_location"]
@@ -566,26 +360,241 @@ async def location_date_end_entered(
@router.callback_query(
F.data.startswith("travel_delete"),
F.data.startswith("travel_locations_page"),
RegisteredCallback(),
StateFilter(None),
)
async def delete_travel_callback(
async def travel_locations_page_callback(
callback: CallbackQuery,
):
if callback.data is None or not isinstance(callback.message, Message):
if (
callback.message is None
or callback.data is None
or not isinstance(callback.message, Message)
):
return
travel_id = int(callback.data.replace("travel_delete_", ""))
travel_id, page = map(
int,
callback.data.replace("travel_locations_page_", "").split("_"),
)
travel = Travel.get_travel_queryset_by_id(travel_id)
travel = Travel.get_travel_by_id(travel_id)
travel.delete()
if not travel or travel == []:
return
locations = Travel.get_sorted_locations(travel)
pages = (len(locations) + Config.PAGE_SIZE - 1) // Config.PAGE_SIZE
try:
await callback.message.edit_text(
messages.LOCATIONS,
reply_markup=locations_keyboard(
locations,
page,
pages,
travel_id,
),
)
except TelegramBadRequest:
pass
@router.callback_query(
F.data.startswith("travel_location_detail"),
RegisteredCallback(),
StateFilter(None),
)
async def travel_detail_location_callback(
callback: CallbackQuery,
):
if (
callback.message is None
or callback.data is None
or not isinstance(callback.message, Message)
):
return
location_id = int(callback.data.replace("travel_location_detail_", ""))
location = Location.get_location_by_id(location_id)
if not location or location == []:
return
try:
await callback.message.edit_text(
location.get_location_text(),
reply_markup=location_get(location.travel.id, location.id),
)
except TelegramBadRequest:
pass
@router.callback_query(
F.data.startswith("travel_locationdelete"),
RegisteredCallback(),
StateFilter(None),
)
async def travel_locations_delete_callback(
callback: CallbackQuery,
):
if (
callback.message is None
or callback.data is None
or not isinstance(callback.message, Message)
):
return
location_id = int(callback.data.replace("travel_locationdelete_", ""))
location_queryset = Location.get_location_queryset_by_id(location_id)
if not location_queryset or location_queryset == []:
return
travel = location_queryset.first().travel
location_queryset.delete()
session.commit()
await callback.message.answer(messages.DELETED_TRAVEL)
locations = Travel.get_sorted_locations(travel)
await callback.message.delete()
pages = (len(locations) + Config.PAGE_SIZE - 1) // Config.PAGE_SIZE
try:
await callback.message.edit_text(
messages.LOCATIONS,
reply_markup=locations_keyboard(
locations,
0,
pages,
travel.id,
),
)
except TelegramBadRequest:
pass
await callback.message.answer(
messages.LOCATION_DELETED,
)
await callback.answer()
@router.callback_query(
F.data.startswith("travel_locationsights"),
RegisteredCallback(),
StateFilter(None),
)
async def travel_locationsights_callback(
callback: CallbackQuery,
):
if (
callback.message is None
or callback.data is None
or not isinstance(callback.message, Message)
):
return
location_id = int(callback.data.replace("travel_locationsights_", ""))
location = Location.get_location_by_id(location_id)
if not location or location == []:
return
geocode = get_location_by_name(location.location)
sights = find_trips(geocode[1].raw.get("lat"), geocode[1].raw.get("lon"))
if sights is None or len(sights) == 0:
await callback.message.answer(
messages.NO_SIGHTS_FOUND.format(
location=location.location,
distance=Config.NEARBY_SIGHTS_RADIUS,
),
)
else:
await callback.message.answer(
messages.SIGHTS_HEADER
+ messages.SIGHTS_FOOTER.format(
location=location.location,
sights_count=len(sights),
distance=Config.NEARBY_SIGHTS_RADIUS,
),
reply_markup=sights_keyboard(sights[:20]),
)
await callback.answer()
@router.callback_query(
F.data.startswith("travel_sight_detail"),
RegisteredCallback(),
StateFilter(None),
)
async def travel_sight_detail_callback(
callback: CallbackQuery,
):
if (
callback.message is None
or callback.data is None
or not isinstance(callback.message, Message)
):
return
sight_xid = callback.data.replace("travel_sight_detail_", "")
await get_info_by_xid(callback, sight_xid)
await callback.answer()
@router.callback_query(
F.data.startswith("travel_locationweather"),
RegisteredCallback(),
StateFilter(None),
)
async def travel_locationweather_callback(
callback: CallbackQuery,
):
if (
callback.message is None
or callback.data is None
or not isinstance(callback.message, Message)
):
return
location_id = int(callback.data.replace("travel_locationweather_", ""))
location = Location.get_location_by_id(location_id)
if not location or location == []:
return
geocode = get_location_by_name(location.location)
weather = get_current_weather(
geocode[1].raw.get("lat"),
geocode[1].raw.get("lon"),
)
await callback.message.answer(
messages.LOCATION_WEATHER.format(
location=location.location,
weather_main=weather.get("weather")[0].get("main"),
temp=weather.get("main").get("temp"),
feels_like=weather.get("main").get("feels_like"),
temp_min=weather.get("main").get("temp_min"),
temp_max=weather.get("main").get("temp_max"),
pressure=weather.get("main").get("pressure"),
humidity=weather.get("main").get("humidity"),
),
reply_to_message_id=callback.message.message_id,
)
await callback.answer()
+13
View File
@@ -91,3 +91,16 @@ async def travels_callback(
)
await callback.answer()
@router.callback_query(
F.data == "menu_help",
RegisteredCallback(),
StateFilter(None),
)
async def help_callback(callback: CallbackQuery) -> None:
if not isinstance(callback.message, Message):
return
await callback.message.answer(messages.HELP_MESSAGE)
await callback.answer()
+300
View File
@@ -0,0 +1,300 @@
__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 RegisteredCallback
from app.keyboards.builders import notes_keyboard
from app.keyboards.note import get as notes_get
from app.models.travel import Note, Travel
from app.states.travel import (
CreateNoteState,
)
router = Router(name="menu_callback")
@router.callback_query(
F.data.startswith("travel_add_note"),
RegisteredCallback(),
StateFilter(None),
)
async def travel_add_note_callback(
callback: CallbackQuery,
state: FSMContext,
):
if (
callback.message is None
or callback.data is None
or not isinstance(callback.message, Message)
):
return
travel_id = int(callback.data.replace("travel_add_note_", ""))
travel = Travel.get_travel_by_id(travel_id)
if not travel or travel == []:
return
await state.set_state(CreateNoteState.file_id)
await state.update_data(travel_id=travel_id)
await callback.message.answer(
messages.ADD_NOTE,
)
await callback.answer()
@router.message(
CreateNoteState.file_id,
)
async def create_note_file_id(message: Message, state: FSMContext):
if message.from_user is None:
return
if message.text == "/cancel":
await message.answer(
messages.ACTION_CANCELED,
)
await state.update_data()
await message.delete()
await state.clear()
return
if message.photo is None and message.document is None:
return
if message.photo is not None:
await state.update_data(
file_type="photo",
file_id=message.photo[-1].file_id,
file_name="photo",
)
# await message.answer_photo(message.photo[-1].file_id)
elif message.document is not None:
await state.update_data(
file_type="document",
file_id=message.document.file_id,
file_name=message.document.file_name,
)
# await message.answer_document(message.document.file_id)
data = await state.get_data()
data["author_id"] = message.from_user.id
session.add(Note(**data))
session.commit()
await message.answer(
messages.NOTE_ADDED.format(file_name=data["file_name"]),
)
await state.clear()
@router.callback_query(
F.data.startswith("travel_notes_page"),
RegisteredCallback(),
StateFilter(None),
)
async def travel_notes_page_callback(
callback: CallbackQuery,
):
if (
callback.message is None
or callback.data is None
or not isinstance(callback.message, Message)
):
return
travel_id, page = map(
int,
callback.data.replace("travel_notes_page_", "").split("_"),
)
travel = Travel.get_travel_queryset_by_id(travel_id)
if not travel or travel == []:
return
travel = travel.first()
notes = Travel().get_notes(callback.from_user.id, travel, public=False)
pages = (len(notes) + Config.PAGE_SIZE - 1) // Config.PAGE_SIZE
try:
await callback.message.edit_text(
messages.NOTES,
reply_markup=notes_keyboard(notes, page, pages, travel.id),
)
except TelegramBadRequest:
pass
@router.callback_query(
F.data.startswith("travel_note_detail"),
RegisteredCallback(),
StateFilter(None),
)
async def travel_note_detail_callback(
callback: CallbackQuery,
):
if (
callback.message is None
or callback.data is None
or not isinstance(callback.message, Message)
):
return
note_id = int(callback.data.replace("travel_note_detail_", ""))
note = Note.get_note_by_id(note_id)
if not note or note == []:
return
try:
await callback.message.edit_text(
note.get_note_text(),
reply_markup=notes_get(travel_id=note.travel.id, note=note),
)
except TelegramBadRequest:
pass
@router.callback_query(
F.data.startswith("travel_notesend"),
RegisteredCallback(),
StateFilter(None),
)
async def travel_notesend_callback(
callback: CallbackQuery,
):
if (
callback.message is None
or callback.data is None
or not isinstance(callback.message, Message)
):
return
note_id = int(callback.data.replace("travel_notesend_", ""))
note = Note.get_note_by_id(note_id)
if not note or note == []:
return
if note.file_type == "photo":
await callback.message.answer_photo(
note.file_id,
reply_to_message_id=callback.message.message_id,
)
elif note.file_type == "document":
await callback.message.answer_document(
note.file_id,
reply_to_message_id=callback.message.message_id,
)
await callback.answer()
@router.callback_query(
F.data.startswith("travel_note_change_privacy"),
RegisteredCallback(),
StateFilter(None),
)
async def travel_note_change_privacy_callback(
callback: CallbackQuery,
state: FSMContext,
):
if (
callback.message is None
or callback.data is None
or not isinstance(callback.message, Message)
):
return
note_id = int(callback.data.replace("travel_note_change_privacy_", ""))
note = Note().get_note_by_id(note_id)
if not note or note == []:
return
if note.public:
note.public = False
else:
note.public = True
session.commit()
try:
await callback.message.edit_text(
note.get_note_text(),
reply_markup=notes_get(travel_id=note.travel.id, note=note),
)
except TelegramBadRequest:
pass
@router.callback_query(
F.data.startswith("travel_notedelete"),
RegisteredCallback(),
StateFilter(None),
)
async def travel_notedelete_callback(
callback: CallbackQuery,
):
if (
callback.message is None
or callback.data is None
or not isinstance(callback.message, Message)
):
return
note_id = int(callback.data.replace("travel_notedelete_", ""))
note = Note().get_note_queryset_by_id(note_id)
note_first = note.first()
file_name = note_first.file_name
travel = note_first.travel
if not note or note == []:
return
note.delete()
session.commit()
notes = Travel().get_notes(callback.from_user.id, travel, public=False)
pages = (len(notes) + Config.PAGE_SIZE - 1) // Config.PAGE_SIZE
try:
await callback.message.edit_text(
messages.NOTES,
reply_markup=notes_keyboard(notes, 0, pages, travel.id),
)
except TelegramBadRequest:
pass
await callback.message.answer(
messages.NOTE_DELETED.format(file_name=file_name),
)
+13 -2
View File
@@ -22,7 +22,7 @@ router = Router(name="profile_callback")
@router.callback_query(
F.data.startswith("profile_change_"),
F.data.startswith("profile_change"),
StateFilter(None),
RegisteredCallback(),
)
@@ -227,8 +227,12 @@ async def profile_change_entered(message: Message, state: FSMContext) -> None:
state_data = await state.get_data()
user = User.get_user_queryset_by_telegram_id(message.from_user.id)
user_first = user.first()
if isinstance(state_data["value"], list):
old_value = user_first.country + ", " + user_first.city
new_value = state_data["value"][0] + ", " + state_data["value"][1]
user.update(
{
"country": state_data["value"][0],
@@ -241,6 +245,9 @@ async def profile_change_entered(message: Message, state: FSMContext) -> None:
except TelegramBadRequest:
pass
else:
old_value = getattr(user.first(), str(column))
new_value = state_data["value"]
data = {state_data["column"]: state_data["value"]}
user.update(data)
@@ -260,7 +267,11 @@ async def profile_change_entered(message: Message, state: FSMContext) -> None:
pass
await message.answer(
messages.PROFILE_UPDATED,
messages.PROFILE_UPDATED.format(
key=state_data["column"],
old_value=old_value if old_value else messages.NOT_SET,
new_value=(new_value if new_value else messages.NOT_SET),
),
reply_markup=ReplyKeyboardRemove(),
)
+303
View File
@@ -0,0 +1,303 @@
__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.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="menu_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()