watchlist: sync-from-lampac implemented (Lampa -> [x]) — plan status, automation doc

This commit is contained in:
Alexey Martemyanov committed 2026-09-24 01:10:13 +06:00
1 parent 7af79521ce
commit 337505a33f
2 files changed
+148 -7

No files matched your search

+86 -7
View File
@@ -1,15 +1,22 @@
---
title: Отметка «просмотрено» из Lampa → watchlist.md
type: plan
status: planned-not-implemented
status: implemented-threshold-tbd
namespace: personal
created: 2026-09-23
updated: 2026-09-23
tags: [lampac, lampa, watchlist, timecode, torrserver, kraken, sync-up]
created: 2026-09-23T00:00:00.000Z
updated: '2026-09-24T00:00:00.000Z'
tags:
- lampac
- lampa
- watchlist
- timecode
- torrserver
- kraken
- sync-up
related:
- "[[family/projects/watchlist-automation]]"
- "[[personal/plans/lampac-watchlist-plugin]]"
- "[[family/documents/movies-watchlist]]"
- '[[family/projects/watchlist-automation]]'
- '[[personal/plans/lampac-watchlist-plugin]]'
- '[[family/documents/movies-watchlist]]'
---
# Отметка «просмотрено» из Lampa → `movies-watchlist.md`
@@ -188,6 +195,78 @@ KP-ID (`kinopoisk.ru/film/`, 68 штук в `.md`) в цепочке **не уч
(см. §7) — без него шаг 6 не закрыть.
- ⏳ Не сделано: бэкап (шаг 1), `.env` (шаг 4), крон (шаг 5), доки (шаг 7).
---
## 10. ✅ РЕАЛИЗАЦИЯ 2026-09-24 (коммит `ef44f3e`)
Модуль написан, протестирован, встроен в nightly. Все 8 шагов плана закрыты
(кроме калибровки порога — см. ниже).
### Что сделано
| Шаг | Результат |
|---|---|
| 8 (матч) | Проверен синтетикой: обе ветки работают (cache точный + json фолбэк) |
| 1 (бэкап) | `~/backup-watchlist-before-lampac-sync-20260924-005630/` (TimeCode.sql + .md); репо — git push |
| 2 (код) | `watchlist_sync/sync_from_lampac.py` + команда `sync-from-lampac` в cli.py |
| 3 (dry-run) | Синтетическая БД (8 сценариев) + копия .md → diff ровно 2 ожидаемые строки |
| 4 (.env) | `LAMPAC_TIMECODE_DB`, `LAMPAC_WATCHLIST_JSON`, `LAMPAC_PERCENT_THRESHOLD=90` (бэкап `.env.bak-lampac-20260924`) |
| 5 (крон) | Врезан в `~/scripts/watchlist-nightly.sh` после sync-up, до vault push; md5 новой `edf0e34530692dbb7b6fb9644f1b45a7`, бэкап `.bak-lampac-20260924`; полный ручной прогон 01:05–01:07 ✓ |
| 6 (порог) | `percent >= 90` (env/CLI `--percent`); точная калибровка — после живого досмотра |
| 7 (доки) | Этот план + `family/projects/watchlist-automation.md` + скилл `watchlist-sync-resolver` |
### Матч-цепочка (реализована двухступенчатая)
```
timecodes.identity ('movie-674' / '674_movie' — строгие формы, иначе скип)
→ tmdb_id
→ 1) .resolve_cache.json: candidate.tmdb_id → ключ кэша = заголовок .md (ТОЧНО)
→ 2) фолбэк watchlist.json: href '/movie/<id>' → name (TMDB ru) / original (en)
+ сверка года (расхождение > 1 → пропуск с логом)
→ _mark_watched (как Jellyfin-канал; ⬇️ срезается, эмодзи-префикс сохраняется)
```
### Тестовая матрица (все 8/8 ✓)
| Сценарий | Ожидание | Факт |
|---|---|---|
| cache-матч, percent=95 | `[→WL] via cache` | ✓ («Поступь хаоса», 412656) |
| json-матч, percent=97 | `[→WL] via json:name` | ✓ («Смерть единорога», 1153714) |
| percent=18 | скип ниже порога | ✓ |
| `tv-1234-s1e2` | скип tv | ✓ |
| `deleted=1` | скип | ✓ |
| уже `[x]` фильм | `[ok] ничего не делаю` | ✓ (63958) |
| левый id 999999999 | `[miss] вне watchlist` | ✓ |
| dry-run без `--apply` | 0 записей в .md | ✓ |
### 🔴 Побочный баг найден и починен: `_normalize` в `sync_up.py`
`_normalize` не делал `.strip()` после удаления небуквенных символов:
`'Смерть единорога ⭐'` → `'смерть единорога '` (хвостовой пробел) ≠ `'смерть единорога'`.
Из-за этого `_mark_watched` молча проваливался на заголовках с ⭐/✭ на конце —
**включая канал Jellyfin** (там баг жил незамеченным). Фикс: `return t.strip()`.
Симптом до фикса: `[!] _mark_watched не нашёл строку для 'Смерть единорога'`.
### Новые грабли этой сессии
| # | Грабля | Обход |
|---|---|---|
| 14 | `timecodes` UNIQUE(user, identity) — повторный INSERT той же пары падает | одна строка на пользователя+фильм, percent обновляется на месте; в тесте — разные `user` |
| 15 | `Sync.sql` (`bookmarks` с `categories`) и `Sisi.sql` — ПУСТЫЕ (проверено 2026-09-24) | Lampa не синхронизирует закладки на Lampac; TimeCode — единственный канал |
| 16 | `json.name` = TMDB ru-заголовок (требование «как в tmdb/kp»), ≠ строке .md | двухступенчатый матч: resolve-cache точный → json name/original + год |
| 17 | длинный inline-ssh с URL-подобными строками уходит на апрув tirith и истекает | файл-скрипт через scp (как всегда) |
### Осталось (не блокирует работу канала)
- ⏳ **Калибровка порога**: досмотреть фильм из вотчлиста в Lampa → вычитать
`percent` из `timecodes` → если ≠ 90, поправить `LAMPAC_PERCENT_THRESHOLD`
в `.env` (перезапуск не нужен, читается при каждом запуске).
- ⏳ Сериалы (`tv-*`) — этап 2.
- ⏳ Риск `/lampac/database` не на volume — закрыть bind-mount'ем (отдельный апрув).
- Проверка в UI: после первого реального досмотра фильм должен пропасть из
«Мой список» в Lampa после ночного прогона (каталог 02:30 пересобирается
и выкидывает `[x]`).
**Открытые пункты, ждущие команды Alex** (все три — отдельные апрувы):
1. Лог `nightly`: `/tmp/watchlist-nightly.log` → `/home/kraken/logs/` (одна строка crontab, см. 8.2).
2. `arr.py`: `searchForMovie: False`, `searchForMissingEpisodes: False` (см.