[2026-09-25] eagle: personal/plans/lampac-watchlist-plugin.md personal/tech/lampac-deployment.md
This commit is contained in:
1 parent
aed8c42aa3
commit
7dbfead569
2 files changed
+208
-13
No files matched your search
@@ -8,7 +8,7 @@ related:
|
|||||||
- '[[family/projects/watchlist-automation]]'
|
- '[[family/projects/watchlist-automation]]'
|
||||||
- '[[family/documents/movies-watchlist]]'
|
- '[[family/documents/movies-watchlist]]'
|
||||||
- '[[personal/plans/lampac-watched-to-watchlist]]'
|
- '[[personal/plans/lampac-watched-to-watchlist]]'
|
||||||
status: main-screen-filter-implemented-2026-09-25-awaiting-tv-acceptance
|
status: main-screen-filter-fix-regressed-then-fixed-2026-09-25-acceptance-blocked-on-empty-catalog
|
||||||
tags:
|
tags:
|
||||||
- lampac
|
- lampac
|
||||||
- lampa
|
- lampa
|
||||||
@@ -42,16 +42,21 @@ updated: '2026-09-25'
|
|||||||
прогружается относительно основного CUB списка, почему он не моментально проявляется,
|
прогружается относительно основного CUB списка, почему он не моментально проявляется,
|
||||||
он же статичный».
|
он же статичный».
|
||||||
|
|
||||||
**Статус: ✅ ФИКС ПРИМЕНЁН И ЗАЛИТ 2026-09-25. Ждёт только перезапуска Lampa на ТВ
|
**Статус: ⚠️ ФИКС ПРИМЕНЁН И ЗАЛИТ 2026-09-25, НО ПРИЁМКА ПРОВАЛЕНА — секции на
|
||||||
(ТВ `192.168.1.70` был выключен — ни ping, ни CDP-порт 9998 не отвечали).**
|
главной исчезли. См. «РЕГРЕСС И ВТОРОЙ ФИКС» ниже — там актуальная версия `wlOnMain`.**
|
||||||
|
|
||||||
### ✅ РЕШЕНИЕ: `wlOnMain()` — строгий белый список по активному activity
|
### ✅ РЕШЕНИЕ: `wlOnMain()` — белый список по активному activity
|
||||||
|
|
||||||
Alex: «В смысле всё кроме? **Только главный экран!**» — предикат сделан ЖЁСТКИМ
|
Alex: «В смысле всё кроме? **Только главный экран!**» — предикат сделан строгим
|
||||||
(`=== 'main'`), не «всё кроме списка исключений». Любое незнакомое имя activity
|
(`=== 'main'`), не «всё кроме списка исключений». Любое незнакомое имя activity
|
||||||
обязано по умолчанию секции НЕ получать.
|
обязано по умолчанию секции НЕ получать.
|
||||||
|
|
||||||
|
⚠️ **ПЕРВАЯ ВЕРСИЯ (ниже) НЕРАБОЧАЯ — оставлена как история ошибки.** Она читала
|
||||||
|
`a.activity.url`; правильный уровень — `a.url` (измерено на ТВ, см. «РЕГРЕСС И ВТОРОЙ
|
||||||
|
ФИКС»). Актуальный текст — `wlUrl()` + `wlOnMain()` в разделе регресса.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
// ❌ НЕРАБОЧАЯ ПЕРВАЯ ВЕРСИЯ — оставлена как история ошибки, НЕ КОПИРОВАТЬ
|
||||||
function wlOnMain() {
|
function wlOnMain() {
|
||||||
try {
|
try {
|
||||||
var a = (window.Lampa && Lampa.Activity && Lampa.Activity.active)
|
var a = (window.Lampa && Lampa.Activity && Lampa.Activity.active)
|
||||||
@@ -199,15 +204,117 @@ Lampa.Api.partNext = function (parts, parts_limit, partLoaded, partEmpty) {
|
|||||||
категории. На 2026-09-25 `watchlist-catalog.sh` уже убран в `.bak-removed-20260924-181942`,
|
категории. На 2026-09-25 `watchlist-catalog.sh` уже убран в `.bak-removed-20260924-181942`,
|
||||||
отдельной строки крона `30 2 * * *` в crontab **нет** (п.2 из списка незакрытого — закрыт).
|
отдельной строки крона `30 2 * * *` в crontab **нет** (п.2 из списка незакрытого — закрыт).
|
||||||
|
|
||||||
|
### 🔴 РЕГРЕСС И ВТОРОЙ ФИКС 2026-09-25 (после первой заливки)
|
||||||
|
|
||||||
|
**Alex после перезапуска Lampa:** «Нету теперь списка на главной. Смотри логи.»
|
||||||
|
Секции исчезли ПОЛНОСТЬЮ — первая версия фильтра оказалась нерабочей.
|
||||||
|
|
||||||
|
**Логи сняты с живой Lampa через CDP** (ТВ `192.168.1.70:9998`, скрипт
|
||||||
|
`/Users/admin/lampac-tmp/wl_console.py` + `/tmp/wl_probe*.py`; `websocket-client`,
|
||||||
|
`Runtime.enable` + `Log.enable`):
|
||||||
|
|
||||||
|
```
|
||||||
|
act = undefined ← фильтр сравнивал с 'main', получал пустое
|
||||||
|
comp = [object Object]
|
||||||
|
wl_menu_type = undefined ← window.__wl_menu НЕ создан
|
||||||
|
catalog_all = NOMANIFEST ← Lampa.Manifest.catalogs вообще пуст
|
||||||
|
patch = true ← перехватчик стоял, фильтр работал
|
||||||
|
src = cub
|
||||||
|
```
|
||||||
|
|
||||||
|
**🔴 КОРНЕВАЯ ПРИЧИНА №1 — `url` лежит НА ВЕРХНЕМ уровне activity, а не во вложенном.**
|
||||||
|
Измерено на живом ТВ (`/tmp/wl_probe5.py`, вывод дословно):
|
||||||
|
|
||||||
|
```
|
||||||
|
Lampa.Activity.active() → {url, title, component, source, page, params, activity}
|
||||||
|
Lampa.Activity.active().activity → {component, object, slide, body, is_stopped, is_started}
|
||||||
|
↑ url ЗДЕСЬ НЕТ
|
||||||
|
```
|
||||||
|
|
||||||
|
Первая версия читала `active().activity.url` → **всегда `undefined`** → `=== 'main'`
|
||||||
|
всегда `false` → секции пропускались на главной ВСЕГДА. Фильтр не «слишком строгий» —
|
||||||
|
он смотрел не туда. **Проверять форму объекта ЗАМЕРОМ, а не по памяти: в доках
|
||||||
|
сессии 7 форма не была зафиксирована.**
|
||||||
|
|
||||||
|
**🔴 КОРНЕВАЯ ПРИЧИНА №2 — `Manifest.catalogs` пуст** → `loadCatalogs()` не получил
|
||||||
|
`/catalog` от Lampac → `window.__wl_menu` не создан → **вставлять нечего**, даже если
|
||||||
|
фильтр пропускает. Строгая первая версия заодно отсекала ЕДИНСТВЕННЫЙ вызов `wlMenu()`,
|
||||||
|
который дозагружает меню повторным запросом. То есть фильтр не только не пропускал —
|
||||||
|
он снял путь восстановления.
|
||||||
|
|
||||||
|
**Фикс (залит 2026-09-25 22:14):** новая функция `wlUrl(a)` читает **оба уровня**,
|
||||||
|
верхний первым, вложенный — фолбэк; плюс смягчающая ветка «пустой `url` + пустой
|
||||||
|
`catalogs` = инициализация главной → пропустить»:
|
||||||
|
|
||||||
|
```js
|
||||||
|
function wlUrl(a) {
|
||||||
|
if (!a) return '';
|
||||||
|
if (a.url) return a.url; // ← ПРАВИЛЬНЫЙ уровень
|
||||||
|
if (a.activity && a.activity.url) return a.activity.url; // фолбэк
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function wlOnMain() {
|
||||||
|
var a = (window.Lampa && Lampa.Activity && Lampa.Activity.active)
|
||||||
|
? Lampa.Activity.active() : null;
|
||||||
|
var act = wlUrl(a);
|
||||||
|
if (act === 'main') return true;
|
||||||
|
if (!act) { // главная ещё инициализируется
|
||||||
|
var c = (window.Lampa && Lampa.Manifest && Lampa.Manifest.catalogs) || {};
|
||||||
|
if (!Object.keys(c).length) return true;
|
||||||
|
}
|
||||||
|
console.log('[watchlist] не главная (' + (act || '?') + ') — секции пропущены');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Ложная вставка на чужом экране при этом невозможна: без `__wl_menu` вставлять нечего.
|
||||||
|
|
||||||
|
**Сборка и деплой (все инварианты пройдены):**
|
||||||
|
```
|
||||||
|
python3 build_plugin.py → 12/12, 18281 байт
|
||||||
|
node --check plugin-cub.js → SYNTAX OK
|
||||||
|
```
|
||||||
|
Новые инварианты сборщика: `wlUrl def`, `wlUrl верхний уровень`
|
||||||
|
(`if (a.url) return a.url;`) — сборка падает, если чтение уровня откатится назад.
|
||||||
|
Бэкап: `catalog/plugin.js.bak-before-fixurl-<ts>`. Залито → 20934 Б,
|
||||||
|
`docker exec lampac grep -n "function wlUrl" -A4 /lampac/module/Catalog/plugin.js` → на месте.
|
||||||
|
|
||||||
|
**⚠️ НА МОМЕНТ ЗАПИСИ ФИКС НЕ ПРИЁМКОВАН.** Замер после заливки: `url = ""`
|
||||||
|
на ОБОИХ уровнях, `hasCats = false`, `menu = 0`. То есть Lampa стоит на главной давно
|
||||||
|
(URL страницы `component=main&source=cub`), но `Activity.active().url` пуст — это НЕ
|
||||||
|
стадия инициализации. Пока `/catalog` не отвечает, `__wl_menu` пуст и секции взять
|
||||||
|
неоткуда: **перезапуск Lampa без починенного `/catalog` ничего не даст.**
|
||||||
|
|
||||||
|
**Следующий шаг (обязательный, не сделан):** проверить боевой запрос Lampa → Lampac
|
||||||
|
`/catalog` — отвечает ли он с ТВ, отвечает ли с Кра́кена, не сломан ли он вообще.
|
||||||
|
|
||||||
|
### Инструменты диагностики ТВ, написанные в этой сессии (переиспользовать)
|
||||||
|
|
||||||
|
| Скрипт | Что делает |
|
||||||
|
|---|---|
|
||||||
|
| `/Users/admin/lampac-tmp/wl_console.py` | CDP-клиент: сбор `console`-логов Lampa за 12 с + снимок состояния (`act`, `patch`, `menu`, `pending`, `src`) |
|
||||||
|
| `/tmp/wl_probe2..5.py` | точечные пробы структуры `Activity.active()` (ключи, типы, значения) |
|
||||||
|
|
||||||
|
🔴 **Питфоллы CDP-проб, найденные на живом ТВ:**
|
||||||
|
- `JSON.stringify(Lampa.Activity.active())` → **`TypeError: Converting circular structure
|
||||||
|
to JSON`**. Возвращать поля по одному или собирать строку вручную.
|
||||||
|
- Обращаться к отсутствующему полю в `Runtime.evaluate` **без** обёртки — CDP отвечает
|
||||||
|
без `result.value`, и выглядит это как «все пробы пустые» (первый прогон дал девять
|
||||||
|
`<none>` подряд). Каждую пробу оборачивать в `String(...)` / `typeof ...` и проверять
|
||||||
|
`subtype == "error"`.
|
||||||
|
- `Log.enable` + `Runtime.enable` дают **0 строк** лога, если Lampa уже загрузилась —
|
||||||
|
консольные сообщения, напечатанные до подключения, не отдаются. Логи читать СРАЗУ
|
||||||
|
после перезапуска приложения, либо подтверждать состояние пробами, а не логами.
|
||||||
|
|
||||||
### Открытые шаги (для следующей сессии)
|
### Открытые шаги (для следующей сессии)
|
||||||
|
|
||||||
1. ✅ **ЗАКРЫТО 2026-09-25** — фикс «фид на всех экранах»: `wlOnMain()` + гард в
|
1. 🔴 **ПРИЁМКА НЕ ПРОЙДЕНА** — фикс `wlUrl` залит, но секции на главной не появились.
|
||||||
`wlPatchPartNext`, залито на Кра́кен. Осталась приёмка на ТВ (перезапуск Lampa +
|
**Корень — пустой `Manifest.catalogs`: `/catalog` не отвечает Lampa.** Без этого
|
||||||
визуальная проверка главной и «Фильмы → документальные»).
|
фильтр не при чём. Проверить боевой `/catalog` (с ТВ и с Кра́кена) — ПЕРВЫМ делом.
|
||||||
2. **Диагностировать 66 с на карточке** — `docker logs lampac` + трейс `CardController`.
|
2. **Диагностировать 66 с на карточке** — `docker logs lampac` + трейс `CardController`.
|
||||||
Единственный замеренный источник ощущения «не моментально», который НЕ объясняется
|
Запрос: `GET /catalog/card?plugin=watchlist&uri=movie%2F424781&type=movie`
|
||||||
холодным `hybridCache` (2.25 с). Запрос:
|
→ 66 118 мс, 939 Б.
|
||||||
`GET /catalog/card?plugin=watchlist&uri=movie%2F424781&type=movie` → 66 118 мс, 939 Б.
|
|
||||||
3. **Matcher-parity** (главный блокер с 2026-09-24, см. ниже) — всё ещё не закрыт.
|
3. **Matcher-parity** (главный блокер с 2026-09-24, см. ниже) — всё ещё не закрыт.
|
||||||
|
|
||||||
**Правило диагностики этой сессии:** не читать `%{size_download}` как «размер фида»
|
**Правило диагностики этой сессии:** не читать `%{size_download}` как «размер фида»
|
||||||
@@ -219,7 +326,10 @@ Lampa.Api.partNext = function (parts, parts_limit, partLoaded, partEmpty) {
|
|||||||
(`No module named 'psutil'`) — расследование и правки сделаны через `terminal` +
|
(`No module named 'psutil'`) — расследование и правки сделаны через `terminal` +
|
||||||
`read_file` + `patch`, БЕЗ python-скриптов. `scp` файла `wwwroot/catalog.js` не нашёл:
|
`read_file` + `patch`, БЕЗ python-скриптов. `scp` файла `wwwroot/catalog.js` не нашёл:
|
||||||
такого пути НЕТ, `plugin.js` живёт в `lampac/catalog/plugin.js` и монтируется в
|
такого пути НЕТ, `plugin.js` живёт в `lampac/catalog/plugin.js` и монтируется в
|
||||||
`/lampac/module/Catalog/plugin.js`.
|
`/lampac/module/Catalog/plugin.js`. Alex отдельно и дважды требовал результат
|
||||||
|
расследования (не план, не вопрос): «задача блядь поставлена», «хули ты творишь. ты
|
||||||
|
блядь не можешь в код проекта посмотреть и в доки и все выяснить?» — **сначала читать
|
||||||
|
код проекта и доки, потом отвечать.**
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
title: Lampac — развёртывание и эксплуатация (Кра́кен)
|
title: Lampac — развёртывание и эксплуатация (Кра́кен)
|
||||||
created: '2026-09-22'
|
created: '2026-09-22'
|
||||||
updated: '2026-09-24'
|
updated: '2026-09-25'
|
||||||
type: tech
|
type: tech
|
||||||
namespace: personal
|
namespace: personal
|
||||||
tags:
|
tags:
|
||||||
@@ -28,6 +28,91 @@ related:
|
|||||||
|
|
||||||
> Технический справочник. Развёрнуто 2026-09-22. План и статус шагов — [[personal/plans/lampac-kraken]].
|
> Технический справочник. Развёрнуто 2026-09-22. План и статус шагов — [[personal/plans/lampac-kraken]].
|
||||||
|
|
||||||
|
## 🔴 2026-09-25: деплой `plugin.js` модуля Catalog — контракт и подводные камни
|
||||||
|
|
||||||
|
Правки фида Watchlist в UI Lampa живут НЕ в YAML, а в `plugin.js` модуля Catalog
|
||||||
|
(патч `enumerable:true` + инжект секций через перехват `Lampa.Api.partNext`).
|
||||||
|
Полный план и статус — [[personal/plans/lampac-watchlist-plugin]].
|
||||||
|
|
||||||
|
### Где лежит файл (три разных места — не путать)
|
||||||
|
|
||||||
|
| Слой | Путь | Примечание |
|
||||||
|
|---|---|---|
|
||||||
|
| Mac, исходник | `/Users/admin/lampac-tmp/plugin-cub.js` | результат `build_plugin.py` |
|
||||||
|
| Mac, сборщик | `/Users/admin/lampac-tmp/build_plugin.py` | 🔴 `plugin-cub.js` РУКАМИ не правим |
|
||||||
|
| Кра́кен, хост | `/srv/dev-disk-by-uuid-6194539b-.../lampac/catalog/plugin.js` | bind-mount |
|
||||||
|
| В контейнере | `/lampac/module/Catalog/plugin.js` | `:ro` по compose |
|
||||||
|
| По HTTP | `http://192.168.1.14:9118/catalog.js` | что реально грузит ТВ |
|
||||||
|
|
||||||
|
🔴 **`wwwroot/catalog.js` НЕ существует.** `wwwroot/` содержит только JSON фида
|
||||||
|
(`watchlist.json`, `watchlist-<cat>.json`, `cards.json`, `cards/`, `missing.json`).
|
||||||
|
Попытка `scp` оттуда падает с «No such file or directory» — это не сбой сети.
|
||||||
|
|
||||||
|
### Порядок деплоя (боевой конфиг — коммит ДО, правка, заливка, ПРОВЕРКА, коммит ПОСЛЕ)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /Users/admin/lampac-tmp
|
||||||
|
python3 build_plugin.py # инварианты: сборка падает при нарушении
|
||||||
|
node --check plugin-cub.js # SYNTAX OK обязателен
|
||||||
|
# бэкап боевого
|
||||||
|
ssh kraken 'cp .../lampac/catalog/plugin.js .../catalog/plugin.js.bak-<что>-$(date +%Y%m%d-%H%M%S)'
|
||||||
|
scp plugin-cub.js kraken:.../lampac/catalog/plugin.js
|
||||||
|
# проверка, что файл виден в контейнере (bind-mount)
|
||||||
|
ssh kraken 'docker exec lampac grep -c "<маркер>" /lampac/module/Catalog/plugin.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
### 🔴 Перезапуск Lampa на ТВ обязателен
|
||||||
|
|
||||||
|
`docker restart lampac` **НЕ сбрасывает** кэш `catalog.js` в браузере webOS — ТВ
|
||||||
|
продолжит исполнять старую версию плагина. Нужен рестарт приложения на ТВ:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
scp /Users/admin/lampac-tmp/tv_restart.sh root@192.168.1.70:/tmp/ \
|
||||||
|
&& ssh root@192.168.1.70 'sh /tmp/tv_restart.sh'
|
||||||
|
```
|
||||||
|
|
||||||
|
⚠️ `luna-send` через `ssh 'script -q -c "luna-send ... -a {\"id\":...}"'` ломается на
|
||||||
|
экранировании JSON (luna-send печатает help) — поэтому скрипт кладётся файлом на ТВ.
|
||||||
|
|
||||||
|
### 🔴 Форма `Lampa.Activity.active()` — ИЗМЕРЕНО на живом ТВ 2026-09-25
|
||||||
|
|
||||||
|
```
|
||||||
|
Lampa.Activity.active() → {url, title, component, source, page, params, activity}
|
||||||
|
Lampa.Activity.active().activity → {component, object, slide, body, is_stopped, is_started}
|
||||||
|
↑ url ЗДЕСЬ НЕТ
|
||||||
|
```
|
||||||
|
|
||||||
|
**`url` лежит на ВЕРХНЕМ уровне.** Обращение к `.activity.url` всегда даёт `undefined` —
|
||||||
|
на этом была потеряна приёмка 2026-09-25 (фильтр «только главная» смотрел не туда и
|
||||||
|
секции исчезли полностью). Читать оба уровня, верхний первым.
|
||||||
|
|
||||||
|
### 🔴 CDP-диагностика ТВ (порт 9998) — питфоллы
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -s "http://192.168.1.70:9998/json/list" | jq -r '.[] | select(.title=="Lampac") | .webSocketDebuggerUrl'
|
||||||
|
```
|
||||||
|
Клиент — `websocket-client` (модуля `websockets` на Mac НЕТ). Готовый скрипт:
|
||||||
|
`/Users/admin/lampac-tmp/wl_console.py`.
|
||||||
|
|
||||||
|
- `JSON.stringify(Lampa.Activity.active())` → **`TypeError: Converting circular structure
|
||||||
|
to JSON`**. Возвращать поля по одному.
|
||||||
|
- Обращение к отсутствующему полю в `Runtime.evaluate` без обёртки → ответ без
|
||||||
|
`result.value`, выглядит как «все пробы вернули `<none>`». Оборачивать в
|
||||||
|
`String(...)` / `typeof ...`, проверять `subtype == "error"`.
|
||||||
|
- `Runtime.enable` + `Log.enable` дают **0 строк**, если Lampa уже загрузилась:
|
||||||
|
сообщения, напечатанные до подключения, не отдаются. Логи читать сразу после
|
||||||
|
рестарта приложения либо подтверждать состояние пробами.
|
||||||
|
- 🔴 `URL страницы ТВ — надёжный индикатор экрана`: `...index.html?title=Главная%20-%20CUB
|
||||||
|
&component=main&source=cub` = главная CUB.
|
||||||
|
|
||||||
|
### 🔴 `Manifest.catalogs` пуст = фид вставлять некуда
|
||||||
|
|
||||||
|
Если `/catalog` от Lampac не ответил, `loadCatalogs()` не отработал →
|
||||||
|
`window.__wl_menu` не создан → **секции Watchlist не появятся ни на одном экране**,
|
||||||
|
независимо от фильтров. Наблюдалось 2026-09-25: `catalog_all = NOMANIFEST`,
|
||||||
|
`wl_menu = undefined`, при этом `patch = true`. Диагностировать это ПЕРВЫМ, до
|
||||||
|
разбора логики фильтра.
|
||||||
|
|
||||||
## 🔴 2026-09-24 (вечер): «Мастерская сатаны» — один источник, торренты пусты. План диагностики
|
## 🔴 2026-09-24 (вечер): «Мастерская сатаны» — один источник, торренты пусты. План диагностики
|
||||||
|
|
||||||
**Вопрос Alex:** *«для Мастерская сатаны например в lampac в источниках есть только
|
**Вопрос Alex:** *«для Мастерская сатаны например в lampac в источниках есть только
|
||||||
|
|||||||
Reference in new issue
Block a user