LitVideo — это современный веб-сервис, предоставляющий пользователям возможность загружать, просматривать, комментировать и обмениваться видеоконтентом. Проект разработан для веселья с акцентом на простоту использования.
- Подробное описание проекта
- Ключевые функциональные возможности
- Преимущества и ограничения
- Технический стек
- Архитектура проекта
- Структура проекта
- Установка и настройка
- Руководство по запуску
- Руководство пользователя
- API Документация
- Реализация ключевых технических решений
- Тестирование
- Развертывание
- Вклад в проект
- Дорожная карта
- Контакты
LitVideo – это платформа, вдохновленная популярными видеохостингами, такими как YouTube, но сфокусированная на предоставлении более простого и контролируемого пользовательского опыта. Основная идея проекта – создать удобное пространство, где пользователи могут легко делиться своими видео, находить интересный контент и взаимодействовать друг с другом.
Проект ориентирован на широкую аудиторию. Сценарии использования включают:
- Личные блоги: Пользователи могут вести видеодневники, делиться моментами из жизни, путешествиями и впечатлениями.
- Образовательный контент: Преподаватели и эксперты могут создавать обучающие курсы, лекции и мастер-классы.
- Творческие портфолио: Художники, музыканты, дизайнеры и другие творческие личности могут демонстрировать свои работы.
- Обзоры и распаковки: Пользователи могут делиться своим мнением о товарах и услугах.
- Игровые стримы и записи: Геймеры могут транслировать игровой процесс и делиться записями прохождений.
В отличие от крупных видеохостингов, LitVideo стремится к минимализму и простоте, избегая перегруженности функционалом и сложного интерфейса. Ключевые особенности, отличающие LitVideo:
- Простой и интуитивно понятный интерфейс: Минимум элементов управления, фокус на контенте.
- Высокая скорость загрузки и воспроизведения: Оптимизированное хранение и обработка видео, эффективный фронтенд.
- Адаптивный дизайн: Удобство использования на любых устройствах, от смартфонов до настольных компьютеров.
- Система подписок: Возможность подписываться на каналы других пользователей и получать уведомления о новых видео.
- Удобная система комментирования: Возможность обсуждения видео, обмена мнениями и получения обратной связи.
- Встроенный поиск: Быстрый поиск видео по названию и описанию.
- Система лайков/дизлайков: оценка контента.
Функциональные возможности LitVideo можно разделить на следующие категории:
1. Аутентификация и авторизация:
- Регистрация: Создание учетной записи с указанием имени пользователя и пароля. Реализовано через форму, валидацию данных и хеширование пароля с использованием
werkzeug.security.generate_password_hash. - Вход: Аутентификация пользователя по имени пользователя и паролю. Используется
werkzeug.security.check_password_hashдля проверки пароля. После успешного входа создается сессия Flask (flask_session). - Выход: Завершение сеанса пользователя. Сессия очищается.
- Загрузка и управление аватаром: Пользователи могут загружать и изменять свои аватары. Используется
werkzeug.utils.secure_filenameдля безопасной обработки имен файлов, а такжеuuidдля генерации уникальных имен. Аватары хранятся в файловой системе, а путь к файлу сохраняется в базе данных. - Подписка/Отписка: Пользователи могут подписываться на других пользователей и отписываться от них. Реализовано через AJAX запросы (
fetch API).
2. Управление видео:
- Загрузка: Загрузка видеофайлов с указанием названия и описания. Реализована с использованием
Flask.request.files, валидации формата и размера файла. Используетсяuuidдля генерации уникальных имен файлов иffmpegдля создания превью. Видео и превью хранятся в файловой системе, а пути к файлам сохраняются в базе данных. - Просмотр: Просмотр видео с использованием HTML5-плеера (реализован на базе библиотеки Plyr). Плеер поддерживает основные функции управления воспроизведением, полноэкранный режим и регулировку скорости. При просмотре видео увеличивается счетчик просмотров в базе данных.
- Поиск: Поиск видео по названию и описанию. Реализован с использованием SQL-запроса с оператором
LIKEи параметризованными запросами. - Скачивание: Зарегистрированные пользователи могут скачивать видео. Реализовано с использованием
Flask.send_from_directory. - Лайки/Дизлайки: Реализовано через AJAX запросы (
fetch API) с обновлением счетчиков в БД и изменением состояния кнопок. - Рекомендованные видео: Отображение списка рекомендованных видео, исключая текущее видео.
3. Взаимодействие с пользователями:
- Просмотр профиля: Просмотр информации о пользователе, включая список загруженных им видео, количество подписчиков и подписок. Позволяет подписаться/отписаться от пользователя.
- Комментарии: Добавление комментариев к видео. Реализовано через форму, валидацию данных и AJAX (без перезагрузки страницы, но с добавлением сообщений через
flash). - Подписки: Возможность просматривать профили других пользователей и подписываться на них.
Преимущества:
- Простота установки и использования: Минимальные требования к системе, простая установка зависимостей и запуск приложения. Docker.
- Высокая производительность: Оптимизированное хранение видео, использование
ffmpegдля создания легковесных превью, асинхронная обработка запросов (в перспективе). - Адаптивный дизайн: Корректное отображение и работа на различных устройствах.
- Безопасность: Хеширование паролей, использование
secure_filenameдля обработки имен файлов, параметризованные SQL-запросы для защиты от SQL-инъекций. - Расширяемость: Модульная структура проекта позволяет легко добавлять новые функции.
- Использование современных технологий: Flask, HTML5, CSS3, JavaScript (ES6+), Plyr.
- Открытый исходный код: Возможность свободного использования, модификации и распространения.
Ограничения:
- Ограниченный функционал: В текущей версии реализованы только базовые функции видеохостинга.
- Отсутствие системы модерации: Нет инструментов для контроля за контентом и предотвращения загрузки нежелательных материалов.
- Использование SQLite: SQLite не подходит для высоконагруженных проектов и может стать узким местом при большом количестве пользователей и видео.
- Решение: Переход на более производительную СУБД, такую как PostgreSQL или MySQL.
- Отсутствие CI/CD: В проекте не настроена система CI/CD.
Backend:
- Python 3.12+: Основной язык программирования.
- Flask 2.2.2: Микрофреймворк для создания веб-приложений.
- Обеспечивает маршрутизацию, обработку запросов, шаблонизацию, управление сессиями.
- Flask-Session 0.4.0: Расширение Flask для управления сессиями на стороне сервера.
- Используется для хранения данных о сессии пользователя (ID пользователя, имя пользователя).
- Werkzeug 2.2.2: Библиотека WSGI-утилит.
- Используется для хеширования паролей (
generate_password_hash,check_password_hash) и безопасной обработки имен файлов (secure_filename).
- Используется для хеширования паролей (
- gunicorn 20.1.0: WSGI HTTP-сервер для Python.
- Используется для запуска приложения в production-среде.
- SQLite: Встроенная реляционная СУБД.
- Используется для хранения данных о пользователях, видео, комментариях и подписках. Временно, на этапе разработки.
- FFmpeg: Мощный инструмент для обработки видео и аудио.
- Используется для создания превью видео (thumbnail_service.py).
Frontend:
- HTML5: Язык разметки для создания структуры веб-страниц.
- CSS3: Язык стилей для оформления веб-страниц.
- JavaScript (ES6+): Язык программирования для добавления интерактивности на веб-страницы.
- Используется для обработки событий, AJAX-запросов, управления плеером Plyr, анимаций.
- Plyr: Библиотека для создания HTML5-видеоплеера.
- Font Awesome: Библиотека иконок.
Инфраструктура и инструменты:
- Docker: Платформа для контейнеризации приложений (Dockerfile в корне проекта).
- Git: Система контроля версий.
Проект LitVideo построен на основе архитектурного паттерна Model-View-Controller (MVC), с некоторыми элементами сервисного подхода.
- Model (Модели): Описывают структуру данных и бизнес-логику, связанную с данными. В проекте представлены моделями
User,Video,Comment(в директорииapp/models). Модели взаимодействуют с базой данных через классDatabase(app/models/db.py), который предоставляет абстрактный интерфейс для выполнения SQL-запросов. - View (Представления): Отвечают за отображение данных пользователю. В проекте представлены HTML-шаблонами (директория
app/templates) и CSS-стилями (директорияapp/static/css). Шаблоны используют шаблонизатор Jinja2, встроенный во Flask. - Controller (Контроллеры): Обрабатывают запросы пользователя, взаимодействуют с моделями и представлениями, управляют потоком данных. В проекте представлены функциями-обработчиками маршрутов (директория
app/routes). Функции-обработчики используют декораторы Flask (@bp.route) для привязки к определенным URL-адресам. - Services (Сервисы): Выделенная бизнес-логика, не привязанная к конкретным моделям. В проекте представлены сервисами
thumbnail_service.py(создание thumbnail) иvideo_service.py(сохранение, получение и поиск видео), которые инкапсулируют логику работы с видеофайлами и превью.
Схема взаимодействия компонентов:
Поток данных:
- Пользователь отправляет запрос (например, переход по ссылке, отправка формы).
- Flask получает запрос и передает его соответствующему обработчику маршрута (в
app/routes). - Обработчик маршрута может использовать сервисы (из
app/services) для выполнения бизнес-логики (например, сохранения видео, создания превью). - Сервисы, в свою очередь, могут взаимодействовать с моделями (из
app/models) для доступа к данным и их изменения. - Модели взаимодействуют с базой данных через класс
Database. - Обработчик маршрута получает данные от моделей (или сервисов) и передает их в шаблон (в
app/templates). - Flask генерирует HTML-страницу на основе шаблона и данных.
- Сгенерированная страница отправляется пользователю.
Паттерны проектирования:
- MVC: Основной архитектурный паттерн.
- Singleton: Класс
Databaseреализован как Singleton, чтобы гарантировать наличие только одного экземпляра соединения с базой данных. - Service Layer: Выделение бизнес-логики в отдельные сервисы.
LitVideo/
├── app/ # Основной код приложения
│ ├── models/ # Модели данных
│ │ ├── comment.py # Модель комментария
│ │ ├── db.py # Класс для работы с базой данных
│ │ ├── user.py # Модель пользователя
│ │ └── video.py # Модель видео
│ ├── routes/ # Маршруты (контроллеры)
│ │ ├── auth.py # Маршруты аутентификации и авторизации
│ │ ├── comment.py # Маршруты для работы с комментариями
│ │ └── video.py # Маршруты для работы с видео
│ ├── services/ # Сервисы (бизнес-логика)
│ │ ├── thumbnail_service.py # Сервис для создания превью видео
│ │ └── video_service.py # Сервис для работы с видео (загрузка, сохранение, и т.д.)
│ ├── static/ # Статические файлы (CSS, JavaScript, изображения, иконки)
│ │ ├── css/ # CSS-стили
│ │ │ ├── login.css # Стили страницы входа
│ │ │ ├── profile.css # Стили страницы профиля
│ │ │ ├── register.css # Стили страницы регистрации
│ │ │ ├── style.css # Общие стили
│ │ │ ├── upload.css # Стили страницы загрузки видео
│ │ │ └── video.css # Стили страницы просмотра видео
│ │ ├── js/ # JavaScript-файлы
│ │ │ └── video-player.js # Скрипты для страницы просмотра видео (инициализация плеера, обработка событий)
│ │ ├── svg/ # Векторная графика
│ │ │ └── intro.svg # Интро-анимация
│ │ ├── uploads/ # Директория для загружаемых файлов (генерируется автоматически)
│ │ │ ├── avatars/ # Аватары пользователей
│ │ │ ├── thumbnails/ # Превью видео
│ │ │ └── videos/ # Видеофайлы
│ ├── templates/ # HTML-шаблоны
│ │ ├── base.html # Базовый шаблон
│ │ ├── index.html # Шаблон главной страницы
│ │ ├── login.html # Шаблон страницы входа
│ │ ├── profile.html # Шаблон страницы профиля
│ │ ├── register.html # Шаблон страницы регистрации
│ │ ├── upload.html # Шаблон страницы загрузки видео
│ │ └── video.html # Шаблон страницы просмотра видео
│ └── __init__.py # Файл инициализации приложения Flask
├── flask_session/ # Директория для хранения файлов сессий (генерируется автоматически)
├── instance/ # Директория для хранения базы данных SQLite (генерируется автоматически)
│ └── litvideo.db # Файл базы данных
├── .dockerignore # Файл для игнорирования файлов и директорий при сборке Docker-образа.
├── Dockerfile # Инструкции по сборке Docker-образа.
├── requirements.txt # Список зависимостей проекта
└── wsgi.py # Файл для запуска приложения с помощью Gunicorn
Пояснения:
app: Основная директория, содержащая код приложения.models: Содержит определения моделей данных (User,Video,Comment) и классDatabaseдля взаимодействия с базой данных.routes: Содержит определения маршрутов (контроллеров) для обработки запросов пользователя.services: Содержит сервисы, инкапсулирующие бизнес-логику приложения.static: Содержит статические файлы, такие как CSS, JavaScript, изображения.templates: Содержит HTML-шаблоны, используемые для генерации веб-страниц.__init__.py: Создает и настраивает приложение Flask, инициализирует базу данных и сессии, регистрирует маршруты.
flask_session: Директория, в которой Flask-Session хранит файлы сессий.instance: Директория, в которой находится файл базы данных SQLite..dockerignore: Указывает Docker, какие файлы и директории не нужно включать в образ.Dockerfile: Содержит инструкции для сборки Docker-образа приложения.requirements.txt: Содержит список зависимостей Python, необходимых для работы приложения.wsgi.py: Точка входа для запуска приложения с помощью WSGI-сервера Gunicorn.
Требования к системе:
- Операционная система: Linux, macOS, Windows.
- Python 3.12+
- Менеджер пакетов pip.
- FFmpeg (установленный и доступный в PATH).
- Git (опционально, для клонирования репозитория).
Пошаговая инструкция:
-
Клонирование репозитория (или скачивание архива):
git clone RfailesDev/LitVideo cd LitVideoЕсли вы скачали архив, распакуйте его и перейдите в директорию проекта.
-
Создание и активация виртуального окружения (рекомендуется):
python3 -m venv venv source venv/bin/activate # Для Linux/macOS venv\Scripts\activate # Для Windows
-
Установка зависимостей:
pip install -r requirements.txt
-
Настройка переменных окружения (необязательно, но рекомендуется):
Создайте файл
.envв корне проекта и добавьте туда следующие переменные:SECRET_KEY=your_secret_key_hereЗамените
your_secret_key_hereна надежный случайный ключ. Это важно для безопасности приложения. -
Инициализация базы данных:
База данных будет создана автоматически при первом запуске приложения. В
app/__init__.pyвызывается методdb.init_app(app), который, в свою очередь, вызываетself.init_db(), создающий все необходимые таблицы.
Локальный запуск (для разработки):
-
Убедитесь, что вы находитесь в директории проекта и активировали виртуальное окружение (если вы его создавали).
-
Запустите приложение Flask:
flask run --host=0.0.0.0 --port=5000
--host=0.0.0.0: Приложение будет доступно по всем сетевым интерфейсам (не только по localhost).--port=5000: Приложение будет доступно по порту 5000 (вы можете изменить порт).
-
Откройте браузер и перейдите по адресу
http://localhost:5000(или по другому адресу, если вы указали другой хост или порт).
Запуск с использованием Gunicorn (для production):
-
Убедитесь, что вы находитесь в директории проекта и активировали виртуальное окружение.
-
Запустите приложение с помощью Gunicorn:
gunicorn --workers 4 --bind 0.0.0.0:8000 wsgi:app
--workers 4: Количество рабочих процессов Gunicorn (можно настроить в зависимости от ресурсов сервера).--bind 0.0.0.0:8000: Приложение будет доступно по всем сетевым интерфейсам на порту 8000.wsgi:app: Указывает Gunicorn, как запустить приложение (файлwsgi.pyи объектapp).
-
Откройте браузер и перейдите по адресу
http://<ваш_сервер>:8000.
Возможные ошибки при запуске и их решения:
ModuleNotFoundError: No module named 'flask': Не установлены зависимости. Убедитесь, что вы активировали виртуальное окружение и выполнилиpip install -r requirements.txt.Address already in use: Указанный порт уже занят другим приложением. Попробуйте использовать другой порт (--portдляflask runили--bindдля Gunicorn).- Ошибка при создании превью: Убедитесь, что FFmpeg установлен и доступен в PATH.
- Ошибка при подключении к базе данных: Убедитесь что путь к базе данных указан верно
Главная страница:
- Отображает список последних загруженных видео.
- Превью видео.
- Название видео.
- Имя автора.
- Количество просмотров.
- Дата загрузки.
- Позволяет осуществлять поиск видео по названию и описанию.
- Поле ввода поискового запроса.
- Кнопка поиска.
- Позволяет перейти на страницу входа/регистрации или в профиль пользователя (если пользователь авторизован).
- Кнопка "Войти" / Ссылка на профиль.
- Есть навигационное меню.
Регистрация:
- Переход по ссылке "Регистрация" на странице входа.
- Требует ввода имени пользователя и пароля.
- Поле ввода имени пользователя.
- Поле ввода пароля.
- Кнопка "Зарегистрироваться".
- После успешной регистрации перенаправляет на страницу входа.
Вход:
- Переход по ссылке "Войти" на главной странице.
- Требует ввода имени пользователя и пароля.
- После успешного входа перенаправляет на главную страницу.
Просмотр видео:
- Переход по клику на превью видео на главной странице или в профиле пользователя.
- Отображает видеоплеер, название, описание, автора, количество просмотров, дату загрузки, комментарии.
- Позволяет ставить лайки/дизлайки (если пользователь авторизован).
- Позволяет добавлять комментарии (если пользователь авторизован).
- Позволяет скачивать видео (если пользователь авторизован).
- Позволяет переходить в профиль автора видео.
- Отображает рекомендованные видео.
Загрузка видео:
- Доступна авторизованным пользователям по ссылке в меню.
- Требует указания названия видео и выбора файла.
- Поле ввода названия.
- Поле выбора файла.
- Поле ввода описания (необязательное)
- Кнопка "Загрузить".
- После успешной загрузки перенаправляет на главную страницу.
Профиль пользователя:
- Доступен авторизованным пользователям по ссылке в меню.
- Отображает имя пользователя, аватар, количество подписчиков.
- Позволяет изменить аватар (если это профиль текущего пользователя).
- Отображает список видео, загруженных пользователем.
- Позволяет выйти из учетной записи.
- Позволяет подписываться/отписываться (если это не профиль текущего пользователя)
1. Регистрация пользователя (/auth/register):
-
Метод: POST
-
URL:
/auth/register -
Параметры:
username(string, required): Имя пользователя.password(string, required): Пароль.
-
Тело запроса (form data):
username=<username> password=<password> -
Ответы:
- 200 OK: Успешная регистрация. Перенаправление на
/auth/login. В теле ответа ничего нет. - 400 Bad Request: Ошибка валидации (не указано имя пользователя, пароль, или пользователь с таким именем уже существует). В теле ответа ничего нет (ошибки выводятся через flash-сообщения).
- 200 OK: Успешная регистрация. Перенаправление на
2. Вход пользователя (/auth/login):
-
Метод: POST
-
URL:
/auth/login -
Параметры:
username(string, required): Имя пользователя.password(string, required): Пароль.
-
Тело запроса (form data):
username=<username> password=<password> -
Ответы:
- 200 OK: Успешный вход. Перенаправление на
/. В теле ответа ничего нет. В сессии устанавливаютсяuser_idиusername. - 400 Bad Request: Ошибка валидации (не указано имя пользователя, пароль, или неверное имя пользователя/пароль). В теле ответа ничего нет (ошибки выводятся через flash-сообщения).
- 200 OK: Успешный вход. Перенаправление на
3. Выход пользователя (/auth/logout):
- Метод: GET
- URL:
/auth/logout - Параметры: Нет.
- Ответы:
- 200 OK: Успешный выход. Перенаправление на
/. В теле ответа ничего нет. Сессия очищается.
- 200 OK: Успешный выход. Перенаправление на
4. Загрузка аватара (/auth/profile/<int:user_id>/upload_avatar):
-
Метод: POST
-
URL:
/auth/profile/<int:user_id>/upload_avatar -
Параметры:
user_id(integer, required): ID пользователя.avatar(file, required): Файл аватара.
-
Тело запроса (multipart/form-data):
avatar=<file_content> -
Ответы:
- 200 OK: Успешная загрузка аватара. Перенаправление на
/auth/profile/<user_id>. - 400 Bad Request: Ошибка валидации (файл не выбран, недопустимый формат, файл слишком большой, нет прав). Перенаправление на
/auth/profile/<user_id>. - 500 Internal server error: Ошибка сохранения файла
- 200 OK: Успешная загрузка аватара. Перенаправление на
5. Загрузка видео (/upload):
-
Метод: POST
-
URL:
/upload -
Параметры:
title(string, required): Название видео.description(string, optional): Описание видео.video(file, required): Видеофайл.
-
Тело запроса (multipart/form-data):
title=<title> description=<description> video=<file_content> -
Ответы:
- 200 OK: Успешная загрузка видео. Перенаправление на
/. - 400 Bad Request: Ошибка валидации (не указано название, не выбран файл, неподдерживаемый формат файла). Перенаправление на
/upload.
- 200 OK: Успешная загрузка видео. Перенаправление на
6. Просмотр видео (/video/<int:video_id>):
- Метод: GET
- URL:
/video/<int:video_id> - Параметры:
video_id(integer, required): ID видео.
- Ответы:
- 200 OK: Успешный показ видео. Возвращает HTML-страницу.
- 404 Not Found: Видео не найдено. Перенаправление на
/.
7. Добавление комментария (/comment/add/<int:video_id>):
-
Метод: POST
-
URL:
/comment/add/<int:video_id> -
Параметры:
video_id(integer, required): ID видео.content(string, required): Текст комментария.
-
Тело запроса (form data):
content=<comment_text> -
Ответы:
- 200 OK: Успешное добавление комментария. Перенаправление на
/video/<video_id>. - 400 Bad Request: Ошибка валидации (комментарий пустой). Перенаправление на
/video/<video_id>.
- 200 OK: Успешное добавление комментария. Перенаправление на
8. Лайк видео (/video/<int:video_id>/like):
-
Метод: POST
-
URL:
/video/<int:video_id>/like -
Параметры:
video_id(integer, required): ID видео.
-
Ответы:
- 200 OK: Успешное выполнение операции.
{ "status": "success", "action": "like" | "remove_like", "likes": <int>, "dislikes": <int> } - 401 Unauthorized: Пользователь не авторизован.
- 404 Not Found: Видео не найдено.
- 500 Internal Server Error: Ошибка на сервере.
- 200 OK: Успешное выполнение операции.
9. Дизлайк видео (/video/<int:video_id>/dislike):
-
Метод: POST
-
URL:
/video/<int:video_id>/dislike -
Параметры:
video_id(integer, required): ID видео.
-
Ответы:
- 200 OK: Успешное выполнение операции.
{ "status": "success", "action": "dislike" | "remove_dislike", "likes": <int>, "dislikes": <int> } - 401 Unauthorized: Пользователь не авторизован.
- 404 Not Found: Видео не найдено.
- 500 Internal Server Error: Ошибка на сервере.
- 200 OK: Успешное выполнение операции.
10. Подписка/отписка (/auth/profile/<int:user_id>/subscribe):
-
Метод: POST
-
URL:
/auth/profile/<int:user_id>/subscribe -
Параметры:
user_id(integer, required): ID пользователя, на которого подписываются/отписываются.
-
Ответы:
-
200 OK: Успешное выполнение операции.
{ "status": "success", "action": "subscribe" | "unsubscribe" } -
400 Bad Request: Ошибка (нельзя подписаться на себя).
{ "status": "error", "message": "Нельзя подписаться на себя" } -
401 Unauthorized: Пользователь не авторизован.
11. Скачивание видео (/download/<filename>):
- Метод: GET
- URL:
/download/<filename> - Параметры:
filename(string, required): Имя файла видео.
- Ответы:
- 200 OK: Успешное скачивание. Возвращает файл.
- 401 Unauthorized: Неавторизованный доступ. Перенаправление на
/. - 404 Not Found: Файл не найден. Перенаправление на
/.
12. Получение аватара (/static/uploads/avatars/<filename>):
- Метод: GET
- URL:
/static/uploads/avatars/<filename> - Параметры:
filename(string, required): Имя файла аватара.
- Ответы:
- 200 OK: Успешное получение файла. Возвращает файл изображения.
- 404 Not Found: Файл не найден.
13. Получение видео (/static/uploads/videos/<filename>):
- Метод: GET
- URL:
/static/uploads/videos/<filename> - Параметры:
filename(string, required): Имя файла видео.
- Ответы:
- 200 OK: Успешное получение файла. Возвращает видеофайл.
- 404 Not Found: Файл не найден.
14. Получение превью видео (/static/uploads/thumbnails/<filename>):
- Метод: GET
- URL:
/static/uploads/thumbnails/<filename> - Параметры:
filename(string, required): Имя файла thumbnail.
- Ответы:
- 200 OK: Успешное получение файла. Возвращает файл изображения.
- 404 Not Found: Файл не найден.
Общие коды состояния и обработка ошибок:
- 400 Bad Request: Некорректный запрос (например, отсутствуют обязательные параметры, неверный формат данных).
- 401 Unauthorized: Требуется аутентификация.
- 403 Forbidden: Доступ запрещен (например, попытка изменить чужой профиль).
- 404 Not Found: Ресурс не найден (например, видео с указанным ID не существует).
- 500 Internal Server Error: Внутренняя ошибка сервера.
Для большинства ошибок используются flash-сообщения, которые отображаются пользователю на следующей странице. Для AJAX-запросов (лайки, дизлайки, подписки) ошибки возвращаются в формате JSON.
1. Хранение и обработка видео:
- Хранение: Видеофайлы хранятся в директории
app/static/uploads/videos, а превью к ним – вapp/static/uploads/thumbnails. Имена файлов генерируются с использованиемuuid.uuid4().hexдля обеспечения уникальности. Пути к файлам хранятся в базе данных. - Обработка: Для создания превью используется библиотека
FFmpeg. Функцияgenerate_thumbnail(вapp/services/thumbnail_service.py) выполняет командуffmpegчерезsubprocess.run.ffmpeg -i video_path -ss 00:00:05 -vframes 1 thumbnail_path: Эта команда извлекает кадр из видео (-i video_path) на 5-й секунде (-ss 00:00:05) и сохраняет его как изображение (-vframes 1 thumbnail_path).
- Оптимизация: Превью создаются в формате JPEG, что обеспечивает хороший баланс между качеством и размером файла. Для самих видео можно использовать кодирование с переменным битрейтом (VBR) для оптимизации размера файла в зависимости от сложности сцен.
- Безопасность: Имена файлов видео и thumbnail, получаемые от пользователя, обрабатываются функцией
secure_filename, что помогает предотвратить атаки типа "Path Traversal".
2. Система аутентификации и авторизации:
- Аутентификация: Реализована с использованием Flask-Session. При входе пользователя в сессию записываются его ID и имя пользователя.
- Авторизация: Для защиты маршрутов, требующих авторизации, используется декоратор
login_required(вapp/routes/auth.py). Он проверяет наличиеuser_idв сессии. - Хеширование паролей: Пароли пользователей хранятся в базе данных в зашифрованном виде. Используется функция
generate_password_hashиз библиотекиWerkzeugдля хеширования пароля при регистрации иcheck_password_hashдля проверки пароля при входе. - Защита от CSRF: Flask-Session по умолчанию включает защиту от CSRF.
- Безопасность сессий: В конфигурации приложения (
app/__init__.py) настроены параметры сессий:SESSION_TYPE='filesystem': сессии хранятся в файловой системе;SESSION_PERMANENT=False: сессии не являются постоянными (удаляются при закрытии браузера);SESSION_USE_SIGNER=True: сессии подписываются, что защищает их от подделки.
3. Механизмы кэширования:
- В текущей версии проекта кэширование явно не реализовано.
- Потенциальные улучшения:
- Кэширование на уровне приложения: Можно использовать Flask-Caching для кэширования результатов запросов к базе данных, метаданных видео, списков популярных видео и т.д.
- Кэширование на уровне браузера: Можно настроить HTTP-заголовки (
Cache-Control,Expires) для кэширования статических файлов (CSS, JavaScript, изображения) в браузере пользователя. - Кэширование на уровне сервера (CDN): Для более крупных проектов можно использовать CDN (Content Delivery Network) для кэширования видеофайлов и другого статического контента ближе к пользователям.
4. Оптимизация производительности:
- Использование превью: Вместо полноразмерных изображений видео на страницах списков используются превью, что значительно сокращает время загрузки страниц.
- Пагинация: На главной странице и в профиле пользователя реализована пагинация для списков видео (по 12 видео на страницу). Это предотвращает загрузку большого количества данных за один раз.
- Ленивая загрузка: Можно реализовать ленивую загрузку изображений (превью) с помощью JavaScript, чтобы изображения загружались только тогда, когда они попадают в область видимости пользователя.
- Асинхронная загрузка комментариев: Можно реализовать асинхронную загрузку комментариев с помощью JavaScript (Fetch API), чтобы не блокировать загрузку страницы.
- Оптимизация запросов к БД: Использование индексов в БД для ускорения поиска и выборки данных.
5. Обработка ошибок и логирование:
- Обработка ошибок: В коде приложения используются блоки
try...exceptдля обработки исключений (например, при сохранении файлов, создании превью). В случае ошибок пользователю выводятся соответствующие сообщения с помощьюflash. - Логирование: В
app/__init__.pyнастроено базовое логирование с уровнемINFO. Это позволяет отслеживать основные события в приложении. В production-среде рекомендуется использовать более детальное логирование и сохранять логи в файл. - Обработка 404 ошибки: При обращении к несуществующему видео или пользователю, происходит перенаправление на главную страницу и выводится flash сообщение.
В проекте на данный момент не представлены тесты.
Обзор стратегии тестирования:
- Unit-тесты: Должны проверять отдельные функции и методы классов (моделей, сервисов). Например, тесты для функций
User.create,User.verify_password,Video.create,generate_thumbnail,save_videoи т.д. - Integration-тесты: Должны проверять взаимодействие между различными компонентами приложения (например, между маршрутами и моделями, между сервисами и моделями).
- E2E-тесты (End-to-End): Должны проверять работу приложения в целом, имитируя действия пользователя (например, регистрация, вход, загрузка видео, добавление комментария).
Инструменты:
- unittest: Встроенный модуль Python для unit-тестирования.
- pytest: Более мощный и удобный фреймворк для тестирования.
- Flask-Testing: Расширение Flask для тестирования веб-приложений.
- Selenium: Инструмент для автоматизации браузера (для E2E-тестов).
- Coverage: Инструмент для измерения покрытия кода тестами.
Пример unit-теста (с использованием pytest):
# tests/test_models.py
import pytest
from app.models.user import User
from app import create_app, db
@pytest.fixture
def app():
app = create_app({'TESTING': True, 'DATABASE': 'test_litvideo.db'})
with app.app_context():
db.init_db() # Создаем таблицы в тестовой БД
yield app
with app.app_context():
db.close_db() # Закрываем соединение
import os
os.remove('instance/test_litvideo.db') # Удаляем тестовую БД
@pytest.fixture
def client(app):
return app.test_client()
def test_create_user(app):
with app.app_context():
User.create('testuser', 'testpassword')
user = User.get_by_username('testuser')
assert user is not None
assert User.verify_password('testuser', 'testpassword')Запуск тестов:
pytestПокрытие кода тестами:
В данный момент информация о покрытии кода тестами отсутствует. Рекомендуется использовать инструмент coverage для измерения покрытия и стремиться к высокому показателю (80-90% и выше).
Варианты развертывания:
- Heroku: Облачная платформа (PaaS), предоставляющая простой способ развертывания веб-приложений.
- DigitalOcean: Облачный хостинг, предоставляющий виртуальные серверы (VPS).
- AWS, Google Cloud Platform, Microsoft Azure: Крупные облачные платформы, предоставляющие широкий спектр сервисов, включая виртуальные серверы, базы данных, хранилища объектов и т.д.
- Собственный сервер: Развертывание на собственном физическом или виртуальном сервере.
Руководство по развертыванию (пример для DigitalOcean с использованием Docker):
-
Создайте виртуальный сервер (Droplet) на DigitalOcean:
- Выберите операционную систему (например, Ubuntu).
- Выберите тарифный план.
- Настройте SSH-ключи.
-
Подключитесь к серверу по SSH:
ssh root@<ваш_ip_адрес>
-
Установите Docker и Docker Compose:
# Обновляем список пакетов sudo apt update # Устанавливаем необходимые пакеты sudo apt install -y apt-transport-https ca-certificates curl software-properties-common # Добавляем GPG-ключ Docker curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - # Добавляем репозиторий Docker sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" # Снова обновляем список пакетов sudo apt update # Устанавливаем Docker CE sudo apt install -y docker-ce # Устанавливаем Docker Compose sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose
-
Склонируйте репозиторий проекта на сервер:
git clone RfailesDev/LitVideo cd LitVideo -
Создайте файл
.envи настройте переменные окружения (обязательно!):SECRET_KEY=<ваш_секретный_ключ> DATABASE=../instance/litvideo.db -
Соберите Docker-образ и запустите контейнер:
sudo docker build -t litvideo . sudo docker run -d -p 80:8000 --name litvideo-app -v $(pwd)/instance:/app/instance litvideo
-p 80:8000: Проброс портов. Порт 80 на хост-машине будет перенаправлен на порт 8000 в контейнере.-v $(pwd)/instance:/app/instance: монтирование папкиinstanceв контейнер (чтобы БД сохранялась).litvideo- тэг образа.litvideo-app- имя контейнера.
-
Настройте Nginx (или другой веб-сервер) в качестве обратного прокси (рекомендуется):
Это позволит:
- Обрабатывать HTTPS-запросы (с использованием SSL-сертификата).
- Кэшировать статические файлы.
- Балансировать нагрузку (если у вас несколько экземпляров приложения).
CI/CD интеграция:
В проекте не настроена CI/CD интеграция. Рекомендуется настроить автоматическую сборку и развертывание приложения при каждом push в репозиторий. Для этого можно использовать такие инструменты, как:
- GitHub Actions: Интегрирован с GitHub, позволяет создавать workflows для автоматизации различных задач.
- GitLab CI/CD: Интегрирован с GitLab.
- Jenkins: Популярный инструмент с открытым исходным кодом.
- CircleCI, Travis CI: Облачные сервисы.
Если вы хотите внести свой вклад в развитие проекта, следуйте этим шагам:
-
Сделайте форк репозитория: Нажмите кнопку "Fork" на странице репозитория на GitHub.
-
Склонируйте форк на свой локальный компьютер:
git clone <ссылка_на_ваш_форк> cd LitVideo
-
Создайте новую ветку для своей фичи или исправления:
git checkout -b feature/my-new-feature # Или git checkout -b bugfix/some-bug -
Внесите изменения в код.
-
Закоммитьте изменения:
git add . git commit -m "Добавлена новая функция" # Или другое осмысленное сообщение
-
Отправьте изменения в свой форк:
git push origin feature/my-new-feature
-
Создайте Pull Request: На странице своего форка на GitHub нажмите кнопку "New pull request" и выберите свою ветку. Опишите внесенные изменения и укажите, какую проблему они решают.
Стиль кода и стандарты:
- Следуйте PEP 8 (руководство по стилю кода Python).
- Пишите понятный и хорошо документированный код.
- Используйте осмысленные имена переменных и функций.
- Добавляйте тесты для нового функционала.
Рекомендации для новых участников:
- Перед началом работы ознакомьтесь с кодовой базой проекта.
- Начните с небольших задач, чтобы освоиться.
- Не стесняйтесь задавать вопросы.
- Будьте вежливы и уважайте других участников проекта.
Ближайшие планы:
- Добавить тесты: Написать unit-, integration- и E2E-тесты для обеспечения стабильности и надежности приложения.
- Реализовать систему модерации: Добавить инструменты для модерации контента (жалобы, блокировка пользователей, удаление видео).
- Перейти на PostgreSQL: Заменить SQLite на PostgreSQL для повышения производительности и масштабируемости.
- Настроить CI/CD: Автоматизировать сборку, тестирование и развертывание приложения.
- Добавить постраничную навигацию в профиле пользователя.
Долгосрочные планы:
- Реализовать систему уведомлений: Уведомления о новых подписчиках, комментариях, лайках.
- Добавить возможность редактирования видео: Изменение названия, описания, превью.
- Реализовать систему личных сообщений: Обмен сообщениями между пользователями.
- Добавить поддержку различных форматов видео: Расширить список поддерживаемых форматов.
- Реализовать систему рекомендаций: Рекомендации видео на основе истории просмотров и предпочтений пользователя.
- Добавить поддержку субтитров: Загрузка и отображение субтитров к видео.
- Реализовать аналитику: Сбор статистики о просмотрах, лайках, дизлайках, подписчиках и т.д.
- Добавить возможность проведения прямых трансляций.
- Создать мобильное приложение.
- Автор: RfailesDev, Viktor Brown, Bill Jones, Robert King



