You've already forked Travel-Agent
chore: Added __init__ files, added fallback for callbacks, refactoring & improvements
This commit is contained in:
+14
-22
@@ -6,17 +6,8 @@ from aiogram import Bot, Dispatcher
|
|||||||
from aiogram.enums import ParseMode
|
from aiogram.enums import ParseMode
|
||||||
from aiogram.fsm.storage.redis import RedisStorage
|
from aiogram.fsm.storage.redis import RedisStorage
|
||||||
|
|
||||||
from app.callbacks import location, menu, notes, profile, travel
|
from app import callbacks, handlers, middlewares
|
||||||
from app.config import Config
|
from app.config import Config
|
||||||
from app.handlers import (
|
|
||||||
create_travel_command,
|
|
||||||
help_command,
|
|
||||||
menu_command,
|
|
||||||
profile_command,
|
|
||||||
start_command,
|
|
||||||
travels_command,
|
|
||||||
)
|
|
||||||
from app.middlewares.throttling import ThrottlingMiddleware
|
|
||||||
|
|
||||||
|
|
||||||
async def main() -> None:
|
async def main() -> None:
|
||||||
@@ -29,20 +20,21 @@ async def main() -> None:
|
|||||||
dp = Dispatcher(storage=storage)
|
dp = Dispatcher(storage=storage)
|
||||||
bot = Bot(bot_token, parse_mode=ParseMode.HTML)
|
bot = Bot(bot_token, parse_mode=ParseMode.HTML)
|
||||||
|
|
||||||
dp.message.middleware(ThrottlingMiddleware(0.5))
|
dp.message.middleware(middlewares.throttling.ThrottlingMiddleware(0.5))
|
||||||
|
|
||||||
dp.include_routers(
|
dp.include_routers(
|
||||||
start_command.router,
|
handlers.start_command.router,
|
||||||
help_command.router,
|
handlers.help_command.router,
|
||||||
menu_command.router,
|
handlers.menu_command.router,
|
||||||
profile_command.router,
|
handlers.profile_command.router,
|
||||||
create_travel_command.router,
|
handlers.create_travel_command.router,
|
||||||
travels_command.router,
|
handlers.travels_command.router,
|
||||||
menu.router,
|
callbacks.menu.router,
|
||||||
profile.router,
|
callbacks.profile.router,
|
||||||
travel.router,
|
callbacks.travel.router,
|
||||||
location.router,
|
callbacks.location.router,
|
||||||
notes.router,
|
callbacks.notes.router,
|
||||||
|
callbacks.fallback.router,
|
||||||
)
|
)
|
||||||
|
|
||||||
await bot.delete_webhook(drop_pending_updates=True)
|
await bot.delete_webhook(drop_pending_updates=True)
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
__all__ = ("fallback", "location", "menu", "profile", "travel", "notes")
|
||||||
|
|
||||||
|
from app.callbacks import fallback, location, menu, notes, profile, travel
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
__all__ = ("router",)
|
||||||
|
|
||||||
|
from aiogram import Router
|
||||||
|
from aiogram.filters import StateFilter
|
||||||
|
from aiogram.types import CallbackQuery
|
||||||
|
|
||||||
|
router = Router(name="fallback_callback")
|
||||||
|
|
||||||
|
|
||||||
|
@router.callback_query(~StateFilter(None))
|
||||||
|
async def in_state_callback(callback: CallbackQuery):
|
||||||
|
await callback.answer("Fallback text in state", show_alert=True)
|
||||||
|
|
||||||
|
|
||||||
|
@router.callback_query()
|
||||||
|
async def fallback_callback(callback: CallbackQuery):
|
||||||
|
await callback.answer("Fallback text", show_alert=True)
|
||||||
+29
-7
@@ -17,7 +17,7 @@ from app.states.travel import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
router = Router(name="menu_callback")
|
router = Router(name="notes_callback")
|
||||||
|
|
||||||
|
|
||||||
@router.callback_query(
|
@router.callback_query(
|
||||||
@@ -110,12 +110,26 @@ async def create_note_file_id(message: Message, state: FSMContext):
|
|||||||
|
|
||||||
data["author_id"] = message.from_user.id
|
data["author_id"] = message.from_user.id
|
||||||
|
|
||||||
session.add(Note(**data))
|
note = Note(**data)
|
||||||
|
|
||||||
|
session.add(note)
|
||||||
|
|
||||||
session.commit()
|
session.commit()
|
||||||
|
|
||||||
|
if not note or note == []:
|
||||||
|
return
|
||||||
|
|
||||||
|
if note.file_type == "photo":
|
||||||
|
file_name = f"Photo ID: {note.id}"
|
||||||
|
elif note.file_type == "video":
|
||||||
|
file_name = f"Video ID: {note.id}"
|
||||||
|
elif note.file_type == "voice":
|
||||||
|
file_name = f"Voice ID: {note.id}"
|
||||||
|
else:
|
||||||
|
file_name = note.file_name
|
||||||
|
|
||||||
await message.answer(
|
await message.answer(
|
||||||
messages.NOTE_ADDED.format(file_name=data["file_name"]),
|
messages.NOTE_ADDED.format(file_name=file_name),
|
||||||
)
|
)
|
||||||
|
|
||||||
await state.clear()
|
await state.clear()
|
||||||
@@ -299,13 +313,21 @@ async def travel_notedelete_callback(
|
|||||||
|
|
||||||
note = Note().get_note_queryset_by_id(note_id)
|
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 == []:
|
if not note or note == []:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
note_first = note.first()
|
||||||
|
travel = note_first.travel
|
||||||
|
|
||||||
|
if note_first.file_type == "photo":
|
||||||
|
file_name = f"Photo ID: {note_first.id}"
|
||||||
|
elif note_first.file_type == "video":
|
||||||
|
file_name = f"Video ID: {note_first.id}"
|
||||||
|
elif note_first.file_type == "voice":
|
||||||
|
file_name = f"Voice ID: {note_first.id}"
|
||||||
|
else:
|
||||||
|
file_name = note_first.file_name
|
||||||
|
|
||||||
note.delete()
|
note.delete()
|
||||||
|
|
||||||
session.commit()
|
session.commit()
|
||||||
|
|||||||
+34
-1
@@ -11,6 +11,7 @@ from app.config import Config
|
|||||||
from app.filters.user import Registered, RegisteredCallback
|
from app.filters.user import Registered, RegisteredCallback
|
||||||
from app.keyboards.builders import travels_keyboard
|
from app.keyboards.builders import travels_keyboard
|
||||||
from app.keyboards.travel import get as travel_get
|
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.travel import Travel
|
||||||
from app.models.user import User
|
from app.models.user import User
|
||||||
from app.states.travel import (
|
from app.states.travel import (
|
||||||
@@ -19,7 +20,7 @@ from app.states.travel import (
|
|||||||
from app.utils.states import delete_message_from_state, handle_validation_error
|
from app.utils.states import delete_message_from_state, handle_validation_error
|
||||||
|
|
||||||
|
|
||||||
router = Router(name="menu_callback")
|
router = Router(name="travel_callback")
|
||||||
|
|
||||||
|
|
||||||
@router.callback_query(
|
@router.callback_query(
|
||||||
@@ -301,3 +302,35 @@ async def delete_travel_callback(
|
|||||||
)
|
)
|
||||||
|
|
||||||
await callback.answer()
|
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()
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
__all__ = (
|
||||||
|
"start_command",
|
||||||
|
"help_command",
|
||||||
|
"menu_command",
|
||||||
|
"profile_command",
|
||||||
|
"create_travel_command",
|
||||||
|
"travels_command",
|
||||||
|
)
|
||||||
|
|
||||||
|
from app.handlers import (
|
||||||
|
create_travel_command,
|
||||||
|
help_command,
|
||||||
|
menu_command,
|
||||||
|
profile_command,
|
||||||
|
start_command,
|
||||||
|
travels_command,
|
||||||
|
)
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
__all__ = ("get",)
|
||||||
|
|
||||||
|
from aiogram import types
|
||||||
|
from aiogram.utils.keyboard import InlineKeyboardBuilder
|
||||||
|
|
||||||
|
from app.models.travel import Travel
|
||||||
|
from app.utils.geo import get_location_by_name
|
||||||
|
from app.utils.map import get_url_map
|
||||||
|
|
||||||
|
|
||||||
|
def get(travel: Travel):
|
||||||
|
locations = Travel().get_sorted_locations(travel, asc=False)
|
||||||
|
coordinats = []
|
||||||
|
|
||||||
|
for location in locations:
|
||||||
|
geocode = get_location_by_name(location.location)
|
||||||
|
coordinats.append(
|
||||||
|
[geocode[1].raw.get("lat"), geocode[1].raw.get("lon")],
|
||||||
|
)
|
||||||
|
|
||||||
|
builder = InlineKeyboardBuilder()
|
||||||
|
|
||||||
|
builder.row(
|
||||||
|
types.InlineKeyboardButton(
|
||||||
|
text="🗺️ Route by car",
|
||||||
|
web_app=types.WebAppInfo(
|
||||||
|
url=get_url_map(
|
||||||
|
coordinats=coordinats,
|
||||||
|
profile="car",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
builder.row(
|
||||||
|
types.InlineKeyboardButton(
|
||||||
|
text="🗺️ Route on foot",
|
||||||
|
web_app=types.WebAppInfo(
|
||||||
|
url=get_url_map(
|
||||||
|
coordinats=coordinats,
|
||||||
|
profile="foot",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
builder.row(
|
||||||
|
types.InlineKeyboardButton(
|
||||||
|
text="🗺️ Route by bike",
|
||||||
|
web_app=types.WebAppInfo(
|
||||||
|
url=get_url_map(
|
||||||
|
coordinats=coordinats,
|
||||||
|
profile="bike",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
builder.row(
|
||||||
|
types.InlineKeyboardButton(
|
||||||
|
text="⬅️",
|
||||||
|
callback_data=f"travel_detail_{travel.id}",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
return builder.as_markup()
|
||||||
+4
-78
@@ -4,20 +4,9 @@ from aiogram import types
|
|||||||
from aiogram.utils.keyboard import InlineKeyboardBuilder
|
from aiogram.utils.keyboard import InlineKeyboardBuilder
|
||||||
|
|
||||||
from app.models.travel import Travel
|
from app.models.travel import Travel
|
||||||
from app.utils.geo import get_location_by_name
|
|
||||||
from app.utils.map import get_url_map
|
|
||||||
|
|
||||||
|
|
||||||
def get(travel: Travel):
|
def get(travel: Travel):
|
||||||
locations = Travel().get_sorted_locations(travel, asc=False)
|
|
||||||
coordinats = []
|
|
||||||
|
|
||||||
for location in locations:
|
|
||||||
geocode = get_location_by_name(location.location)
|
|
||||||
coordinats.append(
|
|
||||||
[geocode[1].raw.get("lat"), geocode[1].raw.get("lon")],
|
|
||||||
)
|
|
||||||
|
|
||||||
builder = InlineKeyboardBuilder()
|
builder = InlineKeyboardBuilder()
|
||||||
|
|
||||||
builder.row(
|
builder.row(
|
||||||
@@ -62,35 +51,8 @@ def get(travel: Travel):
|
|||||||
)
|
)
|
||||||
builder.row(
|
builder.row(
|
||||||
types.InlineKeyboardButton(
|
types.InlineKeyboardButton(
|
||||||
text="🗺️ Route by car",
|
text="🗺️ Routes",
|
||||||
web_app=types.WebAppInfo(
|
callback_data=f"travel_routes_{travel.id}",
|
||||||
url=get_url_map(
|
|
||||||
coordinats=coordinats,
|
|
||||||
profile="car",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
builder.row(
|
|
||||||
types.InlineKeyboardButton(
|
|
||||||
text="🗺️ Route on foot",
|
|
||||||
web_app=types.WebAppInfo(
|
|
||||||
url=get_url_map(
|
|
||||||
coordinats=coordinats,
|
|
||||||
profile="foot",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
builder.row(
|
|
||||||
types.InlineKeyboardButton(
|
|
||||||
text="🗺️ Route by bike",
|
|
||||||
web_app=types.WebAppInfo(
|
|
||||||
url=get_url_map(
|
|
||||||
coordinats=coordinats,
|
|
||||||
profile="bike",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
builder.row(
|
builder.row(
|
||||||
@@ -110,15 +72,6 @@ def get(travel: Travel):
|
|||||||
|
|
||||||
|
|
||||||
def get_public(travel: Travel):
|
def get_public(travel: Travel):
|
||||||
locations = Travel().get_sorted_locations(travel, asc=False)
|
|
||||||
coordinats = []
|
|
||||||
|
|
||||||
for location in locations:
|
|
||||||
geocode = get_location_by_name(location.location)
|
|
||||||
coordinats.append(
|
|
||||||
[geocode[1].raw.get("lat"), geocode[1].raw.get("lon")],
|
|
||||||
)
|
|
||||||
|
|
||||||
builder = InlineKeyboardBuilder()
|
builder = InlineKeyboardBuilder()
|
||||||
|
|
||||||
builder.row(
|
builder.row(
|
||||||
@@ -145,35 +98,8 @@ def get_public(travel: Travel):
|
|||||||
)
|
)
|
||||||
builder.row(
|
builder.row(
|
||||||
types.InlineKeyboardButton(
|
types.InlineKeyboardButton(
|
||||||
text="🗺️ Route by car",
|
text="🗺️ Routes",
|
||||||
web_app=types.WebAppInfo(
|
callback_data=f"travel_routes_{travel.id}",
|
||||||
url=get_url_map(
|
|
||||||
coordinats=coordinats,
|
|
||||||
profile="car",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
builder.row(
|
|
||||||
types.InlineKeyboardButton(
|
|
||||||
text="🗺️ Route on foot",
|
|
||||||
web_app=types.WebAppInfo(
|
|
||||||
url=get_url_map(
|
|
||||||
coordinats=coordinats,
|
|
||||||
profile="foot",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
builder.row(
|
|
||||||
types.InlineKeyboardButton(
|
|
||||||
text="🗺️ Route by bike",
|
|
||||||
web_app=types.WebAppInfo(
|
|
||||||
url=get_url_map(
|
|
||||||
coordinats=coordinats,
|
|
||||||
profile="bike",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
builder.row(
|
builder.row(
|
||||||
|
|||||||
+106
-29
@@ -1,10 +1,24 @@
|
|||||||
# flake8: noqa
|
# flake8: noqa
|
||||||
|
|
||||||
|
# Menu
|
||||||
MENU = "<b>Menu:</b>"
|
MENU = "<b>Menu:</b>"
|
||||||
|
|
||||||
|
# Notes
|
||||||
NOTES = "📝 <b>Notes:</b>\n"
|
NOTES = "📝 <b>Notes:</b>\n"
|
||||||
NOTE_DETAIL = "📝 <b>Note detail:</b>\n\n\tFile name: <b>{file_name}</b>\n\tFile type: <b>{file_type}</b>\n\tPublic: <b>{public}</b>"
|
NOTE_DETAIL = (
|
||||||
|
"📝 <b>Note detail:</b>\n\n"
|
||||||
|
"\tFile name: <b>{file_name}</b>\n"
|
||||||
|
"\tFile type: <b>{file_type}</b>\n"
|
||||||
|
"\tPublic: <b>{public}</b>"
|
||||||
|
)
|
||||||
|
ADD_NOTE = (
|
||||||
|
"✏️ Send me a file, photo, video, or voice message to add a note."
|
||||||
|
"\n<i>Enter /cancel to cancel creating.</i>"
|
||||||
|
)
|
||||||
NOTE_ADDED = "✅ Note <b>{file_name}</b> added successfully."
|
NOTE_ADDED = "✅ Note <b>{file_name}</b> added successfully."
|
||||||
NOTE_DELETED = "❌ Note <b>{file_name}</b> deleted."
|
NOTE_DELETED = "❌ Note <b>{file_name}</b> deleted."
|
||||||
|
|
||||||
|
# Locations
|
||||||
LOCATIONS = "🗺️ <b>Locations:</b>"
|
LOCATIONS = "🗺️ <b>Locations:</b>"
|
||||||
LOCATION_DELETED = "❌ Location deleted."
|
LOCATION_DELETED = "❌ Location deleted."
|
||||||
LOCATION_DETAIL = (
|
LOCATION_DETAIL = (
|
||||||
@@ -16,48 +30,77 @@ LOCATION_DETAIL = (
|
|||||||
LOCATION_WEATHER = (
|
LOCATION_WEATHER = (
|
||||||
"🌤️ <b>{location} weather:</b>\n\n"
|
"🌤️ <b>{location} weather:</b>\n\n"
|
||||||
"\t<b>☁️ Weather:</b> {weather_main}\n"
|
"\t<b>☁️ Weather:</b> {weather_main}\n"
|
||||||
"\t<b>🌡️ Current tempurature:</b> {temp} °C\n"
|
"\t<b>🌡️ Current temperature:</b> {temp} °C\n"
|
||||||
"\t<b>🤗 Feels like:</b> {feels_like} °C\n"
|
"\t<b>🤗 Feels like:</b> {feels_like} °C\n"
|
||||||
"\t<b>❄️ Min. tempurature:</b> {temp_min} °C\n"
|
"\t<b>❄️ Min. temperature:</b> {temp_min} °C\n"
|
||||||
"\t<b>🔥 Max. tempurature:</b> {temp_max} °C\n"
|
"\t<b>🔥 Max. temperature:</b> {temp_max} °C\n"
|
||||||
"\t<b>⬇️ Pressure:</b> {pressure} hektopascals\n"
|
"\t<b>⬇️ Pressure:</b> {pressure} hektopascals\n"
|
||||||
"\t<b>💨 Humidity:</b> {humidity}%\n"
|
"\t<b>💨 Humidity:</b> {humidity}%\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Sights
|
||||||
SIGHTS_HEADER = "🗺️ <b>Sights:</b>\n"
|
SIGHTS_HEADER = "🗺️ <b>Sights:</b>\n"
|
||||||
SIGHTS_FOOTER = "Found {sights_count} sights within {distance} m from: <b>{location}</b>."
|
SIGHTS_FOOTER = (
|
||||||
|
"Found {sights_count} sights within {distance} m from: <b>{location}</b>."
|
||||||
|
)
|
||||||
NO_SIGHTS_FOUND = (
|
NO_SIGHTS_FOUND = (
|
||||||
"No sights found within {distance} m from: <b>{location}</b>."
|
"No sights found within {distance} m from: <b>{location}</b>."
|
||||||
)
|
)
|
||||||
SIGHT_DETAIL = "🗺️ <b>Sight detail:</b>\n\n"
|
SIGHT_DETAIL = "🗺️ <b>Sight detail:</b>\n\n"
|
||||||
CREATE_LOCATION = "✈️ Lets create new location!"
|
|
||||||
ENTER_LOCATION = "Enter location:\n<i>Format: country, city, ... etc</i>\n<i>Example: Kremlin, Moscow, Russia</i>\n<i>Enter /cancel to cancel creating.</i>"
|
# Location Creation
|
||||||
|
CREATE_LOCATION = "✈️ Lets create a new location!"
|
||||||
|
ENTER_LOCATION = (
|
||||||
|
"Enter location:\n"
|
||||||
|
"<i>Format: country, city, ... etc</i>\n"
|
||||||
|
"<i>Example: Kremlin, Moscow, Russia</i>\n"
|
||||||
|
"<i>Enter /cancel to cancel creating.</i>"
|
||||||
|
)
|
||||||
CONFIRM_LOCATION = "Is this location correct: <b>{location}</b>?"
|
CONFIRM_LOCATION = "Is this location correct: <b>{location}</b>?"
|
||||||
CONFIRMATION_REEJECTED = (
|
CONFIRMATION_REJECTED = (
|
||||||
"❌ Confirmation rejected. Please re-enter the location."
|
"❌ Confirmation rejected. Please re-enter the location."
|
||||||
)
|
)
|
||||||
OVERLAPPING_LOCATION = "Dates overlap with another location in the same travel(enter /cancel if you cant fix this)."
|
OVERLAPPING_LOCATION = "Dates overlap with another location in the same travel(enter /cancel if you can't fix this)."
|
||||||
ENTER_LOCATION_DATE_START = "Enter location start datetime(in UTC) in this format:\n<i>Format: YYYY-MM-DD HH:MM</i>\n<i>Example: 2022-01-01 00:00</i>"
|
ENTER_LOCATION_DATE_START = (
|
||||||
ENTER_LOCATION_DATE_END = "Enter location end datetime(in UTC) in this format:\n<i>Format: YYYY-MM-DD HH:MM</i>\n<i>Example: 2022-01-01 00:00</i>"
|
"Enter location start datetime(in UTC) in this format:\n"
|
||||||
|
"<i>Format: YYYY-MM-DD HH:MM</i>\n"
|
||||||
|
"<i>Example: 2022-01-01 00:00</i>"
|
||||||
|
)
|
||||||
|
ENTER_LOCATION_DATE_END = (
|
||||||
|
"Enter location end datetime(in UTC) in this format:\n"
|
||||||
|
"<i>Format: YYYY-MM-DD HH:MM</i>\n"
|
||||||
|
"<i>Example: 2022-01-01 00:00>"
|
||||||
|
)
|
||||||
INVALID_DATE_END = "End date can't be earlier or equal to start date."
|
INVALID_DATE_END = "End date can't be earlier or equal to start date."
|
||||||
LOCATION_ADDED = "✅ Location added"
|
LOCATION_ADDED = "✅ Location added"
|
||||||
|
|
||||||
ADD_NOTE = "✏️ Send me file, photo, video or voice nessage to add note.\n<i>Enter /cancel to cancel creating.</i>"
|
# Travel Management
|
||||||
|
|
||||||
DELETED_TRAVEL = "✅ Travel deleted"
|
DELETED_TRAVEL = "✅ Travel deleted"
|
||||||
TRAVELS = "📃 <b>Travels:</b>\n<i>👑 - owner</i>"
|
TRAVELS = (
|
||||||
|
"📃 <b>Travels:</b>"
|
||||||
|
"\n<i>👑 - owner</i>"
|
||||||
|
)
|
||||||
NO_TRAVELS = "No travels yet. You can create one with /create_travel command."
|
NO_TRAVELS = "No travels yet. You can create one with /create_travel command."
|
||||||
CREATE_TRAVEL = (
|
CREATE_TRAVEL = (
|
||||||
"🧳 Let's create new travel!\n<i>Enter /cancel to cancel creating.</i>"
|
"🧳 Let's create a new travel!\n"
|
||||||
|
"<i>Enter /cancel to cancel creating.</i>"
|
||||||
)
|
)
|
||||||
TRAVEL_UPDATED = "✅ Travel updated"
|
TRAVEL_UPDATED = "✅ Travel updated"
|
||||||
EDIT_TRAVEL_DESCRIPTION = "Enter travel description (enter /skip if you want to set it to None):\n<i>Maximum length: 100 characters</i>"
|
EDIT_TRAVEL_DESCRIPTION = (
|
||||||
|
"Enter travel description (enter /skip if you want to set it to None):\n"
|
||||||
|
"<i>Maximum length: 100 characters</i>"
|
||||||
|
)
|
||||||
INPUT_TRAVEL_TITLE = (
|
INPUT_TRAVEL_TITLE = (
|
||||||
"Enter travel title:\n<i>Maximum length: 30 characters</i>"
|
"Enter travel title:\n"
|
||||||
|
"<i>Maximum length: 30 characters</i>"
|
||||||
)
|
)
|
||||||
INPUT_TRAVEL_CALLBACK = (
|
INPUT_TRAVEL_CALLBACK = (
|
||||||
"All right, travel <b>{key}</b> is set to: <b>{value}</b>"
|
"All right, travel <b>{key}</b> is set to: <b>{value}</b>"
|
||||||
)
|
)
|
||||||
INPUT_TRAVEL_DESCRIPTION = "Enter travel description (enter /skip if you want to skip this step):\n<i>Maximum length: 100 characters</i>"
|
INPUT_TRAVEL_DESCRIPTION = (
|
||||||
|
"Enter travel description (enter /skip if you want to skip this step):\n"
|
||||||
|
"<i>Maximum length: 100 characters</i>"
|
||||||
|
)
|
||||||
INPUT_TRAVEL_DESCRIPTION_SKIPPED = "✅ Sure. You can always fill it later."
|
INPUT_TRAVEL_DESCRIPTION_SKIPPED = "✅ Sure. You can always fill it later."
|
||||||
TRAVEL_CREATED = "Travel <b>{title}</b> successfully created! You can now view and edit it in the travels list (/travels command)."
|
TRAVEL_CREATED = "Travel <b>{title}</b> successfully created! You can now view and edit it in the travels list (/travels command)."
|
||||||
ACTION_CANCELED = "❌ Action canceled"
|
ACTION_CANCELED = "❌ Action canceled"
|
||||||
@@ -68,11 +111,12 @@ TRAVEL_DETAIL = (
|
|||||||
"\tDescription: <b>{description}</b>\n"
|
"\tDescription: <b>{description}</b>\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# User Interaction
|
||||||
WELCOME_MESSAGE = "Hello, <b>{name}</b>! Welcome to the ✈️ Travel Agent bot! Let's start our journey by filling out some information about you."
|
WELCOME_MESSAGE = "Hello, <b>{name}</b>! Welcome to the ✈️ Travel Agent bot! Let's start our journey by filling out some information about you."
|
||||||
WELCOME_AGAIN_MESSAGE = "Hello, <b>{name}</b>! Welcome back to the ✈️ Travel Agent bot! If you get lost, you can always call the /help command for assistance."
|
WELCOME_AGAIN_MESSAGE = "Hello, <b>{name}</b>! Welcome back to the ✈️ Travel Agent bot! If you get lost, you can always call the /help command for assistance."
|
||||||
|
|
||||||
HELP_MESSAGE = (
|
HELP_MESSAGE = (
|
||||||
"Welcome to the ✈️ Travel Agent bot! Here is list of commands you can use:\n\n"
|
"Welcome to the ✈️ Travel Agent bot! Here is a list of commands you can use:\n\n"
|
||||||
"/start - Start the bot\n"
|
"/start - Start the bot\n"
|
||||||
"/help - Show this message\n"
|
"/help - Show this message\n"
|
||||||
"/menu - Show the main menu\n"
|
"/menu - Show the main menu\n"
|
||||||
@@ -83,18 +127,39 @@ HELP_MESSAGE = (
|
|||||||
"❓ If you have any questions/issues, feel free to contact us via @itq_travel_agent_support_bot on Telegram."
|
"❓ If you have any questions/issues, feel free to contact us via @itq_travel_agent_support_bot on Telegram."
|
||||||
)
|
)
|
||||||
|
|
||||||
REGISTERED_MESSAGE = "You have successfully registered. Welcome to the ✈️ Travel Agent bot! \nYou can view and edit your profile using the /profile command."
|
REGISTERED_MESSAGE = (
|
||||||
|
"You have successfully registered. Welcome to the ✈️ Travel Agent bot!\n"
|
||||||
|
"You can view and edit your profile using the /profile command."
|
||||||
|
)
|
||||||
|
|
||||||
INPUT_USERNAME = "Enter your username (this will be used to interact with other users):\n<i>Allowed characters: a-z, A-Z, 0-9, _</i>\n<i>Length: 5-20 characters</i>"
|
INPUT_USERNAME = (
|
||||||
INPUT_AGE = "Enter your age:\n<i>Range: 13-120</i>"
|
"Enter your username (this will be used to interact with other users):\n"
|
||||||
INPUT_SEX = "Enter your sex:\n<i>Options: Male or Female</i>"
|
"<i>Allowed characters: a-z, A-Z, 0-9, _</i>\n"
|
||||||
INPUT_BIO = "Enter your bio (enter /skip if you want to skip this step):\n<i>Maximum length: 100 characters</i>"
|
"<i>Length: 5-20 characters</i>"
|
||||||
|
)
|
||||||
|
INPUT_AGE = (
|
||||||
|
"Enter your age:\n"
|
||||||
|
"<i>Range: 13-120</i>"
|
||||||
|
)
|
||||||
|
INPUT_SEX = (
|
||||||
|
"Enter your sex:\n"
|
||||||
|
"<i>Options: Male or Female</i>"
|
||||||
|
)
|
||||||
|
INPUT_BIO = (
|
||||||
|
"Enter your bio (enter /skip if you want to skip this step):\n"
|
||||||
|
"<i>Maximum length: 100 characters</i>"
|
||||||
|
)
|
||||||
INPUT_BIO_SKIPPED = "✅ Sure. You can always fill it later."
|
INPUT_BIO_SKIPPED = "✅ Sure. You can always fill it later."
|
||||||
INPUT_LOCATION = "Enter your location in this format:\n<i>Format: country, city</i>\n<i>Example: Russia, Moscow</i>"
|
INPUT_LOCATION = (
|
||||||
|
"Enter your location in this format:\n"
|
||||||
|
"<i>Format: country, city</i>\n"
|
||||||
|
"<i>Example: Russia, Moscow</i>"
|
||||||
|
)
|
||||||
INPUT_CALLBACK = "✅ All right, your <b>{key}</b> is set to: <b>{value}</b>"
|
INPUT_CALLBACK = "✅ All right, your <b>{key}</b> is set to: <b>{value}</b>"
|
||||||
VALIDATION_ERROR = "❌ Invalid input. Please try again."
|
VALIDATION_ERROR = "❌ Invalid input. Please try again."
|
||||||
CANCEL_CHANGE = "<i>Enter /cancel to cancel change.</i>"
|
CANCEL_CHANGE = "<i>Enter /cancel to cancel change.</i>"
|
||||||
|
|
||||||
|
# User Profile
|
||||||
PROFILE = (
|
PROFILE = (
|
||||||
"<b>👤 Your profile:</b>\n\n"
|
"<b>👤 Your profile:</b>\n\n"
|
||||||
"\tUsername: <b>{username}</b>\n"
|
"\tUsername: <b>{username}</b>\n"
|
||||||
@@ -106,9 +171,21 @@ PROFILE = (
|
|||||||
"\tDate joined: <b>{date_joined} UTC</b>\n"
|
"\tDate joined: <b>{date_joined} UTC</b>\n"
|
||||||
)
|
)
|
||||||
NOT_SET = "<i>Not set</i>"
|
NOT_SET = "<i>Not set</i>"
|
||||||
EDIT_USERNAME = "Enter your username:\n<i>Allowed characters: a-z, A-Z, 0-9, _</i>\n<i>Length: 5-20 characters</i>"
|
EDIT_USERNAME = (
|
||||||
EDIT_BIO = "Enter your bio (enter /skip if you want to set it to None):\n<i>Maximum length: 100 characters</i>"
|
"Enter your username:\n"
|
||||||
PROFILE_UPDATED = "✅ Profile {key} updated\n\t<i>Old value: {old_value}</i>\n\t<i>New value: {new_value}</i>"
|
"<i>Allowed characters: a-z, A-Z, 0-9, _</i>\n"
|
||||||
|
"<i>Length: 5-20 characters</i>"
|
||||||
|
)
|
||||||
|
EDIT_BIO = (
|
||||||
|
"Enter your bio (enter /skip if you want to set it to None):\n"
|
||||||
|
"<i>Maximum length: 100 characters</i>"
|
||||||
|
)
|
||||||
|
PROFILE_UPDATED = (
|
||||||
|
"✅ Profile {key} updated\n"
|
||||||
|
"\t<i>Old value: {old_value}</i>\n"
|
||||||
|
"\t<i>New value: {new_value}</i>"
|
||||||
|
)
|
||||||
CHANGE_CANCELED = "❌ Change canceled"
|
CHANGE_CANCELED = "❌ Change canceled"
|
||||||
|
|
||||||
PROCCESSING = "⌛️ Processing..."
|
# Processing
|
||||||
|
PROCESSING = "⌛️ Processing..."
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
__all__ = ("throttling",)
|
||||||
|
|
||||||
|
from app.middlewares import throttling
|
||||||
@@ -243,7 +243,7 @@ class Note(Base):
|
|||||||
def get_note_text(self):
|
def get_note_text(self):
|
||||||
return messages.NOTE_DETAIL.format(
|
return messages.NOTE_DETAIL.format(
|
||||||
file_name=self.file_name,
|
file_name=self.file_name,
|
||||||
file_type=self.file_type,
|
file_type=self.file_type.capitalize(),
|
||||||
public="Yes" if self.public else "No",
|
public="Yes" if self.public else "No",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user