[2026-09-25] eagle: personal/plans/lampac-watchlist-plugin.md personal/tech/lampac-deployment.md
This commit is contained in:
1 parent
bbfe0329e2
commit
ac78b0b7a2
2 files changed
+181
-28
No files matched your search
@@ -8,7 +8,7 @@ related:
|
||||
- '[[family/projects/watchlist-automation]]'
|
||||
- '[[family/documents/movies-watchlist]]'
|
||||
- '[[personal/plans/lampac-watched-to-watchlist]]'
|
||||
status: fourth-fix-2026-09-25-activity-hook-deployed-awaiting-verdict
|
||||
status: fifth-fix-2026-09-25-global-inject-flag-deployed-awaiting-verdict
|
||||
tags:
|
||||
- lampac
|
||||
- lampa
|
||||
@@ -38,6 +38,59 @@ updated: '2026-09-25'
|
||||
|
||||
## 🔍 2026-09-25: РАССЛЕДОВАНИЕ — фид виден на всех экранах + «долго грузится»
|
||||
|
||||
## 🟡 2026-09-25 (продолжение): ДУБЛИ СЕКЦИЙ — «watchlist снова уплыл вниз»
|
||||
|
||||
**Симптом Alex:** «Ну чето нифига не поменялось. Главная - фильмы - главная -
|
||||
watchlist снова уплыл вниз».
|
||||
|
||||
**Диагноз по DOM-замеру — не «уплыл», а ДУБЛЬ.** В `document.querySelectorAll('.items-line')`
|
||||
оказалось **13 заголовков вместо 9**:
|
||||
|
||||
```
|
||||
0:Новинки 1:Фильмы 2:Мультфильмы 3:Аниме ← наши (вверху, верно)
|
||||
4:Сейчас смотрят ... 8:В высоком качестве ← родные CUB
|
||||
9:Новинки 10:Фильмы 11:Мультфильмы 12:Аниме ← НАШИ ВТОРОЙ РАЗ (внизу)
|
||||
```
|
||||
|
||||
Визуально нижний комплект читается как «секции уплыли вниз», но это **второй экземпляр**:
|
||||
первый остался наверху, Lampa его не удаляет.
|
||||
|
||||
### 🔴 КОРНЕВАЯ ПРИЧИНА: флаг вставки велся на МАССИВЕ, а не глобально
|
||||
|
||||
Было: `if (... && !parts.__wl_done) { parts.__wl_done = true; wlInject(...) }`.
|
||||
|
||||
🔴 **`parts` приходит НОВЫМ массивом на каждый вызов `partNext`** — на нём нет пометки
|
||||
от прошлого вызова, поэтому `!parts.__wl_done` **истинно всегда**, и `wlInject`
|
||||
добавлял второй комплект через `unshift`. Флаг, повешенный на объект пула, не работает.
|
||||
|
||||
Плюс `window.__wl_done = false` в хуке сбрасывал **не ту переменную**: проба показала
|
||||
`wl_done = None` (undefined в глобальной области) — хук не влиял ни на что.
|
||||
|
||||
### ✅ ФИКС: глобальный `window.__wl_injected`
|
||||
|
||||
```js
|
||||
// wlPatchPartNext:
|
||||
if (wlOnMain() && Lampa.Arrays.isArray(parts) && !window.__wl_injected) {
|
||||
window.__wl_injected = true; // ГЛОБАЛЬНО, не на parts
|
||||
wlInject(parts, menu);
|
||||
}
|
||||
// wlWatchActivity: при уходе с главной разрешаем вставку при возврате
|
||||
if (comp !== 'main') { window.__wl_injected = false; return; }
|
||||
```
|
||||
|
||||
Логика: ушли с главной → флаг снят; вернулись → вставили ОДИН раз; повторные вызовы
|
||||
`partNext` на той же главной → флаг держит, дублей нет.
|
||||
|
||||
**Инвариантов в сборщике — 20.** Добавлены: `глобальный флаг вставки` (=2, синхронная
|
||||
и async-ветки), `флаг ставится` (=2), `флаг снимается при уходе` (=1),
|
||||
`НЕТ старого parts.__wl_done` (=0).
|
||||
|
||||
🔴 **Проверка, что правка реально на ТВ:** проба `window.__wl_activity_hook === true`
|
||||
(уникальный маркер этой сборки). `ready`/`patch` для этого НЕ годятся — они истинны
|
||||
и для старой версии, из-за чего три круга правок выглядели «не применёнными».
|
||||
|
||||
## 🔍 2026-09-25: РАССЛЕДОВАНИЕ — фид виден на всех экранах + «долго грузится»
|
||||
|
||||
**Жалоба Alex (дословно):** «есть проблема с watchlist фидом в лампе: он отображается
|
||||
не только на "главной" но даже когда я выбираю категорию например "документальные"
|
||||
в разделе Фильмы, то есть независимо от активного экрана. и он как будто долго
|
||||
@@ -340,35 +393,37 @@ dom_titles = Сейчас смотрят | Клиника | Мыс страха
|
||||
параллельно с `loadCatalogs()`. Тогда к моменту отрисовки главной `__wl_menu` уже в
|
||||
памяти, `wlInject` срабатывает в первом же раунде, секции встают в голову без отставания.
|
||||
|
||||
#### 🔴 Коммитить правку НЕКУДА — это выяснено, не пытаться снова
|
||||
#### ✅ РЕШЕНО: репозиторий `~/Developer/lampac-scripts` — история НЕ в `lampac-tmp`
|
||||
|
||||
Alex: «Коммить и переходим к предзагрузке». Проверка обеих площадок:
|
||||
**Изначальная ошибка вывода (сохранена как урок).** Проверка «в лоб» дала:
|
||||
|
||||
```
|
||||
/Users/admin/lampac-tmp → fatal: not a git repository
|
||||
/srv/.../lampac (на Кра́кене) → fatal: not a git repository
|
||||
```
|
||||
|
||||
Ни папка сборки, ни папка lampac на Кра́кене под git **не лежат**. `plugin.js` — файл,
|
||||
который **монтируется** в контейнер (`./catalog/plugin.js:/lampac/module/Catalog/plugin.js:ro`),
|
||||
рядом только `.bak`-копии. То есть версионировать «в лоб» нечего.
|
||||
Отсюда был сделан **неверный вывод** «коммитить некуда». На деле репозиторий
|
||||
**существовал давно** — я искал его не там, потому что в доке пути к плагину были
|
||||
записаны как `/Users/admin/lampac-tmp/`.
|
||||
|
||||
**Что служит страховкой вместо коммита:**
|
||||
🔴 **Настоящее место: `~/Developer/lampac-scripts`** (Gitea
|
||||
`git_admin/lampac-scripts`), там же `scripts/`, `tests/`. Alex дважды указал на это
|
||||
(«Проект на маке в developer это в доке записано. Ведь так?!», «И на gitea залит»).
|
||||
**Урок: прежде чем объявить «некуда коммитить» — искать репозиторий по
|
||||
`~/Developer/`, а не только рядом с файлом.**
|
||||
|
||||
| Артефакт | Путь | Размер |
|
||||
|---|---|---|
|
||||
| бэкап «до фильтра» | `catalog/plugin.js.bak-before-mainfilter-20260925-220809` | 17476 Б |
|
||||
| бэкап «до фикса url» | `catalog/plugin.js.bak-before-fixurl-<ts>` | 19576 Б |
|
||||
| текущий боевой | `catalog/plugin.js` | 20934 Б |
|
||||
| локальные копии | `lampac-tmp/plugin-cub.js` + `build_plugin.py` | 20934 / 14619 Б |
|
||||
**Репы на Кра́кене:** только `docker/`, `obsidian/`, `watchlist-sync/`. В `lampac/`
|
||||
git нет и не заводится — бэкапы там `.bak-*` (закрыты `.gitignore`).
|
||||
|
||||
Плюс `build_plugin.py` держит весь `INJECT` в себе → файл воспроизводится
|
||||
**детерминированно**, с 12 проверками инвариантов.
|
||||
| Артефакт | Путь |
|
||||
|---|---|
|
||||
| **Исходник (источник истины)** | `~/Developer/lampac-scripts/scripts/build_plugin.py` |
|
||||
| **Собранный выход** | `~/Developer/lampac-scripts/scripts/plugin-cub.js` |
|
||||
| Скрэтч, вне git | `/Users/admin/lampac-tmp/` |
|
||||
| Боевой на Кра́кене | `.../lampac/catalog/plugin.js` + `.bak-*` рядом |
|
||||
|
||||
**Предложенная развилка (решение за Alex, не сделано):** завести в репе
|
||||
`watchlist-sync` папку `lampac_plugin/` и положить туда `build_plugin.py` +
|
||||
`plugin-cub.js` под git — тогда правка плагина поедет вместе с проектом и попадёт
|
||||
в историю. Второе правильнее, но это новая сущность в репе → спрашивать один раз.
|
||||
`build_plugin.py` держит весь `INJECT` в себе → файл воспроизводится
|
||||
**детерминированно**, с 20 проверками инвариантов.
|
||||
|
||||
#### ✅ ЗАКОММИЧЕНО 2026-09-25 — репозиторий найден, «некуда коммитить» СНЯТО
|
||||
|
||||
@@ -676,19 +731,31 @@ docker exec lampac grep -c wlWatchActivity /lampac/module/Catalog/plugin.js →
|
||||
|
||||
### Приёмка (ждёт Alex) — полный цикл, а не только первый экран
|
||||
|
||||
1. главная → 4 секции Watchlist сверху
|
||||
1. главная → 4 секции Watchlist сверху, **БЕЗ дублей внизу**
|
||||
2. Фильмы → документальные → секций Watchlist нет
|
||||
3. **назад на главную → секции СНОВА сверху** ← пункт, который ломался
|
||||
3. **назад на главную → секции СНОВА сверху, снова без дублей** ← пункт, который ломался
|
||||
|
||||
⚠️ **Коммит четвёртого фикса НЕ сделан** — ждёт приёмки. Файлы в
|
||||
`/Users/admin/lampac-tmp/`; после приёмки скопировать в
|
||||
`~/Developer/lampac-scripts/scripts/` и закоммитить порядком `5e55a47`.
|
||||
✅ **Коммиты СДЕЛАНЫ и запушены** (в `~/Developer/lampac-scripts`, Gitea):
|
||||
- `5e55a47` — «секции CUB только на главной экране» (фильтр `wlOnMain`)
|
||||
- `3a35475` — «фильтр по component + предзагрузка меню + хук на activity»
|
||||
|
||||
🔴 **Правки обязаны попадать в репу ДО доклада.** В этой сессии `5e55a47` был
|
||||
закоммичен, а работа по фильтру по `component` осталась незакоммиченной, и Alex
|
||||
справедливо спросил «Коммит ты сделал текущей работы я надеюсь». Порядок:
|
||||
`build_plugin.py` правится → собирается → **копируется в `scripts/` → коммит → push**,
|
||||
и только потом заливка и приёмка. Файлы в `/Users/admin/lampac-tmp/` — НЕ источник.
|
||||
|
||||
🔴 **Правило процесса:** Alex не принимает статус-репорты и вопросы вместо результата
|
||||
(«Ты заебал. Ты блядь задачу решаешь или мозг мне ебешь?!», «Ты делаешь блядь или
|
||||
опять залип», «Ты все починил? Проверять?») — **доделать и доложить один раз**.
|
||||
Замер — часть работы, а не отдельная задача на согласование.
|
||||
|
||||
🔴 **Правило проверки перед докладом.** Дважды за сессию доклад «готово, проверяй»
|
||||
был **ложным**: правка физически не доезжала до ТВ (неработающий рестарт приложения).
|
||||
Перед словом «готово» обязателен замер уникального маркера сборки на ТВ. Alex ловил
|
||||
это сам («С чего ты взял что лампа перезапущена?», «Ты где его взял? Эта ебанина
|
||||
где-то записана?») — это не должно повторяться.
|
||||
|
||||
---
|
||||
|
||||
## 🔴 2026-09-24 (вечер): ПЕРЕПИСЫВАНИЕ — один sync-скрипт вместо отдельного генератора
|
||||
|
||||
@@ -43,7 +43,7 @@ related:
|
||||
|
||||
| Слой | Путь | Примечание |
|
||||
|---|---|---|
|
||||
| **Mac, репо** | `~/Developer/lampac-scripts/scripts/build_plugin.py` | сборщик, 14 инвариантов |
|
||||
| **Mac, репо** | `~/Developer/lampac-scripts/scripts/build_plugin.py` | сборщик, 20 инвариантов |
|
||||
| **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 |
|
||||
@@ -53,7 +53,9 @@ related:
|
||||
**Репозиторий:** `https://git.mallexxx.duckdns.org/git_admin/lampac-scripts.git`
|
||||
(remote `origin`, ветка `main`). Локально в нём же: `scripts/gen_watchlist.py`,
|
||||
`scripts/deploy_lampac.py`, `scripts/mark_missing.py`, `tests/`.
|
||||
Коммит плагина 2026-09-25: **`5e55a47`** «секции CUB только на главной экране».
|
||||
Коммиты плагина 2026-09-25:
|
||||
- **`5e55a47`** — «секции CUB только на главной экране» (фильтр `wlOnMain`)
|
||||
- **`3a35475`** — «фильтр по component + предзагрузка меню + хук на activity»
|
||||
|
||||
```bash
|
||||
cd ~/Developer/lampac-scripts
|
||||
@@ -82,8 +84,59 @@ git commit -m "..." && git push origin main
|
||||
| **`Log.enable` + `Runtime.enable` дают 0 строк** | консольные сообщения, напечатанные ДО подключения, не отдаются | читать логи СРАЗУ после рестарта, либо подтверждать состояние пробами, а не логами |
|
||||
|
||||
⚠️ **`docker restart lampac` НЕ сбрасывает кэш `catalog.js` в браузере webOS** — нужен
|
||||
рестарт приложения на ТВ через `luna-send`. И **не спать** в ожидании: Alex на паузу
|
||||
`sleep 20` отреагировал резко («Чё нахуй за слип 20?!») — вместо сна опрашивать состояние.
|
||||
рестарт приложения на ТВ. И **не спать** в ожидании: Alex на паузу `sleep 20` отреагировал
|
||||
резко («Чё нахуй за слип 20?!») — вместо сна опрашивать состояние в цикле.
|
||||
|
||||
### 🔴🔴 ПЕРЕЗАПУСК LAMPA НА ТВ: `tv_restart.sh` БЕЗ PTY = НОЛЬ ЭФФЕКТА (2026-09-25)
|
||||
|
||||
**Самый дорогой питфолл сессии. Три круга правок «не доезжали» до ТВ из-за этого.**
|
||||
|
||||
`tv_restart.sh` (лежит в `/Users/admin/lampac-tmp/`) делает `close` → `sleep 5` → `launch`
|
||||
и печатает свои `echo`. **Это НЕ ответ `luna-send`.** Без PTY `luna-send` детектирует
|
||||
отсутствие TTY и **отказывается писать в pipe** — молча не работает. Вывод скрипта
|
||||
(`--- закрываю --- --- запускаю --- --- готово ---`) означает лишь то, что `echo`
|
||||
отработали; приложение при этом **не перезапускается**.
|
||||
|
||||
**КАК ПРАВИЛЬНО — только через враппер с `script -q -c`:**
|
||||
|
||||
```bash
|
||||
TV_HOST=root@192.168.1.70 ~/Automation/tv-luna-send.sh -n 1 \
|
||||
-f luna://com.webos.applicationManager/closeByAppId '{"id":"com.lampac.tv"}'
|
||||
# → {"appId":"com.lampac.tv","returnValue":true} ← живой ответ, доказательство
|
||||
|
||||
TV_HOST=root@192.168.1.70 ~/Automation/tv-luna-send.sh -n 1 \
|
||||
-f luna://com.webos.applicationManager/launch '{"id":"com.lampac.tv"}'
|
||||
# → {"returnValue":true}
|
||||
```
|
||||
|
||||
🔴 **Критерий «рестарт реально произошёл» = получен `returnValue: true`**, а НЕ
|
||||
наличие `echo`-строк в выводе. Без этого критерия легко принять неработающий
|
||||
рестарт за работающий и уйти в ложную диагностику «правка не применяется».
|
||||
|
||||
🔴 **Проверка, что новая версия плагина в памяти ТВ** — проба уникального маркера
|
||||
новой сборки, а не `ready`/`patch` (они истинны и для старой версии):
|
||||
|
||||
```js
|
||||
String(!!window.__wl_activity_hook) // маркер конкретной фичи этой сборки
|
||||
```
|
||||
|
||||
Выводить новый глобальный маркер в каждой существенной правке — иначе нечем
|
||||
отличить «старая версия в памяти» от «новая не применилась».
|
||||
|
||||
🔴 **Первый замер после рестарта — ВСЕГДА гонка.** Опрашивать в цикле:
|
||||
```
|
||||
попытка 1: ready=false activityHook=false ← Lampa грузится, НЕ вердикт
|
||||
попытка 2: ready=false activityHook=false
|
||||
попытка 3: ready=true activityHook=true ← только здесь вердикт
|
||||
```
|
||||
|
||||
⚠️ **`docker restart lampac` для доставки `plugin.js` НЕ НУЖЕН.** Проверено в сессии:
|
||||
`/catalog.js` отдаётся с `Cache-Control: no-cache, no-store, must-revalidate`,
|
||||
`Expires: 0`, `Pragma: no-cache` — сервер прямо запрещает кэширование. `catalog.js`
|
||||
подключается как **плагин** Lampa (`plugins_add` в `lampainit.js`), а не лежит в
|
||||
приложении на ТВ; `localStorage` хранит только СПИСОК плагинов (`plugins`), не код.
|
||||
Два адреса дают разный `Content-Length` (44198 через `127.0.0.1:9118` vs 44204 через
|
||||
`192.168.1.14:9118`) — разница ТОЛЬКО в подстановке `api_host`, код идентичен.
|
||||
|
||||
### 🔴 Форма `Lampa.Activity.active()` — ИЗМЕРЕНО (CDP, 2026-09-25)
|
||||
|
||||
@@ -149,15 +202,48 @@ 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
|
||||
# 🔴 права + macOS-мусор (обязательно: файл монтируется :ro в контейнер)
|
||||
ssh kraken 'cd .../lampac/catalog && chmod 644 plugin.js && chown 1000:1000 plugin.js && rm -f ._*'
|
||||
# проверка, что файл виден в контейнере (bind-mount)
|
||||
ssh kraken 'docker exec lampac grep -c "<маркер>" /lampac/module/Catalog/plugin.js'
|
||||
# проверка по HTTP — что реально отдаётся ТВ
|
||||
ssh kraken 'curl -s http://127.0.0.1:9118/catalog.js | grep -c "<маркер>"'
|
||||
# рестарт ТВ ТОЛЬКО через враппер (см. выше) + проба маркера сборки
|
||||
```
|
||||
|
||||
⚠️ `docker restart lampac` в порядок **НЕ входит** — сервер отдаёт файл с
|
||||
`no-store`, рестарт нужен только приложению на ТВ (и только через `tv-luna-send.sh`).
|
||||
|
||||
🔴 **`plugin-cub.js` в репе — это ВЫХОД сборщика.** Правку вносим в `INJECT` внутри
|
||||
`build_plugin.py`, потом пересобираем; руками `plugin-cub.js` не редактируем, иначе
|
||||
следующая сборка затрёт правку. Инварианты в `checks{}` обязаны покрывать любую
|
||||
новую функцию — иначе регресс пройдёт молча.
|
||||
|
||||
### 🔴 Питфолл: инварианты, считающие ПОДСТРОКИ, ловят КОММЕНТАРИИ
|
||||
|
||||
Дважды за сессию сборка падала с `[x] ИНВАРИАНТ НАРУШЕН` **на корректном коде**:
|
||||
|
||||
1. `"wlWatchActivity call": out.count("wlWatchActivity()")` → `3` вместо `1`:
|
||||
вхождение есть и в определении функции, и в `startPlugin`.
|
||||
**Фикс:** считать по уникальному контексту — `out.count("wlPrefetch();wlWatchActivity();")`.
|
||||
2. `"НЕТ старого parts.__wl_done": _code.count("parts.__wl_done")` → `4` вместо `0`:
|
||||
строки-комментарии в `INJECT` начинаются с эмодзи + пробелов (``, U+1F534),
|
||||
поэтому фильтр `l.strip().startswith(("*","/*","//"))` их **не отфильтровал**.
|
||||
|
||||
**Рабочий фильтр — вырезать блочные комментарии регуляркой:**
|
||||
```python
|
||||
_inject_body = out.split(MARK)[1].split("function startPlugin")[0]
|
||||
_code = re.sub(r"/\*.*?\*/", "", _inject_body, flags=re.DOTALL)
|
||||
_code = "\n".join(l for l in _code.splitlines()
|
||||
if not l.strip().startswith("//"))
|
||||
# затем _code.count(...) — счёт только по исполняемому коду
|
||||
```
|
||||
⚠️ `re` надо **импортировать** — сборщик его изначально не подключал (`NameError`).
|
||||
|
||||
**Правило:** прежде чем «чинить» код из-за упавшего инварианта — проверить
|
||||
`grep -n "<строка>"` в собранном файле и убедиться, что счёт не из комментариев.
|
||||
Дважды соблазн был «поправить код», хотя ломалась ПРОВЕРКА.
|
||||
|
||||
### 🔴🔴 Как определить активный экран Lampa — по `component`, НЕ по `url`
|
||||
|
||||
**ИЗМЕРЕНО на живом ТВ 2026-09-25.** Форма объекта:
|
||||
|
||||
Reference in new issue
Block a user