Добавлено описание проекта PVideoDl, включая функциональность, стек технологий, архитектуру, инструкции по запуску и API. Обновлён README.md для лучшего понимания проекта.

This commit is contained in:
Leonid Pershin
2026-06-19 12:07:55 +03:00
parent e15d0af056
commit 3281fa2a5d
43 changed files with 4699 additions and 0 deletions
+90
View File
@@ -1,2 +1,92 @@
# PVideoDl
Локальная скачивалка файлов и видео с веб-интерфейсом. Запускается одной командой,
открывается в браузере, принимает список ссылок, качает в фоне и показывает прогресс
в реальном времени.
- **Прямые файлы** (`.zip`, `.pdf`, `.mp4`, …) качаются через `httpx` по chunk'ам.
- **Видео с сайтов** (YouTube и сотни других) — через `yt-dlp`.
- Прогресс течёт в UI по **SSE** в реальном времени.
## Стек
- Бэкенд: Python 3.12, FastAPI, Uvicorn, httpx, yt-dlp, aiosqlite, sse-starlette
- Фронтенд: SvelteKit (SPA), TypeScript, Tailwind CSS v4, lucide-svelte
- Менеджер зависимостей: `uv`
## Архитектура
Реализации спрятаны за интерфейсами в `app/core/` — роуты и сервисы зовут абстракции,
а не конкретику. Сегодня `asyncio.Queue` + SQLite, завтра Redis + Postgres — меняется
только начинка обёртки.
```
app/
main.py точка входа, lifespan, отдача статики
config.py настройки (env PVDL_*)
models.py Pydantic-модели
api/ роуты: downloads.py, events.py (SSE)
core/ абстракции: queue.py, storage.py, events.py (EventBus)
services/ downloader.py (httpx/yt-dlp), worker.py (пул воркеров)
frontend/ SvelteKit SPA → собирается в frontend/build
```
## Запуск (прод, «для себя») — одна команда
Фронт собирается в статику, FastAPI отдаёт её с того же origin:
```bash
# 1. зависимости
uv sync
cd frontend && npm install && npm run build && cd ..
# 2. запуск
uv run pvideodl
```
Открыть <http://127.0.0.1:8000>. Файлы складываются в `downloads/`.
## Запуск (дев) — два процесса
```bash
# терминал 1 — бэкенд на :8000
uv run python -m app.main
# терминал 2 — Vite dev-сервер на :5173 (проксирует /api на :8000)
cd frontend && npm run dev
```
Открыть <http://localhost:5173> — с hot-reload фронта.
## API
| Метод | Путь | Назначение |
| -------- | --------------------- | ----------------------------------- |
| `POST` | `/api/downloads` | Добавить ссылки (`{"urls": [...]}`) |
| `GET` | `/api/downloads` | Список всех загрузок |
| `DELETE` | `/api/downloads/{id}` | Удалить задачу |
| `GET` | `/api/events` | SSE-поток обновлений прогресса |
| `GET` | `/api/health` | Проверка живости |
## Настройки (переменные окружения)
| Переменная | По умолчанию | Описание |
| ------------------- | ------------------ | ---------------------------- |
| `PVDL_DOWNLOAD_DIR` | `./downloads` | Куда складывать файлы |
| `PVDL_DB_PATH` | `./app.db` | Файл SQLite |
| `PVDL_STATIC_DIR` | `./frontend/build` | Собранная статика фронтенда |
| `PVDL_WORKERS` | `3` | Сколько воркеров параллельно |
| `PVDL_HOST` | `127.0.0.1` | Хост сервера |
| `PVDL_PORT` | `8000` | Порт сервера |
## Тесты
```bash
uv run pytest
```
## Задел на будущее
Эндпоинты `pause` / `resume` / `retry` и статус `PAUSED` лягут естественно —
модель и слои уже к ним готовы. Тяжёлую инфраструктуру (Redis, Celery, WebSocket,
Postgres) вводим только когда конкретная фича упрётся в текущую реализацию.