watchlist: sync-from-lampac implemented (Lampa -> [x]) — plan status, automation doc
This commit is contained in:
1 parent
7af79521ce
commit
337505a33f
2 files changed
+148
-7
No files matched your search
@@ -12,6 +12,68 @@ tags:
|
||||
|
||||
Полная цепочка: как `family/documents/movies-watchlist.md` превращается в скачанный контент.
|
||||
|
||||
## ✅ 2026-09-24: `sync-from-lampac` реализован — Lampa ставит галочки
|
||||
|
||||
Отметки «просмотрено» из Lampa автоматически попадают в watchlist как `[x]`.
|
||||
Коммит `ef44f3e` (код), план — [[personal/plans/lampac-watched-to-watchlist]] §10.
|
||||
|
||||
**Ночной пайплайн теперь:**
|
||||
```
|
||||
sync-vault (pull) → process-thumbs → resolve --recheck → [sync-down ПРОПУЩЕН]
|
||||
→ sync-up (Jellyfin, non-fatal) → sync-from-lampac --apply (NEW)
|
||||
→ sync-vault (push)
|
||||
```
|
||||
|
||||
**Как работает матч** (`watchlist_sync/sync_from_lampac.py`):
|
||||
```
|
||||
timecodes.identity ('movie-674' / '674_movie', строгие формы)
|
||||
→ tmdb_id
|
||||
→ 1) .resolve_cache.json (candidate.tmdb_id → ключ = заголовок .md) — ТОЧНО
|
||||
→ 2) фолбэк: watchlist.json (href → name TMDB-ru / original + год ±1)
|
||||
→ _mark_watched ([x], строка уезжает в блок просмотренных)
|
||||
```
|
||||
|
||||
**Критерий просмотренного:** `deleted=0` И `percent >= 90` (env
|
||||
`LAMPAC_PERCENT_THRESHOLD`, CLI `--percent`). `watched_at` — НЕ критерий
|
||||
(бывает >0 при 18%). Сериалы `tv-*` — скип, этап 2.
|
||||
|
||||
**Ключевые факты:**
|
||||
- БД `TimeCode.sql` — только внутри контейнера lampac (НЕ на volume!),
|
||||
читается копией `docker cp`; `sqlite3` в контейнере нет.
|
||||
- `Sync.sql` (bookmarks) и `Sisi.sql` — ПУСТЫЕ: закладки Lampa не
|
||||
синхронизируются на Lampac, TimeCode — единственный канал просмотров.
|
||||
- `timecodes`: UNIQUE(user, identity) — одна строка на юзера+фильм,
|
||||
percent обновляется на месте.
|
||||
- Ручной прогон: `uv run watchlist-sync sync-from-lampac` (dry-run по
|
||||
умолчанию, `--apply` для записи).
|
||||
|
||||
**.env (Kraken, `$WS/.env`, бэкап `.env.bak-lampac-20260924`):**
|
||||
```
|
||||
LAMPAC_TIMECODE_DB=lampac:/lampac/database/TimeCode.sql
|
||||
LAMPAC_WATCHLIST_JSON=/srv/dev-disk-by-uuid-6194539b-03e0-4f33-986b-4da09834e82f/lampac/wwwroot/watchlist.json
|
||||
LAMPAC_PERCENT_THRESHOLD=90
|
||||
```
|
||||
|
||||
**nightly:** md5 новой `edf0e34530692dbb7b6fb9644f1b45a7` (было
|
||||
`4401882e...`), бэкап `~/scripts/watchlist-nightly.sh.bak-lampac-20260924`.
|
||||
Полный ручной прогон 01:05–01:07 ✓, новый шаг ~2 сек, non-fatal.
|
||||
|
||||
**Побочный фикс:** `_normalize` в `sync_up.py` не делал `.strip()` после
|
||||
удаления небуквенных — заголовки с хвостовым ⭐ молча проваливали
|
||||
`_mark_watched` (в т.ч. в Jellyfin-канале). Фикс в `ef44f3e`.
|
||||
|
||||
**Тест:** синтетическая БД (8 сценариев: cache/json матч, 18%, tv, deleted,
|
||||
уже-[x], левый id, dry-run) — 8/8 ✓; `--apply` на копии .md — diff ровно
|
||||
2 ожидаемые строки. Бэкап до работы:
|
||||
`~/backup-watchlist-before-lampac-sync-20260924-005630/`.
|
||||
|
||||
**Осталось:** калибровка порога живым досмотром (досмотреть фильм из
|
||||
списка в Lampa, вычитать percent, при ≠90 поправить env); сериалы этап 2;
|
||||
bind-mount для `/lampac/database` (риск потери истории при пересоздании
|
||||
контейнера — отдельный апрув). Проверка в UI: после первого реального
|
||||
досмотра фильм пропадает из «Мой список» в Lampa после ночного прогона
|
||||
(каталог 02:30 выкидывает `[x]`).
|
||||
|
||||
## 🔴 2026-09-23: канал «Lampa → `[x]`» найден; фиксы сирот закоммичены
|
||||
|
||||
### Коммит `ffe7974` — закрыт должок по грязному дереву
|
||||
|
||||
@@ -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` (см.
|
||||
|
||||
Reference in new issue
Block a user