Сценарий работы, схему бд и архитектуру проекта можно посмотреть на миро
-
Склонируйте репозиторий и перейдите в него
git clone https://github.com/Central-University-IT-prod/backend-K1rL3s.git cd ./backend-K1rL3s
-
Запустите бота через docker compose
(должен быть установлен движок)docker compose up -d
Для работы проекта я выделил 5 контейнеров (сервисов):
-
СУБД PostgreSQL (database)
Постгресу было отдано предпочтение вместо sqlite'а, так как с ним удобнее взаимодействовать в ручном режиме, когда идёт разработка.
-
СУБД Redis (redis)
Редис был добавлен для сохранения данных состояния пользователей в независимом от бота места.
-
Фласк сервер (route)
Создание изображения с маршрутом использует
Pillow
иrequests
, синхронная работа которого будет намертво тормозить асинхронного бота.
Поэтому было принято решение о вынесении создания изображения в отдельный контейнер (процесс). -
Миграции (migrations)
Контейнер запускается, прогоняет миграции и выключается. Это немного, но это честная работа.
-
Бот (bot)
Сам бот, в котором и происходит общение с телегой и управление всем-всем.
❗ Возможный костыль, за который я прошу прощения у проверяющего.
Хранилище для постгреса и редиса указано /var/prod/k1rles-bot/
(bind mount), так как при создании Docker Volume'а постгрес не может найти что-то и выходит с ошибкой.
Если вы используете докер не на винде, то не забудьте удалить эту директорию.
-
Откройте бота и отправьте
/start
-
Пройдите регистрацию (0:00 - 0:30)
-
Регистрация с геолокацией (8:07 - 8:33)
-
По желанию отредактируйте профиль (0:30 - 1:15)
-
Создайте своё первое путешествие (1:15 - 1:30)
-
По желанию отредактируйте его (1:30 - 1:56)
-
Добавьте локации в путешествии (1:56 - 3:12)
-
Геолокация при создании и изменении локаций (8:33 - 9:28)
-
Посмотрите прогноз погоды в локациях (7:45 - 8:07)
-
Посмотрите маршрут путешествия (3:12 - 3:23) \
-
Добавьте, отредактируйте и удалите заметки (3:23-4:25)
-
Пригласите своего друга, пусть он посмотрит всё (4:25 - 6:30)
-
Пригласите кого-то из рекомендованных (6:30 - 7:45)
-
Выйдите из чужого путешествия (9:28 - 9:46)
-
Бот при первом запуске запрашивает у пользователя имя, возраст, город и страну. После юзер может сменить любые указанные данные.
Создание и изменение профиля поддерживает как текстовый ввод города и страны, так и геолокацию телеграма. Без прохождения регистрации человек не может получить доступ к остальному функционалу бота. -
Юзер может создать, посмотреть, отредактировать и удалить путешествие и локации в своих путешествиях. Создание и изменение локаций поддерживает как текстовый ввод города и страны, так и геолокацию телеграма.
-
Юзер в любом путешествии, к которому он имеет доступ, может создать приватные (доступные только ему) и публичные (доступные всем в путешествии) заметки.
Бот поддерживает текст, фото, видео, документы, голосовые и кружочки. -
Владелец путешествия может создать пригласительную ссылку в своё приключение.
Пользователь, перешедший по ней, присоединяется к путешествию и может просматривать локации, публичные заметки и других участников. -
При создании и редактировании локаций сохраняются их координаты, которые после используются для прокладывания маршрута и создания изображения с ним.
Изображение делается долго :(
-
В каждой локации есть кнопка "Погода", по ней бот отправляет текущую погоду и прогноз через 5 дней.
-
Владелец путешествия может нажать на кнопку "Поиск путешественников", по которой бот найдёт юзеров, возраст которых отличается не более чем на 5 лет, и они живут в одном из городов путешествия или в одном городе с владельцем.
Бот сделает пригласительную ссылку, которую владелец должен будет отправить юзеру. Так они смогут познакомиться лучше в личных сообщениях :) -
Путешествия, локации, заметки, друзья и рекомендации выводятся страницами по 6 штук на странице.
Если чего-то больше шести, то появляются стрелочки для перехода по страницами
Постгрес - это объектно-реляционная система управления базами данных с открытым исходным кодом.
Он используется для хранения информации о пользователях, путешествиях, локациях, заметках и других данных, необходимых для работы бота.
Почему именно он?
- Открытый исходный код
- Высокая производительность
- Расширяемость и гибкость
- Надежность и отказоустойчивость
- Активное сообщество и поддержка
Редис - это резидентная система управления базами данных класса NoSQL с открытым исходным кодом.
Он используется для хранения данных состояний пользователей бота (например, последовательного ввода в диалогах).
Почему он?
- Открытый исходный код
- Молниеносная скорость (всё хранится в оперативной памяти)
- Простота использования
- Масштабируемость
GeoPy — это библиотека для Python, которая предоставляет удобный интерфейс для работы с гео-данными,
включая сервис геокодирования Nominatim с открытым исходным кодом, использующий данные OpenStreetMap.
Они помогают определять координаты городов и локаций, а также проверяют существование городов и стран, указываемые пользователями.
Почему они?
- Открытый исходный код
- Простота использования
- Достаточный функционал
Описание API
https://nominatim.openstreetmap.org/search?q={query}
query - название места в свободном формате
OpenWeather - сервис, предоставляющий HTTP API для получения погоды. В бесплатной версии даёт доступ к текущей погоде и прогнозу на 5 суток.
В боте отображается для каждой локации в путешествии можно посмотреть погоду на данный момент и прогноз через 5 дней.
Почему он?
- Понятная документация и простота использования
- Наличие бесплатного доступа
Описание API
Получения текущей погоды по координатам.
https://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&units={units}&lang={lang}&appid={API_KEY}
Получения прогноза погоды на 5 суток по координатам.
https://api.openweathermap.org/data/2.5/forecast?lat={lat}&lon={lon}&units={units}&lang={lang}&appid={API_KEY}
lat - широта, lon - долгота, appid - ключ апи, units - единицы измерения, lang - язык короткого описания погоды
GraphHopper - сервис, предоставляющий HTTP API для построения маршуртов. С его помощью фласк-сервер получает координаты промежуточных точек.
staticmap - библотека для Python, которая с помощью Tiles OSM создаёт изображение с указанными клиентом линиями. Библиотека используется фласк-сервом и готовое изображение отдаётся боту.
Почему они?
- Открытый исходный код (слава OSM!)
- Скорость работы (построение маршурта за пару секунд)
- Простота использования
Описание API
Построение маршрута, проходящий через переданные точки
curl -X POST -H "Content-Type: application/json" "https://graphhopper.com/api/1/route?key={API_KEY}" -d '{"elevation":false,"points":[[-0.087891,51.534377],[-0.090637,51.467697]],"profile":"car"}'
tzfpy и pytz - библиотеки для Python, упрощающие работу с таймзонами.
Почему они?
- Открытый исходный код
- Простота использования
- Скорость работы (tzfpy написан на Rust'е)
PostgreSQL
В проекте используются ruff, black и isort - линтеры, приводящие код к одному стилю.
Также установлен pre-commit, чтобы не забыть использовать всё перед отправкой на гитхаб.
В проекте бизнес-логика приложения отделена от бота, базы данных и гео-сервисов.
Для инверсии зависимостей используются абстрактные классы (тык, тык), определяющие интерфейс.
Для гео-сервисов написаны классы-адаптеры (тык).
Взаимодействие с базой данных реализует интерфейс репозиториев (тык).
Обо всех классах с конкретной реализацией известно только в DI мидлваре (тык), поэтому сервисы и хэндлеры ничего о них не знают и зависят только от интерфейсов.
- core - независимый, центральный слой
- bot - слой бота
- database - слой базы данных
- geo - слой реализации гео-сервисов