Jellybit

Jellybit — связующий сервис между qBittorrent и Jellyfin. Принимает торрент (magnet, .torrent или ссылку) вместе с текстовым контекстом, ставит загрузку в qBittorrent, дожидается её завершения, распознаёт содержимое (фильм или сериал, сезоны и серии) и раскладывает готовые файлы по конвенциям библиотеки Jellyfin.

Полный замысел и причины — в BRIEF.md.

Зачем

Arr-стек (prowlarr/radarr/sonarr) плохо ложится на русские трекеры, аниме и ручные раздачи. Jellybit намеренно сокращает путь: одна точка входа → готовая раскладка для Jellyfin, без каталога индексаторов и сложных правил качества. Распознавание делает LLM, которому помогает переданный человеком контекст и (опционально) внешние базы метаданных.

Как работает

  1. Точка входа принимает torrent/magnet + контекст (HTTP API, веб-UI или Telegram-бот).
  2. Загрузка ставится в qBittorrent в выделенную категорию.
  3. Сервис отслеживает завершение загрузки.
  4. По именам файлов, контексту и (опц.) базам метаданных определяется фильм/сериал и нужная раскладка.
  5. Файлы хардлинкаются в библиотеку Jellyfin — источник остаётся в раздаче, место на диске не дублируется.

При высокой уверенности раскладка выполняется автоматически, иначе — уходит на подтверждение человеку.

Статус

Ранняя разработка. Готовы каркас (Ф0) и приём + трекинг (Ф1): добавление magnet в qBittorrent, идемпотентность по infohash, поллинг завершения и машина состояний (downloading → completed, плюс stuck/failed); наружу — REST API, веб-UI и jellybit add. Источники кроме magnet (.torrent/url) и распознавание (Ф2) — дальше. См. дорожную карту.

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

  • docs/specs/ — спецификации: целевое устройство системы. Начать с architecture.md.
  • docs/adr/ — журнал архитектурных решений (почему так).
  • docs/drafts/ — черновики: планы, идеи, нерешённое.

Стек

Go (один статический бинарь), SQLite (modernc.org/sqlite + sqlx, миграции goose), HTTP — chi + html/template + htmx, конфигурация — TOML, логи — структурированный JSON (slog). Подробнее — в architecture.md.

Разработка

Нужны Go 1.26 и Task. Полный список задач — task --list.

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-образ из готового бинаря

Отладка распознавания на реальной раздаче (только чтение, без раскладки):

jellybit recognize <infohash> --dry-run [--context "..."] --config ./config.toml

Берёт торрент из qBittorrent по infohash, прогоняет распознавание (LLM + метабазы) и печатает план: тип/название/год, матч в базе, решение авто/review и превью целевых путей — то, что создалось бы при Apply.

Доставка

Сборка здесь → готовый бинарь копируется на медиа-сервер umbar (/home/av/projects/private/umbar). Деплой-обвязка живёт в umbar.

Артефакты этого репозитория: статический бинарь (task build) и Dockerfile (упаковка в distroless/static). Образ собирается на сервере из доставленного бинаря — Go-тулчейн на сервере не нужен. В distroless нет shell/curl, поэтому HEALTHCHECK зовёт сам бинарь: jellybit healthcheck (GET /healthz по порту из конфига, exit 0/1).

Деплой одной командой из umbar (собирает бинарь локально, доставляет, строит образ на сервере, рендерит конфиг с секретами из vault, поднимает compose):

inv pl -- jellybit       # umbar/playbook-jellybit.yml

Контейнер: user 1000:1000, порт 8080 на хост, mount /srv/media (единая песочница для хардлинков) + data-том с config.toml/SQLite, к qBittorrent — через host.docker.internal.

S
Description
No description provided
Readme 520 KiB
Languages
Go 97.1%
HTML 2.6%
Dockerfile 0.3%