[2026-09-22] eagle: personal/plans/lampac-watchlist-plugin.md personal/tech/lampac-deployment.md
This commit is contained in:
1 parent
0191154384
commit
5e85c81767
2 files changed
+143
-1
No files matched your search
@@ -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` остался русский ключ.
|
||||
|
||||
Reference in new issue
Block a user