From 5e85c8176775dc620be0406166778c2f89b8aa09 Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Tue, 22 Sep 2026 15:57:00 +0600 Subject: [PATCH] [2026-09-22] eagle: personal/plans/lampac-watchlist-plugin.md personal/tech/lampac-deployment.md --- personal/plans/lampac-watchlist-plugin.md | 32 ++++++- personal/tech/lampac-deployment.md | 112 ++++++++++++++++++++++ 2 files changed, 143 insertions(+), 1 deletion(-) diff --git a/personal/plans/lampac-watchlist-plugin.md b/personal/plans/lampac-watchlist-plugin.md index f8febd3c..f013ecd0 100644 --- a/personal/plans/lampac-watchlist-plugin.md +++ b/personal/plans/lampac-watchlist-plugin.md @@ -7,7 +7,7 @@ related: - '[[family/projects/watchlist-sync]]' - '[[family/projects/watchlist-automation]]' - '[[family/documents/movies-watchlist]]' -status: cub-sections-blocked +status: cub-sections-pending tags: - lampac - lampa @@ -44,6 +44,36 @@ updated: '2026-09-22' > отдаёт все поля: 352/352 с числовым `tmdb_id`**. Родной CUB не тронут. > Осталась приёмка глазами на ТВ. > +> **Обновление 2026-09-22 (четвёртая сессия): 🔴🔴 НАЙДЕНА ИСТИННАЯ ПРИЧИНА «ЗДЕСЬ ПУСТО» — КИРИЛЛИЦА В КЛЮЧЕ КАТАЛОГА.** +> Все предыдущие фиксы (числовой `tmdb_id`, права, macOS-tar) были **не той причиной**. +> `tcpdump` на Кра́кене при клике на ТВ показал реальный запрос: +> `GET /catalog/card?plugin=%D0%9C%D0%BE%D0%B9%20%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA&uri=... → 400 Bad Request`. +> **`plugin=Мой список`** — кириллица. `ModInit.goInit` строки 51-52 чистит имя регуляркой +> `[^a-z0-9\-]`, то есть **вырезает всю кириллицу целиком** → `""` → `File.Exists("sites/.yaml")` = false → +> fallback `FindSiteByDisplayName("")` тоже мимо (сравнивает уже с пустой строкой) → `null` → +> `BadRequest("init not found")` → **400** → «Здесь пусто». +> **ФИКС:** явный `plugin: watchlist` в `watchlist.yaml` (переопределяет ключ по +> `ApiController.cs:136`); `displayname: Мой список` остаётся надписью в UI. Ключ каталога стал `watchlist`. +> Проверено: `plugin=Мой список` → **400**, `plugin=watchlist` → **200** с полными данными. +> 🔴 **Урок диагностики:** проверять карточку curl'ом надо ТЕМ ЖЕ ключом, который шлёт ТВ +> (я подставлял латиницу руками → 200 → ложный вывод «проблема в клиенте»). Детали — +> [[personal/tech/lampac-deployment]] раздел «🔴🔴 ГЛАВНАЯ ПРИЧИНА». +> +> **⚠️ ЗАДАЧА СЛЕДУЮЩЕЙ СЕССИИ (требование Alex, не закрыто):** секции должны быть +> **ВНУТРИ CUB без ручного переключения источника**. Дословно: «надо блядь добавить в CUB +> список новые секции а не ручное блядь переключение!». Хук `Listener.follow('menu')` + +> `e.abort()` в `plugin.js:59` молчит при активном CUB (`Api.getCatalog()` читает манифест +> текущего источника). Решение — дорисовывать ряды в корень CUB через +> `Lampa.Listener.follow('activity')` либо патч рендера главной. +> +> **Обновление 2026-09-22 (четвёртая сессия, ранее): ✅ ЧИСЛОВОЙ `tmdb_id` В КАРТОЧКАХ.** +> 352 из 352 карточек отдают `tmdb_id` числом, `source`, `runtime`, `vote_average`, жанры. +> Механика: `ModInit.cs:285 nodeValue` возвращает любой `JValue` СТРОКОЙ → в `card_args` +> нужен `format: "long.TryParse(value, out long v) ? v : 0"` (`format` = CSharpEval, +> `CatalogNodeValue(value, host)`). Кэш `catalog:card:{plugin}:{uri}` живёт в ПАМЯТИ и +> переживает `docker restart` — после правки данных обязателен рестарт И проверка на +> НЕзакэшированном uri. Детали — [[personal/tech/lampac-deployment]]. +> > **Обновление 2026-09-22 (третья сессия): ✅ КАРТОЧКА ПОЧИНЕНА ОКОНЧАТЕЛЬНО.** > «Здесь пусто» давало отсутствие **числового** `tmdb_id`: `plugin.js` делает > `if(json.tmdb_id)`, а `ModInit.cs:285` возвращает любое `JValue` СТРОКОЙ. diff --git a/personal/tech/lampac-deployment.md b/personal/tech/lampac-deployment.md index 5f3d8300..884f5ded 100644 --- a/personal/tech/lampac-deployment.md +++ b/personal/tech/lampac-deployment.md @@ -1563,3 +1563,115 @@ Lampa.Listener.follow('menu', function (e) { `Lampa.Listener.follow('activity')`. Цель: Alex открывает **обычный CUB** и **сверху видит наши секции** с реальными элементами (постеры, рейтинги) — как в исходной формулировке из [[personal/plans/lampac-watchlist-plugin]]. + +## 🔴🔴 ГЛАВНАЯ ПРИЧИНА «ЗДЕСЬ ПУСТО»: кириллица в ключе каталога (2026-09-22) + +**Это была настоящая причина. Не данные, не формат, не кэш — ключ каталога.** + +### Как найдено + +`tcpdump` на Кра́кене, фильтр по ТВ (`192.168.1.70`), клик по фильму в UI: + +``` +GET /catalog/card?plugin=%D0%9C%D0%BE%D0%B9%20%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA&uri=movie%2F1280015&type=movie HTTP/1.1 +HTTP/1.1 400 Bad Request +``` + +`plugin=Мой список` — **URL-encoded кириллица**. Воспроизведено curl'ом: + +```bash +curl "http://192.168.1.14:9118/catalog/card?plugin=%D0%9C%D0%BE%D0%B9%20%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA&uri=movie%2F424781&type=movie" +# → "init not found", HTTP 400 +``` + +### Механика (две строки в `ModInit.cs` + одна в `ApiController.cs`) + +`ApiController.cs:136` — ключ каталога в `/catalog`: +```csharp +string siteKey = !string.IsNullOrEmpty(init.plugin) ? init.plugin : init.displayname ?? site; +``` +Без явного `plugin` ключ = **`displayname`** = «Мой список». ТВ берёт `plugin` +именно оттуда и шлёт его синхронно в `/catalog/list` и `/catalog/card`. + +`ModInit.goInit` строки **51-52** — очистка имени перед поиском файла: +```csharp +site = site.ToLowerAndTrim(); +site = Regex.Replace(site, "[^a-z0-9\\-]", "", RegexOptions.IgnoreCase); +``` +🔴 **Регулярка вырезает ВСЮ кириллицу целиком.** `«Мой список»` → `""`. +Дальше: `File.Exists("/lampac/module/Catalog/sites/.yaml")` = false → +`FindSiteByDisplayName("")` = пусто (сравнивает с **уже очищенной** строкой) → +`return null` → `CardController`: `BadRequest("init not found")` → **HTTP 400** +→ в Lampa **«Здесь пусто»**. + +**Ключевой вывод:** fallback `FindSiteByDisplayName` **никогда не сработает для +кириллического `displayname`** — regex убивает строку ДО сравнения. Это не лечится +названием файла, только явным `plugin` в латинице. + +### ФИКС — явный `plugin` в YAML + +```yaml +enable: true +jsonPath: true +displayindex: 1 +displayname: Мой список # ← остаётся, это НАДПИСЬ в UI +plugin: watchlist # ← 🔴 ОБЯЗАТЕЛЬНО, латиница = ключ каталога +host: http://127.0.0.1:9118 +``` + +`init.plugin` переопределяет ключ (`ApiController.cs:136`), и ТВ зовёт +`plugin=watchlist` → файл `sites/watchlist.yaml` находится штатно. + +⚠️ **Побочный эффект (ожидаемый):** ключ в `/catalog` меняется `Мой список` → +`watchlist`. Надпись на ТВ не меняется, только внутренний идентификатор. + +### Проверка + +| Ключ | Запрос | Ответ | +|---|---|---| +| `Мой список` (было) | `plugin=%D0%9C%D0%BE%D0%B9...` | **400 `init not found`** | +| `watchlist` (стало) | `plugin=watchlist` | **200**, `tmdb_id: 424781` числом, `source: "movie"` | + +### 🔴 ПРАВИЛО ДИАГНОСТИКИ (стоило часа) + +**Проверять карточку curl'ом надо ТЕМ ЖЕ ключом, который шлёт ТВ.** Я подставлял +`plugin=watchlist` руками и получал 200, а ТВ слал `plugin=Мой список` и получал 400 — +и это выглядело как «сервер всё отдаёт, проблема в клиенте». Единственный надёжный +способ узнать реальный запрос — `tcpdump` на сервере во время клика: +```bash +ssh kraken "sudo timeout 40 tcpdump -i any -n -A 'host 192.168.1.70 and port 9118' 2>/dev/null | grep -aE 'GET /|HTTP/1'" +``` + +## Права, tar и macOS-мусор при заливке `cards/` + +Три отдельных питфолла, каждый даёт **молчаливый 404** на статике: + +1. **`macOS tar` кладёт AppleDouble-файлы `._*`** в архив → мусор в `wwwroot`. + Фикс: `tar --no-mac-metadata` + `sudo rm -f .../._*`. +2. **Права.** Если файлы приехали `root:root 600` — dotnet отдаёт **`Permission denied`**, + статика отвечает **404** (не 403!), и это выглядит как «файла нет». + Фикс: `chown -R 1000:1000` (пользователь `lampac` в контейнере) + `chmod -R 755`, + затем `chmod -R a+rX`. +3. **`find -exec` через `ssh -t` рвётся** — `find: missing argument to '-exec'` + (tty съедает `{} \;`). Фикс: два отдельных `chmod -R` вместо `find -exec`. + +⚠️ Также: `&&`-цепочка в `ssh -t` рвёт tty-сессию («Connection closed»). +Каждую команду — отдельным вызовом. + +## Итоговое состояние (2026-09-22, конец сессии) + +| Что | Статус | +|---|---| +| Ключ каталога | `plugin: watchlist` (латиница) ✅ | +| `/catalog` | `watchlist` первым, `main` = Новинки/Фильмы/Мультфильмы/Аниме | +| Карточки | **352 из 352** отдают числовой `tmdb_id` ✅ | +| Списки | films 360 (постеров 308), new 33 (30), cartoons 3 (3), anime 7 (7) | +| `tmdb_id` в карточке | числом через `format: "long.TryParse(value, out long v) ? v : 0"` | +| `runtime`, `vote_average` | тем же способом через `format` | +| `displayname` | «Мой список» — надпись в UI | +| ✅ Проверено Alex в UI | ожидает | + +Скрипты: `/Users/admin/lampac-tmp/gen_watchlist_v2.py`, `deploy_lampac.py` +(`--skip-plugin` для быстрого прогона). Проверка в шаге 7 теперь валидирует +именно ключ `watchlist` и предупреждает, если в `/catalog` остался русский ключ. +