From db766abb58bf7c7dffaa84c34efa851d757bcf9f Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Tue, 22 Sep 2026 18:44:34 +0600 Subject: [PATCH] [2026-09-22] eagle: personal/plans/watchlist-tmdb-missing-marker.md personal/tech/lampac-deployment.md --- .../plans/watchlist-tmdb-missing-marker.md | 144 +++++++++++-- personal/tech/lampac-deployment.md | 197 +++++++++++++++++- 2 files changed, 324 insertions(+), 17 deletions(-) diff --git a/personal/plans/watchlist-tmdb-missing-marker.md b/personal/plans/watchlist-tmdb-missing-marker.md index 5a088d1c..94f87c54 100644 --- a/personal/plans/watchlist-tmdb-missing-marker.md +++ b/personal/plans/watchlist-tmdb-missing-marker.md @@ -2,16 +2,99 @@ # Watchlist — автопоиск TMDB + маркер «нет в базе» (без ручных правок) **Дата:** 2026-09-22 -**Статус:** ✅ ЗАВЕРШЕНО. Шаги 1, 1.3, 2, 3 задеплоены и приняты в UI. -Маркер `❓` применён к боевому `.md` (**24 снято, 18 поставлено**), автозакачка -в Radarr отключена, кэш резолва перенесён с SD на HDD. -Коммиты: `lampac-scripts` **`0345df2`**, `watchlist-sync` **`396acc3`**. -Осталось (не блокеры): имя в карточке из TMDB/КП, порядок категорий в ленте, -коммит правки `mark_missing.py` в обе стороны. +**Статус:** ✅ ОСНОВНАЯ ЗАДАЧА ЗАВЕРШЕНА. Шаги 1, 1.3, 2, 3 задеплоены и приняты в UI. +Маркер `❓` работает **в обе стороны** (24 снято, 18 поставлено), боевой `.md` +синхронизирован с каталогом, автозакачка в Radarr отключена, кэш резолва на HDD, +кэш-копия с SD удалена. +Коммиты: `lampac-scripts` **`1122b71`** (маркер в обе стороны), `watchlist-sync` **`396acc3`**. +**Открытые задачи (в работе / ждут Alex)** → [[#🔜 Открытые задачи (2026-09-22, вечер)]] **Связано:** [[personal/plans/lampac-watchlist-plugin]], [[family/projects/watchlist-automation]], [[family/projects/watchlist-sync]], [[personal/tech/lampac-deployment]] --- +## 🔜 Открытые задачи (2026-09-22, вечер) + +### 1. Удаление авто-закачек из Radarr/Sonarr — ЖДЁТ КОМАНДЫ + +Alex: *«закачки отменять и проверить еще раз что заново не добавятся»* → +*«удалить все добавленные автоматикой закачки в т.ч. файлы. и radarr и sonarr»*. + +Инвентаризация выполнена, дамп снят, удаление **не запущено** — Alex ещё не +подтвердил финальный список (16 Radarr-позиций vs все 50). + +``` +Radarr : 16 авто-добавленных (added >= 2026-09-20), 12 из них с файлами +Sonarr : авто-закачек НЕТ (все 13 сериалов добавлены 18.05–01.06) +дамп : /tmp/radarr-sonarr-dump-20260922-184351/ +``` + +🔴 Полная таблица, API-вызовы и питфолл `deleteFiles=true` — в +[[personal/tech/lampac-deployment#📋 Инвентаризация авто-закачек в Radarr/Sonarr (2026-09-22)]]. + +**Гарантия «заново не добавятся» — проверена фактом:** +``` +1. sync-down вырезан из watchlist-nightly.sh → в кроне вызова нет +2. все 50 фильмов Radarr: monitored=false → поиск раздач не запускается + + queue 0 записей + wanted/missing 0 записей +``` + +⚠️ НЕ сделано: коммит правки `watchlist-nightly.sh` в git (вырезанный `sync-down`). + +### 2. Имя в карточке — из источника (TMDB/КП), НЕ из `.md` + +Alex: *«че по имени в карточке? оно должно из источника ставиться»*. + +Сейчас генератор пишет в карточку `it["name"]` = название **из `.md`**: + +```python +# gen_watchlist.py, блок записи карточки (~строка 733) +card_body = {"card": { + "name": it["name"], # ← из .md, не из TMDB/КП + "title": it["name"], # дублируется намеренно: + "original": it["original"], # CardController ищет attribute name, + "original_title": it["original"], # в ответе ключи title/original_title + ... +}} +``` + +Требование Alex: «Отображать как в tmdb/kp», «Ничего не укорачивать». +**Нужно:** брать имя из источника (TMDB `title`/`name` из `tmdb_details()`, +либо `name` документа КП) и писать его в `card.title` + `watchlist.json[].name`. +Функция `tmdb_details()` уже тянет детали и кэширует — там есть `poster_path`, +но **имени она сейчас не сохраняет**, надо добавить. + +⚠️ Осторожно с `original`: это EN-название, нужен RU/title из TMDB при +`language=ru-RU`. Проверить на 3 позициях, где `.md`-название ≠ название TMDB +(`Духless` → TMDB 132759, `Бумбараш` → 109940, `Хамнет` → 858024). + +### 3. Категории в ленте прыгают при перезагрузке + +Alex: *«категории прыгают при перезагрузке.. там либо insert либо конфликт id»*. + +Гипотеза Alex: **`insert` вместо присваивания ЛИБО конфликт `id`**. +Уже известно: `displayindex` не сдвигает встроенные блоки Lampa +(«Сейчас Смотрят», «Рекомендуем посмотреть» — они НЕ из `sites/`). +`watchlist.yaml`: `displayindex: 1` (самый низкий из всех). + +``` +displayindex: watchlist 1, rezka 10, kinobase 15, filmix 20, vokino 30, + eneyida 35, kinoukr 40, getstv 45, aniliberty 60 +``` + +**Куда смотреть:** порядок вставки каналов в ленту (`insert` vs `push`/присваивание), +стабильность `id` канала между перезапусками lampac (`catalog:` в памяти — +см. питфолл `catalog:card:*` переживает `docker restart`). +Требует отдельного разбора кода Lampac (LampaWeb/Lampa). + +### 4. Мелочи + +- `Астрал. Могильный ритуал 2` — маркер `🗓️` не снимается автоматически, позиция + названа по-старому имени; резолв идёт по `kp_id` (работает), но снятие + маркера `﮼🗓️` — работа `resolve --recheck` в nightly, не генератора. +- Кэш-копия на SD — **удалена** (закрыто, см. ниже). + +--- + ## ✅ ФИНАЛ СЕССИИ (2026-09-22, ночь): маркер ❓ работает В ОБЕ СТОРОНЫ ### 🔴🔴 Главная находка: маркер умел только СТАВИТЬ, но не СНИМАТЬ @@ -69,16 +152,49 @@ if norm(title) not in missing: `The kill room` · `Godfathers` · `Stand by me` · `Мементо` · `девять` · `Приятель 2026` · `Презумпция невиновности сериал` · `Орлеан` · `Итальянцы в ..?` + 7. -### 🔴 Питфолл: 24 ≠ реальное число рассинхронов +⚠️ Ранее зафиксированный «открытый вопрос»: `Джеймс Кемерон морские приключения?` — +**разобран и закрыт.** Это НЕ баг. Фильма с таким названием не существует; Alex +написал заметку-воспоминание («морские приключения Кэмерона?»). Резолвер честно +ищет в КП и находит только чужие документы: -Два маркера в очереди не снимаются **никогда** (нет нормализованного совпадения): +``` +'Джеймс Кэмерон: Путешествие к центру Земли' sim=0.57 +'Достать Джеймса Кэмерона' sim=0.44 +'Безымянный проект Джеймса Кэмерона' sim=0.38 +``` -1. `могильный ритуал. зло вернулось` — кэш резолвит под актуальным именем КП, - а в `.md` позиция названа по-старому (`Астрал. Могильный ритуал 2`). -2. `Джеймс Кемерон морские приключения?` — **в `missing.json` И резолвится - одновременно**: `kp|джеймс кемерон морские приключения?|5` → `list[5]` в кэше, - но генератор всё равно пишет его в miss. Причина требует отдельного разбора. - ⚠️ **Открытый вопрос сессии, зафиксирован.** +Все ниже порога 0.75 → miss → `❓`. Поведение верное. +🔴 **Моя ошибка разбора:** я принял ключ кэша `'джеймс кемерон морские приключения?|'` += `list[5]` за успешный резолв. Это **документы КП** (результаты поиска), а не +резолв в TMDB. Ключ `'{title}|'` = `tmdb_search` (это резолв), `'kp|{title}|{limit}'` += `kp_search` (это сырьё поиска). Различать обязательно. + +### ✅ ИТОГ: боевой `.md` приведён в соответствие с каталогом + +Запись выполнена (`--apply`), бэкап `/tmp/movies-watchlist.md.bak-marker-20260922-183910` +и `.bak-questions` рядом с файлом: + +``` +размер 29632 -> 29608 Б (-24 = 24 снятых ❓) +позиций 596 -> 596 (ни одна не потеряна) +❓ 34 -> 28 🗓️ 39 👎 2 [x] 179 [ ] 417 +``` + +Три правки Alex — чистые, без маркера: + +``` + 86: - [ ] Everything Everywhere All at Once 2021 +167: - [ ] Духless +216: - [ ] Бумбараш +``` + +Коммит `lampac-scripts` **`1122b71`** (запушен на gitea, `0345df2..1122b71 main -> main`). + +--- + +## ✅ ПОСТ-ДЕПЛОЙНАЯ ИТЕРАЦИЯ (2026-09-22, поздний вечер) + +### 🔴 Автозакачка в Radarr ОТКЛЮЧЕНА ### 🔴 Питфолл режима проверки: `grep -c` считает СТРОКИ, а не вхождения diff --git a/personal/tech/lampac-deployment.md b/personal/tech/lampac-deployment.md index 216e64e9..66f8e26f 100644 --- a/personal/tech/lampac-deployment.md +++ b/personal/tech/lampac-deployment.md @@ -118,8 +118,9 @@ sync-vault → process-thumbs → resolve --recheck --apply → sync-up → sync **Единственный автоматический путь в закачку** (проверено grep по `~/scripts/*.sh`): в активном виде не осталось ни одного. Все упоминания `sync-down` — комментарии. -⚠️ **Radarr уже получил закачки за прошлые прогоны** (9 фильмов в статистике). -Их судьба на момент записи не решена — отдельный вопрос к Alex. +⚠️ **Radarr уже получил закачки за прошлые прогоны** — 16 фильмов, см. раздел +«Инвентаризация авто-закачек в Radarr/Sonarr» ниже. Судьба решается Alex'ом +(на момент записи — ждём команду на удаление). ### Разграничение двух «лимитов» (частый источник путаницы) @@ -159,7 +160,197 @@ DETAILS_FILE = _cache_dir() / ".lampac_tmdb_details.json" сначала решил, что копирование не сработало. **Проверено по времени правки файла:** кэш на HDD обновляется прогоном, -на SD застыл. На SD остаётся копия — удалять её отдельным шагом с подтверждением. +на SD застыл. + +### ✅ Копия кэша с SD УДАЛЕНА (2026-09-22, 18:42) + +``` +удалено с SD: /home/kraken/.lampac_tmdb_cache.json (72 118 Б, было 18:24) + /home/kraken/.lampac_tmdb_details.json (425 929 Б, было 18:24) +бэкап: /tmp/sd-cache-backup-20260922/ (оба файла, до удаления) +HDD на месте: $H/lampac/cache/.lampac_tmdb_{cache,details}.json (18:29, свежие) +``` + +**Проверка, что на SD не пересоздаются** (`verify_cache_path.py`): + +``` +CACHE_FILE → $H/lampac/cache/.lampac_tmdb_cache.json существует: True +DETAILS_FILE → $H/lampac/cache/.lampac_tmdb_details.json существует: True +_cache_dir() → /srv/.../lampac/cache это HDD? True +SD-путь /home/kraken/.lampac_tmdb_cache.json существует: False +``` + +`_cache_dir()` строит путь от `__file__`, поэтому `Path.home()` больше не +выбирается при запуске на Кра́кене — генератор физически не может писать на SD. + +## 📋 Инвентаризация авто-закачек в Radarr/Sonarr (2026-09-22) + +Полный дамп: `/tmp/radarr-sonarr-dump-20260922-184351/` (`radarr-movies.json`, +`sonarr-series.json`) — **единственный откат**, Radarr корзины не имеет. + +### Доступ к API (креды из `/srv/...6194539b.../watchlist-sync/.env`) + +```bash +UR=http://localhost:7878/radarr # Radarr :7878, сегмент /radarr +US=http://localhost:8989/sonarr # Sonarr :8989, сегмент /sonarr +curl -sL "$UR/api/v3/movie" -H "X-Api-Key: $RADARR_KEY" +curl -sL "$US/api/v3/series" -H "X-Api-Key: $SONARR_KEY" +curl -sL "$UR/api/v3/queue" -H "X-Api-Key: $RADARR_KEY" # очередь загрузок +curl -sL "$UR/api/v3/wanted/missing?pageSize=50" -H "X-Api-Key: $RADARR_KEY" +``` + +🔴 Только `curl -sL` (без `-L` редирект даёт 301 → пустой ответ). +Рабочий скрипт: `~/lampac-tmp/dump_arr.sh`, обёртка `dump_arr_wrap.sh`. + +### Radarr: 50 фильмов, из них 16 добавлено автоматикой + +Признак авто-закачки — **`added >= 2026-09-20`** (окно работы `sync-down`; +пайплайн watchlist'а включён в сентябре). Всё добавленное 18.05–04.06 — ручное. + +| added | id | Фильм | Файл на диске | +|---|---|---|---| +| 2026-09-20 | 40 | American History X (1998) | ✅ | +| 2026-09-20 | 41 | Oficina do Diabo (2025) | ❌ | +| 2026-09-20 | 42 | I Swear (2025) | ✅ | +| 2026-09-20 | 43 | Gladiator (2000) | ❌ | +| 2026-09-20 | 44 | Warfare (2025) | ✅ | +| 2026-09-20 | 45 | The Secret Agent (2025) | ✅ | +| 2026-09-20 | 46 | Den of Thieves 2: Pantera (2025) | ✅ | +| 2026-09-20 | 47 | The Ugly Stepsister (2025) | ✅ | +| 2026-09-20 | 48 | Rental Family (2025) | ✅ | +| 2026-09-20 | 49 | The Life List (2025) | ✅ | +| 2026-09-20 | 50 | People We Meet on Vacation (2026) | ✅ | +| 2026-09-20 | 51 | It Was Just an Accident (2025) | ✅ | +| 2026-09-20 | 52 | The Perfect Neighbor (2025) | ❌ | +| 2026-09-20 | 53 | Chasing the Wind (2025) | ❌ | +| 2026-09-20 | 54 | Sirāt (2025) | ✅ | +| 2026-09-21 | 55 | Death of a Unicorn (2025) | ✅ | + +**12 с файлами, 4 без.** Root folder Radarr: `/media/movies-radarr` +(свободно 511 GB — чистка не требовалась). Теги: `[]` (пусто). + +### Sonarr: авто-закачек НЕТ + +13 сериалов, все добавлены **18.05–01.06**, ни одного в окне 20–21.09: +`Our Flag Means Death`, `Stranger Things`, `The Cyberfarm`, `Magical Police +Department`, `Место встречи изменить нельзя`, `MOZU`, `Delicious in Dungeon`, +`Rick and Morty`, `Severance`, `Brassic`, `Double or Quits`, `Futurama`, +`True Detective`. Root: `/media/series-sonarr`. + +### Гарантия «заново не добавятся» — два независимых барьера + +``` +1. sync-down вырезан из watchlist-nightly.sh → в кроне вызова нет +2. все 50 фильмов Radarr: monitored=false → поиск раздач не запускается + + очередь (queue) 0 записей + + wanted/missing 0 записей +``` + +### Удаление (по команде Alex) + +🔴 **Radarr по умолчанию НЕ удаляет файл с диска.** Нужен явный +`deleteFiles=true` в DELETE-запросе, иначе файл останется в +`/media/movies-radarr/ (<Year>)/` сиротой. Корзины нет — удаление +необратимо без `/tmp`-дампа. + +```bash +# ОДИН фильм +curl -sL -X DELETE "$UR/api/v3/movie/<id>?deleteFiles=true&addImportExclusion=false" \ + -H "X-Api-Key: $RADARR_KEY" +# исключения импорта НЕ добавляем: addImportExclusion=true — только если +# фильм НЕ должен вернуться; для авто-закачек это и нужно, но решает Alex. +``` + +⚠️ Удаление 12 фильмов с файлами освободит место в `/media/movies-radarr`, +но **не влияет на каталог Lampa** — `watchlist.json` строится из `.md`, +Radarr в отображении не участвует. + +## 🔴 Маркер `❓` работает В ОБЕ СТОРОНЫ (2026-09-22, финал) + +### Симптом: `.md` расходился с каталогом + +Три правки Alex (`Духless`, `Бумбараш`, `Everything Everywhere All at Once`) +**были в `watchlist.json` с постерами**, но в `.md` стояли с `❓`. Казалось, +резолв не работает — на деле резолв прошёл, а **маркер остался с прошлого прогона**. + +### Первопричина + +`mark_missing.py` реализовывал правило «позиции НЕТ в `missing.json` → не трогать». +Маркер **ставился, но никогда не снимался**. Правка названия → резолв проходит → +`❓` в `.md` остаётся навсегда. + +### Фикс + +Правило заменено на «нет в `missing.json` → **СНЯТЬ** `❓`». Список нерезолвленных — +ИСТИНА, работает в обе стороны. + +```python +# mark_missing.py, analyze() +if norm(title) not in missing: + stats["не_в_missing"] += 1 + if QUESTION in body: # <- НОВОЕ: снятие + cleaned = re.sub(r"\s*" + QUESTION + r"\s*", " ", body).strip() + stats["снято"] += 1 + changes.append((i, raw.rstrip("\n"), + "%s- [%s] %s" % (indent, box, cleaned))) + continue +``` + +⚠️ **Защита «файл стал меньше → отмена» удалена** — снятие метки законно +уменьшает файл. Замена: число строк-позиций (`ITEM_RE`) не должно измениться. + +### Боевой прогон + +``` +всего 596 | не в missing 350 | календарь 39 | просмотрено 179 | уже вопрос 10 +снято 24 | поставлено 18 +размер 29632 -> 29608 Б (-24) | позиций 596 -> 596 +вопрос 34 -> 28 +``` + +Коммит `lampac-scripts` **`1122b71`** (`0345df2..1122b71 main -> main`). + +### 🔴 Питфолл: два формата ключа кэша — не путать сырьё с резолвом + +``` +'{title}|' <- ключ tmdb_search() -> list[3] = РЕЗОЛВ ОТРАБОТАЛ +'kp|{title}|{limit}' <- ключ kp_search() -> list[5] = СЫРЬЁ поиска КП +'kpid|{id}' <- ключ kp_search_by_id() +``` + +Наличие `'{title}|'` = список `[tmdb_id, media_type, poster]` = **резолв успешен**. +А `'kp|...'` со списком = документы Кинопоиска, **резолва может и не быть**. +Я принял второе за первое и раздул ложную тревогу по +`Джеймс Кемерон морские приключения?` — фильма с таким названием не существует, +`❓` на нём **правильный**. + +### 🔴 Питфолл: `grep -c` считает СТРОКИ, а не вхождения + +`grep -c` дал 34 — я счёл это числом маркеров. Правильный счёт — `str.count()` +в Python по прочитанному файлу. Проверять сырьём, не грепом по счётчикам. + +### 🔴 Питфолл: кириллица в `grep` через ssh = блок апрува + +`ssh kraken 'grep "Духless" file'` → запрос апрува → таймаут → `BLOCKED`. +Рабочий обход — **скрипт файлом**: `write_file` локально → `scp` → `ssh bash /tmp/x.sh`. + +### 🔴 Питфолл: структура `watchlist.json` + +Ключ названия — **`name`**, НЕ `title`. Проверка «есть ли фильм в каталоге» +обязана читать `channels.*.items[].name`, иначе даёт ложный «0 позиций». + +```json +{ "generated": true, "count": 373, + "channels": { "films": { "title": "Фильмы", "items": [ + { "name": "...", "original": "...", "year": null, "rating": 0.0, + "image": "https://image.tmdb.org/...", "href": "..." } ] } } } +``` + +### Путь боевого `.md` + +`$H/obsidian/family/documents/movies-watchlist.md` +(`$H` = `/srv/dev-disk-by-uuid-6194539b-03e0-4f33-986b-4da09834e82f/lampac`), +`kraken:kraken`, бэкапы `/tmp/movies-watchlist.md.bak-*` + `.bak-questions` рядом. ## 🚀 Деплой генератора на Кра́кен (проверено 2026-09-22)