--- created: '2026-05-20' updated: '2026-09-04' status: active tags: - kraken - watchlist - automation - movies --- # Watchlist Automation — Полный Flow Полная цепочка: как `family/documents/movies-watchlist.md` превращается в скачанный контент. ## Полная цепочка ``` [вс 09:00] watchlist-discover ← KP API топ фильмов 2024-2025 ↓ добавляет в секцию "Новинки 👍/👎" movies-watchlist.md Alex ставит 👍 / 👎 ↓ [ежедн 09:00] watchlist-resolve ← SSH Кракен → resolve → commit [ежедн 10:00] watchlist-sync-down → process-thumbs (перемещает 👍 → начало списка) → sync-down (добавляет батч в Radarr/Sonarr) ↓ Radarr (7878) / Sonarr (8989) → Prowlarr (9696) → RuTracker / Kinozal(M) / NoNaMe / etc. → Transmission (9091) → /media/movies-radarr или /media/series-sonarr ↓ router.py (Custom Script) → читает жанры из NFO/TMDb → symlink в /media/{movies,cartoons,documentaries,...}/ ↓ Jellyfin (8096) → rescan → виден контент ``` ## Статусы в movies-watchlist.md | Символ | Значение | Действие | |--------|---------|---------| | `[ ]` | не смотрел, в очереди | sync-down добавляет в Radarr/Sonarr | | `[x]` | просмотрено | sync-up из Jellyfin watched history | | `⬇️` | добавлено в Radarr/Sonarr | ждёт скачки | | `👍` | нравится (новинка) | process-thumbs переносит в начало → попадёт в sync-down | | `👎` | не хочу (новинка) | process-thumbs перемещает в `## Новинки👎` | | `🗓️` | upcoming (ещё не вышел) | discover помечает, не скачивается | | `❓` | не найдено / ambiguous | ждёт ручного уточнения | | `🧟‍♀️` | horror (genre_id=27) | информационный маркер | ## Структура секций movies-watchlist.md ``` ## Новинки - 👍/👎 ← discover добавляет сюда ## Фильмы ← основной список, отступ 2 пробела ( - [ ]) ## Мультфильмы ## Аниме ## Новинки👎 ← без пробела перед 👎 ## Связанные заметки ``` **Важно:** `process_thumbs` автоматически определяет отступ из `## Фильмы` и сохраняет при переносе. `SECTION_THUMBDN = "## Новинки👎"` (без пробела) — должно точно совпадать с заголовком. ## Cron Jobs (на Кракене с 2026-05-27) Весь watchlist pipeline работает на Кракене (мигрировал с Eagle 2026-05-27). | Job | Расписание | Скрипт | |-----|-----------|--------| | `watchlist-nightly` | ежедн. 01:00 | `~/.hermes/scripts/watchlist-nightly.sh` | | `watchlist-discover` | вс 09:00 | `~/.hermes/scripts/watchlist-discover.sh` | **watchlist-nightly.sh** (на Кракене): 1. `sync-vault.sh` (pull) → `process-thumbs --apply` → `sync-vault.sh` (push) 2. `resolve --recheck --apply` → `sync-down --apply --batch 5` → `sync-up --apply` → `sync-vault.sh` (push) **Пути на Кракене (HDD UUID 49e8f586-3839-4c5d-a1e1-58bfc3579ade):** - `/home/kraken/obsidian` → symlink на `/srv/dev-disk-by-uuid-.../obsidian` - `~/Developer/watchlist-sync` → symlink. **Реальный корень репо** (проверено 2026-09-04): `/srv/dev-disk-by-uuid-6194539b-03e0-4f33-986b-4da09834e82f/watchlist-sync` — находится **в корне диска, НЕ под `Developer/`** (в доке ранее путь был ошибочный). Внутри: `watchlist_sync/` (cli.py, arr.py, sync_down.py, sync_up.py, resolver.py, parser.py, discover.py, jellyfin.py), `.venv` (py3.11+httpx+click), `.resolve_cache.json`, pyproject.toml. ## Discover — Фильтрация | Тип | Порог | |-----|-------| | Мировые | IMDb ≥ 7.0 или KP ≥ 7.0 | | Российские | KP ≥ 8.5 (защита от накрутки) | | Upcoming | год ≥ текущий−1 | | Минимум голосов | IMDb ≥ 1000 или KP ≥ 500 | KP API endpoint: `https://api.poiskkino.dev/v1.4/movie` (redirect с api.kinopoisk.dev). ## *arr Stack — Индексеры (Prowlarr) | ID | Имя | Тип | Примечание | |----|-----|-----|-----------| | 1 | RuTracker | semi-private | блокирует при rate limit на сутки | | 2 | RuTor | public | поиск по imdbid | | 3 | Byrutor | public | | | 4 | NoNaMe Club | semi-private | анонимный | | 5 | Kinozal | semi-private | резерв | | 6 | Kinozal (M) | semi-private | магнет ✅ — без grab limit, **предпочтительный** | **Pi-hole питфолл:** блокирует `skyhook.sonarr.tv` → Sonarr/Radarr поиск молча не запускается. Фикс: `dns: [8.8.8.8]` в docker-compose.yml. ## Router Script — Маршрутизация по жанру После импорта Sonarr/Radarr: `router.py --apply` создаёт symlinks: - Animation (не R/18+) → `/media/cartoons/` или `/media/cartoons-series/` - Documentary → `/media/documentaries/` или `/media/documentaries-series/` - Прочее → `/media/movies/` или `/media/series/` Копирует NFO + постер рядом с symlink (Jellyfin не видит метадату через symlink напрямую). ## watchlist-sync — Python CLI Репо: `~/Developer/watchlist-sync` (GitHub: `mallexxx/watchlist-sync`). ``` watchlist-sync resolve — TMDB + KP API → ID, тип (movie/tv) watchlist-sync sync-down — добавить батч (max 5) в Radarr/Sonarr, поставить ⬇️ watchlist-sync sync-up — Jellyfin watched → [x] в .md ``` **Резолвер:** TMDB `/search/multi` + KP fallback. Пороги: `min_rating: 6.0`, `min_score: 0.75`. При 2+ кандидатах → `❓` (LLM разрешает в cron каждые 6ч, нерешённые → уточнение в Zulip). **Stage 2 (после ≥50 просмотров):** AI-curated recommendations — три списка (с женой / один / семья) на основе TMDB профиля, добавляются в конец watchlist как `## 🤖 Рекомендации (YYYY-WNN)`. Jellyfin library mapping: Movies → `movies`, Cartoons → `mixed` (movies + episodes). ## Питфоллы ### KP Markdown Link Parsing Bug Фильмы из Kinopoisk с синтаксисом `[Title](https://kinopoisk.ru/film/12345/) (2025)` передавались как есть в TMDB search → не находились → помечались `❓` навсегда (`not i.ambiguous` пропускает при следующем запуске). Фикс: commit `2db1ed9` — извлекать plain title из markdown link до передачи в TMDB. Ошибочно помеченные `❓` требуют ручного `--recheck`. ### KP API Endpoint `api.kinopoisk.dev` редиректит на `api.poiskkino.dev/v1.4/movie`. Использовать destination redirect напрямую. ### 🔴 Жёстко зашитый `qualityProfileId: 1` в arr.py (корень жирных remux) Найдено 2026-09-04. В `watchlist_sync/arr.py` **`qualityProfileId: 1` захардкожен** и для Radarr, и для Sonarr: ```python # radarr_add (~стр. 77) / sonarr_add (~стр. 112) "qualityProfileId": 1, ``` Профиль 1 (Radarr) = **'Any'** — разрешает ВСЁ вплоть до Remux-2160p и BR-DISK. Поэтому **каждый новый фильм/сериал, добавляемый watchlist-sync, попадает в «Any»** и Radarr скачивает самый жирный доступный релиз (60GB remux'ы). Готового профиля «2160p, но без Remux» на Kraken нет (нужно создавать). Решение по стратегии — открыто (см. ниже). Чтобы новые шли в поддерживаемое качество: либо создать профиль «2160p без Remux/BR-DISK» и поменять `qualityProfileId` в `arr.py` (Radarr+Sonarr), либо сузить сам профиль 1, либо зашить `4` (HD-1080p). ## Open Tasks - 🔴 **[2026-09-04] Решить стратегию качества загрузки новых фильмов** (см. профили в [[arr-stack-kraken]]). Корень — захардкоженный `qualityProfileId: 1` (`Any`) в `watchlist_sync/arr.py`. Пока НЕ менялось (НИЧЕГО не правилось, ждём решение Alex). Вопрос юзеру: сохранить 4K (→ создать профиль «2160p без Remux/BR-DISK» и сменить id в arr.py) или опустить до 1080p (id 4); и менять ли и для Sonarr (сериалы) тоже. - 🟡 Передавать Transmission locations через router script при каждом импорте (сейчас вручную) - 🔴 rsync невыполненных фильмов с HTPC на Кракен (`Фильмы не перенесенные с htpc на кракен.md`) - 🟡 Watchlist sync-up: добавить перенесённые фильмы в нужные разделы ## Связанные заметки - [[watchlist-discover]] — шаг discover: KP API, format, CLI команды - [[watchlist-sync]] — основной проект (resolve, sync-down, sync-up) - [[arr-stack-kraken]] — детальные питфоллы *arr стека - [[jellyfin-transcode-rpi5]] — Jellyfin PGS/ASS питфоллы