[2026-09-25] eagle: personal/plans/lampac-watchlist-plugin.md personal/tech/lampac-deployment.md
This commit is contained in:
1 parent
f295d5e903
commit
f184b707a1
2 files changed
+208
-13
No files matched your search
@@ -43,7 +43,7 @@ related:
|
||||
|
||||
| Слой | Путь | Примечание |
|
||||
|---|---|---|
|
||||
| **Mac, репо** | `~/Developer/lampac-scripts/scripts/build_plugin.py` | сборщик, 12 инвариантов |
|
||||
| **Mac, репо** | `~/Developer/lampac-scripts/scripts/build_plugin.py` | сборщик, 14 инвариантов |
|
||||
| **Mac, репо** | `~/Developer/lampac-scripts/scripts/plugin-cub.js` | 🔴 собранный выход, РУКАМИ не правим |
|
||||
| Mac, скрэтч | `/Users/admin/lampac-tmp/` | рабочая папка, вне git — не источник истины |
|
||||
| Кра́кен, хост | `/srv/dev-disk-by-uuid-6194539b-.../lampac/catalog/plugin.js` | bind-mount, вне git |
|
||||
@@ -71,6 +71,27 @@ git commit -m "..." && git push origin main
|
||||
(`watchlist.json`, `watchlist-<cat>.json`, `cards.json`, `cards/`, `missing.json`).
|
||||
Попытка `scp` оттуда падает с «No such file or directory» — это не сбой сети.
|
||||
|
||||
### 🔴 CDP-пробы на ТВ (порт 9998) — питфоллы, стоившие сессии
|
||||
|
||||
| Питфолл | Симптом | Как правильно |
|
||||
|---|---|---|
|
||||
| **Цель искать по `url`, а не `title`** | сразу после рестарта Lampa `title=""`, `url=about:blank` → скрипт молча не находит цель, проба даёт пустоту | выбирать `"com.lampac.tv" in t.get("url")`, НЕ `title == "Lampac"` |
|
||||
| **Первый замер — гонка** | `ready=false, plugin=false, patch=false, act_url=ERR` выглядит как «плагин не доехал» | подождать/опрашивать `ready`, пока не станет `true` |
|
||||
| **`JSON.stringify(active())` падает** | `TypeError: Converting circular structure to JSON` | собирать поля по одному или строку вручную |
|
||||
| **Отсутствующее поле без обёртки** | CDP отвечает без `result.value` — выглядит как «все пробы пустые» (получили 9 `<none>` подряд) | каждую пробу оборачивать в `String(...)` / `typeof ...`, проверять `subtype == "error"` |
|
||||
| **`Log.enable` + `Runtime.enable` дают 0 строк** | консольные сообщения, напечатанные ДО подключения, не отдаются | читать логи СРАЗУ после рестарта, либо подтверждать состояние пробами, а не логами |
|
||||
|
||||
⚠️ **`docker restart lampac` НЕ сбрасывает кэш `catalog.js` в браузере webOS** — нужен
|
||||
рестарт приложения на ТВ через `luna-send`. И **не спать** в ожидании: Alex на паузу
|
||||
`sleep 20` отреагировал резко («Чё нахуй за слип 20?!») — вместо сна опрашивать состояние.
|
||||
|
||||
🔴 **Правило диагностики:** не читать `curl -w %{size_download}` как «размер фида» —
|
||||
это размер ПОСЛЕ распаковки gzip. Брать `ls -la` или `Accept-Encoding: identity`.
|
||||
Пример: `watchlist-films.json` = 88 КБ несжатых при 347 позициях, а `cards.json` = 548 КБ.
|
||||
|
||||
⚠️ **`ifconfig` на Кра́кене отсутствует** — каждая `ssh kraken` печатает
|
||||
`bash: line 1: ifconfig: command not found` безвредным шумом. Это НЕ ошибка команды.
|
||||
|
||||
### Порядок деплоя
|
||||
|
||||
```
|
||||
@@ -93,6 +114,59 @@ ssh kraken 'docker exec lampac grep -c "<маркер>" /lampac/module/Catalog/p
|
||||
следующая сборка затрёт правку. Инварианты в `checks{}` обязаны покрывать любую
|
||||
новую функцию — иначе регресс пройдёт молча.
|
||||
|
||||
### 🔴🔴 Как определить активный экран Lampa — по `component`, НЕ по `url`
|
||||
|
||||
**ИЗМЕРЕНО на живом ТВ 2026-09-25.** Форма объекта:
|
||||
|
||||
```
|
||||
Lampa.Activity.active() → {url, title, component, source, page, params, activity}
|
||||
Lampa.Activity.active().activity → {component, object, slide, body, is_started, is_stopped}
|
||||
```
|
||||
|
||||
🔴 **На главной `url` ПУСТОЙ.** Реальный замер в момент, когда открыта главная
|
||||
(`?component=main&source=cub&page=1`):
|
||||
|
||||
```
|
||||
url = "" title = "Главная - CUB" component = "main"
|
||||
source = "cub" page = 1
|
||||
```
|
||||
|
||||
`url === 'main'` **не срабатывает никогда.** Если строить фильтр секций на `url`,
|
||||
он либо не работает, либо работает случайно — через смягчающую ветку «пусто +
|
||||
`Manifest.catalogs` пуст». Как только манифест заполнится, **фильтр начнёт резать
|
||||
саму главную** и секции исчезнут.
|
||||
|
||||
**Правильное поле — `component`:**
|
||||
| Экран | `component` | `url` |
|
||||
|---|---|---|
|
||||
| Главная | `main` | `""` (пусто) |
|
||||
| Категория / Фильмы | `category_full` / `category` | `movie`, `cartoons`, … |
|
||||
|
||||
```js
|
||||
function wlComp(a) {
|
||||
if (!a) return '';
|
||||
if (a.component) return String(a.component);
|
||||
if (a.activity && a.activity.component) return String(a.activity.component);
|
||||
return '';
|
||||
}
|
||||
// фильтр: if (wlComp(Lampa.Activity.active()) === 'main') → вставляем
|
||||
```
|
||||
|
||||
⚠️ `url` при этом остаётся полезным для другого: на экране Фильмов он даёт
|
||||
`"movie"`. Замер `act_url = "movie"` использовался как доказательство работы фильтра.
|
||||
|
||||
### 🔴 `Manifest.catalogs` и `window.__wl_menu` рассинхронизированы
|
||||
|
||||
Меряно одновременно: `menu = Новинки,Фильмы,Мультфильмы,Аниме` при
|
||||
`Manifest.catalogs = NOMANIFEST`. То есть `__wl_menu` заполнен, а штатный манифест —
|
||||
нет. **На `loadCatalogs()` полагаться нельзя**, для меню нужен независимый запрос
|
||||
(`wlPrefetch()` в `startPlugin()`, параллельно `loadCatalogs()`).
|
||||
|
||||
Без предзагрузки первый `partNext` застаёт `__wl_menu` пустым → уходит в
|
||||
асинхронный `wlMenu()` → пока летит запрос, родной `cub.main()` уже отрисовал свои
|
||||
секции и `slice(0, parts_limit)` отработал → наши секции попадают в пул только
|
||||
следующим раундом. Alex видел это как «есть, но сильно после первых секций».
|
||||
|
||||
### 🔴 Перезапуск Lampa на ТВ обязателен
|
||||
|
||||
`docker restart lampac` **НЕ сбрасывает** кэш `catalog.js` в браузере webOS — ТВ
|
||||
@@ -1724,10 +1798,12 @@ node --check plugin-cub.js
|
||||
`lampac-tmp` вне git, файлы там не переживут чистку. Коммит: `5e55a47`.
|
||||
|
||||
Детерминирован: режет `[до startPlugin] + INJECT + [новый startPlugin] + '})();'`,
|
||||
проверяет инварианты. **Текущий набор (12):** `INJECT=1`, `partNext def=1`,
|
||||
проверяет инварианты. **Текущий набор (14):** `INJECT=1`, `partNext def=1`,
|
||||
`wlInject def=1`, `unshift (не push)=1`, `push в INJECT=0`, `startPlugin=1`,
|
||||
`нет network.silent в INJECT=0`, плюс добавленные 2026-09-25 —
|
||||
**`wlOnMain def=1`, `wlOnMain guard=1`, `wlUrl def=1`, `wlUrl верхний уровень=1`**.
|
||||
`нет network.silent в INJECT=0`, `wlOnMain def=1`, `wlComp def=1`,
|
||||
`wlComp читает component=1`, `wlOnMain guard=1`, `wlPrefetch def=1`,
|
||||
`wlPrefetch call=3`. Инварианты `wlUrl*` **убраны** вместе с `wlUrl()` —
|
||||
поле `url` оказалось не тем (см. раздел про `component`).
|
||||
|
||||
🔴 **Правило: новая функция в INJECT = новый инвариант в `checks{}`.** Иначе
|
||||
регресс (например, потерянный фильтр по экрану) пройдёт сборку молча и всплывёт
|
||||
|
||||
Reference in new issue
Block a user