mospoly-helper/docs
2025-06-27 13:50:08 +03:00
..
README.md release docs 2025-05-19 22:04:46 +03:00
report.pdf release docx 2025-06-27 13:49:40 +03:00

Документация по проектной практике

Реализация телеграм-бота "МосПолиХелпер"

В данном документе представлена подробная документация по разработке и реализации телеграм-бота "МосПолиХелпер" в рамках вариативной части проектной практики. Документ содержит детальное описание технических аспектов разработки, архитектурных решений, использованных технологий и методологий.

Исследование предметной области

Анализ проблемы навигации в кампусе

Перед началом разработки был проведен анализ существующей проблемы ориентирования в кампусах Московского Политехнического Университета. Основные выявленные сложности:

  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)

Модуль отвечает за настройку экземпляра бота, инициализацию диспетчера сообщений и подготовку команд меню:

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)

Ключевой модуль, отвечающий за формирование и обработку видеомаршрутов:

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)

Модуль содержит обработчики команд и событий пользовательского интерфейса:

@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)

Модуль реализует хранение и получение данных о пользовательских сессиях:

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)

Модуль является точкой входа в приложение и отвечает за запуск и общую координацию работы бота:

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. Расширение охвата:

    • Добавление маршрутов между корпусами университета
    • Включение маршрутов до близлежащих объектов инфраструктуры (общежития, столовые и т.д.)
    • Интеграция с общественным транспортом для полной навигации до университета

Заключение

Телеграм-бот "МосПолиХелпер" является практическим решением реальной проблемы ориентирования в кампусах Московского Политехнического Университета. Проект демонстрирует применение современных технологий разработки и обработки мультимедиа для создания полезного интерактивного инструмента.

Модульная архитектура и тщательное проектирование обеспечивают надежность работы бота и возможности для дальнейшего расширения функциональности. Оптимизация обработки видео и система кеширования позволяют обеспечить высокую производительность и хороший пользовательский опыт.

В ходе выполнения проекта были успешно применены знания и навыки, полученные в рамках основного обучения, а также приобретен ценный практический опыт в разработке асинхронных приложений, обработке мультимедиа и создании удобных пользовательских интерфейсов.