mirror of
https://github.com/EDeev/mospoly-helper.git
synced 2026-06-16 21:10:58 +03:00
release docs
This commit is contained in:
parent
8fbb128f03
commit
3dbffdce4a
1 changed files with 495 additions and 4 deletions
499
docs/README.md
499
docs/README.md
|
|
@ -1,5 +1,496 @@
|
|||
# Документация
|
||||
# Документация по проектной практике
|
||||
|
||||
- Папка для размещения документации по практике в формате Markdown.
|
||||
- README.md — основной файл с документацией, описывающий процесс выполнения практики.
|
||||
- При необходимости могут добавляться дополнительные файлы Markdown.
|
||||
## Реализация телеграм-бота "МосПолиХелпер"
|
||||
|
||||
В данном документе представлена подробная документация по разработке и реализации телеграм-бота "МосПолиХелпер" в рамках вариативной части проектной практики. Документ содержит детальное описание технических аспектов разработки, архитектурных решений, использованных технологий и методологий.
|
||||
|
||||
## Исследование предметной области
|
||||
|
||||
### Анализ проблемы навигации в кампусе
|
||||
|
||||
Перед началом разработки был проведен анализ существующей проблемы ориентирования в кампусах Московского Политехнического Университета. Основные выявленные сложности:
|
||||
|
||||
1. **Разнородность кампусов**:
|
||||
- Пять различных кампусов с уникальной планировкой
|
||||
- Отсутствие унифицированной системы навигации между корпусами
|
||||
|
||||
2. **Сложность обозначения кабинетов**:
|
||||
- Разные форматы нумерации в зависимости от корпуса
|
||||
- Неинтуитивные префиксы в обозначениях (например, "ав" для Автозаводской)
|
||||
|
||||
3. **Потребности пользователей**:
|
||||
- Новые студенты и сотрудники часто теряются в кампусе
|
||||
- Гости университета испытывают сложности при поиске аудиторий
|
||||
- Необходимость быстрого ориентирования при плотном расписании
|
||||
|
||||
### Обзор существующих решений
|
||||
|
||||
В рамках исследования были рассмотрены различные подходы к решению проблемы навигации:
|
||||
|
||||
1. **Статические карты и указатели**:
|
||||
- Недостаточно интерактивны
|
||||
- Не обеспечивают персонализированные маршруты
|
||||
|
||||
2. **Мобильные приложения с GPS-навигацией**:
|
||||
- Требуют специальной инфраструктуры для точного позиционирования внутри зданий
|
||||
- Высокая стоимость разработки и поддержки
|
||||
|
||||
3. **Текстовые инструкции**:
|
||||
- Сложны для восприятия без визуального сопровождения
|
||||
- Трудности с описанием сложных маршрутов
|
||||
|
||||
После анализа было принято решение разработать решение на базе Telegram, объединяющее доступность мессенджера и наглядность видеоинструкций.
|
||||
|
||||
## Архитектурное проектирование
|
||||
|
||||
### Определение требований
|
||||
|
||||
На основе проведенного анализа были сформулированы следующие функциональные и нефункциональные требования:
|
||||
|
||||
**Функциональные требования**:
|
||||
1. Предоставление интерфейса для выбора корпуса университета
|
||||
2. Возможность указать конкретный кабинет в соответствии с принятыми обозначениями
|
||||
3. Формирование видеомаршрута от территории кампуса или от входа в корпус
|
||||
4. Создание комбинированных маршрутов из отдельных видеофрагментов
|
||||
5. Кеширование сгенерированных маршрутов для оптимизации
|
||||
|
||||
**Нефункциональные требования**:
|
||||
1. Время отклика не более 5 секунд на запрос маршрута (при наличии в кеше)
|
||||
2. Максимальное время генерации нового маршрута не более 30 секунд
|
||||
3. Поддержка обработки до 100 одновременных пользователей
|
||||
4. Оптимизация видеоинструкций для минимизации объема данных
|
||||
5. Модульная архитектура для упрощения дальнейшего расширения
|
||||
|
||||
### Выбор технологического стека
|
||||
|
||||
Для реализации проекта были выбраны следующие технологии и инструменты:
|
||||
|
||||
1. **Python 3.10+**:
|
||||
- Высокоуровневый язык программирования с богатой экосистемой библиотек
|
||||
- Простота интеграции с различными API и сервисами
|
||||
- Наличие специализированных библиотек для обработки мультимедиа
|
||||
|
||||
2. **Aiogram 3.x**:
|
||||
- Асинхронный фреймворк для работы с Telegram Bot API
|
||||
- Поддержка современных паттернов разработки (FSM, роутеры)
|
||||
- Встроенная поддержка обработки интерактивных элементов интерфейса
|
||||
|
||||
3. **MoviePy**:
|
||||
- Библиотека для обработки видео на Python
|
||||
- Возможности для конкатенации, ускорения и модификации видеопотоков
|
||||
- Простой и понятный API для манипуляции видеофайлами
|
||||
|
||||
4. **JSON для хранения данных**:
|
||||
- Легковесный формат для хранения структурированной информации
|
||||
- Нативная поддержка в Python без дополнительных зависимостей
|
||||
- Достаточная производительность для данных объемов данных
|
||||
|
||||
### Проектирование модульной структуры
|
||||
|
||||
Для обеспечения масштабируемости и поддержки кода в будущем, была разработана модульная архитектура с четким разделением ответственности:
|
||||
|
||||
```
|
||||
src/code/
|
||||
├── bot.py # Точка входа в приложение
|
||||
├── config.py # Конфигурационные параметры
|
||||
├── database.py # Модуль работы с данными пользователя
|
||||
├── handlers.py # Обработчики команд и сообщений
|
||||
├── init.py # Инициализация компонентов бота
|
||||
└── scripts.py # Модуль обработки видео
|
||||
```
|
||||
|
||||
**Взаимодействие модулей**:
|
||||
|
||||
1. `bot.py` инициализирует приложение и подключает роутеры из `handlers.py`
|
||||
2. `init.py` настраивает экземпляр бота, используя конфигурацию из `config.py`
|
||||
3. `handlers.py` содержит логику обработки сообщений и вызывает функции из `scripts.py`
|
||||
4. `scripts.py` отвечает за обработку видео и использует путь из `database.py`
|
||||
5. `database.py` обеспечивает хранение и получение данных о пользовательских сессиях
|
||||
|
||||
## Реализация программных компонентов
|
||||
|
||||
### Модуль инициализации (init.py)
|
||||
|
||||
Модуль отвечает за настройку экземпляра бота, инициализацию диспетчера сообщений и подготовку команд меню:
|
||||
|
||||
```python
|
||||
from aiogram import Bot, Dispatcher
|
||||
from aiogram.enums.parse_mode import ParseMode
|
||||
from aiogram.fsm.storage.memory import MemoryStorage
|
||||
from aiogram.client.bot import DefaultBotProperties
|
||||
from aiogram.types import BotCommand, BotCommandScopeDefault
|
||||
from aiogram.methods import SetMyCommands
|
||||
|
||||
import config
|
||||
|
||||
# Структурированное определение команд для меню
|
||||
async def setup_bot_commands():
|
||||
commands = [
|
||||
BotCommand(command="help", description="Получить помощь"),
|
||||
BotCommand(command="route", description="Построить маршрут")
|
||||
]
|
||||
|
||||
await bot(SetMyCommands(
|
||||
commands=commands,
|
||||
scope=BotCommandScopeDefault()
|
||||
))
|
||||
|
||||
bot = Bot(token=config.BOT_TOKEN, default=DefaultBotProperties(parse_mode=ParseMode.HTML))
|
||||
dp = Dispatcher(storage=MemoryStorage())
|
||||
```
|
||||
|
||||
Использование `MemoryStorage` обеспечивает хранение состояний пользовательских сессий в оперативной памяти, что оптимально для данной задачи, учитывая относительно небольшое количество состояний.
|
||||
|
||||
### Модуль обработки маршрутов (scripts.py)
|
||||
|
||||
Ключевой модуль, отвечающий за формирование и обработку видеомаршрутов:
|
||||
|
||||
```python
|
||||
def get_routes(id_building: str, id_cab: str, other=False):
|
||||
"""
|
||||
Формирует список путей к видеофрагментам для маршрута.
|
||||
|
||||
Args:
|
||||
id_building: Идентификатор корпуса
|
||||
id_cab: Идентификатор кабинета
|
||||
other: Флаг для специальных случаев
|
||||
|
||||
Returns:
|
||||
list: Список путей к видеофрагментам
|
||||
"""
|
||||
# Логика определения путей к видеофрагментам
|
||||
# в зависимости от выбранного корпуса и кабинета
|
||||
|
||||
def make_full_clip(paths):
|
||||
"""
|
||||
Создает полный видеоклип из фрагментов маршрута.
|
||||
|
||||
Args:
|
||||
paths: Список путей к видеофрагментам
|
||||
|
||||
Returns:
|
||||
str: Путь к готовому видеоклипу или None в случае ошибки
|
||||
"""
|
||||
# Проверка наличия файлов
|
||||
if not all(os.path.exists(path) for path in paths):
|
||||
print("Некоторые файлы не найдены")
|
||||
return None
|
||||
|
||||
# Создание клипов из файлов
|
||||
clips = [VideoFileClip(path) for path in paths]
|
||||
|
||||
# Объединение клипов
|
||||
full_clip = concatenate_videoclips(clips)
|
||||
|
||||
# Оптимизация видео
|
||||
full_clip = full_clip.without_audio() # Удаление звука
|
||||
full_clip = full_clip.time_transform(lambda t: t * 1.5).with_duration(full_clip.duration / 1.5) # Ускорение в 1.5 раза
|
||||
full_clip = full_clip.resized(height=512) # Оптимизация размера
|
||||
|
||||
# Генерация имени выходного файла
|
||||
full_clip_name = f"{paths[-1][21:].replace('.mp4', '')}-{'all' if len(paths) == 3 else 'small'}.mp4"
|
||||
|
||||
# Рендеринг видео с оптимизированными параметрами
|
||||
full_clip.write_videofile(
|
||||
f"../data/cache/{full_clip_name}",
|
||||
fps=30,
|
||||
codec="libx264",
|
||||
bitrate="1500k",
|
||||
preset="fast",
|
||||
ffmpeg_params=["-crf", "23"]
|
||||
)
|
||||
|
||||
return f"../data/cache/{full_clip_name}"
|
||||
```
|
||||
|
||||
Функция `make_full_clip` выполняет следующие оптимизации:
|
||||
- Удаление аудиодорожки для уменьшения размера файла
|
||||
- Ускорение видео в 1.5 раза для сокращения продолжительности
|
||||
- Уменьшение разрешения для оптимизации передачи через Telegram
|
||||
- Применение эффективных параметров кодирования H.264
|
||||
|
||||
### Модуль обработчиков команд (handlers.py)
|
||||
|
||||
Модуль содержит обработчики команд и событий пользовательского интерфейса:
|
||||
|
||||
```python
|
||||
@router.message(CommandStart())
|
||||
async def start_handler(msg: Message) -> None:
|
||||
"""Обработчик команды /start"""
|
||||
await msg.answer("Здравствуйте! Этот бот поможет вам добраться до кабинета в структуре корпусов Московского "
|
||||
"Политехнического Университета. Для начала работы просто пропишите команду <b>/route</b>")
|
||||
|
||||
@router.message(Command("route"))
|
||||
async def route_handler(msg: Message) -> None:
|
||||
"""Обработчик команды /route"""
|
||||
buttons = [[InlineKeyboardButton(text=f"На Большой Семёновской", callback_data="edu:bs")],
|
||||
[InlineKeyboardButton(text=f"На Павла Корчагина", callback_data="edu:pk")],
|
||||
[InlineKeyboardButton(text=f"На Прянишкова", callback_data="edu:pr"),
|
||||
InlineKeyboardButton(text=f"На Михалковской", callback_data="edu:mi")],
|
||||
[InlineKeyboardButton(text=f"На Автозаводской", callback_data="edu:av")]]
|
||||
keyboard = InlineKeyboardMarkup(inline_keyboard=buttons)
|
||||
|
||||
await msg.answer(text="Выберите корпус на котором вы хотите проложить маршрут:", reply_markup=keyboard)
|
||||
|
||||
@router.callback_query(F.data.startswith("route:"))
|
||||
async def var_button(call: CallbackQuery) -> None:
|
||||
"""Обработчик выбора типа маршрута"""
|
||||
action = call.data.split(":")[1]
|
||||
|
||||
# Получение данных о сессии пользователя
|
||||
jsn = JsonTools(call.from_user.id)
|
||||
user_dict = jsn.read_json()
|
||||
edu_keys = list(user_dict.keys())
|
||||
lst_routes = user_dict[edu_keys[0]]
|
||||
|
||||
# Уведомление о начале обработки
|
||||
msg = await call.message.answer("1. Получение видео...")
|
||||
path = ""
|
||||
|
||||
# Логика выбора или генерации маршрута
|
||||
if action == "build": # От входа на территорию
|
||||
# Проверка наличия в кеше
|
||||
if os.path.exists(f"../data/cache/{lst_routes[-1][21:].replace('.mp4', '-all.mp4')}"):
|
||||
path = f"../data/cache/{lst_routes[-1][21:].replace('.mp4', '-all.mp4')}"
|
||||
else:
|
||||
# Генерация нового маршрута
|
||||
path = make_full_clip(lst_routes)
|
||||
if not path:
|
||||
await msg.edit_text("Данного маршрута в нашей базе пока нет, извините за неудобство...")
|
||||
return 0
|
||||
elif action == "floor": # От входа в корпус
|
||||
# Аналогичная логика для маршрута от входа в корпус
|
||||
# ...
|
||||
|
||||
# Отправка результата
|
||||
msg_finally = await msg.edit_text("2. Видео готово!")
|
||||
await msg.answer_video_note(video_note=FSInputFile(path))
|
||||
await msg_finally.delete()
|
||||
```
|
||||
|
||||
Применен декларативный подход с использованием роутеров и фильтров, что делает код модульным и легко расширяемым.
|
||||
|
||||
### Модуль работы с данными (database.py)
|
||||
|
||||
Модуль реализует хранение и получение данных о пользовательских сессиях:
|
||||
|
||||
```python
|
||||
class JsonTools:
|
||||
"""
|
||||
Класс для работы с JSON-данными пользователей.
|
||||
|
||||
Attributes:
|
||||
f_name (str): Путь к файлу пользовательской сессии
|
||||
"""
|
||||
|
||||
def __init__(self, user_id):
|
||||
"""
|
||||
Инициализация инструмента работы с данными.
|
||||
|
||||
Args:
|
||||
user_id: Идентификатор пользователя Telegram
|
||||
"""
|
||||
self.f_name = f"../data/users/{user_id}.json"
|
||||
|
||||
def save_json(self, data):
|
||||
"""
|
||||
Сохранение данных в JSON-файл.
|
||||
|
||||
Args:
|
||||
data: Данные для сохранения
|
||||
|
||||
Returns:
|
||||
dict: Результат операции сохранения
|
||||
"""
|
||||
with open(self.f_name, "w", encoding="utf8") as f:
|
||||
return json.dump(data, f)
|
||||
|
||||
def read_json(self):
|
||||
"""
|
||||
Чтение данных из JSON-файла.
|
||||
|
||||
Returns:
|
||||
dict: Прочитанные данные
|
||||
"""
|
||||
with open(self.f_name, "r", encoding="utf8") as f:
|
||||
return json.load(f)
|
||||
|
||||
def get_buildings(self):
|
||||
"""
|
||||
Получение списка корпусов из данных пользователя.
|
||||
|
||||
Returns:
|
||||
list: Список идентификаторов корпусов
|
||||
"""
|
||||
return self.read_json().keys()
|
||||
```
|
||||
|
||||
Использование файлового хранилища обеспечивает сохранность данных между перезапусками бота и обладает достаточной производительностью для данной задачи.
|
||||
|
||||
### Основной модуль приложения (bot.py)
|
||||
|
||||
Модуль является точкой входа в приложение и отвечает за запуск и общую координацию работы бота:
|
||||
|
||||
```python
|
||||
import asyncio, logging
|
||||
|
||||
from init import *
|
||||
from handlers import router
|
||||
|
||||
async def main() -> None:
|
||||
"""
|
||||
Основная функция запуска бота.
|
||||
Настраивает роутеры, веб-хук и команды.
|
||||
"""
|
||||
dp.include_router(router)
|
||||
await bot.delete_webhook(drop_pending_updates=True)
|
||||
|
||||
await setup_bot_commands()
|
||||
await dp.start_polling(bot, allowed_updates=dp.resolve_used_update_types())
|
||||
|
||||
if __name__ == "__main__":
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
try:
|
||||
asyncio.run(main())
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
```
|
||||
|
||||
Использование асинхронного подхода позволяет эффективно обрабатывать множество одновременных запросов и обеспечивает высокую производительность бота.
|
||||
|
||||
## Тестирование и валидация
|
||||
|
||||
### Разработка тестовых сценариев
|
||||
|
||||
Для проверки работоспособности бота были разработаны следующие тестовые сценарии:
|
||||
|
||||
1. **Базовая функциональность**:
|
||||
- Тестирование команды `/start` и получение приветственного сообщения
|
||||
- Проверка команды `/help` и полноты предоставляемой информации
|
||||
- Тестирование команды `/route` и корректности отображения интерфейса выбора корпуса
|
||||
|
||||
2. **Выбор корпуса и кабинета**:
|
||||
- Проверка обработки выбора каждого из корпусов через интерактивные кнопки
|
||||
- Тестирование ввода корректных номеров кабинетов для каждого корпуса
|
||||
- Проверка реакции на некорректный формат номера кабинета
|
||||
|
||||
3. **Формирование видеомаршрутов**:
|
||||
- Тестирование генерации маршрутов "от входа на территорию"
|
||||
- Проверка формирования маршрутов "от входа в корпус"
|
||||
- Тестирование системы кеширования и повторного использования маршрутов
|
||||
|
||||
4. **Обработка ошибок**:
|
||||
- Проверка поведения при отсутствии необходимых видеофрагментов
|
||||
- Тестирование обработки сетевых ошибок и сбоев при рендеринге видео
|
||||
- Проверка корректного информирования пользователя о проблемах
|
||||
|
||||
### Результаты тестирования
|
||||
|
||||
В ходе тестирования были выявлены и устранены следующие проблемы:
|
||||
|
||||
1. **Производительность**:
|
||||
- Оптимизированы параметры рендеринга видео для ускорения процесса
|
||||
- Реализовано кеширование для минимизации повторной обработки маршрутов
|
||||
- Улучшена асинхронная обработка запросов для повышения отзывчивости
|
||||
|
||||
2. **Обработка ошибок**:
|
||||
- Добавлена проверка наличия файлов перед объединением видеофрагментов
|
||||
- Реализованы информативные сообщения при невозможности построения маршрута
|
||||
- Добавлена корректная обработка прерываний и исключений
|
||||
|
||||
3. **Улучшение пользовательского опыта**:
|
||||
- Добавлено отображение прогресса обработки видео
|
||||
- Оптимизированы размер и продолжительность видеомаршрутов
|
||||
- Улучшены подсказки и инструкции для пользователей
|
||||
|
||||
## Развертывание и сопровождение
|
||||
|
||||
### Подготовка среды выполнения
|
||||
|
||||
Для эффективной работы бота требуется следующая инфраструктура:
|
||||
|
||||
1. **Серверные требования**:
|
||||
- Операционная система: Linux (Ubuntu 20.04 или новее)
|
||||
- Python 3.10 или выше
|
||||
- Не менее 2 ГБ оперативной памяти
|
||||
- Не менее 10 ГБ дискового пространства для хранения видеофрагментов и кеша
|
||||
|
||||
2. **Необходимые зависимости**:
|
||||
- aiogram==3.0.0
|
||||
- moviepy==1.0.3
|
||||
- ffmpeg (системный пакет)
|
||||
|
||||
3. **Структура каталогов**:
|
||||
```
|
||||
/
|
||||
├── src/
|
||||
│ └── code/ # Исходный код бота
|
||||
├── data/
|
||||
│ ├── cache/ # Сгенерированные видеомаршруты
|
||||
│ ├── users/ # Пользовательские данные
|
||||
│ └── videos/ # Исходные видеофрагменты маршрутов
|
||||
└── logs/ # Журналы работы бота
|
||||
```
|
||||
|
||||
### Мониторинг и обслуживание
|
||||
|
||||
Для обеспечения стабильной работы бота рекомендуется:
|
||||
|
||||
1. **Регулярное обслуживание**:
|
||||
- Мониторинг использования дискового пространства
|
||||
- Периодическая очистка устаревших кешированных маршрутов
|
||||
- Обновление исходных видеофрагментов при изменениях в кампусе
|
||||
|
||||
2. **Резервное копирование**:
|
||||
- Создание резервных копий видеофрагментов маршрутов
|
||||
- Периодическое копирование пользовательских данных
|
||||
- Хранение копий конфигурационных файлов
|
||||
|
||||
3. **Обновление и расширение**:
|
||||
- Добавление новых маршрутов по запросам пользователей
|
||||
- Актуализация существующих маршрутов при изменениях в кампусе
|
||||
- Расширение функциональности по результатам обратной связи
|
||||
|
||||
## Выводы и перспективы развития
|
||||
|
||||
### Результаты проекта
|
||||
|
||||
В результате выполнения вариативной части проектной практики:
|
||||
|
||||
1. Разработан и внедрен телеграм-бот "МосПолиХелпер", предоставляющий интерактивные видеомаршруты по кампусам Московского Политехнического Университета.
|
||||
|
||||
2. Реализована модульная архитектура с четким разделением ответственности, обеспечивающая масштабируемость и поддерживаемость кода.
|
||||
|
||||
3. Создана эффективная система обработки видеофрагментов с оптимизацией для использования в мессенджере Telegram.
|
||||
|
||||
4. Реализовано кеширование маршрутов для повышения производительности и оптимизации пользовательского опыта.
|
||||
|
||||
5. Проведено комплексное тестирование и оптимизация производительности бота.
|
||||
|
||||
### Перспективы развития
|
||||
|
||||
Проект имеет следующие перспективы дальнейшего развития:
|
||||
|
||||
1. **Расширение функциональности**:
|
||||
- Добавление текстовых инструкций к видеомаршрутам
|
||||
- Интеграция с расписанием занятий для автоматического определения нужного кабинета
|
||||
- Добавление статических карт и схем кампуса
|
||||
|
||||
2. **Технологические улучшения**:
|
||||
- Переход на базу данных (SQLite или PostgreSQL) для более эффективного хранения данных
|
||||
- Внедрение системы аналитики для отслеживания популярных маршрутов
|
||||
- Оптимизация алгоритмов обработки видео для дальнейшего повышения производительности
|
||||
|
||||
3. **Расширение охвата**:
|
||||
- Добавление маршрутов между корпусами университета
|
||||
- Включение маршрутов до близлежащих объектов инфраструктуры (общежития, столовые и т.д.)
|
||||
- Интеграция с общественным транспортом для полной навигации до университета
|
||||
|
||||
## Заключение
|
||||
|
||||
Телеграм-бот "МосПолиХелпер" является практическим решением реальной проблемы ориентирования в кампусах Московского Политехнического Университета. Проект демонстрирует применение современных технологий разработки и обработки мультимедиа для создания полезного интерактивного инструмента.
|
||||
|
||||
Модульная архитектура и тщательное проектирование обеспечивают надежность работы бота и возможности для дальнейшего расширения функциональности. Оптимизация обработки видео и система кеширования позволяют обеспечить высокую производительность и хороший пользовательский опыт.
|
||||
|
||||
В ходе выполнения проекта были успешно применены знания и навыки, полученные в рамках основного обучения, а также приобретен ценный практический опыт в разработке асинхронных приложений, обработке мультимедиа и создании удобных пользовательских интерфейсов.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue