93 lines
4.3 KiB
Markdown
93 lines
4.3 KiB
Markdown
# 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) вводим только когда конкретная фича упрётся в текущую реализацию.
|