[2026-09-29] eagle: family/how-to/arr-stack-kraken.md family/index.md personal/tech/flaresolverr-taiga.md personal/tech/music-library-gap-analysis.md personal/tech/skill-arr-media-stack-setup-additions.md
This commit is contained in:
1 parent
d8313b126f
commit
fe5eff6854
5 files changed
+148
-785
No files matched your search
Executable → Regular
+143
-778
@@ -1,826 +1,191 @@
|
||||
---
|
||||
title: Arr Stack — Kraken
|
||||
title: Arr stack — Kraken
|
||||
created: '2026-05-23'
|
||||
updated: '2026-09-22'
|
||||
updated: '2026-09-29'
|
||||
type: tech
|
||||
namespace: family
|
||||
tags:
|
||||
- arr
|
||||
- radarr
|
||||
- sonarr
|
||||
- prowlarr
|
||||
- transmission
|
||||
- jellyfin
|
||||
- infra
|
||||
- kraken
|
||||
tags: [arr, kraken, radarr, sonarr, prowlarr, transmission, jellyfin]
|
||||
related:
|
||||
- '[[tech/jellyfin-config]]'
|
||||
- '[[tech/arr-stack-taiga]]'
|
||||
- '[[tech/prowlarr-flaresolverr-cloudflare]]'
|
||||
- '[[concepts/kraken-media-stack]]'
|
||||
- '[[personal/tech/lampac-deployment]]'
|
||||
- '[[family/how-to/lampac-torrents]]'
|
||||
- '[[family/projects/watchlist-automation]]'
|
||||
- "[[family/how-to/arr-stack-taiga]]"
|
||||
- "[[family/how-to/kraken-access]]"
|
||||
- "[[family/how-to/kraken-watchtower]]"
|
||||
- "[[personal/tech/kraken-docker-startup-order]]"
|
||||
---
|
||||
|
||||
# Arr Stack — Kraken
|
||||
# Arr stack — Kraken
|
||||
|
||||
## Pipeline
|
||||
Каноническая документация arr-стека на Kraken. Taiga описывается отдельно в [[family/how-to/arr-stack-taiga]].
|
||||
|
||||
```
|
||||
Prowlarr → Radarr + Sonarr → Transmission → Jellyfin
|
||||
↓
|
||||
router.py (cron 10min)
|
||||
↓
|
||||
symlinks → /media/{movies,cartoons,series,documentaries,...}/
|
||||
```
|
||||
## Архитектура
|
||||
|
||||
Два параллельных пути поступления контента:
|
||||
Prowlarr → Radarr / Sonarr → Transmission → /media
|
||||
↓
|
||||
media-pipeline / router.py
|
||||
↓
|
||||
Jellyfin через symlink
|
||||
|
||||
1. **Radarr/Sonarr** → качают в `/media/movies-radarr/` и `/media/series-sonarr/`
|
||||
2. **Transmission (ручные торренты)** → `on-download-complete.sh` → `sync.py` → `/media/{movies,cartoons,...}/`
|
||||
| Компонент | Порт | Назначение |
|
||||
|---|---:|---|
|
||||
| Prowlarr | 9696 | индексаторы и sync |
|
||||
| Radarr | 7878 | фильмы |
|
||||
| Sonarr | 8989 | сериалы |
|
||||
| Transmission | 9091 | torrent download client |
|
||||
| FlareSolverr | 8191 | browser challenge, если включён |
|
||||
| Jellyfin | 8096 | media server |
|
||||
|
||||
### router.py — жанровая маршрутизация
|
||||
Все arr-сервисы и Transmission должны видеть общую Docker-сеть media_net. Проверять фактические сети через docker inspect, а не только compose.
|
||||
|
||||
`router.py` читает NFO-файлы (которые Radarr/Sonarr создают при загрузке), определяет жанр и возрастной рейтинг, и создаёт symlink в нужную Jellyfin-библиотеку:
|
||||
## Пути
|
||||
|
||||
Базовый диск:
|
||||
|
||||
/srv/dev-disk-by-uuid-49e8f586-3839-4c5d-a1e1-58bfc3579ade/
|
||||
|
||||
Проверка реального диска:
|
||||
|
||||
readlink -f /srv/dev-disk-by-uuid-49e8f586-3839-4c5d-a1e1-58bfc3579ade
|
||||
df -h /srv/dev-disk-by-uuid-49e8f586-3839-4c5d-a1e1-58bfc3579ade
|
||||
|
||||
Внутри контейнеров media path — /media.
|
||||
|
||||
| Путь | Назначение |
|
||||
|---|---|
|
||||
| /media/movies-radarr | рабочая библиотека Radarr |
|
||||
| /media/series-sonarr | рабочая библиотека Sonarr |
|
||||
| /media/movies | Jellyfin movies |
|
||||
| /media/series | Jellyfin series |
|
||||
| /media/cartoons | Jellyfin cartoons |
|
||||
| /media/documentaries | Jellyfin documentaries |
|
||||
| /media/downloads/complete | завершённые ручные загрузки |
|
||||
|
||||
Не путать /media Kraken с /storage Taiga.
|
||||
|
||||
## Compose и restart
|
||||
|
||||
Перед изменением:
|
||||
|
||||
docker compose config -q
|
||||
docker compose ps
|
||||
|
||||
Определить владельца контейнера:
|
||||
|
||||
docker inspect <container> --format '{{index .Config.Labels "com.docker.compose.project"}} {{index .Config.Labels "com.docker.compose.project.config_files"}}'
|
||||
|
||||
Запускать compose из каталога, указанного в project.config_files. Не запускать второй compose с тем же container_name.
|
||||
|
||||
Проверка после reboot:
|
||||
|
||||
docker ps --format 'table {{.Names}} {{.Status}} {{.Networks}}'
|
||||
docker network inspect media_net
|
||||
docker compose ps
|
||||
|
||||
restart: unless-stopped не задаёт порядок между разными compose-проектами. Межпроектный порядок описан в [[personal/tech/kraken-docker-startup-order]].
|
||||
|
||||
## Media routing
|
||||
|
||||
Radarr/Sonarr используют рабочие каталоги, а router.py публикует их в Jellyfin через symlink:
|
||||
|
||||
| Источник | Условие | Цель |
|
||||
|---|---|---|
|
||||
| movies-radarr/ | Documentary | `/media/documentaries/` |
|
||||
| movies-radarr/ | Animation + !R/18+ | `/media/cartoons/` |
|
||||
| movies-radarr/ | всё остальное | `/media/movies/` |
|
||||
| series-sonarr/ | Documentary | `/media/documentaries-series/` |
|
||||
| series-sonarr/ | Animation + !TV-MA | `/media/cartoons-series/` |
|
||||
| series-sonarr/ | всё остальное | `/media/series/` |
|
||||
| movies-radarr | documentary | documentaries |
|
||||
| movies-radarr | animation без adult rating | cartoons |
|
||||
| movies-radarr | остальное | movies |
|
||||
| series-sonarr | documentary | documentaries-series |
|
||||
| series-sonarr | animation без TV-MA | cartoons-series |
|
||||
| series-sonarr | остальное | series |
|
||||
|
||||
**Расположение:** `/srv/dev-disk-by-uuid-49e8f586-3839-4c5d-a1e1-58bfc3579ade/docker/media-pipeline/router.py`
|
||||
**Запуск:** `python3 router.py --dry-run` (проверка) / `python3 router.py --apply` (исполнение)
|
||||
Проверка без изменений:
|
||||
|
||||
### media-router.sh — cron-скрипт для Telegram-уведомлений
|
||||
cd /srv/.../docker/media-pipeline
|
||||
python3 router.py --dry-run
|
||||
|
||||
Обёртка над `router.py`, которая:
|
||||
- запускает `router.py --apply`
|
||||
- если `Nothing to do` — **SILENT**, ничего не шлёт
|
||||
- если созданы symlink'и или ошибка — отправляет отчёт в Telegram Kraken
|
||||
Применение:
|
||||
|
||||
**Расположение:** рядом с `router.py` — `media-router.sh`
|
||||
**Cron (Kraken crontab):** каждые 10 минут
|
||||
**Telegram:** kraken_htpc_bot → чат @mallex87
|
||||
python3 router.py --apply
|
||||
|
||||
### sync.py — обработка ручных торрентов (Transmission)
|
||||
|
||||
`sync.py` работает внутри Transmission-контейнера. При завершении загрузки:
|
||||
1. Определяет название через TMDB API
|
||||
2. Определяет жанр
|
||||
3. Перемещает файл в `/media/{movies,cartoons,series,documentaries}/`
|
||||
4. Обновляет `downloadDir` в Transmission через RPC
|
||||
|
||||
**Расположение:** `/srv/.../docker/media-pipeline/sync.py`
|
||||
**Триггер:** `on-download-complete.sh` (смонтирован в Transmission как `/config/on-download-complete.sh:ro`)
|
||||
Ручные torrents обрабатываются sync.py и on-download-complete.sh. После перемещения обновлять location через Transmission RPC, а не вручную менять путь.
|
||||
|
||||
## Transmission
|
||||
|
||||
- **download-dir:** `/downloads` (без `complete`)
|
||||
- **incomplete-dir:** `/downloads/incomplete`
|
||||
- **Язык:** отключён auth для локальных
|
||||
- **RPC:** `localhost:9091`
|
||||
Проверка RPC:
|
||||
|
||||
При перемещении файлов для уже завершённых торрентов:
|
||||
1. Переименовать файл/папку под кейс торрента (Linux ext4 case-sensitive)
|
||||
2. Вызвать `torrent-set-location` с `move=false`
|
||||
3. Запустить торрент на сидирование
|
||||
docker exec transmission transmission-remote --list
|
||||
|
||||
## Cron'ы на Kraken (crontab)
|
||||
Проверка mount:
|
||||
|
||||
✅ **Watchlist-крон ВОССТАНОВЛЕН 2026-09-20 21:21** (был мёртв с 2026-06-20). Бэкап `~/crontab-backup-20260920-212155.txt`. Детали и разбор — в [[family/projects/watchlist-automation]].
|
||||
docker inspect transmission --format '{{range .Mounts}}{{.Source}} -> {{.Destination}}{{println}}'
|
||||
|
||||
Актуальное `crontab -l` юзера `kraken` (проверено 2026-09-22):
|
||||
```
|
||||
0 * * * * bash ~/scripts/sync-vault.sh # Obsidian sync
|
||||
0 * * * * pgs-to-srt.sh /media/downloads/complete # PGS→SRT новые
|
||||
0 3 * * * pgs-to-srt.sh /media # PGS→SRT вся библиотека
|
||||
0 2 * * * bash ~/scripts/watchlist-cleanup.sh --apply # cleanup просмотренного
|
||||
0 1 * * * bash ~/scripts/watchlist-nightly.sh # watchlist nightly (БЕЗ sync-down)
|
||||
0 9 * * 0 bash ~/scripts/watchlist-discover.sh # watchlist discover
|
||||
30 2 * * * bash ~/scripts/watchlist-catalog.sh # JSON-каталог для Lampa ← НОВЫЙ 2026-09-22
|
||||
```
|
||||
Если Radarr/Sonarr получают Authentication failure, проверить штатный download-client test, текущие RPC credentials и host transmission:9091. Password в Obsidian не записывать.
|
||||
|
||||
🔴 **`watchlist-catalog.sh` (30 2 * * *)** — генерация `watchlist.json` для модуля Catalog
|
||||
в Lampa + маркера `❓`. Порядок намеренный: nightly 01:00 → cleanup 02:00 → catalog 02:30.
|
||||
Детали: [[personal/tech/lampac-deployment]], разбор генератора —
|
||||
[[personal/plans/watchlist-tmdb-missing-marker]].
|
||||
## Prowlarr и FlareSolverr
|
||||
|
||||
⚠️ **`media-router.sh` (роутер symlink'ов, каждые 10 мин) в crontab ОТСУТСТВУЕТ.** В таблице «Два параллельных пути» выше он описан как работающий по cron 10min — фактически его там нет. Проверить, нужен ли: без него symlink'и в `/media/{movies,cartoons,...}/` не создаются автоматически.
|
||||
На Kraken proxy/DNS topology отличается от Taiga. Не переносить Taiga entrypoint и vless-proxy настройки сюда вслепую.
|
||||
|
||||
Точная проверка наличия любого крон-джоба (не верить доке, смотреть систему):
|
||||
```bash
|
||||
crontab -l # юзер kraken
|
||||
sudo crontab -l # root
|
||||
sudo ls -la /var/spool/cron/crontabs/ # все юзерские
|
||||
sudo grep -rl watchlist /var/spool/cron/ /etc/cron.d/ /etc/crontab
|
||||
systemctl --user list-timers --all ; systemctl list-timers --all | grep -i watchlist
|
||||
systemctl is-active cron # демон жив?
|
||||
```
|
||||
Приёмка индексаторов:
|
||||
|
||||
**Установка крон-джоба безопасно (с бэкапом):**
|
||||
```bash
|
||||
crontab -l > ~/crontab-backup-$(date +%Y%m%d-%H%M%S).txt
|
||||
cp ~/crontab-backup-*.txt /tmp/crontab-new.txt
|
||||
# дописать строки в /tmp/crontab-new.txt
|
||||
crontab /tmp/crontab-new.txt
|
||||
crontab -l # проверка
|
||||
grep -c watchlist /var/spool/cron/crontabs/kraken # демон подхватил?
|
||||
```
|
||||
1. Prowlarr видит flaresolverr:8191.
|
||||
2. Индексер имеет нужные tags.
|
||||
3. Реальный search возвращает результаты.
|
||||
4. IndexerStatus не содержит старый quarantine.
|
||||
5. LOG_LEVEL не пишет tracker credentials в logs.
|
||||
|
||||
## API Keys
|
||||
## Jellyfin
|
||||
|
||||
| Service | API Key |
|
||||
|-------------|----------------------|
|
||||
| Radarr | `cbcb8ec3...` |
|
||||
| Sonarr | `15fbec32...` |
|
||||
| Prowlarr | `134ac38a...` |
|
||||
Jellyfin читает target libraries: movies, series, cartoons, documentaries и варианты. movies-radarr и series-sonarr не добавлять в Jellyfin, если router должен быть единственным слоем публикации.
|
||||
|
||||
(Full keys truncated — retrieve from each service's settings page.)
|
||||
Проверка:
|
||||
|
||||
## Качество загрузки для НОВЫХ фильмов/сериалов (2026-09-04)
|
||||
docker inspect jellyfin --format '{{range .Mounts}}{{.Source}} -> {{.Destination}} ({{.Mode}}){{println}}'
|
||||
namei -l /srv/.../media/movies
|
||||
|
||||
`watchlist-sync` (автодобавление из watchlist) использует профиль **`WEB-4K (no remux)`** (Radarr id **7**, Sonarr id **7**) вместо бывшего `Any`/id=1.
|
||||
Проверять execute/traverse на каждом parent directory, uid/gid и read-only mount.
|
||||
|
||||
Что разрешает профиль (в порядке предпочтения, кодированные, БЕЗ remux/BR-DISK):
|
||||
- 2160p: HDTV / WEBDL / WEBRip / BluRay-2160p (кодир.)
|
||||
- fallback 1080p: HDTV / WEBDL / WEBRip / BluRay-1080p (кодир.)
|
||||
- fallback 720p: HDTV / WEBDL / WEBRip / BluRay-720p (кодир.)
|
||||
- **Запрещены:** Remux-1080p, Remux-2160p, BR-DISK, Raw-HD, SDTV/DVD/480/576.
|
||||
- cutoff = **Bluray-2160p (кодир.)**; upgrade выключен после скачивания.
|
||||
## Watchlist и cron
|
||||
|
||||
**Где менять:** `watchlist-sync/watchlist_sync/arr.py` строки `qualityProfileId: 7` (radarr_add ~L77, sonarr_add ~L112). НЕ редактировать профили вручную иначе watchlist-sync надо обновить на новый id. Создать/править профиль «WEB-4K (no remux)» — Radarr/Sonarr → Settings → Quality Profiles.
|
||||
Перед POST новой записи в Radarr/Sonarr делать pre-check существующей библиотеки. SeriesExistsValidator — duplicate, а не отказ индексатора.
|
||||
|
||||
✅ **Профиль подтверждён в бою (2026-09-20):** первый же фильм, добавленный через обновлённый `arr.py` (`Gladiator` 2000), взял релиз `UHD BDRip [H.265/2160p] [4K]` — то есть **4K, но кодированный `BDRip`, БЕЗ Remux**. Профиль фильтрует корректно, цель (4K без 60GB-ремьюксов) достигнута.
|
||||
Cron проверять фактически:
|
||||
|
||||
**Подтверждение через API (рабочие вызовы):**
|
||||
```bash
|
||||
# список профилей Sonarr (проверить что id=7 существует)
|
||||
curl -s "http://localhost:8989/sonarr/api/v3/qualityprofile" -H "X-Api-Key: $SONARR_KEY"
|
||||
# корневые папки (проверить /media/series-sonarr и freeSpace)
|
||||
curl -s "http://localhost:8989/sonarr/api/v3/rootfolder" -H "X-Api-Key: $SONARR_KEY"
|
||||
```
|
||||
crontab -l
|
||||
sudo crontab -l
|
||||
systemctl is-active cron
|
||||
|
||||
### 📁 Актуальные пути контейнеров (проверено 2026-09-20)
|
||||
Документация не доказывает, что job установлен. Перед изменением crontab делать backup и проверять новый crontab сразу после установки.
|
||||
|
||||
Пути на дисках легко перепутать — два HDD с разными UUID. Точные значения через `docker inspect`:
|
||||
## Watchtower и reboot pitfalls
|
||||
|
||||
| Сервис | Хост-путь конфига |
|
||||
|--------|-------------------|
|
||||
| Radarr | `/srv/dev-disk-by-uuid-6194539b-.../docker/radarr/config/` (внутри `config.xml` с ApiKey) |
|
||||
| Transmission | `/srv/dev-disk-by-uuid-6194539b-.../docker/transmission/` → `/config` (внутри `settings.json`) |
|
||||
| Медиа (общая) | `/srv/dev-disk-by-uuid-49e8f586-.../media/` → `/media` и `/downloads` |
|
||||
- Watchtower может остановить контейнеры через SIGTERM/SIGKILL во время update.
|
||||
- exit 137 не равен автоматически OOM; сверять kernel logs и Docker events.
|
||||
- depends_on работает только внутри одного compose-проекта.
|
||||
- Правка compose-файла не меняет уже созданный контейнер до up -d --force-recreate.
|
||||
- Bind mount и docker inspect важнее того, что написано в заметке.
|
||||
|
||||
⚠️ **НЕ** `/srv/...49e8f586.../docker/transmission/config/settings.json` — такого файла нет. Transmission на **6194539b**, Radarr-конфиг тоже на **6194539b** (в подпапке `config/`, не в корне radarr). Проверять через:
|
||||
```bash
|
||||
docker inspect radarr --format '{{range .Mounts}}{{.Source}} -> {{.Destination}}{{println}}{{end}}'
|
||||
docker inspect transmission --format '{{range .Mounts}}{{.Source}} -> {{.Destination}}{{println}}{{end}}'
|
||||
```
|
||||
## Troubleshooting
|
||||
|
||||
**Чтение ApiKey Radarr:** `grep -oP '(?<=<ApiKey>)[^<]+' /srv/...6194539b.../docker/radarr/config/config.xml`
|
||||
**Transmission RPC:** `docker exec transmission transmission-remote --list` (без `-n` работает, rpc-username пустой)
|
||||
|
||||
## Ports (Docker network `media_net`)
|
||||
|
||||
All services in the shared external network `media_net` — доступны друг другу по имени контейнера (`radarr:7878`, `prowlarr:9696`, `transmission:9091`, `flaresolverr:8191`) и с хоста по `kraken:<port>`:
|
||||
|
||||
| Service | Port |
|
||||
|--------------|------|
|
||||
| Radarr | 7878 |
|
||||
| Sonarr | 8989 |
|
||||
| Prowlarr | 9696 |
|
||||
| Transmission | 9091 |
|
||||
| Jellyfin | 8096 |
|
||||
| FlareSolverr | 8191 |
|
||||
|
||||
**Сеть (проверено 2026-09-20):** radarr, sonarr, prowlarr, transmission, flaresolverr — все в `media_net`. Пересечение сетей (radarr и transmission дополнительно ещё в `docker_default`) — нормально, роутинг по `media_net`.
|
||||
Порядок починки, если контейнер выпал из сети: `sudo docker network connect media_net <container>` (обратимо, без пересоздания) либо `docker compose up -d` из каталога сервиса.
|
||||
|
||||
## Jellyfin библиотеки
|
||||
|
||||
| Библиотека | Тип | Путь |
|
||||
| Симптом | Проверка | Действие |
|
||||
|---|---|---|
|
||||
| Movies | movies | `/media/movies` |
|
||||
| Series | tvshows | `/media/series` |
|
||||
| Cartoons | movies | `/media/cartoons` |
|
||||
| Cartoon Series | tvshows | `/media/cartoons-series` |
|
||||
| Documentaries | movies | `/media/documentaries` |
|
||||
| Documentary Series | tvshows | `/media/documentaries-series` |
|
||||
| Container conflict | compose labels | запускать из владельца проекта |
|
||||
| Prowlarr 0 results | real search + IndexerStatus | сеть, tags, proxy, quarantine |
|
||||
| Radarr/Sonarr 401 к Prowlarr | URL base и API path | сверить URL из API sync |
|
||||
| Transmission auth | download-client test | credentials и RPC path |
|
||||
| Jellyfin пустая библиотека | mount + namei -l | исправить parent traverse/read |
|
||||
| Symlink не появился | router.py --dry-run | проверить NFO, source и cron |
|
||||
| После reboot сервис не встал | проекты и restart policy | запускать каждый проект из его каталога |
|
||||
| Диск заполнен | df -h и disk usage | остановить auto-download перед cleanup |
|
||||
|
||||
## Безопасность
|
||||
|
||||
- API keys, passwords и tracker credentials не хранить в Obsidian.
|
||||
- Перед SQLite cleanup делать backup.
|
||||
- Не использовать rm -rf для media/config.
|
||||
- Не удалять torrents с deleteFiles=true без проверки hardlinks/symlinks.
|
||||
- Для cleanup сначала dry-run и список конкретных файлов.
|
||||
|
||||
## Связанные документы
|
||||
|
||||
- [[family/how-to/arr-stack-taiga]] — отдельный TrueNAS Taiga stack.
|
||||
- [[personal/tech/kraken-docker-startup-order]] — startup/reboot.
|
||||
- [[family/how-to/kraken-watchtower]] — Watchtower.
|
||||
- [[family/how-to/kraken-network]] — сеть.
|
||||
- [[family/how-to/kraken-access]] — доступ.
|
||||
|
||||
> `movies-radarr` и `series-sonarr` НЕ добавлены в Jellyfin — router.py создаёт symlink'и из них в перечисленные пути.
|
||||
|
||||
## Индексера Prowlarr — диагностика и починка (2026-09-20)
|
||||
|
||||
> ✅ **Задача закрыта в тот же день.** Ниже — история диагностики (полезна как метод), а актуальное решение с командами — в секции «🔴 Индексера Prowlarr — починка Cloudflare (2026-09-20)».
|
||||
> **Итог: было 3 «красных» из 6, стало 6/6 рабочих. Radarr 4/4, Sonarr 5/5 зелёные.**
|
||||
|
||||
Запрос Alex: «что с torrent трекерами в arr, красные». Диагноз снят по логам Prowlarr, не по теории.
|
||||
|
||||
### Что показывал UI на момент диагностики
|
||||
|
||||
| id | Индексер | privacy | Было | Стало |
|
||||
|----|----------|---------|------|-------|
|
||||
| 1 | RuTracker | semiPrivate | ❌ красный (Cloudflare) | ✅ 48 результатов на «matrix» |
|
||||
| 5 | Kinozal | semiPrivate | ❌ красный (Cloudflare) | ✅ 50 |
|
||||
| 6 | Kinozal (M) | semiPrivate | ❌ красный (Cloudflare) | ✅ 50 |
|
||||
| 2 | RuTor | public | ✅ 100 | ✅ 100 |
|
||||
| 4 | NoNaMe Club | public | ✅ 50 | ✅ 50 |
|
||||
| 3 | Byrutor | public | ✅ 6 | ✅ 6 |
|
||||
|
||||
### Root cause #1 — Cloudflare (RuTracker + Kinozal + Kinozal (M))
|
||||
|
||||
Из `/srv/.../docker/prowlarr/config/logs/prowlarr.debug.txt`:
|
||||
|
||||
```
|
||||
Warn|IndexerHttpClient|HTTP Error - Res: HTTP/2.0 [POST] https://rutracker.org/forum/login.php: 403.Forbidden (5620 bytes)
|
||||
<title>Just a moment...</title> ... challenges.cloudflare.com ... cType: 'managed'
|
||||
Warn|RuTracker|RuTracker HTTP request failed: [403:Forbidden] [POST] at [https://rutracker.org/forum/login.php]
|
||||
at NzbDrone.Core.Indexers.Definitions.RuTracker.DoLogin() in ./NzbDrone.Core/Indexers/Definitions/RuTracker.cs:line 103
|
||||
Error|Cardigann|Cloudflare protection detected for [Kinozal], Flaresolverr may be required.
|
||||
Error|Cardigann|Cloudflare protection detected for [Kinozal (M)], Flaresolverr may be required.
|
||||
Debug|IndexerFactory|Temporarily ignoring indexer RuTracker till 09/21/2026 17:30:42 due to recent failures.
|
||||
```
|
||||
|
||||
- RuTracker: CF **managed Turnstile** на `/forum/login.php` → Prowlarr не может залогиниться (нужен JS-челлендж). Аккаунт при этом может быть жив — падает именно логин.
|
||||
- Kinozal / Kinozal (M): kinozal.me тоже за Cloudflare, Prowlarr сам пишет «Flaresolverr may be required».
|
||||
- Лечится FlareSolverr-прокси (см. решение). На момент диагностики версия была **v2.5.2.5491**.
|
||||
|
||||
### Root cause #2 — Docker network split (Radarr полностью без индексеров)
|
||||
|
||||
```
|
||||
radarr: docker_default 172.22.0.3 ← НЕ видел prowlarr
|
||||
sonarr: media_net 172.23.0.2
|
||||
prowlarr: media_net 172.23.0.3
|
||||
transmission: docker_default 172.22.0.2 ← НЕ был виден сонаром
|
||||
```
|
||||
|
||||
Radarr `POST /api/v3/indexer/testall` → **все 4 индексера** `false`:
|
||||
`Unable to connect to indexer... Name does not resolve (prowlarr:9696)`
|
||||
|
||||
Вывод: **Radarr был красный не из-за трекеров, а из-за сети.** У Sonarr красные = реальные трекеры (CF).
|
||||
Ключевой урок: compose-файлы уже содержали `media_net`, но контейнеры остались в старой сети — **проверять фактическое `docker inspect`, а не compose-файл**.
|
||||
|
||||
### ⚠️ Питфолл: `POST /api/v3/indexer/test` по одному id НЕ работает
|
||||
|
||||
`{"indexerId": N}` на Radarr/Sonarr/Prowlarr возвращает **HTTP 400** со списком `validationFailures`: `'Name' must not be empty`, `'Implementation' must not be empty`, `'ConfigContract' must not be empty`, `'App Profile Id' must be greater than '0'`, `'Priority' must be between 1 and 50`. То есть эндпоинт валидирует тело как новый индексер, а не берёт существующий по id.
|
||||
|
||||
**Рабочий способ тестирования — `testall`:**
|
||||
|
||||
```bash
|
||||
# Radarr
|
||||
curl -s -X POST -H "X-Api-Key: $RKEY" \
|
||||
"http://localhost:7878/radarr/api/v3/indexer/testall" \
|
||||
| jq -r '.[] | "\(.id)\t\(.isValid)\t\(.validationFailures[0].errorMessage // "")"'
|
||||
|
||||
# Sonarr (UrlBase /sonarr)
|
||||
curl -s -X POST -H "X-Api-Key: $SKEY" \
|
||||
"http://localhost:8989/sonarr/api/v3/indexer/testall" \
|
||||
| jq -r '.[] | "\(.id)\t\(.isValid)\t\(.validationFailures[0].errorMessage // "")"'
|
||||
|
||||
# Prowlarr: тест одного индексера требует полного объекта из GET, не {indexerId}
|
||||
# Быстрая проверка «кто живой» — сразу поиском:
|
||||
curl -s -H "X-Api-Key: $PKEY" "http://localhost:9696/prowlarr/api/v1/search?query=matrix&type=search" \
|
||||
| jq -r 'group_by(.indexer)[] | "\(.[0].indexer): \(length)"'
|
||||
```
|
||||
|
||||
Поиск через Prowlarr полезнее теста индексеров: `?query=X&type=search` по умолчанию возвращает **до 100 результатов на индексер** (был соблазн прочитать «156 всего» как «по 26 на каждый» — неверно; смотреть `group_by(.indexer)`).
|
||||
|
||||
### Итог и уроки
|
||||
|
||||
Все три причины были независимы и требовали независимых фиксов:
|
||||
1. **Сеть** — `docker network connect media_net radarr|transmission` (обратимо, без пересоздания контейнеров).
|
||||
2. **FlareSolverr не применялся** — нужен одинаковый tag на прокси И на индексере (главная засада: при `tags=[]` молча не работает).
|
||||
3. **Блокировки в `IndexerStatus`** — рестарт контейнера их НЕ сбрасывает, чистить через `sqlite3` между stop/start.
|
||||
|
||||
Плюс побочно: RuTor не фильтрует по категориям → ему нужна категория `8000(Other)`, не `5000`.
|
||||
|
||||
**⚠️ Безопасность:** FlareSolverr на `LOG_LEVEL=info` пишет логин и пароль RuTracker в plaintext в свои логи. Обязательно `warning`.
|
||||
|
||||
## Известные проблемы
|
||||
|
||||
### 🔴 2026-09-22: авто-закачка УБРАНА ПОЛНОСТЬЮ
|
||||
|
||||
Требование Alex: **закачек быть не должно**. Сделано:
|
||||
|
||||
1. **`sync-down` вырезан из крона.** `watchlist-nightly.sh` стр. 32-36 — вызов закомментирован,
|
||||
вместо него `log "sync-down: ПРОПУЩЕН (автозакачка отключена 2026-09-22)"`.
|
||||
Бэкап `watchlist-nightly.sh.bak-20260922-182655`. Код `sync_down.py` НЕ удалён — можно
|
||||
запустить вручную.
|
||||
2. **16 авто-закачек удалены из Radarr** (все с `added >= 2026-09-20`) через API с
|
||||
`deleteFiles=true` — без этого параметра файл остаётся на диске сиротой.
|
||||
50 → 34 фильма, 12 с файлами, ошибок 0.
|
||||
Дамп для отката: `/tmp/radarr-sonarr-dump-20260922-184351/radarr-movies.json`.
|
||||
3. **Sonarr не тронут** — 13 сериалов, авто-закачек там не было.
|
||||
4. **Все 34 фильма `monitored=false`** — Radarr не будет ничего докачивать.
|
||||
|
||||
⚠️ **Порядок при удалении закачки критичен:** сначала `PUT monitored=false`, потом
|
||||
`DELETE` с `deleteFiles=true`. Иначе Radarr скачает заново.
|
||||
|
||||
### Ранее: инцидент переполнения диска (2026-09-21, устранён)
|
||||
|
||||
### Три страховки `sync-down` (введены 2026-09-21, коммиты `2642882`, `a131208`)
|
||||
|
||||
Читать перед любой правкой `sync_down.py` / `watchlist-nightly.sh`:
|
||||
|
||||
| Страховка | Где | Значение | Поведение |
|
||||
|---|---|---|---|
|
||||
| Проверка места | `sync_down.py` | `MIN_FREE_GB = 100.0` | `free < 100 GiB` → `[STOP]`, ничего не очередь |
|
||||
| Фильтр ужасов | `sync_down.py:95` | `candidate.is_horror()` | ужас без `⭐` → `[🧟] skipped` |
|
||||
| Приоритет | `sync_down.py` | `⭐` (U+2B50) | обходит **и** рейтинг, **и** ужасы |
|
||||
| Рейтинг | `sync_down.py` | `MIN_RATING = 6.0` | ниже → `[−] skipped` |
|
||||
| Батч | `watchlist-nightly.sh` | `--batch 2` | было 5 |
|
||||
|
||||
⚠️ **Проверка места — через `shutil.disk_usage`, НЕ `df`** (`df` учитывает root-резерв
|
||||
ext4 и завышает заполнение на ~4%). Путь из env `WATCHLIST_MEDIA_ROOT`, иначе — родитель
|
||||
watchlist-файла.
|
||||
|
||||
⚠️ **`⭐` (U+2B50) ≠ `✭` (U+272D).** `✭` — декоративная звёздочка в конце названия,
|
||||
срезается `_clean()` и **приоритетом НЕ является**. Не путать при чтении списка.
|
||||
|
||||
**Фильтр ужасов работает по ЖАНРУ (TMDB id 27), не по эмодзи.** В dry-run отсекается
|
||||
33 записи, хотя эмодзи `🧟♀️` стоит на 41 строке — жанр надёжнее ручной метки. Решение
|
||||
Alex: **ожидаемое поведение**; если фильм нужен — ставить `⭐`.
|
||||
|
||||
### `mark_queued` / `unmark_queued` — надёжность (те же коммиты)
|
||||
|
||||
`parser.py`: `mark_queued` возвращает **`bool`**, поглощает эмодзи-префикс
|
||||
(`🧟♀️`, `🗓️`, `⭐`, `✭`, `⬇️`…) и ставит метку **перед** ним:
|
||||
`- [ ] ⬇️ 🧟♀️ midsommar 2019`. Добавлена **`unmark_queued`** (её не было).
|
||||
`sync_down._mark()` логирует `[!] could not write ⬇️ marker` при промахе — раньше
|
||||
функция молча ничего не делала, и фильмы попадали в Radarr без метки.
|
||||
|
||||
⚠️ **Правило для будущих правок:** любая функция, мутирующая файл, должна возвращать
|
||||
результат, а вызывающий — его проверять. Молчаливый провал regex = тихая потеря данных.
|
||||
|
||||
### `_clean` — эмодзи и год (коммит `a131208`)
|
||||
|
||||
- `_EMOJI_PREFIX`: `^(?:[chars]+\s*)+` — **повторяющиеся** группы. Старая форма
|
||||
`^[chars]+\s*` брала только **первый** эмодзи, и `🧟♀️` оставался внутри `title`
|
||||
(уходил в TMDB и Radarr).
|
||||
- Год: `\(\d{4}(?:/\d{4})*\)` — `*`, не `+`. С `+` одиночный `(2022)` не срезался.
|
||||
Пара `(1995/2003)` от `mark_year_ambiguous` обрабатывается так же.
|
||||
- `sync_up._mark_watched`: учитывает эмодзи-префикс по обе стороны `⬇️`, сохраняет его.
|
||||
|
||||
- **⚠️ 2026-09-20: compose-файл может ВРАТЬ про сеть.** Ранее в compose Radarr был указан `jellyfin_default`, а реально контейнер жил в `docker_default`; при починке выяснилось, что compose уже писал `media_net`, но контейнеры не были пересозданы. **Всегда проверять фактическое `docker inspect -f '{{range $k,$v := .NetworkSettings.Networks}}{{$k}} {{end}}' <container>`, а не docker-compose.yml.**
|
||||
- **17 фильмов в Radarr `hasFile=False`** — ждут подходящего релиза в Prowlarr. Scream (1996) в процессе загрузки.
|
||||
- **Prowlarr** — если долго не находит релизы, проверить статус индексеров (`/api/v1/health`). ⚠️ health врёт, реальную причину блокировки смотреть в `config/logs/prowlarr.debug.txt` — см. секцию «🔴 Индексера Prowlarr — починка Cloudflare (2026-09-20)» ниже.
|
||||
- ✅ **2026-09-20: все индексера Prowlarr починены (6/6), Radarr 4/4 и Sonarr 5/5 зелёные.** Причины были: сеть (`docker_default` вместо `media_net`), непривязанный tag у FlareSolverr-прокси, и блокировки в `IndexerStatus`. Детали и команды — в секции ниже.
|
||||
- 🔴🔴 **2026-09-29: КАРАНТИН НА КРА́КЕНЕ ВСЁ ЕЩЁ СТОИТ (проверено вживую).**
|
||||
`SELECT ProviderId, EscalationLevel, DisabledTill FROM IndexerStatus` в
|
||||
`/srv/dev-disk-by-uuid-49e8f586-3839-4c5d-a1e1-58bfc3579ade/docker/prowlarr/config/prowlarr.db`:
|
||||
```
|
||||
1 RuTracker EscalationLevel=9 DisabledTill=2026-09-27 ← В КАРАНТИНЕ
|
||||
5 Kinozal 9 2026-09-27 ← В КАРАНТИНЕ
|
||||
6 Kinozal (M) 9 2026-09-27 ← В КАРАНТИНЕ
|
||||
2 RuTor 3 — 3 Byrutor 0 — 4 NoNaMe 0 —
|
||||
```
|
||||
⚠️ Фикс от 2026-09-24 (`shm_size: 1gb` + снятие `IndexerStatus`) **доведён не был** —
|
||||
записи остались. Список индексеров id 1–6 идентичен Тайге (RuTracker, RuTor, Byrutor,
|
||||
NoNaMe Club, Kinozal, Kinozal (M)).
|
||||
- 🔴 **2026-09-29: капча-солвера на Кра́кене НЕТ.** Проверено: `docker ps -a | grep -iE
|
||||
"solver|capsolve|2captcha|capmonster"` → только `flaresolverr`. В env FS —
|
||||
`LOG_LEVEL, BROWSER_TIMEOUT, PATH, LANG, GPG_KEY, PYTHON_*`, **нет `CAPTCHA_SOLVER`**.
|
||||
Единственный прокси-элемент: `(1, 'FlareSolverr', {"host":"http://flaresolverr:8191/",
|
||||
"requestTimeout":60})`. То есть **на Кра́кене нет средства решать капчу** — не ссылаться
|
||||
на него как на работающий образец.
|
||||
- **2026-09-29: у FS на Кра́кене объявлен `/config`, но он ПУСТ.** Монтирование
|
||||
`.../docker-data/volumes/fcca433276af5e66b4f8273956294532850cc9c37597d83d89c24f33dd694d49/_data
|
||||
=> /config`, `ls /config` → `total 8` (только `.` и `..`), `sessions: []`, FS `v3.5.2`.
|
||||
Persistent Chrome-профиль **фактически не используется**. Env: **`PROXY_URL` отсутствует** —
|
||||
на Кра́кене DNS-блока провайдера нет, FS ходит в трекер напрямую.
|
||||
- 🔴 **2026-09-24: РЕЦИДИВ — «6/6» больше не действует.** RuTracker (1), Kinozal (5), Kinozal (M) (6)
|
||||
снова заблокированы, `EscalationLevel=9`, `disabledTill=2026-09-25T10:17Z` — то есть **сутки**.
|
||||
Первопричина не Cloudflare и не теги (они на месте), а **FlareSolverr в crash-loop**:
|
||||
Chrome не поднимается под chromedriver (`session not created: cannot connect to chrome at
|
||||
127.0.0.1:PORT`), HTTP `:8191` не отвечает. Симптом в UI: `error IndexerProxyStatusCheck:
|
||||
All indexer proxies are unavailable due to failures`. Диагноз и незавершённый фикс
|
||||
(`shm_size: 1gb` + снятие `IndexerStatus`): [[personal/tech/prowlarr-flaresolverr-cloudflare]]
|
||||
§«2026-09-24». ⚠️ Ни `GET /api/v1/health`, ни `/api/v1/indexerstatus` пустотой не отделались —
|
||||
на этот раз они **показали** блокировки; но авторитет всё равно за `prowlarr.debug.txt`
|
||||
и таблицей `IndexerStatus`.
|
||||
- 🔴 **2026-09-24: swap на Кра́кене может быть МЁРТВ.** `/proc/swaps` пуст при живом
|
||||
`/var/swap` (512 MB), `dphys-swapfile` не поднимает его автоматически, строки в `/etc/fstab`
|
||||
нет. Лечение: `sudo swapon /var/swap` (⚠️ `swapoff -a && swapon -a` даёт `SwapFree: 0 kB`).
|
||||
Без swap Chrome-контейнеры падают при пике старта. Проверка: `cat /proc/swaps`.
|
||||
- **🔴 2026-09-04: 4K UHD Remux при Direct Play подтормаживает на ТВ (webOS).** Симптом у `Неистовый (Unhinged 2020)` — 60.9GB `...Remux.2160p.mkv` avg ~99 Мбит/с. После фикса eth0 Kraken → 1G (был 100M, см. [[kraken-network]]) торможение **сохранилось**. Подтверждено по логу Jellyfin `log_20260904.log`: сессия 10:18→10:28 «Jellyfin for WebOS 1.2.2», Stop at 400916ms (~6:40), **ни одной строки transcode → это Direct Play**, не CPU-рендер субтитров.
|
||||
- **🔴🔴 2026-09-04 (вживую): тормозит Direct Play даже лёгкого 4K → пока шло по Wi-Fi, причина не сервер/диск.** В живом воспроизведении по Wi-Fi `Project Hail Mary (2026)` (`...2160p.iT.WEB-DL...mkv`, HEVC Main10 4K HDR10+, avg ~24.5-25.7 Мбит/с, 30.2GB, Direct Play) подёргивание было, при этом: транскода нет (0 ffmpeg, CPU Kraken load 0.1), сервер отдаёт всего ~21 Мбит/с, Wi-Fi ТВ «чист» по MAC-счётчикам (0 CRC/0 retries, -53 dBm), линки с запасом ×10+.
|
||||
- ✅ **2026-09-04 РАЗРЕШЕНИЕ (проверено пользователем вживую):** после двух правок — (1) eth0 Kraken возвращён на **1G** (замена патч-корда) и (2) **ТВ переведён на проводной Ethernet** (100M downshift-линк) — и `Unhinged` (remux, ~89 Мбит/с), и `Project Hail Mary` (лёгкий 4K) **идут без тормозов**. Вывод: причиной были НЕ пропускная способность и НЕ декодер-клиента, а **нестабильный Wi-Fi-линк последней мили ТВ** (даже при чистых MAC-счётчиках — джиттер/переупорядочивание в зашумлённом эфире). Провод (даже 100M) стабильно отдаёт. Профиль `WEB-4K (no remux)` остаётся разумной страховкой, но не был обязательной причиной тормозов.
|
||||
|
||||
## Radarr Quality Profiles на Kraken (проверено 2026-09-04)
|
||||
|
||||
Via `http://kraken:7878/radarr/api/v3/qualityprofile` (X-Api-Key из config.xml; **UrlBase=`/radarr`**). Linuxserver image, сеть `media_net` (с 2026-09-20; ранее ошибочно жил в `docker_default`). Версия — см. таблицу актуальных версий ниже.
|
||||
|
||||
| id | Профиль | Разрешённые качества | Cutoff |
|
||||
|----|---------|----------------------|--------|
|
||||
| 1 | **Any** | весь диапазон CAM..BR-DISK, вкл. все 2160p | Remux-1080p |
|
||||
| 2 | SD | до Bluray-576p | — |
|
||||
| 3 | HD-720p | до Bluray-720p | — |
|
||||
| 4 | HD-1080p | HDTV/Bluray/Remux-1080p | Bluray-1080p |
|
||||
| 5 | **Ultra-HD** | HDTV/Bluray/**Remux-2160p** (BR-DISK не allowed) | **Remux-2160p** |
|
||||
| 6 | HD-720p/1080p | 1080p и ниже | — |
|
||||
| **7** | **WEB-4K (no remux)** ✅ создан | кодир. HDTV/WEB/BluRay **2160p+1080p+720p** | **Bluray-2160p (кодир.)** |
|
||||
| 8 | (если появится из id авто-инкремента — перепроверить) | — | — |
|
||||
|
||||
Профиль id=7 разрешает код HDTV/WEBDL/WEBRip/BluRay в 2160/1080/720; **запрещает** Remux-1080p, Remux-2160p, BR-DISK, Raw-HD, SDTV/DVD/480/576. upgrade выключен. Sonarr: аналогичный профиль тоже id=7.
|
||||
|
||||
- **Корень «почему новые качаются в любой жир»:** `watchlist-sync` (который добавляет фильмы/сериалы из watchlist в Radarr/Sonarr) жёстко прописывает `"qualityProfileId": 1` (= профиль `Any`) в `arr.py`:
|
||||
- Реальный путь репо: `/srv/dev-disk-by-uuid-6194539b-03e0-4f33-986b-4da09834e82f/watchlist-sync` (НЕ `~/Developer/watchlist-sync`, хотя симлинк `~/Developer/watchlist-sync` → `.../49e8.../watchlist-sync` есть; 49e8 — симлинк на 6194).
|
||||
- `watchlist_sync/arr.py` → `radarr_add()` (~стр 77) и `sonarr_add()` (~стр 112), обе `"qualityProfileId": 1`. Radarr POST `/api/v3/movie` c `addOptions.searchForMovie:true`; Sonarr POST `/api/v3/series`.
|
||||
- ✅ Решение принято и применено (см. выше): профиль `WEB-4K (no remux)` (Radarr/Sonarr id 7), fallback 1080→720, remux запрещён. Применено 2026-09-04.
|
||||
- ✅ **2026-09-04: стратегия качества РЕШЕНА И ПРИМЕНЕНА.** Новые фильмы/сериалы (через watchlist-sync) добавляются с профилем **`WEB-4K (no remux)`** (Radarr id 7, Sonarr id 7) — см. секцию «Качество загрузки для НОВЫХ». Fallback: если нет 2160p-кодированного — 1080p → 720p; remux не берётся никогда. Было принято так (fallback=1080, если нет — 720). Существующие файлы НЕ трогаются.
|
||||
|
||||
### Реальный состав жирного remux (пример Unhinged, ffprobe 2026-09-04)
|
||||
|
||||
Важно для понимания «что даёт remux» перед выбором профиля. Файл `Неистовый.2020.UHD.Blu-Ray.Remux.2160p.mkv` = **60.9GB, 1:31:05, контейнер 89.17 Мбит/с средний**.
|
||||
|
||||
FFprobe потоки:
|
||||
| idx | тип | кодек | каналы | язык / роль |
|
||||
|----|-----|-------|--------|------|
|
||||
| 0 | video | **HEVC Main10, 3840×2160, 24fps** | — | HDR10 (BT.2020, PQ smpte2084) |
|
||||
| 1 | audio | AC3 | 5.1(side) 384k | rus «Dub, iTunes» |
|
||||
| 2 | audio | **DTS-HD MA** | 7.1 | rus «Д. Есарев» |
|
||||
| 3 | audio | **TrueHD** | 7.1 | eng |
|
||||
| 4 | audio | AC3 | 5.1 640k | eng |
|
||||
| 5 | audio | DTS | stereo 320k | eng Commentary (реж. Деррик Борте) |
|
||||
| 6-8 | sub | SRT/SPU | — | rus / eng full / eng SDH |
|
||||
|
||||
Вывод: размер 60GB раздувает НЕ видео (HDR10 HEVC-часть типичная), а **множество звуковых дорожек (lossless DTS-HD MA + TrueHD) + аудиокомментарий**. «Что даёт remux» на бытовом ТВ: видео-выигрыш против аккуратного 4K-рипа почти незаметен с дивана; бонус реализуется только при lossless-прокачке звука (AVR/eARC). Если ТВ играет через собственные динамики/стерео или делает audio-transcode — плюс remux теряется, а вес/сеть/лаг остаются. Это аргумент за профиль «2160p без Remux» для бытового просмотра на webOS-TB.
|
||||
|
||||
### Бенчмарк WEB-4K (замерено по библиотеке Kraken, 2026-09-04)
|
||||
|
||||
«Поддерживаемое качество» для сравнения с жирным remux — это кодированные 2160p. Замер файлов с `WEB`+`2160` в имени в `/media`:
|
||||
- Полнометражки (2ч): `Project Hail Mary` 28.1GB, `The Drama` 19.2GB, `The Crow` 17.4GB, `They Will Kill You` 17.2GB, `Кот в сапогах` 19.9GB → **range 17–28GB, медиана ~19GB**.
|
||||
- 45-50 мин эпизоды док-сериалов (`prehistoric.planet` s01): ~7.2–7.7GB каждый.
|
||||
- Статсводка по всем 10 файлам: min 7.2 / median 12.5 / mean 13.9 / max 28.1 GB. Средний битрейт ~20–40 Мбит/с.
|
||||
- **Практичный floor benchmark: «нормальная» копия 4K для этого ТВ ≈ 17–28GB/фильм** (в 2.5–3× меньше remux). ⚠️ ⚠️ Важно: подёргивание 4K Direct Play (и лёгкого, и remux) было вызвано Wi-Fi-линком последней мили ТВ — по проводу оба идут (см. «РАЗРЕШЕНИЕ» в «Известные проблемы»). Напротив клиента webOS не виноват.
|
||||
|
||||
## 🔴 Индексера Prowlarr — починка Cloudflare (2026-09-20)
|
||||
|
||||
**Итог: было 3 «красных» из 6, стало 6/6 рабочих. Radarr 4/4, Sonarr 5/5 зелёные.**
|
||||
|
||||
### Симптом
|
||||
Radarr: `error IndexerLongTermStatusCheck` — «All indexers are unavailable due to failures for more than 6 hours».
|
||||
Sonarr: `error DownloadClientCheck` — «Unable to communicate with Transmission. Name does not resolve (transmission:9091)».
|
||||
В UI Prowlarr индексера RuTracker / Kinozal / Kinozal (M) показывались красными.
|
||||
|
||||
### Три независимые причины (все три надо было починить)
|
||||
|
||||
**(1) Сеть — Radarr и Transmission в неправильной сети.**
|
||||
Compose-файлы УЖЕ были прописаны на `media_net`, но живые контейнеры остались в `docker_default` (compose обновили, контейнеры не пересоздали). Итог: Radarr не резолвит `prowlarr:9696` → **все** индексеры false; Sonarr не резолвит `transmission:9091`.
|
||||
```bash
|
||||
sudo docker network connect media_net radarr
|
||||
sudo docker network connect media_net transmission
|
||||
# проверка: docker exec radarr getent hosts prowlarr
|
||||
# docker exec sonarr curl -sw "%{http_code}" http://transmission:9091/transmission/rpc → 409 = связь есть (штатный CSRF-ответ)
|
||||
```
|
||||
|
||||
**(2) FlareSolverr-прокси в Prowlarr не применялся (главный баг).**
|
||||
Контейнер `flaresolverr` был жив, запись прокси создана (`id=1`), но в логе Prowlarr — прямой `403 login.php`, а FlareSolverr вообще не вызывался.
|
||||
**Причина: в Prowlarr v2.x прокси применяется к индексерам ТОЛЬКО если у прокси И у индексера стоит одинаковый tag.** При `tags=[]` с обеих сторон прокси молча НЕ применяется, никакой ошибки в UI нет.
|
||||
```bash
|
||||
KEY=$(grep -oP "(?<=<ApiKey>)[^<]+" .../docker/prowlarr/config/config.xml)
|
||||
# 1. создать тег
|
||||
curl -X POST -H "X-Api-Key: $KEY" -H "Content-Type: application/json" \
|
||||
-d '{"label":"flaresolverr"}' http://localhost:9696/prowlarr/api/v1/tag
|
||||
# 2. повесить tag на ПРОКСИ
|
||||
curl -s -H "X-Api-Key: $KEY" http://localhost:9696/prowlarr/api/v1/indexerproxy/1 | jq ".tags=[1]" > /tmp/p.json
|
||||
curl -X PUT -H "X-Api-Key: $KEY" -H "Content-Type: application/json" -d @/tmp/p.json \
|
||||
http://localhost:9696/prowlarr/api/v1/indexerproxy/1
|
||||
# 3. повесить ТОТ ЖЕ tag на индексера (RuTracker=1, Kinozal=5, Kinozal M=6)
|
||||
curl -s -H "X-Api-Key: $KEY" http://localhost:9696/prowlarr/api/v1/indexer/1 | jq ".tags=[1]" > /tmp/i.json
|
||||
curl -X PUT -H "X-Api-Key: $KEY" -H "Content-Type: application/json" -d @/tmp/i.json \
|
||||
http://localhost:9696/prowlarr/api/v1/indexer/1
|
||||
```
|
||||
**Пруф работы** — только лог FlareSolverr, не UI:
|
||||
```bash
|
||||
sudo docker logs --tail 30 flaresolverr
|
||||
# → Challenge detected. Title found: Just a moment...
|
||||
# → Challenge solved!
|
||||
```
|
||||
Проверка поиска: `curl "http://localhost:9696/prowlarr/1/api?t=search&q=matrix&apikey=$KEY"` → RuTracker 48 items, Kinozal 50, Kinozal M 50, RuTor 100, NoNaMe 50.
|
||||
|
||||
**(3) Блокировки индексера в БД — рестарт их НЕ сбрасывает.**
|
||||
Prowlarr сам выключает упавший индексер на 24ч: `Temporarily ignoring indexer X till +24h`. В health API и `/api/v1/indexerstatus` это НЕ видно (оба возвращают пусто, врут) — только в debug-логе. Состояние лежит в таблице `IndexerStatus` в `prowlarr.db`.
|
||||
```bash
|
||||
sudo docker stop prowlarr
|
||||
sqlite3 /srv/.../docker/prowlarr/config/prowlarr.db "DELETE FROM IndexerStatus WHERE ProviderId IN (1,5,6);"
|
||||
sudo docker start prowlarr
|
||||
```
|
||||
⚠️ В контейнерах `sqlite3` НЕТ; на хосте Kraken `/usr/bin/sqlite3` ЕСТЬ.
|
||||
|
||||
> 🔴 **Тайга 2026-09-29:** эта процедура (`DELETE FROM IndexerStatus`) на Тайге **не выполнялась
|
||||
> ни разу** — карантины снимали тестами через API, что их **продлевало** (`EscalationLevel`
|
||||
> доходил до 9, `DisabledTill` +24 ч). Урок: **`POST /indexer/test` карантин не сбрасывает,
|
||||
> а эскалирует.** Всегда SQL. Разбор — [[personal/tech/flaresolverr-taiga]] §«IndexerStatus».
|
||||
>
|
||||
> ⚠️ **И общий предел метода (обе машины):** снятие карантина даёт `caps 200` и пустой
|
||||
> `indexerstatus`, но **не гарантирует работу поиска**. Если RuTracker не пропускает
|
||||
> автоматический логин (нет куки `bb_data` в cookies FS), поиск через него не идёт при
|
||||
> формально «зелёной» инфраструктуре. **Приёмка — `search` с `group_by(.indexer)`,**
|
||||
> не `caps` и не `health`.
|
||||
|
||||
**Побочно: RuTor не фильтрует по категориям.** У него в caps заявлены 2000(Movies)/5000(TV)/8000(Other), но при передаче `cat=5000` он возвращает 0 результатов, а без `cat` — 100. Prowlarr сам подсказывает в полях индексера: *«RuTor does not return categories in its search results. To sync to your apps, include 8000(Other)»*. Поэтому в Sonarr (indexer id=8) категория RuTor переставлена `5000` → `8000`.
|
||||
|
||||
### Версии и сервис
|
||||
- Prowlarr обновлён **2.5.2.5491 → 2.6.5.5623** (в 2.5.2 прокси-модель ещё только вводилась).
|
||||
- FlareSolverr `ghcr.io/flaresolverr/flaresolverr:latest` v3.5.2, порт 8191, сеть `media_net`, env `PROWLARR__FLARESOLVERR_URL=http://flaresolverr:8191`.
|
||||
- ⚠️ **FlareSolverr `LOG_LEVEL` понижен `info` → `warning`**: на level `info` FlareSolverr пишет `postData` запросов в лог, т.е. **логин и пароль RuTracker в plaintext**. После понижения — лог пуст, пароль не пишется.
|
||||
|
||||
### Бэкапы (перед изменениями)
|
||||
`/home/kraken/arr-fix-backup-20260920/` — networks.txt, 4× docker inspect, 3 compose-файла, `prowlarr.db.bak`, `prowlarr-config-preupgrade.tar.gz`.
|
||||
|
||||
### Диагностические грабли
|
||||
- `POST /api/v3/indexer/test` с телом `{"indexerId":N}` → HTTP 400 (валидирует как НОВЫЙ индексер, требует Name/Implementation). Для теста всех сразу: `POST /api/v3/indexer/testall`.
|
||||
- `GET /api/v1/health` в Prowlarr и `/api/v1/indexerstatus` НЕ показывают причины блокировки. Смотреть `.../docker/prowlarr/config/logs/prowlarr.debug.txt` (grep по имени индексера и `Cloudflare`/`403`).
|
||||
|
||||
## Sonarr `sonarr_add()` не проверяет дубли → `400 SeriesExistsValidator` (2026-09-20)
|
||||
|
||||
**Симптом:** при `sync-down` для уже существующей серии в логе появляется шум:
|
||||
```
|
||||
[!] 'Волшебный участок' — error: Client error '400 Bad Request' for url
|
||||
'http://localhost:8989/sonarr/api/v3/series?apikey=...'
|
||||
```
|
||||
|
||||
**Причина (безобидная):** серия **уже есть** в Sonarr. Тело ответа:
|
||||
```json
|
||||
[{"propertyName":"TvdbId","errorMessage":"This series has already been added",
|
||||
"attemptedValue":442038,"errorCode":"SeriesExistsValidator"}]
|
||||
```
|
||||
«Волшебный участок» → TVDB **Magical Police Department** (tvdbId=442038).
|
||||
|
||||
**Корень:** `watchlist_sync/arr.py::sonarr_add()` шлёт `POST /api/v3/series` **без pre-check**, в отличие от `radarr_add()`, где есть `radarr_exists()`. Sonarr отвечает ошибкой валидатора, `sync_down` ловит её как исключение и печатает `[!]`, не помечая позицию `⬇️`.
|
||||
|
||||
**Следствие:** позиция остаётся `[ ]` и будет заново пытаться добавиться на каждом прогоне, каждый раз занимая слот батча и не помечаясь.
|
||||
|
||||
**Починка (не сделана):** добавить проверку по `tvdbId` перед POST — как в Radarr. Реэкспорт `series/lookup` в Sonarr дубли не отсекает, проверять надо по библиотеке:
|
||||
```
|
||||
GET /api/v3/series → сверить tvdbId
|
||||
```
|
||||
|
||||
## Обновление Radarr / Sonarr (2026-09-20)
|
||||
|
||||
Watchtower их не обновлял (см. [[family/how-to/kraken-watchtower]]), поэтому обновлено вручную:
|
||||
**Radarr 6.1.1.10360 → 6.4.4.10685**, **Sonarr 4.0.17.2952 → 4.0.20.3014**.
|
||||
|
||||
```bash
|
||||
# Sonarr — метаданные проекта правильные, обычный up:
|
||||
cd /srv/.../docker/sonarr && sudo docker compose pull sonarr && sudo docker compose up -d sonarr
|
||||
```
|
||||
|
||||
### ⚠️ Ловушка: Radarr принадлежал ЧУЖОМУ compose-проекту
|
||||
|
||||
`docker compose up -d radarr` из `docker/radarr/` падал:
|
||||
`Conflict. The container name "/radarr" is already in use`.
|
||||
|
||||
Причина: контейнеры `radarr` и `transmission` были созданы **17.05.2026 из общего проекта `docker`** (файл `/srv/.../docker/docker-compose.yml`, **сейчас его нет — удалён**). Метаданные: `com.docker.compose.project=docker`. При этом `docker/radarr/docker-compose.yml` существовал и не использовался.
|
||||
|
||||
Проверка, к какому проекту принадлежит контейнер:
|
||||
```bash
|
||||
sudo docker inspect radarr -f '{{index .Config.Labels "com.docker.compose.project"}} {{index .Config.Labels "com.docker.compose.project.config_files"}}'
|
||||
```
|
||||
|
||||
Фикс (**данные в `config/` не трогаются**, только контейнер):
|
||||
```bash
|
||||
sudo docker stop radarr && sudo docker rm radarr
|
||||
cd /srv/.../docker/radarr && sudo docker compose up -d radarr
|
||||
# стало: project=radarr file=.../docker/radarr/docker-compose.yml, сеть media_net
|
||||
```
|
||||
`transmission` остался в проекте `docker` (его compose-файл в `docker/transmission/`), но подключён к `media_net` — работает.
|
||||
|
||||
### Диагностические грабли (Radarr/Sonarr API)
|
||||
|
||||
- `POST /api/v3/indexer/test` с телом `{"indexerId":N}` → **HTTP 400** (валидирует как НОВЫЙ индексер, требует Name/Implementation/AppProfileId). Использовать **`POST /api/v3/indexer/testall`**.
|
||||
- То же для клиентов: **`POST /api/v3/downloadclient/testall`**.
|
||||
- Триггер `UrlBase`: Radarr `/radarr/api/v3/...`, Sonarr `/sonarr/api/v3/...`.
|
||||
|
||||
### Итоговое состояние compose-проектов и сетей (2026-09-20)
|
||||
|
||||
После всех правок важно, потому что **`docker compose up -d` надо запускать из своего каталога**, иначе будет конфликт имени контейнера.
|
||||
|
||||
| Контейнер | Compose-проект | Файл | Сеть |
|
||||
|---|---|---|---|
|
||||
| radarr | `radarr` ✅ | `docker/radarr/docker-compose.yml` | `media_net` |
|
||||
| sonarr | `sonarr` ✅ | `docker/sonarr/docker-compose.yml` | `media_net` |
|
||||
| prowlarr | `prowlarr` ✅ | `docker/prowlarr/docker-compose.yml` | `media_net` |
|
||||
| flaresolverr | (в том же файле prowlarr) | `docker/prowlarr/docker-compose.yml` | `media_net` |
|
||||
| transmission | `transmission` ✅ | `docker/transmission/docker-compose.yml` | `media_net` |
|
||||
| watchtower | `watchtower` | `docker/watchtower/docker-compose.yml` | — |
|
||||
|
||||
✅ **`transmission` тоже исправлен (2026-09-20, позже в той же сессии).** Был в проекте `docker`, пересоздан так же: `stop` → `rm` → `up -d` из `docker/transmission/`. Данные **не пострадали**: 244 торрента в `./torrents/` + 244 resume-файла на месте, RPC вернул `torrents: 244`. Проверка перед пересозданием обязательна — считать торренты ДО и ПОСЛЕ:
|
||||
```bash
|
||||
sudo ls $D/transmission/torrents/ | wc -l # до и после должно совпасть
|
||||
```
|
||||
|
||||
**Общее правило:** если `docker compose up -d` даёт `Conflict. The container name "/X" is already in use` — контейнер принадлежит чужому (возможно, удалённому) compose-проекту. Смотреть `com.docker.compose.project` и `project.config_files`, затем `stop` → `rm` → `up -d` из правильного каталога. Данные в bind-mount (`config/`, `torrents/`) при этом не трогаются.
|
||||
|
||||
Проверка принадлежности любого контейнера:
|
||||
```bash
|
||||
sudo docker inspect <name> -f '{{index .Config.Labels "com.docker.compose.project"}} {{index .Config.Labels "com.docker.compose.project.config_files"}}'
|
||||
```
|
||||
|
||||
### Версии после обновления (2026-09-20)
|
||||
|
||||
| Сервис | Версия |
|
||||
|---|---|
|
||||
| Radarr | **6.4.4.10685** |
|
||||
| Sonarr | **4.0.20.3014** |
|
||||
| Prowlarr | **2.6.5.5623** |
|
||||
| FlareSolverr | 3.5.2 |
|
||||
| Watchtower | **1.22.2** (`nickfedor/watchtower`, см. [[family/how-to/kraken-watchtower]]) |
|
||||
|
||||
Автообновлением занимается Watchtower — **проверить его конфиг перед тем, как ждать обновлений**: [[family/how-to/kraken-watchtower]], теория — [[personal/tech/watchtower-docker-updates]].
|
||||
|
||||
## Автообновление (Watchtower) — 2026-09-20
|
||||
|
||||
Все сервисы стека (`radarr`, `sonarr`, `prowlarr`, `flaresolverr`, `transmission`) **плюс `jellyfin` и `portainer`** размечены label `com.centurylinklabs.watchtower.enable=true` → обновляются автоматически (7 контейнеров, проверено `scanned=7`). Полный разбор и список того, что НЕ обновляется: [[family/how-to/kraken-watchtower]]. Теория: [[personal/tech/watchtower-docker-updates]].
|
||||
|
||||
## Watchlist-sync: ручной запуск и баг дублирования (2026-09-20)
|
||||
|
||||
> Детальный разбор бага и полная механика — в [[family/projects/watchlist-automation]]. Здесь — операционная выжимка.
|
||||
|
||||
### Ручной запуск (пока крон не восстановлен)
|
||||
|
||||
```bash
|
||||
ssh kraken
|
||||
bash ~/scripts/watchlist-nightly.sh # pull → process-thumbs → resolve → sync-down → sync-up → push
|
||||
```
|
||||
Отдельные шаги:
|
||||
```bash
|
||||
cd /srv/dev-disk-by-uuid-49e8f586-3839-4c5d-a1e1-58bfc3579ade/watchlist-sync
|
||||
uv run --project . watchlist-sync <resolve|sync-down|sync-up|process-thumbs|discover> [--apply] [--recheck] [--batch N]
|
||||
```
|
||||
`uv` = `~/.local/bin/uv`. Без `--apply` — dry-run.
|
||||
|
||||
### 🔴 Баг `mark_ambiguous()` — исправлен
|
||||
|
||||
`watchlist_sync/parser.py`, функция `mark_ambiguous()`: паттерн снимал **только саму `❓`-строку**, а замена вставляла новые кандидаты **перед** старыми → под-буллеты дублировались **на каждом прогоне** `resolve` (+3 строки / +100 байт за раз). `❓`-строки при этом НЕ дублировались — только под-буллеты под ними.
|
||||
|
||||
```python
|
||||
# ФИКС: захват всего блока — маркер + под-буллеты
|
||||
_SUB_BULLETS = r'(?:\n[ \t]{4,}-[ \t]*(?!\[[ xX]\])[^\n]*)'
|
||||
pattern = re.compile(
|
||||
r'(^[ \t]*-[ \t]*\[ \][ \t]*)[❓]?[ \t]*(' + escaped + r')[ \t]*'
|
||||
r'(?P<subs>' + _SUB_BULLETS + r'*)',
|
||||
re.MULTILINE
|
||||
)
|
||||
```
|
||||
|
||||
**Правило для парсеров этого файла:** под-буллет кандидата = отступ **≥4 пробела** + буллет + **НЕ чекбокс** (`- [ ]`/`- [x]`). Строки фильмов имеют отступ **2 пробела** — их надо исключать явно. Внутри `*`-группы **перенос строки обязателен** (`(?:` + `\n` + ...) + `*`): если сделать `\n?` опциональным, regex перешагивает на следующую строку и **проглатывает соседние фильмы** (проверено — так потеряли `❓ The kill room`, `The burial`, `Past lives`).
|
||||
|
||||
**Верификация:** прогнать `mark_ambiguous()` 3× на свежей копии → размер обязан быть **идентичным**. Плюс проверка, что 0 не-кандидатных строк потеряно.
|
||||
|
||||
### Скрипт дедупа кандидатов
|
||||
|
||||
Одноразовая чистка накопленных дублей: под каждой `❓`/`🗓️`-строкой оставить уникальные под-буллеты (ключ `title|year|rating`), порядок не менять, строки фильмов не трогать.
|
||||
```bash
|
||||
python3 /tmp/wl_dedupe.py # dry-run
|
||||
python3 /tmp/wl_dedupe.py --apply # запись + авто-бэкап .dedupe-backup-<ts>
|
||||
```
|
||||
Прогон 2026-09-20: **168 дублей в 15 блоках**, 26430 → 21032 байт (838 → 670 строк).
|
||||
|
||||
⚠️ **Скрипты этой сессии — в `/tmp` на Кракене** (`wl_dedupe.py`, `wl_fix_parser*.py`, `wl_verify*.py`); `/tmp` чистится при перезагрузке. Для постоянной копии — перенести в `~/scripts/`.
|
||||
|
||||
### Sonarr 400 «This series has already been added» — не сбой
|
||||
|
||||
При `sync-down` уже существующей серии Sonarr отвечает `400 SeriesExistsValidator` («Волшебный участок» = «Magical Police Department», tvdbId=442038). `arr.py::sonarr_add()` **не проверяет дубли перед POST** — в отличие от `radarr_add()`. Шумит в логе, данные не портит. Диагноз смотреть в теле ответа: `errorCode: SeriesExistsValidator`.
|
||||
|
||||
### Zulip-пинг не настроен
|
||||
|
||||
`_zulip_ping()` (`cli.py`) требует `ZULIP_URL` / `ZULIP_API_KEY` / `ZULIP_BOT_EMAIL`, которых **нет в `.env`** репо → `[warn] not set — skipping ping`. Уведомления о нерезолвленных items до Alex **не доходят** (59 штук ушли молча).
|
||||
|
||||
## Подготовка к авто-удалению просмотренного (2026-09-20)
|
||||
|
||||
Требование Alex: удалять `[x]` при заполнении диска >90%, через API Radarr. План и открытые вопросы — [[family/plans/watchlist-cleanup]]. Здесь — только инфраструктурные факты, добытые при разведке.
|
||||
|
||||
### ⚠️ `df` ВРЁТ про заполнение — считать через `shutil.disk_usage`
|
||||
|
||||
```
|
||||
df -h → 88% (учитывает root-резерв ext4)
|
||||
shutil.disk_usage → 83.7% (реальные 1647 / 1968 GB, free 220.8 GB)
|
||||
```
|
||||
Разница ~4%. Порог «>90%» проверять **только** через `shutil.disk_usage`, иначе сработает на 86%.
|
||||
|
||||
### Jellyfin: заголовок авторизации и отсутствие `DatePlayed`
|
||||
|
||||
```python
|
||||
# ПРАВИЛЬНО (как в watchlist_sync/jellyfin.py:_auth)
|
||||
{"Authorization": 'MediaBrowser Token="<token>"'}
|
||||
# НЕПРАВИЛЬНО
|
||||
{"X-Emby-Token": token} # → 401
|
||||
```
|
||||
Рабочие вызовы:
|
||||
```
|
||||
GET /Users → 200; юзеры alex, lisa
|
||||
GET /Users/{uid}/Items?IsPlayed=true&IncludeItemTypes=Movie&Fields=DatePlayed,Path
|
||||
```
|
||||
|
||||
🔴 **`DatePlayed` возвращается `None` для всех просмотренных.** Логику, зависящую от даты просмотра, строить нельзя. `IsPlayed=true` работает, `UserData.Played` работает — дата нет.
|
||||
|
||||
**Jellyfin видит просмотренными всего 6 фильмов** (Король Лев, Меч короля, Эль рояль, Остров сокровищ, Схватка с дьяволом, Труп невесты) — все из `/media/movies` (ручные торренты). Ни одного из `/media/movies-radarr` (на 2026-09-21 — 28 фильмов). То есть пересечение `[x]` ∩ Radarr-файлы **пусто**.
|
||||
|
||||
⚠️ **Это не косметика, а причина, по которой авто-очистка диска не работает.** `sync-up` переносит watched-историю Jellyfin в `[x]`, а `cleanup` удаляет только то, что помечено `[x]`. Пока Jellyfin не видит Radarr-библиотеку, диск (94.7%) будет заполняться, а cleanup будет ежедневно писать «nothing to delete». Разбираться с этим, а не с cleanup. Детали — [[family/plans/watchlist-cleanup]].
|
||||
|
||||
### Radarr: состояние библиотеки (замер 2026-09-22)
|
||||
|
||||
- **34 фильма в базе, 12 с файлами** (до удаления 16 авто-закачек было 50/28).
|
||||
- 🔴 **`monitored=0` — ни один фильм не отслеживается.** Radarr ничего не докачает.
|
||||
- Объём библиотеки на диске: **251.9 GB**.
|
||||
- Топ по размеру: Chaos Walking 63 GB, Oldboy 31, Project Hail Mary 30, Whiplash 25, The Drama 21.
|
||||
- Диск: **73%, свободно 477 GB** (`/dev/sda1`, 1.8T).
|
||||
- ✅ **Диск был освобождён 2026-09-21: 100% → 77%.** История: `sync-down --batch 5` качал
|
||||
5 фильмов ежедневно без проверки места → диск в 0 байт, Radarr отдавал `disk I/O error`
|
||||
(SQLite не пишет при нуле места). Удалены 5 remux = 403.4 ГБ (Babylon 92.0, Schindler's
|
||||
List 89.4, Midsommar 85.6, Triangle of Sadness 79.7, Unhinged 56.7). Бэкапы:
|
||||
`~/backup-movies-watchlist-20260921-150759.md`, `~/backup-radarr-unmonitor-20260921-151117.json`.
|
||||
**Порядок при удалении: `RescanMovie` → `PUT monitored=false` → `DELETE`.**
|
||||
Без снятия monitored Radarr перекачал бы все 403 ГБ.
|
||||
- ✅ **Стоп-кран `MIN_FREE_GB = 100.0`** в `sync_down.py` (коммит `2642882`): проверка через
|
||||
**`shutil.disk_usage`, НЕ `df`** (`df` врёт на ~4%, учитывает root-резерв ext4).
|
||||
При нехватке — `[STOP] free space ... < 100 GiB` и выход без добавления.
|
||||
Там же фильтр ужасов (`is_horror()`, `⭐` обходит). Разбор — [[family/plans/watchlist-disk-overflow-fix]].
|
||||
- ⚠️ **С 2026-09-22 `sync-down` в кроне не запускается вообще** — стоп-кран и профиль качества
|
||||
остаются как страховка для ручного запуска.
|
||||
- `recycleBin: ''` — **корзины нет, и настраивать её решено НЕ будет** (2026-09-21). `PUT config/mediamanagement` с путём хоста даёт `400 FolderWritableValidator: not writable by user 'abc'`: внутри контейнера Radarr медиа замаплено как `/media`, хостового пути `/srv/...6194539b.../media/.recyclebin` там не существует. Обходить маппингом ради корзины признано нецелесообразным — удаление идёт через Radarr API, а не `rm`. `recycleBinCleanupDays: 7`, `deleteEmptyFolders: False`.
|
||||
- 🔴 **Все `monitored=false` (2026-09-22).** Если удалять файл — `PUT monitored=false` **до** `DELETE` (порядок критичен, иначе скачает заново).
|
||||
|
||||
Проверка одним вызовом:
|
||||
```bash
|
||||
KEY=$(grep -oP '(?<=<ApiKey>)[^<]+' /srv/...6194539b.../docker/radarr/config/config.xml)
|
||||
# только фильмы с файлами
|
||||
curl -s "http://localhost:7878/radarr/api/v3/movie?apikey=$KEY" \
|
||||
| jq -r '.[] | select(.hasFile) | "\(.id)\t\(.sizeOnDisk/1e9|floor)GB\t\(.monitored)\t\(.title)"'
|
||||
# сводка одной строкой
|
||||
curl -s "http://localhost:7878/radarr/api/v3/movie?apikey=$KEY" | jq -r '
|
||||
"всего=\(length) сФайлом=\([.[]|select(.hasFile)]|length) monitored=\([.[]|select(.monitored)]|length)"'
|
||||
```
|
||||
|
||||
## Watchlist → Lampa: JSON-каталог (2026-09-22)
|
||||
|
||||
Второй потребитель watchlist, помимо Radarr/Sonarr: **модуль Catalog в Lampa**. Пайплайн:
|
||||
|
||||
```
|
||||
movies-watchlist.md (боевой .md)
|
||||
↓ gen_watchlist.py ← крон 30 2 * * * (watchlist-catalog.sh)
|
||||
watchlist.json + missing.json
|
||||
↓
|
||||
Lampa (Catalog): карточки с постерами + маркер ❓ для нерезолвленных
|
||||
```
|
||||
|
||||
### Пути
|
||||
|
||||
| Что | Путь |
|
||||
|---|---|
|
||||
| Генератор | `$H/lampac/scripts/gen_watchlist.py` |
|
||||
| Маркер | `$H/lampac/scripts/mark_missing.py` |
|
||||
| Крон-скрипт | `~/scripts/watchlist-catalog.sh` |
|
||||
| Боевой `.md` | `$H/obsidian/family/documents/movies-watchlist.md` |
|
||||
| Вывод | `$H/lampac/wwwroot/watchlist.json` (376 позиций) |
|
||||
| Нерезолвленные | `$H/lampac/wwwroot/missing.json` |
|
||||
| Кэш | `$H/lampac/cache/.lampac_tmdb_{cache,details}.json` (скрытые файлы) |
|
||||
|
||||
где `$H = /srv/dev-disk-by-uuid-6194539b-03e0-4f33-986b-4da09834e82f`
|
||||
|
||||
### Резолв позиции — три уровня
|
||||
|
||||
```
|
||||
1. Radarr (по названию) ← самый надёжный
|
||||
2. TMDB поиск по названию (+год ±1)
|
||||
2b. эвристика КП по названию
|
||||
2c. kp_id из ссылки в .md → КП → TMDB ← машинный, однозначный (проверяется ПЕРВЫМ из КП)
|
||||
3. промах → маркер ❓ в .md
|
||||
```
|
||||
|
||||
`KP_SIM_THRESHOLD = 0.75` — порог совпадения названия в КП.
|
||||
|
||||
⚠️ **`watchlist.json` использует `channels.*.items[].name`**, НЕ `title`. Поле `title` там отсутствует — не путать при парсинге.
|
||||
|
||||
🔴 **Кириллица в ключе каталога Lampa → `ModInit.goInit` чистит `[^a-z0-9\-]` → HTTP 400.**
|
||||
Нужен `plugin: watchlist` + **числовой** `tmdb_id` (`format: "long.TryParse(...)"`).
|
||||
Проверять через `/catalog/card?...&type=movie`, НЕ `/card`.
|
||||
|
||||
### Маркеры в боевом `.md`
|
||||
|
||||
| Маркер | Значение |
|
||||
|---|---|
|
||||
| `❓` | не резолвлен (нет в TMDB/КП) |
|
||||
| `🗓️` | ещё не вышел |
|
||||
| `👎` | не надо |
|
||||
| `[x]` | смотрел |
|
||||
| `⭐` | приоритет (обходит фильтр ужасов и рейтинг) |
|
||||
|
||||
`mark_missing.py` работает **в обе стороны**: нет позиции в `missing.json` → маркер `❓` **снимается**.
|
||||
|
||||
Полный разбор генератора: [[personal/plans/watchlist-tmdb-missing-marker]].
|
||||
Деплой и плагин: [[personal/tech/lampac-deployment]].
|
||||
|
||||
## Notes
|
||||
|
||||
- See [[arr-stack-taiga]] for Taiga (secondary) arr stack
|
||||
- Media pipeline pitfalls: [[media-pipeline-pitfalls]]
|
||||
- FlareSolverr / Cloudflare / Prowlarr-питфоллы: [[prowlarr-flaresolverr-cloudflare]]
|
||||
- Watchlist pipeline (полный flow, cron, баги): [[family/projects/watchlist-automation]]
|
||||
- Синтез: [[concepts/kraken-media-stack]]
|
||||
+1
-1
@@ -47,7 +47,7 @@ Hub: [[family/how-to/truenas-infrastructure|TrueNAS Infrastructure]]
|
||||
- [[family/how-to/truenas-rclone-backup|TrueNAS Rclone Backup]]
|
||||
- [[family/projects/media-toolbox-taiga|Media Toolbox (Taiga)]] — *arr стек на TrueNAS
|
||||
- [[family/how-to/arr-stack-taiga|Arr Stack — Taiga]]
|
||||
- [[family/plans/lidarr-taiga-deploy|Lidarr на Taiga]] — ✅ SkyHook работает; 🔴 2 дефекта: RuTracker/Kinozal таймаут, Transmission auth
|
||||
- [[family/how-to/arr-stack-taiga|Arr stack на Taiga]] — ✅ SkyHook, Transmission и RuTracker проверены после рестарта
|
||||
- [[family/plans/lidarr-artist-watchlist|Lidarr — список артистов]] — 🟡 **150 позиций в 3 тирах** + дельта: 195 артистов «слушаю много / на NAS мало-нет»; можно ставить
|
||||
- [[family/how-to/jellyfin-config|Jellyfin Config]] — живой инстанс на Taiga
|
||||
- [[family/documents/google-books-api-key|Google Books API Key]] — ключ для library-app
|
||||
|
||||
@@ -7,7 +7,6 @@ namespace: personal
|
||||
tags: [flaresolverr, prowlarr, rutracker, taiga, truenas]
|
||||
related:
|
||||
- "[[family/how-to/arr-stack-taiga]]"
|
||||
- "[[personal/tech/prowlarr-flaresolverr-cloudflare]]"
|
||||
---
|
||||
|
||||
# FlareSolverr на TrueNAS Taiga
|
||||
|
||||
@@ -136,7 +136,7 @@ Alex требует называть её явно. Их **четыре**, ра
|
||||
## Связанное
|
||||
|
||||
- [[family/plans/lidarr-artist-watchlist]] — результат
|
||||
- [[family/plans/lidarr-taiga-deploy]] — деплой Lidarr, §АУДИТ СТЕКА
|
||||
- [[family/how-to/arr-stack-taiga]] — деплой и эксплуатация Lidarr на Taiga
|
||||
- [[personal/music-download-practices]] — как качать (hitmotop/mp3party)
|
||||
- `music-batch-download-nas` — скилл загрузки на NAS
|
||||
|
||||
|
||||
@@ -15,8 +15,7 @@ tags:
|
||||
- lidarr
|
||||
- navidrome
|
||||
related:
|
||||
- '[[personal/plans/lidarr-taiga-and-indexer-unblock]]'
|
||||
- '[[family/plans/lidarr-taiga-deploy]]'
|
||||
- '[[family/how-to/arr-stack-taiga]]'
|
||||
- '[[family/projects/media-toolbox-taiga]]'
|
||||
- '[[family/how-to/navidrome-truenas-android]]'
|
||||
---
|
||||
@@ -28,7 +27,7 @@ related:
|
||||
## 1a. Lidarr — музыкальный *arr (патч 2026-09-28)
|
||||
|
||||
**Связка — с NAVIDROME, не с Jellyfin.** Jellyfin для музыки непригоден (баг #18162, имя папки
|
||||
перекрывает теги). План деплоя на Тайге — [[family/plans/lidarr-taiga-deploy]] §2026-09-28.
|
||||
перекрывает теги). Актуальный Taiga runbook — [[family/how-to/arr-stack-taiga]].
|
||||
|
||||
**Сервис = копия radarr:** `lscr.io/linuxserver/lidarr:latest`, порт `8686`, `PUID=950 PGID=950`,
|
||||
volumes `/mnt/RED_2TB/docker/arr/lidarr:/config` + `/mnt/RED_2TB/storage:/storage` (`:rw`),
|
||||
@@ -176,5 +175,5 @@ docker logs lidarr 2>&1 | grep -i proxy # ProxyCheck failed ⇒ НЕ исп
|
||||
|
||||
## Связанные заметки
|
||||
|
||||
- [[personal/plans/lidarr-taiga-and-indexer-unblock]] — план, из которого выросли эти находки
|
||||
- [[family/how-to/arr-stack-taiga]] — актуальная реализация на Taiga
|
||||
- [[family/projects/media-toolbox-taiga]] — состояние стека на Тайге
|
||||
Reference in new issue
Block a user