99 lines
6.0 KiB
Markdown
99 lines
6.0 KiB
Markdown
# Jellybit
|
||
|
||
Jellybit — связующий сервис между qBittorrent и Jellyfin. Принимает
|
||
magnet-ссылку вместе с текстовым контекстом, ставит загрузку в
|
||
qBittorrent, дожидается её завершения, распознаёт содержимое (фильм или
|
||
сериал, сезоны и серии) и раскладывает готовые файлы по конвенциям
|
||
библиотеки Jellyfin.
|
||
|
||
Полный замысел и причины — в [BRIEF.md](BRIEF.md).
|
||
|
||
## Зачем
|
||
|
||
Arr-стек (prowlarr/radarr/sonarr) плохо ложится на русские трекеры,
|
||
аниме и ручные раздачи. Jellybit намеренно сокращает путь: одна точка
|
||
входа → готовая раскладка для Jellyfin, без каталога индексаторов и
|
||
сложных правил качества. Распознавание делает LLM, которому помогает
|
||
переданный человеком контекст и (опционально) внешние базы метаданных.
|
||
|
||
## Как работает
|
||
|
||
1. Точка входа принимает magnet + контекст (HTTP API, веб-UI,
|
||
Telegram-бот или CLI).
|
||
2. Загрузка ставится в qBittorrent в выделенную категорию.
|
||
3. Сервис отслеживает завершение загрузки.
|
||
4. По именам файлов, контексту и (опц.) базам метаданных определяется
|
||
фильм/сериал и нужная раскладка.
|
||
5. Файлы **хардлинкаются** в библиотеку Jellyfin — источник остаётся в
|
||
раздаче, место на диске не дублируется.
|
||
|
||
При высокой уверенности раскладка выполняется автоматически, иначе —
|
||
уходит на подтверждение человеку.
|
||
|
||
Доступ к внешним сервисам (LLM, базы метаданных, Telegram) при
|
||
необходимости идёт через HTTP-прокси — задаётся полем `proxy` в
|
||
соответствующих секциях конфигурации.
|
||
|
||
## Статус
|
||
|
||
Рабочий прототип с полным сквозным путём: приём magnet → загрузка в
|
||
qBittorrent → распознавание (LLM + опционально базы метаданных
|
||
TMDB/TVDB/TVMaze) → раскладка в библиотеку хардлинками, автоматически при
|
||
уверенном результате либо через подтверждение человеком. Транспорты приёма:
|
||
REST API, веб-UI, Telegram-бот и CLI (`jellybit add`).
|
||
|
||
Из источников пока поддержан magnet; `.torrent` и обычные ссылки — в планах.
|
||
См. [дорожную карту](docs/drafts/roadmap.md).
|
||
|
||
## Документация
|
||
|
||
- [docs/specs/](docs/specs/) — спецификации: целевое устройство системы.
|
||
Начать с [architecture.md](docs/specs/architecture.md).
|
||
- [docs/adr/](docs/adr/) — журнал архитектурных решений (почему так).
|
||
- [docs/drafts/](docs/drafts/) — черновики: планы, идеи, нерешённое.
|
||
|
||
## Стек
|
||
|
||
Go (один статический бинарь), SQLite (`modernc.org/sqlite` + `sqlx`,
|
||
миграции `goose`), HTTP — `chi` + `html/template` + htmx, конфигурация —
|
||
TOML, логи — структурированный JSON (`slog`). Подробнее — в
|
||
[architecture.md](docs/specs/architecture.md).
|
||
|
||
## Разработка
|
||
|
||
Нужны Go 1.26 и [Task](https://taskfile.dev). Полный список задач —
|
||
`task --list`.
|
||
|
||
```bash
|
||
cp config.example.toml config.toml # локально: db_path -> ./jellybit.db
|
||
task setup # golangci-lint + git-хуки lefthook
|
||
task tidy # go mod tidy
|
||
task run # go run ./cmd/jellybit --config ./config.toml
|
||
task test lint # тесты и golangci-lint
|
||
task build # статический бинарь (linux/amd64) для сервера
|
||
task image # docker-образ из готового бинаря
|
||
```
|
||
|
||
Отладка распознавания на реальной раздаче (только чтение, без раскладки):
|
||
|
||
```bash
|
||
jellybit recognize <infohash> --dry-run [--context "..."] --config ./config.toml
|
||
```
|
||
|
||
Берёт торрент из qBittorrent по infohash, прогоняет распознавание (LLM +
|
||
метабазы) и печатает план: тип/название/год, матч в базе, решение авто/review
|
||
и превью целевых путей — то, что создалось бы при Apply.
|
||
|
||
## Доставка
|
||
|
||
Рассчитан на домашний медиа-сервер. Артефакты репозитория — статический
|
||
бинарь (`task build`) и `Dockerfile` (упаковка в `distroless/static`). Образ
|
||
собирается **на сервере** из доставленного бинаря, поэтому Go-тулчейн на
|
||
сервере не нужен. В distroless нет shell/curl, поэтому HEALTHCHECK зовёт сам
|
||
бинарь: `jellybit healthcheck` (GET `/healthz` по порту из конфига, exit 0/1).
|
||
|
||
Контейнер: `user 1000:1000`, порт `8080` на хост, mount `/srv/media` (единая
|
||
песочница для хардлинков) + data-том с `config.toml`/SQLite; к qBittorrent —
|
||
по сети Docker. Конкретная деплой-обвязка (плейбук, секреты) держится в
|
||
отдельном приватном репозитории и в комплект не входит.
|