[2026-09-22] eagle: family/how-to/tv-lampac-plugin.md personal/plans/lampac-watchlist-plugin.md personal/tech/lampac-deployment.md

This commit is contained in:
Alexey Martemyanov committed 2026-09-22 12:28:40 +06:00
1 parent e1256f18b9
commit e783957622
3 files changed
+298 -40

No files matched your search

+64 -15
View File
@@ -50,21 +50,61 @@ Lampa в webOS использует `localStorage`, который Chromium хр
## 🔴 Пункта «Настройки → Источник» НЕ СУЩЕСТВУЕТ (проверено 2026-09-22)
**Не повторять эту ошибку — Alex дважды сказал, что пункта нет.**
Я его выдумал, отвечая «как увидеть списки». Правильный путь ниже — **и он не сработает,
пока не исправлен баг `plugin.js`** (см. следующий раздел).
Я его выдумал, отвечая «как увидеть списки».
В Lampa **нет** отдельного пункта меню для выбора источника каталога. Источник переключается
**прямо из меню каталогов на главной**:
**Правильный путь (Alex нашёл сам 2026-09-22):**
**Настройки → «остальное» → основной источник → «Мой список».**
1. Открыть Lampa на главной странице
2. Встать на любой ряд каталога и нажать **влево** на пульте
3. Слева выедет **панель со списком источников**
4. Выбрать **«Мой список»** и нажать OK
5. Каталог перестроится на watchlist
⚠️ Мой предыдущий вариант («влево на ряду → панель источников») **не подтверждён**.
🔴 **НО:** UI Lampa строит этот список через `Object.keys(Lampa.Api.sources)`.
Плагин Lampac регистрирует источник **не-enumerable** → в панели его **нет**.
Alex именно это и увидел: «Ни на главной ни в Фильмах нет».
⚠️ **При выборе «Мой список» исчезает родной каталог CUB** — это **не баг Lampa**,
а следствие архитектурной ошибки в нашей конфигурации (заполнен блок `menu`).
Разбор и фикс — раздел «🔴 Архитектура: `menu` подменяет каталог» ниже.
## 🔴 Архитектура: `menu` подменяет каталог, `main` добавляет сверху
**Что хотел Alex:**
> «Я предполагал что будет отображаться то что и раньше (список cub) но В НЕГО будет
> сверху добавлено несколько секций в которых будут РЕАЛЬНЫЕ ЭЛЕМЕНТЫ — а не сгенерируют
> пустые заглушки!»
| Блок YAML | Поведение |
|---|---|
| **`menu`** | ❌ **подменяет** родные разделы (Фильмы/Сериалы/Аниме) — родной каталог **исчезает** |
| **`main`** | ✅ **добавляет секции на главную сверху** — родной каталог **остаётся** |
Наша конфигурация заполнила **оба** → при выборе источника «Мой список» пропал весь CUB.
**Фикс:** в `catalog/sites/watchlist.yaml` **убрать `menu`**, оставить только `main`.
Механика в `plugin.js`: `function menu()` собирает из `catalog.menu`;
`function main()` строит `parts_data` из `catalog.main` и подмешивает в `Lampa.Api.partNext`.
## 🟡 «Здесь пусто» и нет постеров — потому что данные не из Radarr
Второй симптом: элементы без превью, при открытии «здесь пусто».
Замер выдачи `/catalog/list?plugin=watchlist&cat=films`:
| Метрика | Значение |
|---|---|
| Всего позиций | 360 |
| С постером (`img != null`) | **0** |
| С реальным ID (`film/...`) | **18** |
Причина: генератор парсил `movies-watchlist.md` — **текст названий**, без TMDB ID и постеров.
Остальным 342 подставлялся `href` на **поиск** Кинопоиска → Lampa открывала страницу поиска.
**Правильный источник — Radarr API** (туда фильмы и добавлялись, там уже есть `tmdbId`
и `images[].remoteUrl`). Alex: «Они уже резолвятся же блядь!! Оно же добавлялось в arr!»
```bash
curl -sL "http://localhost:7878/api/v3/movie?apikey=$KEY" | jq length # → 50
# ⚠️ -L обязателен, без него 307 и пустое тело
```
Покрытие: Radarr **50** фильмов vs `.md` **360**. Что делать с остальными 310 — открытый
вопрос к Alex.
## 🔴 БАГ: источник не виден в панели (`enumerable: false`)
@@ -260,12 +300,21 @@ var plugins_add = [
- Плагин `catalog.js` **добавлен**, `window.plugin_catalog = true`, `appready = true`.
- `Storage.field('source')` = `'Мой список'` — источник **выбран**.
- `Lampa.Api.sources['Мой список']` **существует** и отдаёт каталог
(`search, movie, cartoons, anime, menu, main`) — **пользоваться каталогом можно**.
(`search, movie, cartoons, anime, menu, main`) — **технически доступен**.
- ❌ В панели выбора источника его **нет** — `plugin.js` регистрирует свойство
без `enumerable: true`. **Баг в Lampac, не в нашей настройке.**
**Осталось:** смонтировать поправленный `plugin.js` через compose (ждёт апрува Alex).
Полный разбор — [[personal/plans/lampac-watchlist-plugin]], раздел «ГЛАВНЫЙ ПИТФОЛЛ».
**Что переделывается (2026-09-22, после разбора с Alex):**
1. Убрать блок `menu` из `watchlist.yaml` → вернуть родной каталог CUB, оставить только `main`
2. Переключить источник данных с парсинга `.md` на **Radarr API** → постеры + TMDB ID
3. Смонтировать поправленный `plugin.js` (`enumerable: true`)
**Ждёт апрува Alex.** Полный разбор — [[personal/plans/lampac-watchlist-plugin]],
раздел «🔴 АРХИТЕКТУРНАЯ ОШИБКА».
**Скрипт-автоматизация по-прежнему не создана** — и, вероятно, не нужна: источник
переключается через **Настройки → «остальное» → основной источник** (Alex сделал сам).
**Скрипт-автоматизация по-прежнему не создана.** Прямая запись в localStorage **не нужна**:
проблема оказалась не в настройках Lampa, а в коде плагина. Если автоматизация понадобится —
+147 -21
View File
@@ -7,7 +7,7 @@ related:
- '[[family/projects/watchlist-sync]]'
- '[[family/projects/watchlist-automation]]'
- '[[family/documents/movies-watchlist]]'
status: active
status: rework
tags:
- lampac
- lampa
@@ -16,6 +16,7 @@ tags:
- webos
- plugin
- kraken
- radarr
title: Watchlist в UI Lampa — каталог из списка
type: plan
updated: '2026-09-22'
@@ -26,18 +27,122 @@ updated: '2026-09-22'
> Реализовано 2026-09-22. План был переписан после разведки кода модуля Catalog.
> Базовое развёртывание — [[personal/plans/lampac-kraken]] (шаги 1–6 закрыты).
>
> **Итог одной строкой:** Lampac отдаёт `movies-watchlist.md` как каталог Lampa
> через модуль `Catalog` → 4 категории (360/33/3/7 позиций), автообновление кроном 02:30.
> Серверная часть полностью рабочая. **Осталось одно:** в `plugin.js` Lampac баг
> (`defineProperty` без `enumerable:true`) — из-за него источник «Мой список» не виден
> в списке выбора Lampa на ТВ. Фикс готов, ждёт апрува Alex (2026-09-22).
> См. «🔴 ГЛАВНЫЙ ПИТФОЛЛ».
> 🔴 **АРХИТЕКТУРА ПРИЗНАНА НЕВЕРНОЙ 2026-09-22 — переписывается.**
> Сделано `menu` (подмена родных разделов) вместо `main` (секции СВЕРХУ).
> Плюс источник данных — парсинг текстового `.md` вместо **Radarr API**, где уже
> есть TMDB ID и постеры. Alex: «Я предполагал что будет отображаться то что и раньше
> (список cub) но В НЕГО будет сверху добавлено несколько секций в которых будут
> РЕАЛЬНЫЕ ЭЛЕМЕНТЫ - а не сгенерируют пустые заглушки!»
> См. «🔴 АРХИТЕКТУРНАЯ ОШИБКА» — читать ПЕРВЫМ.
>
> **Итог одной строкой:** серверная часть каталога работает (4 категории, 360/33/3/7),
> но реализована не по замыслу: подменяет каталог вместо добавления секций,
> и не использует Radarr как источник постеров/ID.
## 🔴 АРХИТЕКТУРНАЯ ОШИБКА 2026-09-22 — почему каталог «не работает»
**Что хотел Alex (дословно):**
> «Я предполагал что будет отображаться то что и раньше (список cub) но В НЕГО будет
> сверху добавлено несколько секций в которых будут РЕАЛЬНЫЕ ЭЛЕМЕНТЫ — а не сгенерируют
> пустые заглушки! Нахуя это надо то?! Чё блядь значит оно так и должно быть?!»
**Что сделано вместо этого — две независимые ошибки:**
### Ошибка 1 — структура: `menu` вместо `main`
Модуль Catalog умеет **два независимых блока**, и они делают РАЗНОЕ:
| Блок YAML | Что делает | Поведение |
|---|---|---|
| **`menu`** | **подменяет** родные разделы Lampa (Фильмы/Сериалы/Аниме) | ❌ заполнен → родной каталог исчезает |
| **`main`** | **добавляет секции на главную СВЕРХУ** | ✅ родной каталог остаётся |
Реализация заполнила **оба** (`menu` и `main`) → при выборе источника «Мой список»
исчез весь CUB-контент.
**Симптом по словам Alex:** «при его выборе исчезло все что было до этого из списка CUB
во всех разделах. Нет превью.»
**Фикс:** в `sites/watchlist.yaml` **убрать блок `menu`**, оставить только `main`.
Тогда родной каталог (CUB/tmdb) работает как раньше, а твои секции идут рядами сверху.
Код: `plugin.js` → `function menu()` собирает из `catalog.menu`; если ключа нет —
`menu` не подменяется (вернётся пустой, Lampa использует родные). `main()` строит
`parts_data` из `catalog.main` и подмешивает их в `Lampa.Api.partNext`.
### Ошибка 2 — источник данных: парсинг `.md` вместо Radarr API
Генератор читал `movies-watchlist.md` — **текстовый список названий**. В нём
**нет ни TMDB ID, ни постеров**. Результат:
| Метрика | Значение |
|---|---|
| Всего позиций (films) | 360 |
| Из них с постером (`img != null`) | **0** |
| Из них с реальным ID (`film/...`) | **18** |
Остальные 342 отдавались с `id` = **ссылка на поиск Кинопоиска**
(`index.php?kp_query=...`). Отсюда жалоба «при открытии элемента пишет *здесь пусто*»:
Lampa идёт по ссылке, получает страницу поиска, а не фильм.
**Правильный источник — Radarr API.** Alex: «Они уже резолвятся же блядь!! Оно же
добавлялось в arr!» — TMDB ID и постеры уже есть там, потому что фильмы добавлялись
в Radarr.
```bash
# API-ключ Radarr
grep -oE "<ApiKey>[^<]+</ApiKey>" /srv/dev-disk-by-uuid-6194539b-.../docker/radarr/config.xml
# → cbcb8ec320104359920c0f611d503c7b
# ⚠️ ВАЖНО: -L обязателен! Без него Radarr отдаёт 307, тело пустое
curl -sL "http://localhost:7878/api/v3/movie?apikey=$KEY" | jq length
# → 50
```
**Форма ответа Radarr (то, что нужно было брать с самого начала):**
```json
{
"tmdbId": 1292695,
"title": "They Will Kill You",
"year": 2026,
"hasFile": true,
"images": [{"coverType":"poster",
"remoteUrl":"https://image.tmdb.org/t/p/original/6oI4oQKTWMVUlr8Ivqydp28R"}]
}
```
Есть **всё**: TMDB ID → рабочий `href`, `remoteUrl` → постер, `title`/`year` → название,
`hasFile` → скачан или нет. Плюс постеры локально: `/config/MediaCover/` (46 каталогов).
⚠️ **Покрытие:** в Radarr **50 фильмов**, в `.md` — **360**. Разница (310) — то, что
в список записано, но в Radarr не заказано. Что с ними делать — **решение Alex
не получено**, открытый вопрос №1 ниже.
### Что НЕ надо было делать (записано, чтобы не повторять)
- Парсить текст вместо API, где данные уже резолвлены
- Складывать `menu` + `main` одновременно
- Считать «список названий» готовым каталогом для UI с постерами
### Alex: корневая претензия к процессу
> «А нахуя ты это так реализовал?? Подумать блядь вообще не твое!»
Разбор: задача звучала как «покажи список в UI» — и была прочитана буквально
(«отдать строки файла»). **Надо было сначала выяснить, откуда брать постеры и ID**
(а ответ — Radarr, куда фильмы и добавлялись), а не начинать с парсера текста.
## Задача
Показывать список фильмов Alex (`family/documents/movies-watchlist.md`) **в UI Lampa на ТВ** — каталогом.
Не локальный плейбэк. Формулировка Alex: «отображение фильмов из списка».
**Уточнение от 2026-09-22 (важное!):** каталог **добавляется СЕКЦИЯМИ СВЕРХУ** к родному
каталогу Lampa. Родной CUB-контент **не подменяется и не исчезает**. Элементы — **реальные**
фильмы с постерами и карточками, а не пустые заглушки (см. «🔴 АРХИТЕКТУРНАЯ ОШИБКА»).
⚠️ **Что НЕ спрашивать повторно.** Задача — **отображение**, не воспроизведение.
Список — это перечень, а не источник видео. Вопрос «а что играть по клику?» —
**выдумка сверх постановки**, Alex на него реагировал раздражением («я чё тебе сказал в постановке задачи»).
@@ -167,18 +272,21 @@ Cron: `30 2 * * *` → лог `~/logs/watchlist-catalog.log`.
Причина: `nightly` — рабочий боевой скрипт, его падение остановило бы весь пайплайн списка.
Отдельный cron падает изолированно.
## Что осталось (единственное незакрытое)
## Что осталось — ПЕРЕДЕЛКА (после признания архитектуры неверной)
**Не шаг Alex, а правка сервера.** Плагин на ТВ уже добавлен и **источник уже выбран**
(`Storage.field('source') = 'Мой список'`). Проблема — баг в `plugin.js` Lampac
(см. «🔴 ГЛАВНЫЙ ПИТФОЛЛ»): источник не виден в UI из-за `enumerable: false`.
| # | Шаг | Статус |
|---|---|---|
| 1 | Генератор берёт данные **из Radarr API** (`localhost:7878/api/v3/movie`), а не парсит текст | ⏳ ждёт апрува |
| 2 | Подставлять в `id` → `tmdbId`, в `img` → `images[].remoteUrl` (постер), `year` → `year` | ⏳ |
| 3 | Из `sites/watchlist.yaml` **убрать блок `menu`**, оставить `main` → родной CUB остаётся | ⏳ |
| 4 | Постеры кэшировать локально (Radarr `MediaCover/` или проксировать через `tmdbproxy`) | ⏳ |
| 5 | Фикс `plugin.js` (`enumerable:true`) — **отдельная независимая правка**, см. ниже | ⏳ ждёт апрува |
**Ждёт апрува Alex** (2026-09-22): смонтировать поправленный `plugin.js` через compose.
**Порядок:** шаги 1–4 закрывают жалобу «пустые заглушки + исчез CUB».
Шаг 5 — про то, что источника вообще не видно в списке выбора.
Путь на ТВ, который раньше писался («влево → панель → выбрать источник») — **не сработает**,
пока баг не исправлен: в панели источника просто нет.
Приёмка = категории видны в UI Lampa, названия совпадают с `movies-watchlist.md`.
Приёмка (формулировка Alex): **родной список CUB на месте, сверху добавлены ряды
с реальными фильмами из списка, у элементов есть постеры и рабочие карточки.**
## Диагностический скрипт для ТВ (`/tmp/lampa_probe.py`)
@@ -497,15 +605,33 @@ ssh kraken 'sed -i "s/\"catalog\": true/\"catalog\": false/" \
Для строк без рейтинга (например `- [ ] Gods don't give gifts`) — сортировать как `0`, в конец группы.
Опционально: добирать через TMDB (кэш `tmdbproxy` в Lampac) — решить при реализации.
## Открытые вопросы (не блокируют, решение Alex не запрошено)
## Открытые вопросы — БЛОКИРУЮЩИЕ (2026-09-22, ждут решения Alex)
1. **Постеры** — тянуть через TMDB-кэш Lampac или не тянуть вовсе? Сейчас пустые.
2. **Карточка** — нужна ли (описание/рейтинг внутри Lampa), или достаточно списка названий?
1. **Что делать с 310 фильмами, которых нет в Radarr?**
В `.md` — 360, в Radarr — 50. У 310 нет TMDB ID и постера.
Варианты: (а) показывать только 50 из Radarr; (б) добирать остальные через TMDB-search
(часть названий найдётся криво: «девять» → не то); (в) показывать заглушкой без постера.
**Без решения шаг 1 переделки не начать.**
2. **Нужны 4 секции или одна?** Секции «Фильмы / Новинки / Мультфильмы / Аниме»
или одна «Мой список» сверху. Вопрос задан, ответа нет.
## Открытые вопросы (не блокируют)
1. **Постеры** — тянуть через TMDB-кэш Lampac, через Radarr `MediaCover/`, или `remoteUrl` CDN?
2. **Карточка** — `card_parse` не настроен. С реальным TMDB ID карточка должна
подтянуться штатным механизмом Lampa — проверить после переделки.
3. **`🗓️` upcoming** — показывать или прятать? Сейчас показываем.
4. **`❓` ambiguous** — сейчас показываем с названием как есть.
Ни один из них **не мешает работе** — каталог отдаётся, категории на месте.
Спрашивать только если Alex сам затронет тему.
## ⚠️ Отменённые/ошибочные указания (не повторять)
- ❌ **«Настройки → Источник»** — такого пункта в Lampa **не существует**. Выдумано,
Alex не нашёл. Источник переключается в разделе «остальное → основной источник»
(Alex нашёл сам 2026-09-22).
- ❌ **«влево → панель источников»** — тоже не подтверждено.
- ❌ **`plugins_add` в `lampainit.js`** — это серверные плагины Lampac
(`tmdbproxy.js`, `cubproxy.js`, `online.js`, `catalog.js`…), а **не** список плагинов Lampa.
`catalog.js` там есть при `"catalog": true` в init.conf.
## Связанные
+87 -4
View File
@@ -198,6 +198,93 @@ Configure complete ← HTTP начинает отвечать
Плагин на ТВ: `http://192.168.1.14:9118/catalog.js` → источник «Мой список».
⏳ **Переделывается (2026-09-22).** Текущая реализация признана неверной: заполнен
блок `menu` (подменяет родной каталог CUB вместо добавления секций сверху), а данные
берутся парсингом `.md` вместо **Radarr API** (в `.md` нет TMDB ID и постеров).
Разбор ошибки — [[personal/plans/lampac-watchlist-plugin]], секция «🔴 АРХИТЕКТУРНАЯ ОШИБКА».
### 🔴 `menu` vs `main` — принципиальная разница
| Блок YAML | Что делает |
|---|---|
| `menu` | **подменяет** родные разделы Lampa (Фильмы/Сериалы/Аниме) → родной каталог исчезает |
| `main` | **добавляет секции на главную СВЕРХУ** → родной каталог остаётся |
Заполнять нужно **только `main`**, если задача — «добавить ряды к родному каталогу».
`plugin.js` → `function menu()` собирает из `catalog.menu`; `function main()` строит
`parts_data` из `catalog.main` и подмешивает в `Lampa.Api.partNext`.
### ⚠️ Баг Lampac: источник не виден в списке выбора
`plugin.js`, строка 59 (`loadCatalogs()`), **два вхождения**:
```js
Object.defineProperty(Lampa.Api.sources, key, { get: function(){ return Api; } });
```
`defineProperty` по умолчанию `enumerable: false` → `Object.keys(Lampa.Api.sources)`
не перечисляет источник → Lampa не рисует его в панели выбора. При этом
`Api.sources['Мой список']` работает напрямую и каталог отдаёт.
**Фикс:** `{ get: ..., enumerable: true, configurable: true }`.
`plugin.js` живёт **в образе**, не на HDD (`docker inspect` — монтируются только
`catalog/sites` и `catalog/override`). Правка через `docker exec` теряется при
пересоздании. Постоянный путь — volume:
```yaml
volumes:
- ./catalog/plugin.js:/lampac/module/Catalog/plugin.js:ro
```
Проверка синтаксиса ПЕРЕД заливкой: `node --check /tmp/catalog-plugin.js`.
Статус: **не применено**, ждёт апрува Alex.
### Radarr как источник данных (постеры, TMDB ID)
Фильмы уже резолвлены в Radarr — там есть TMDB ID и постеры. Это **правильный
источник** для каталога; `.md` их не содержит.
```bash
# API-ключ
grep -oE "<ApiKey>[^<]+</ApiKey>" /srv/dev-disk-by-uuid-6194539b-.../docker/radarr/config.xml
# ⚠️ -L обязателен, иначе 307 и пустое тело
curl -sL "http://localhost:7878/api/v3/movie?apikey=$KEY" | jq length # → 50
```
Поля ответа: `tmdbId`, `title`, `year`, `hasFile`, `images[].remoteUrl` (постер TMDB),
`images[].coverType == "poster"`. Кэш постеров на диске: Radarr `/config/MediaCover/`.
## Занятые порты на Кра́кене (2026-09-22)
`7878` Radarr · `8096` Jellyfin · `8191` FlareSolverr · `8989` Sonarr · `9000` Portainer ·
`9091` Transmission · `9696` Prowlarr · `51413` Transmission (UDP) · **`9118` Lampac**
## Отладка UI Lampa на ТВ (webOS)
Правки по SSH не сделать, но **состояние читается** через Chrome DevTools Protocol:
```bash
# webOS отдаёт DevTools на порту 9998 (WebAppMgr --remote-debugging-port=9998)
curl -s http://192.168.1.70:9998/json | jq -r '.[] | "\(.type): \(.url)"'
# → file:///.../com.lampac.tv/index.html?card=...&source=cub
```
Дальше `websocket` + `Runtime.evaluate` читает живые переменные:
| Выражение | Что даёт |
|---|---|
| `Lampa.Storage.field('source')` | выбранный источник |
| `Object.keys(Lampa.Api.sources).join('\|')` | перечисляемые источники |
| `Object.getOwnPropertyDescriptor(Lampa.Api.sources,'Мой список')` | `enumerable`/`configurable` |
| `Lampa.Api.sources['Мой список'].getCatalog()` | ключи каталога |
Скрипты-пробы: `/tmp/lampa_probe.py`, `/tmp/lampa_probe2.py`, `/tmp/lampa_probe3.py`.
⚠️ `tcpdump` на Кра́кене **нет**. `luna://com.webos.service.capture/takeScreenShot`
на этом ТВ **не существует**. `luna-send` пишет в tty → нужен `script -q -c`.
Подробности: [[family/how-to/tv-lampac-plugin]].
### Общее про модуль
| Что | Как |
@@ -235,10 +322,6 @@ Proxy, SISI, Sync, Telemetry, Tracks, Transcoding, WebLog`.
Полный пример YAML (`vokino.yaml`): `docker exec lampac cat /lampac/module/Catalog/sites/vokino.yaml`.
## Занятые порты на Кра́кене (2026-09-22)
`7878` Radarr · `8096` Jellyfin · `8191` FlareSolverr · `8989` Sonarr · `9000` Portainer ·
`9091` Transmission · `9696` Prowlarr · `51413` Transmission (UDP) · **`9118` Lampac**
Выбор порта — `docker compose config` + `sudo ss -tlnp` перед деплоем.
## Интеграция с Lampa (ТВ) — ✅ СДЕЛАНО 2026-09-22