From 97237168a02e44f77ad611f846f9ba766ce488e1 Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Tue, 22 Sep 2026 12:13:29 +0600 Subject: [PATCH] [2026-09-22] eagle: family/how-to/tv-lampac-plugin.md family/projects/watchlist-automation.md personal/plans/lampac-kraken.md personal/plans/lampac-watchlist-plugin.md personal/tech/lampac-deployment.md --- family/how-to/tv-lampac-plugin.md | 85 ++++++++++++++++++++++- family/projects/watchlist-automation.md | 80 +++++++++++++++++++-- personal/plans/lampac-kraken.md | 18 +++-- personal/plans/lampac-watchlist-plugin.md | 23 ++++-- personal/tech/lampac-deployment.md | 50 +++++++++++++ 5 files changed, 238 insertions(+), 18 deletions(-) diff --git a/family/how-to/tv-lampac-plugin.md b/family/how-to/tv-lampac-plugin.md index ff600327..bf72fdc4 100644 --- a/family/how-to/tv-lampac-plugin.md +++ b/family/how-to/tv-lampac-plugin.md @@ -47,7 +47,81 @@ Lampa в webOS использует `localStorage`, который Chromium хр 2. Записать значение в localStorage 3. Запустить приложение -## ⚠️ Питфоллы (проверено 2026-09-22) +## 🔴 НЕ СУЩЕСТВУЕТ пункта «Настройки → Источник» (проверено 2026-09-22) + +**Не повторять эту ошибку — Alex дважды сказал, что пункта нет.** + +В Lampa **нет** отдельного пункта меню для выбора источника каталога. Источник переключается +**прямо из меню каталогов на главной**: + +1. Открыть Lampa на главной странице +2. Встать на любой ряд каталога и нажать **влево** на пульте +3. Слева выедет **панель со списком источников** (Rezka, Kinobase, FilmixApp, VoKino, + Eneyida, KinoUkr, «Мой список», …) +4. Выбрать **«Мой список»** и нажать OK +5. Каталог перестроится на watchlist + +Скриншота/подтверждения от Alex ещё нет — он не дошёл до этого шага. + +## Как плагин `catalog.js` регистрирует источник (механика) + +Важно для диагностики — плагин **не добавляет новый пункт в главное меню**, он **подменяет +существующие**: + +```js +// при старте / app ready: +Lampa.Utils.account(Manifest.api_host + '/catalog', function(json){ + Manifest.catalogs = json; // все каталоги с сервера + keys.forEach(function(key){ + Lampa.Params.values.source[key] = key; // регистрирует источник + Lampa.Api.sources[key] = Api; // подменяет API + if (Manifest.catalogs[key].search) + Lampa.Search.addSource(Api.discovery(key)); // добавляет в поиск + }); +}); +// хук на меню: клик по movie/tv/cartoon/anime/relise подменяется на URL из catalogs[key].menu +Lampa.Listener.follow('menu', ...) +``` + +Отсюда следует: +- Отдельного переключателя в настройках нет **by design** — источник выбирается панелью слева. +- Плагин **подтягивает каталоги только при старте приложения**. Если добавить плагин и не + перезапустить Lampa — каталоги не зарегистрируются. Нужен полный перезапуск (не сворачивание). +- Заголовок каталога после переключения содержит имя источника в верхнем регистре: + «Фильмы — МОЙ СПИСОК». + +## Что должен отдавать сервер (проверено 2026-09-22) + +| Endpoint | Ответ | Значение | +|---|---|---| +| `/catalog.js` | 200, ~32 КБ | сам плагин, манифест с `api_host` | +| `/catalog` | JSON, 7 ключей | список каталогов: Rezka, Kinobase, FilmixApp, VoKino, Eneyida, KinoUkr, **Мой список** | +| `/catalog/list?plugin=watchlist&cat=films` | `{page, results, total_pages}` | 360 позиций, `total_pages: 1` | + +`api_host` подставляется по IP запроса → `http://192.168.1.14:9118` (не `localhost`), +поэтому ТВ получает рабочие ссылки. + +**7 источников в `/catalog`** — нормальный минимум: модуль `Catalog` собирает их из bundled-плагинов +плюс `watchlist`. «Мой список» идёт **первым** ключом. + +## ⚠️ Ловушка диагностики: `plugins_add` в `lampainit.js` — НЕ то, что кажется + +`http://192.168.1.14:9118/lampainit.js` содержит: +```js +var plugins_add = [ + {"url":"http://192.168.1.14:9118/catalog.js","status":1,"name":"Альтернативные источники каталога", ...}, + ... +]; +``` + +Это **серверный список плагинов, которые Lampac сам подсовывает** в UI. +Клиент на ТВ (webOS-приложение `com.lampac.tv`) — **не отдельная Lampa**: он грузит `app.min.js` +и `lampainit.js` **с сервера** (`loader.js` → `lampac_url` из localStorage, дефолт `http://192.168.1.14:9118`). + +Следствие: каталог watchlist работает через **серверный модуль `Catalog`**, а не через строку +`plugins_add`. Не искать причину поломки в этом массиве. + +## Питфоллы (проверено 2026-09-22) 1. **localStorage у webOS-приложений изолирован.** Файл в `.localstorage/` у сторонних (Homebrew) приложений **может отсутствовать** — Chromium держит стор в памяти и @@ -58,7 +132,14 @@ Lampa в webOS использует `localStorage`, который Chromium хр 3. **LevelDB нельзя править на живом приложении.** Сначала `closeByAppId`, потом запись. -4. **Проще всего — через UI самого пульта**, если он доступен: +4. **`init.conf` лежит НЕ в корне каталога Lampac, а в `config-module/init.conf`** + (монтируется в `/lampac/init.conf:ro`). Искать там, а не по `lampac/init.conf` + — иначе получишь ложный «файл пропал». + +5. **После добавления плагина обязательно полный перезапуск Lampa** — иначе `/catalog` + не запрашивается, и источник не появляется (соединений с `:9118` будет **ноль**). + +6. **Проще всего — через UI самого пульта**, если он доступен: Lampa → Настройки → Плагины → добавить URL. Скрипт нужен, когда пульта нет. ## Что должно быть прописано для Lampac diff --git a/family/projects/watchlist-automation.md b/family/projects/watchlist-automation.md index c8380193..673f14c0 100644 --- a/family/projects/watchlist-automation.md +++ b/family/projects/watchlist-automation.md @@ -134,12 +134,84 @@ crontab -l # проверка ## 🔴 2026-09-22: ОСИРОТЕВШИЕ СТРОКИ в `## Новинки` — баг и фикс **Симптом (сообщил Alex):** «Проект Конец света» показывался в каталоге Lampa как непросмотренный, -хотя в главном списке он `[x]` (просмотрен) и был скачан. +хотя в главном списке он `[x]` (просмотрен) и был скачан. Alex предположил «опять синк не работает». -**Корень — `process_thumbs()` в `parser.py`.** +**Корень — НЕ синк, а `process_thumbs()` в `parser.py`.** -Функция обрабатывает только три случая по регекспу -`_THUMBS_RE = r'^(\s*-\s*\[.\]\s*)(👍|👎)?\s*(.*?)\s*(👍|👎)? +Регексп функции матчит только строки с плиткой: +```python +_THUMBS_RE = r'^(\s*-\s*\[.\]\s*)(👍|👎)?\s*(.*?)\s*(👍|👎)?$' +``` +Ветвление (актуальное поведение): +- `👍` → строка **копируется** в начало `## Фильмы`, из `## Новинки` **удаляется** +- `👎` → переносится в `## Новинки👎` +- `[x]` → переносится в конец `[x]`-блока главного списка +- **всё остальное (в т.ч. `⬇️` без плитки) → попадает в `keep` = остаётся в `## Новинки` НАВСЕГДА** + +**Осиротевшая строка в файле (была):** +``` +- [ ] ⬇️ [Проект «Конец света»](kinopoisk/1382256/) (2026) IMDb 8.4 KP 8.4 +``` +`⬇️` = «добавлен в Radarr», но плитки нет → ни под одно правило не подпадала → вечно `[ ]` +в `## Новинки` → вечно в каталоге Lampa как непросмотренная. + +**Почему не нашёл поиском по названию:** написания разные — +`Проект «Конец света»` (Новинки, со ссылкой KP) vs `Проект конец света` (главный список, `[x]`, без ссылки). + +### Фикс 1 — `parser.py::process_thumbs()`: удаление сирот + +Добавлен блок: **собирает ключи всех `[x]`-строк из ВСЕХ секций** (кроме `## Новинки` и `## Новинки👎`), +затем выкидывает из `keep` строки, чей ключ совпал. + +Сравнение по **двум** ключам: ссылка Кинопоиска (`kinopoisk/NNN/`) **или** нормализованное название. + +```python +# Нормализация: срезаем эмодзи, год, рейтинги, регистр, пробелы, «ё»→«е» +_norm_title = lambda s: re.sub(r'[^а-яa-z0-9]+', '', + re.sub(r'\b(?:IMDb|KP)\s*[\d.,]+', '', re.sub(r'\(?\b(19|20)\d{2}\b\)?', '', s.lower()))).replace('ё','е') +``` + +Результат: `Проект «Конец света» (2026) IMDb 8.4 KP 8.4` → `проектконецсвета`, +`Проект конец света` → `проектконецсвета`. Совпадают. + +⚠️ **Критично — снятие раннего `return []`.** Блок стоит ПОСЛЕ сбора `keep`, но в функции есть +проверка `if not thumbs_up and not thumbs_down and not watched_items: return []`. +Когда патч удаляет последнюю сироту, все три списка пусты → функция выходила **до записи файла**, +и удаление терялось. Условие расширено флагом `orphans_removed`, чтобы запись состоялась. + +### Фикс 2 — `cli.py`: корректный вывод действия + +`[drop]` попадал в `else`-ветку и печатался как перенос в «Новинки 👎» (косметика, но путает логи). +Разведены явные ветки по типу действия. + +### Проверка +Прогон на **копии** боевого файла: удаляется **ровно 1** строка, 683 → 682, потерь нет. +После прогона на боевом: каталог Lampa **404 → 403 позиции**. +`## Новинки`: 34 → 33. «Конец света» отсутствует во всех 4 категориях. + +Бэкап перед правкой: `~/backup-watchlist-before-orphan-fix-20260922-113925.md` + +### 🩹 ГЛАВНЫЕ ГРАБЛИ: patch-скрипты съедают обратные слэши (наступил 3 раза) + +При правке через write_file+python **двойное экранирование превращает escape-последовательности +в сырые байты**. Синтаксис остаётся валидным, `ast.parse()` проходит, но **регекспы молча не работают**. + +| Написано | Осело в файл | Эффект | +|---|---|---| +| `r'\1'` | байт `\x01` | подстановка ссылки ломается | +| `r'\b'` | байт `\x08` (backspace) | `\b` не матчит границу слова → рейтинги `IMDb 8.4 KP 8.4` не срезаются | + +**Как диагностировать:** ключ `проектконецсветаimdb84kp84` — рейтинги остались в ключе, значит `\b` мёртв. +Проверять регекспы побайтово (`repr()` строки из файла), а не глазами через `read_file`. + +**Правило:** для regex-замен в этих скриптах использовать `chr(92)+'1'` / `chr(92)+'b'` либо +проверять `repr()` после записи. Отлаживать через печать `repr()` реально загруженной строки. + +### 📌 Следствие для будущего +Ночной cron (01:00, `watchlist-nightly`) теперь **сам вычищает** такие сироты при каждом прогоне. +Если в каталоге снова появится просмотренный фильм — первым делом `grep` по `## Новинки`. + +## 🔴 Инцидент переполнения диска (2026-09-21) — историческая справка **Симптом:** диск `/dev/sda1` на Kraken — **0 байт свободно** (`df` 100%). Radarr API отдавал `disk I/O error` (SQLite не может писать при нуле места) — метаданные недоступны. diff --git a/personal/plans/lampac-kraken.md b/personal/plans/lampac-kraken.md index 475b321e..2c34db61 100644 --- a/personal/plans/lampac-kraken.md +++ b/personal/plans/lampac-kraken.md @@ -144,10 +144,15 @@ curl -fsS "http://localhost:9118/version?type=hash" Итог: `movies-watchlist.md` отдаётся каталогом Lampa через модуль `Catalog`: -- Плагин на ТВ: `http://192.168.1.14:9118/catalog.js` → источник **«Мой список»** -- 4 категории: Фильмы 360 · Новинки 34 · Мультфильмы 3 · Аниме 7 +- Плагин на ТВ: `http://192.168.1.14:9118/catalog.js` +- Источник выбирается **панелью слева** в меню каталогов (пункта «Настройки → Источник» НЕ существует!) +- 4 категории: Фильмы 360 · Новинки **33** · Мультфильмы 3 · Аниме 7 - Автообновление: cron `30 2 * * *` → `~/scripts/watchlist-catalog.sh` +⚠️ **Не проверено в UI ТВ.** Alex добавил плагин, но каталог не увидел; соединений ТВ → `:9118` — ноль. +Гипотеза: нужен **полный перезапуск Lampa** (каталоги регистрируются только при старте). +Порядок диагностики — [[personal/tech/lampac-deployment]], раздел «Выбор источника каталога в Lampa». + ⚠️ **Исходная формулировка шага 7 была неточной** («плагин, который ходит к библиотеке как к источнику воспроизведения»). Уточнено Alex: задача — **отображение списка**, не плейбэк. Механизм — встроенный модуль `Catalog`, свой плагин не писался. @@ -266,7 +271,9 @@ curl -fsS "http://localhost:9118/version?type=hash" ⚠️ **Смонтирован `config-module/init.conf` — это исправляет шаг «init.conf без volume»**, который раньше числился в открытых задачах. -Осталось на Alex: добавить на ТВ плагин `http://192.168.1.14:9118/catalog.js` (пультом). +Осталось на Alex: добавить на ТВ плагин `http://192.168.1.14:9118/catalog.js` (пультом), +**полностью перезапустить Lampa** и выбрать источник **панелью слева** в меню каталогов +(пункта «Настройки → Источник» не существует). Сопутствующие доки: [[family/how-to/tv-luna-send]], [[family/how-to/htpc-webos-luna]], [[family/how-to/tv-lampac-plugin]]. @@ -326,8 +333,9 @@ curl -fsS "http://localhost:9118/version?type=hash" ### Что осталось -1. **Лимит кэша TorrServer** (шаг 3) — дефолт. Единственный незакрытый шаг. Критичность низкая. -2. **Alex добавляет плагин на ТВ** пультом — `catalog.js`. +1. **Лимит кэша TorrServer** (шаг 3) — дефолт. Критичность низкая. +2. **Каталог watchlist не подтверждён в UI ТВ** — плагин добавлен, но не виден. Нужен полный + перезапуск Lampa + выбор источника панелью слева. Соединений ТВ → `:9118` было ноль. 3. **Проверка полосы на торрент-источнике** — не сделана. ## Журнал сессии 2026-09-22 diff --git a/personal/plans/lampac-watchlist-plugin.md b/personal/plans/lampac-watchlist-plugin.md index 6bbf9d49..a3ac4ee1 100644 --- a/personal/plans/lampac-watchlist-plugin.md +++ b/personal/plans/lampac-watchlist-plugin.md @@ -27,9 +27,9 @@ updated: '2026-09-22' > Базовое развёртывание — [[personal/plans/lampac-kraken]] (шаги 1–6 закрыты). > > **Итог одной строкой:** Lampac отдаёт `movies-watchlist.md` как каталог Lampa -> через модуль `Catalog` → 4 категории (360/34/3/7 позиций), автообновление кроном 02:30. +> через модуль `Catalog` → 4 категории (360/33/3/7 позиций), автообновление кроном 02:30. > Работает на стороне сервера; на ТВ остаётся добавить плагин -> `http://192.168.1.14:9118/catalog.js` (см. «Что осталось на Alex»). +> `http://192.168.1.14:9118/catalog.js` и выбрать источник (см. «Что осталось на Alex»). ## Задача @@ -170,7 +170,11 @@ Cron: `30 2 * * *` → лог `~/logs/watchlist-catalog.log`. Добавить плагин на ТВ — **пультом**, 1 минута: 1. Lampa → **Настройки → Плагины** → добавить URL `http://192.168.1.14:9118/catalog.js` -2. Lampa → **Настройки → Источник** → выбрать **«Мой список»** +2. **Полностью перезапустить Lampa** (не сворачивать) — каталоги регистрируются только при старте +3. На главной встать на ряд каталога и нажать **влево** → в выехавшей панели выбрать **«Мой список»** + +🔴 **Пункта «Настройки → Источник» в Lampa НЕ СУЩЕСТВУЕТ** — я его выдумал, Alex дважды указал на ошибку. +Источник переключается панелью слева в меню каталогов. Подробно: [[family/how-to/tv-lampac-plugin]]. Приёмка = категории видны в UI Lampa, названия совпадают с `movies-watchlist.md`. @@ -192,16 +196,21 @@ Cron: `30 2 * * *` → лог `~/logs/watchlist-catalog.log`. | Проверка | Результат | |---|---| -| `/catalog.js` по IP | 200, `api_host:'http://192.168.1.14:9118'` | -| Каталог в `/catalog` | «Мой список» в списке каналов | +| `/catalog.js` по IP | 200, ~32 КБ, `api_host:'http://192.168.1.14:9118'` | +| Каталог в `/catalog` | **7 ключей**, «Мой список» первым (Rezka, Kinobase, FilmixApp, VoKino, Eneyida, KinoUkr, Мой список) | | JSON-файлы | `watchlist.json` + `watchlist-{films,new,cartoons,anime}.json` — все 200 | -| Выдача по категориям | films 360 · new 34 · cartoons 3 · anime 7 | +| Выдача по категориям | films 360 · new **33** · cartoons 3 · anime 7 (после фикса сирот 2026-09-22) | +| Формат ответа `/catalog/list` | `{page, results, total_pages}`, `total_pages: 1` для films | | Сортировка | ⭐ → рейтинг ↓ → ужасы | | Чистота названий | эмодзи-маркеров 0 | +| Сирота «Конец света» | ❌ отсутствует во всех 4 категориях | **НЕ проверено:** -- ❌ **UI Lampa на ТВ** — Alex ещё не добавил плагин. Это единственная непроверенная часть. +- ❌ **UI Lampa на ТВ** — Alex добавил плагин, но каталог в UI не увидел. + Соединений ТВ → `:9118` на момент диагностики — **ноль**. Гипотеза: не сделан полный + перезапуск Lampa (каталоги регистрируются только при старте) либо не выбран источник + в панели слева. **Требуется подтверждение от Alex.** - ❌ Боевой прогон крона в 02:30 (скрипт отработал вручную успешно). - ❌ Карточка/постеры в UI. diff --git a/personal/tech/lampac-deployment.md b/personal/tech/lampac-deployment.md index 21c6dbf2..b641427a 100644 --- a/personal/tech/lampac-deployment.md +++ b/personal/tech/lampac-deployment.md @@ -324,6 +324,56 @@ ssh root@TV 'script -q -c "luna-send -n 1 -f luna://service/method {json}" /tmp/ **Как убрать выбор источника:** Lampa → Настройки → Плагины → выключить `online.js`. Останутся только торренты. +## 🔴 Выбор источника каталога в Lampa (проверено 2026-09-22) + +**В Lampa НЕТ пункта «Настройки → Источник».** Я его выдумал — Alex дважды указал на ошибку. +Не повторять. + +Источник (Rezka / Kinobase / «Мой список» / …) переключается **из меню каталогов на главной**: + +1. Открыть Lampa на главной +2. Встать на любой ряд каталога → нажать **влево** на пульте +3. Слева выедет **панель со списком источников** +4. Выбрать нужный → OK; каталог перестроится, в заголовке появится имя источника + в верхнем регистре («Фильмы — МОЙ СПИСОК») + +**Плагин `catalog.js` не добавляет пункт меню — он подменяет существующие.** +Механика: при старте приложения `Lampa.Utils.account(api_host + '/catalog', …)` получает список +каталогов, регистрирует каждый как `Lampa.Params.values.source[key]` и подменяет +`Lampa.Api.sources[key]`. Затем хук `Lampa.Listener.follow('menu', …)` перехватывает клики по +`movie`/`tv`/`cartoon`/`anime`/`relise` и подставляет URL из `catalogs[key].menu`. + +⚠️ **Следствие — каталоги регистрируются ТОЛЬКО при старте приложения.** +Добавил плагин и не перезапустил Lampa → источника не будет, `/catalog` не запрашивается, +соединений с `:9118` ноль. Нужен **полный перезапуск** (не сворачивание). + +### ⚠️ Клиент на ТВ — это не «отдельная Lampa» + +`com.lampac.tv` (webOS) грузит UI **с сервера**: `loader.js` читает `lampac_url` из localStorage +(дефолт `http://192.168.1.14:9118`) и подключает `app.min.js` + `lampainit.js`. +Значит логика каталога на ТВ = **серверная**, и править её надо на Lampac, а не на ТВ. + +`/lampainit.js` содержит `var plugins_add = [...]` со строкой +`{"url":".../catalog.js","name":"Альтернативные источники каталога","status":1}` — +это **серверный список плагинов, которые Lampac сам подсовывает** в UI. +Каталог watchlist работает через **модуль `Catalog`**, не через эту строку. +Не искать причину поломки в `plugins_add`. + +### Диагностика «каталога нет в UI» + +| Проверка | Команда | Норма | +|---|---|---| +| Плагин отдаётся | `curl -sI http://192.168.1.14:9118/catalog.js` | 200, ~32 КБ | +| Каталоги зарегистрированы | `curl -s http://192.168.1.14:9118/catalog \| jq 'keys'` | 7 ключей, «Мой список» есть | +| Данные отдаются | `curl -s "…/catalog/list?plugin=watchlist&cat=films" \| jq .total_pages` | 1 | +| ТВ реально ходит | `ssh kraken 'sudo ss -tnp \| grep :9118'` | есть ESTABLISHED
**ноль = Lampa не запускалась заново** | + +Порядок разбора: сначала `ss` (ходит ли ТВ вообще), потом `/catalog` (что отдаёт сервер), +потом UI. Если ноль соединений — проблема не в сервере. + +⚠️ `docker logs lampac` **HTTP-запросы не пишет** — по логам факт обращения ТВ не проверить. +Использовать `ss`, а не логи. + ## Внутреннее устройство Lampac (разведка 2026-09-22) **33 модуля** в образе (`/lampac/module/`):