From 3dbffdce4a98040bee2e7f431ea20b48ca8c01e9 Mon Sep 17 00:00:00 2001 From: Egor Deev <67710823+IGlek@users.noreply.github.com> Date: Mon, 19 May 2025 22:04:46 +0300 Subject: [PATCH] release docs --- docs/README.md | 499 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 495 insertions(+), 4 deletions(-) diff --git a/docs/README.md b/docs/README.md index ee16ad7..4cd8897 100644 --- a/docs/README.md +++ b/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("Здравствуйте! Этот бот поможет вам добраться до кабинета в структуре корпусов Московского " + "Политехнического Университета. Для начала работы просто пропишите команду /route") + +@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. **Расширение охвата**: + - Добавление маршрутов между корпусами университета + - Включение маршрутов до близлежащих объектов инфраструктуры (общежития, столовые и т.д.) + - Интеграция с общественным транспортом для полной навигации до университета + +## Заключение + +Телеграм-бот "МосПолиХелпер" является практическим решением реальной проблемы ориентирования в кампусах Московского Политехнического Университета. Проект демонстрирует применение современных технологий разработки и обработки мультимедиа для создания полезного интерактивного инструмента. + +Модульная архитектура и тщательное проектирование обеспечивают надежность работы бота и возможности для дальнейшего расширения функциональности. Оптимизация обработки видео и система кеширования позволяют обеспечить высокую производительность и хороший пользовательский опыт. + +В ходе выполнения проекта были успешно применены знания и навыки, полученные в рамках основного обучения, а также приобретен ценный практический опыт в разработке асинхронных приложений, обработке мультимедиа и создании удобных пользовательских интерфейсов.