--- created: '2026-09-24' namespace: personal related: - '[[personal/plans/lampac-watchlist-plugin]]' - '[[family/projects/watchlist-sync]]' - '[[personal/tech/lampac-deployment]]' tags: - watchlist-sync - feed - lampa - lampac - sync-down - matcher-parity - skill-mirror title: watchlist-sync: sync-down как генератор фида Lampa type: tech updated: '2026-09-24' --- # watchlist-sync: `sync-down` как генератор фида Lampa > Зеркало раздела скилла `watchlist-sync-resolver` § «sync-down = Lampa feed». ## Что изменилось `sync-down` больше **не добавляет в arr** — он строит фид Lampa. Требование Alex: «не отдельный скрипт на лампу, а один sync скрипт и писал сразу lampa feed», уточнение: «это же чистая доработка sync-down?». **Коммит `a524f5d`** — «sync-down: build Lampa feed instead of adding to arr; drop arr.py». ``` sync-down [--apply] [--feed-root PATH] резолв через resolver.resolve() → $LAMPAC_ROOT/wwwroot/watchlist.json {channels:{films,new,cartoons,anime}} wwwroot/watchlist-.json wwwroot/cards/card-.json tmdb_id ЧИСЛОМ (иначе «здесь пусто») wwwroot/cards.json wwwroot/missing.json → ❓ в .md (двусторонний) ``` | Решение | Деталь | |---|---| | Пути | `--feed-root` → env `LAMPAC_ROOT` → `/../lampac`. UUID-путей в коде НЕТ | | `--batch` | deprecated: фид несёт весь список | | `arr.py` | 🔴 удалён (`git rm`), история в гите. Бэкапы не делались (решение Alex) | | ⬇️ | не ставится нигде: закачки нет | | ❓ | `_sync_question_marks` в `sync_down.py` — двусторонний (ставит и снимает) | | Где код | **в проекте** `~/Developer/watchlist-sync/` (`watchlist_sync/sync_down.py`), не в `/tmp` | ## Питфоллы переноса (три итерации) 1. **Фильтры рейтинга/ужасов в фиде НЕ нужны.** `rating >= 6.0` и horror-skip — правила ЗАКАЧКИ (Radarr), не каталога. С ними фид упал 392 → 268 позиций. Старый генератор отдавал horror тоже (Вивариум, Субстанция, Ужасающий, Зубастики в живом фиде). 2. **`item.ambiguous` (❓) не исключает позицию из фида.** ❓ = «название неточное, добавь год», а не «нерезолвлено». Из фида исключают только отсутствие `tmdb_id`. 3. **Бери `all_candidates[0]`.** При `status="ambiguous"` у `resolve()` `candidate=None`, но топ-3 в `all_candidates`. Alex: «бери лучшего кандидата и пиши вопрос» → кандидат в фид, название в `missing` → ❓ (год пиннит позицию на следующем прогоне). ⚠️ Ранний `continue` на `status != "ok"` съедал этот путь — проверять порядок веток. Метрики dry-run: **268 → 332 → 397** (цель — не меньше старого фида 392; больше, потому что старый генератор терял часть позиций на Radarr-фастпатче и ❓-строках). ## 🔴 Блокер: matcher-parity (НЕ закрыт) Резолвер проекта матчит **хуже** старого `gen_watchlist.py`: сверка по `tmdb_id` дала **86 позиций с другим фильмом**. ⚠️ **Сверять только по `tmdb_id`.** По названию бесполезно: в фиде имена из TMDB (`Несломленный`), в `.md` — из строки (`Unbroken`). **Причина:** в генераторе 4 ступени резолва — Radarr → TMDB → **КП-по-номеру из ссылки** (`kinopoisk.ru/film/N/`, машинный ключ, не зависит от переименований) → КП-по-названию. В `resolver.py` ступени «по номеру из ссылки» **нет**. До удаления arr-контента расхождение маскировал Radarr-фастпатч. **Решение:** перенести `kp_search_by_id` + `_docs_to_tmdb` (с флагом `_by_id`) из `lampac/scripts/gen_watchlist.py` в резолв фида. Это ~30 мин, проверяется тем же diff по `tmdb_id`. 🔴 **НЕ удалять** `lampac/scripts/gen_watchlist.py`, `mark_missing.py`, `watchlist-catalog.sh` (крон 02:30) до переноса — оттуда берётся код. ## Открытые пункты 1. Matcher-parity (см. выше) — без него выкат покажет не те фильмы на ~86 позициях. 2. Вернуть `sync-down` в `watchlist-nightly.sh` (строка 40 — «ПРОПУЩЕН») и убрать `watchlist-catalog.sh` + строку крона `30 2 * * *`. 3. Удалить `gen_watchlist.py` (878) + `mark_missing.py` (179) — ПОСЛЕ п.1. 4. `--apply` на живой фид + `docker restart lampac` + приёмка в UI Lampa.