1014 lines
53 KiB
Markdown
1014 lines
53 KiB
Markdown
---
|
||
title: Lampac — развёртывание и эксплуатация (Кра́кен)
|
||
created: '2026-09-22'
|
||
updated: '2026-09-22'
|
||
type: tech
|
||
namespace: personal
|
||
tags:
|
||
- lampac
|
||
- torrserver
|
||
- docker
|
||
- kraken
|
||
- streaming
|
||
- webos
|
||
related:
|
||
- '[[personal/plans/lampac-kraken]]'
|
||
- '[[personal/plans/lampac-watchlist-plugin]]'
|
||
- '[[personal/tech/multistream-single-flow-limit]]'
|
||
- '[[family/how-to/kraken-network]]'
|
||
- '[[family/how-to/tv-luna-send]]'
|
||
---
|
||
|
||
# Lampac — развёртывание и эксплуатация (Кра́кен)
|
||
|
||
> Технический справочник. Развёрнуто 2026-09-22. План и статус шагов — [[personal/plans/lampac-kraken]].
|
||
|
||
## Что это
|
||
|
||
`lampac-nextgen/lampac` (MIT, .NET 10) — серверный бэкенд для Lampa. Один контейнер, порт **9118**.
|
||
|
||
**Внутри (всё в одном образе):**
|
||
- **TorrServer** — subprocess, кэш раздач
|
||
- **JacRed** — Jackett-совместимый индексатор
|
||
- **LampaWeb** — веб-морда
|
||
- **TmdbProxy**, **DLNA**, **Sync**
|
||
|
||
🔴 **TorrServer встроенный. Отдельный контейнер не нужен.** Проверено 2026-09-22:
|
||
в логах первого старта видно `compilation TorrServer`. Внешний TS — лишняя сущность.
|
||
|
||
## Расположение на Кра́кене
|
||
|
||
```
|
||
/srv/dev-disk-by-uuid-6194539b-03e0-4f33-986b-4da09834e82f/lampac/
|
||
├── docker-compose.yml (бэкапы .bak-*, .bak2-*)
|
||
├── config/ → /lampac/config
|
||
├── cache/ → /lampac/cache (кэш TorrServer — только сюда)
|
||
├── data/ → /lampac/data (БД JacRed)
|
||
├── config-module/init.conf → /lampac/init.conf:ro (наш конфиг)
|
||
├── catalog/sites/ → /lampac/module/Catalog/sites
|
||
├── catalog/override/ → /lampac/module/Catalog/override
|
||
├── wwwroot/ → /lampac/wwwroot (JSON-каталог watchlist)
|
||
└── scripts/gen_watchlist.py (генератор .md → JSON)
|
||
```
|
||
|
||
Владелец `kraken:kraken`, права `755`.
|
||
|
||
⚠️ Всё пишущее — на data-диск (1.8T). **НЕ на SD** (`/`, 14G, 8.6G свободно).
|
||
|
||
## docker-compose.yml (актуальный, 2026-09-22)
|
||
|
||
```yaml
|
||
services:
|
||
lampac:
|
||
image: ghcr.io/lampac-nextgen/lampac:latest
|
||
container_name: lampac
|
||
platform: linux/arm64
|
||
restart: unless-stopped
|
||
ports:
|
||
- "9118:9118"
|
||
environment:
|
||
- TZ=Asia/Bishkek
|
||
- LANG=ru_RU.UTF-8
|
||
volumes:
|
||
- ./config:/lampac/config
|
||
- ./cache:/lampac/cache
|
||
- ./data:/lampac/data
|
||
# Наш конфиг: перекрывает base.conf из образа. Включает модуль Catalog.
|
||
# Без монтирования правки теряются при пересоздании контейнера.
|
||
- ./config-module/init.conf:/lampac/init.conf:ro
|
||
# Каталоги Catalog
|
||
- ./catalog/sites:/lampac/module/Catalog/sites
|
||
- ./catalog/override:/lampac/module/Catalog/override
|
||
# Статика: JSON-каталог watchlist (Lampac отдаёт wwwroot по HTTP сам)
|
||
- ./wwwroot:/lampac/wwwroot
|
||
```
|
||
|
||
⚠️ В контейнере рабочий каталог `/lampac`, часть файлов читается **из корня**, не из `config/`.
|
||
|
||
### Минимальный `config-module/init.conf`
|
||
|
||
Перекрывает `base.conf`, поэтому список `SkipModules` нужно **повторить целиком**, без `Catalog`:
|
||
|
||
```json
|
||
{
|
||
"BaseModule": {
|
||
"SkipModules": [
|
||
"Tracks", "Transcoding", "WebLog", "CacheMedia", "ForkPlayerXML",
|
||
"MsxNative", "Potok", "TelegramAuth", "TelegramAuthBot"
|
||
]
|
||
},
|
||
"LampaWeb": { "initPlugins": { "catalog": true } }
|
||
}
|
||
```
|
||
|
||
После любой правки — `docker compose up -d` (пересоздаст контейнер) или `docker restart lampac`.
|
||
|
||
## Управление
|
||
|
||
```bash
|
||
ssh kraken
|
||
cd /srv/dev-disk-by-uuid-6194539b-03e0-4f33-986b-4da09834e82f/lampac
|
||
|
||
docker compose up -d
|
||
docker compose logs -f
|
||
docker compose restart
|
||
docker compose down
|
||
```
|
||
|
||
Правка `docker-compose.yml` — без `sudo` (каталог `kraken:kraken`).
|
||
Создание новых каталогов в корне диска — **через `sudo`** (корень `root:root`). У `kraken` sudo без пароля.
|
||
|
||
## Проверка работоспособности
|
||
|
||
```bash
|
||
curl -sS --max-time 20 "http://localhost:9118/version?type=hash"
|
||
# → 46b29e1fe8fa6021cd83e75c41abffb7 (для текущего :latest)
|
||
```
|
||
|
||
По сети: `http://192.168.1.14:9118/version?type=hash` — то же значение.
|
||
|
||
## ⚠️ Питфоллы
|
||
|
||
### 1. Первый старт долгий (~4 минуты)
|
||
|
||
Контейнер компилирует и грузит ~40 native-модулей:
|
||
`compilation LampaWeb`, `DLNA`, `GStreamer`, `Sync`, `TorrServer`, ... затем `loaded module: <имя>`.
|
||
|
||
Пока идёт загрузка, HTTP **рвёт соединение**:
|
||
```
|
||
curl: (56) Recv failure: Connection reset by peer
|
||
```
|
||
|
||
🔴 **`health: healthy` не означает готовность HTTP.** Статус встаёт раньше.
|
||
Признак готовности — лог **`Configure complete`** (идёт после последнего `loaded module:`).
|
||
|
||
**Не перезапускать контейнер, не считать это поломкой.** Просто ждать.
|
||
|
||
### 2. `docker manifest inspect` с Mac отдаёт `denied`
|
||
|
||
GHCR требует авторизацию при обращении с Mac. Проверять наличие `linux/arm64` **из Кра́кена**:
|
||
```bash
|
||
ssh kraken 'docker manifest inspect ghcr.io/lampac-nextgen/lampac:latest' | jq -r '.manifests[].platform | .os + "/" + .architecture'
|
||
# linux/amd64
|
||
# linux/arm64 ← есть, сборка из исходников не нужна
|
||
# unknown/unknown
|
||
# unknown/unknown
|
||
```
|
||
|
||
### 3. Шаблон логов первого старта
|
||
|
||
```
|
||
compilation Alloha
|
||
compilation LampaWeb
|
||
...
|
||
loaded module: Vibix
|
||
loaded module: TorrServer
|
||
...
|
||
Configure complete ← HTTP начинает отвечать
|
||
```
|
||
|
||
## Сеть
|
||
|
||
| Хост | IP |
|
||
|---|---|
|
||
| Кра́кен (eth0) | `192.168.1.14` (второй адрес `192.168.1.15`) |
|
||
| ТВ LG | `192.168.1.70` |
|
||
| Mac Alex | `192.168.1.57` |
|
||
|
||
Один сегмент `192.168.1.x` — туннели и проброс портов не нужны.
|
||
Подробнее: [[family/how-to/kraken-network]].
|
||
|
||
## Модуль Catalog — каталоги из YAML
|
||
|
||
Модуль **`Catalog`** (в образе, по умолчанию **выключен**) отдаёт свои каталоги как плагин Lampa.
|
||
Разобрано по коду и **включено в работу 2026-09-22** — см. [[personal/plans/lampac-watchlist-plugin]].
|
||
|
||
### Наш каталог «Мой список»
|
||
|
||
Отдаёт `movies-watchlist.md` как каталог в Lampa. Файлы:
|
||
|
||
| Путь на HDD (`.../lampac/`) | Роль |
|
||
|---|---|
|
||
| `config-module/init.conf` | включает Catalog (монтируется в `/lampac/init.conf:ro`) |
|
||
| `catalog/sites/watchlist.yaml` | описание каталога для Catalog |
|
||
| `catalog/override/` | переопределения (пусто) |
|
||
| `wwwroot/watchlist.json` + `watchlist-<code>.json` | JSON-данные (Lampac отдаёт по HTTP) |
|
||
| `scripts/gen_watchlist.py` | генератор: .md → JSON |
|
||
| `~/scripts/watchlist-catalog.sh` | обёртка + перезапуск (сброс кэша), cron 02:30 |
|
||
|
||
Плагин на ТВ: `http://192.168.1.14:9118/catalog.js` → источник «Мой список».
|
||
|
||
⏳ **Переделывается (2026-09-22).** Текущая реализация признана неверной: заполнен
|
||
блок `menu` (подменяет родной каталог CUB вместо добавления секций сверху), а данные
|
||
берутся парсингом `.md` вместо **Radarr API** (в `.md` нет TMDB ID и постеров).
|
||
Разбор ошибки — [[personal/plans/lampac-watchlist-plugin]], секция «🔴 АРХИТЕКТУРНАЯ ОШИБКА».
|
||
|
||
### 🔴 Рабочая форма `sites/watchlist.yaml` (проверена 2026-09-22, откат после провала)
|
||
|
||
```yaml
|
||
enable: true
|
||
jsonPath: true
|
||
displayindex: 1
|
||
displayname: Мой список
|
||
host: http://127.0.0.1:9118
|
||
|
||
menu: # ← ОБЯЗАТЕЛЕН (регистрирует канал), единственный блок категорий
|
||
- categories:
|
||
Фильмы: films
|
||
Новинки: new
|
||
Мультфильмы: cartoons
|
||
Аниме: anime
|
||
format:
|
||
"-": |
|
||
return $"http://127.0.0.1:9118/watchlist-{cat}.json";
|
||
|
||
search:
|
||
uri: watchlist.json
|
||
|
||
list:
|
||
uri: watchlist-films.json
|
||
firstpage: watchlist-films.json
|
||
total_pages: 1
|
||
|
||
content:
|
||
nodes: "$.items[*]"
|
||
name: { attribute: name }
|
||
original_name: { attribute: original }
|
||
year: { attribute: year }
|
||
href: { attribute: href }
|
||
image: { attribute: image }
|
||
args:
|
||
- { name_arg: rating, attribute: rating }
|
||
```
|
||
|
||
### 🔴 `main` в YAML ЗАПРЕЩЁН — ломает канал (опровергнуто 2026-09-22)
|
||
|
||
**Раздел ниже (гипотеза «`menu` подменяет / `main` добавляет») — НЕВЕРЕН.** Проверено
|
||
на живом сервере: попытка добавить блок `main` в YAML → **«Мой список» исчез из `/catalog`**,
|
||
`catalog/list?plugin=watchlist` отдавал пустоту. **Три раунда правок, три рестарта.**
|
||
|
||
| Гипотеза (неверна) | Факт (проверено) |
|
||
|---|---|
|
||
| `menu` подменяет родные разделы | ❌ `menu` **регистрирует канал**. `ApiController.cs:70`: `if (init == null \|\| !init.enable \|\| init.menu == null \|\| init.hide) continue;` — без `menu` сайт **отбрасывается** |
|
||
| `main` добавляет секции сверху | ❌ блока `main` **не существует** во входном YAML. YamlDotNet давится неизвестным полем → `ModInit.goInit(site)` → **null** → сайт молча пропадает |
|
||
| Заполнять нужно только `main` | ❌ `main` Catalog **генерирует САМ** из `menu`. В JSON-ответе `/catalog` есть **оба** ключа с одинаковым содержимым |
|
||
|
||
⚠️ **Обе формы `main` ломают одинаково** — и список, и словарь:
|
||
```yaml
|
||
main: # вариант 1 — список: НЕ работает
|
||
- categories:
|
||
Фильмы: films
|
||
```
|
||
```yaml
|
||
main: # вариант 2 — словарь: НЕ работает
|
||
Фильмы: http://...
|
||
```
|
||
|
||
⚠️ **Ошибка не логируется.** В логах Lampac — тишина (`docker logs lampac | grep -i yaml`
|
||
пусто). Сайт просто не появляется в `/catalog`. Диагностика только перебором YAML.
|
||
|
||
**Кто на самом деле подменяет родные разделы — `plugin.js`, а не YAML:**
|
||
|
||
```js
|
||
Lampa.Listener.follow('menu', function(e){
|
||
if (e.type=='action' && (e.action=='tv'||'cartoon'||'anime'||'movie'||'relise')) {
|
||
var catalog = Api.getCatalog();
|
||
if (!catalog) return;
|
||
...
|
||
Lampa.Router.call('category', {...});
|
||
e.abort(); // ← перехват клика по родному разделу
|
||
}
|
||
});
|
||
```
|
||
|
||
**Перехват срабатывает ТОЛЬКО когда выбран источник «Мой список».** Родной CUB/tmdb
|
||
не трогается, пока источник не переключён на наш.
|
||
|
||
### 🔴 `host` + `uri` СКЛЕИВАЮТСЯ — `uri` обязан быть относительным
|
||
|
||
`ListController.cs:53`:
|
||
```csharp
|
||
string url = $"{init.host}/{(page==1 && init.list?.firstpage != null
|
||
? init.list?.firstpage : init.list?.uri)}";
|
||
```
|
||
|
||
Полный URL в `uri`/`firstpage` даёт **двойной префикс** → пусто:
|
||
```
|
||
http://127.0.0.1:9118/http://127.0.0.1:9118/watchlist-films.json
|
||
```
|
||
|
||
Правильно: только `watchlist-films.json`, `host` приклеится сам. Так же устроены
|
||
родные YAML (`vokino.yaml` → `uri: search?name={search}`).
|
||
|
||
### ⚠️ Питфолл: явный `format` в `menu` перезагружает страницу
|
||
|
||
С `format`-блоком в `menu` Lampa **перезагружает прогрузку страницы при каждом выборе
|
||
раздела** (наблюдение Alex). Если перезагрузка не нужна — убрать `format` из `menu`,
|
||
оставить только `categories`.
|
||
|
||
### 🎯 Как добиться «CUB + мой список сверху» — варианты (решение Alex, не принято)
|
||
|
||
Родной CUB и «Мой список» — это **два источника Lampa**, переключаются в
|
||
«остальное → основной источник». Одновременно показать нельзя без вмешательства:
|
||
|
||
| Путь | Реализуемость |
|
||
|---|---|
|
||
| Блок `main` в YAML | ❌ **невозможно** — ломает парсинг |
|
||
| Оставить `menu` как есть | ⚠️ источник работает, но разделы подменяются, пока он выбран |
|
||
| Патч `plugin.js` | ⚠️ убрать `Listener.follow('menu')` → перехвата нет, но и секции сверху **не появятся** |
|
||
| Написать свой плагин | ✅ единственный путь для «сверху», объём работы |
|
||
|
||
### ⚠️ Баг 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) — ✅ ПРОВЕРЕНО 2026-09-22
|
||
|
||
Фильмы уже резолвлены в Radarr — там есть TMDB ID и постеры. Это **правильный
|
||
источник** для каталога; `.md` их не содержит.
|
||
|
||
```bash
|
||
# API-ключ Radarr
|
||
grep -oE "<ApiKey>[^<]+</ApiKey>" \
|
||
/srv/dev-disk-by-uuid-6194539b-.../docker/radarr/config/config.xml
|
||
# → cbcb8ec320104359920c0f611d503c7b
|
||
|
||
# ⚠️ -L обязателен, иначе 307 и пустое тело
|
||
curl -sL "http://localhost:7878/api/v3/movie?apikey=$KEY" | jq length # → 50
|
||
|
||
# Sonarr, порт 8989, ключ 15fbec32f1cb4b05b1c2b229ce27359b
|
||
curl -sL "http://localhost:8989/api/v3/series?apikey=$SKEY" | jq length # → 13
|
||
```
|
||
|
||
**Поля ответа Radarr (для каталога нужны все):**
|
||
`tmdbId`, `imdbId`, `title`, `originalTitle`, `year`, `titleSlug`, `hasFile`,
|
||
`genres`, `ratings.tmdb.value`, `images[] | select(.coverType=="poster") | .remoteUrl`.
|
||
Кэш постеров на диске: Radarr `/config/MediaCover/` (46 каталогов).
|
||
|
||
```json
|
||
{
|
||
"tmdbId": 1292695, "imdbId": "tt31728330",
|
||
"title": "They Will Kill You", "year": 2026,
|
||
"hasFile": true, "genres": ["Horror"],
|
||
"ratings": {"tmdb": {"value": 6.945}},
|
||
"images": [{"coverType": "poster",
|
||
"remoteUrl": "https://image.tmdb.org/t/p/original/6oI4oQKTWMVUlr8Ivqydp28Ruu6.jpg"}]
|
||
}
|
||
```
|
||
|
||
⚠️ **Названия в Radarr латиницей** (`They Will Kill You`), в `.md` — по-русски.
|
||
Перевод делает **TMDB Proxy** (`proxy_tmdb = true` в `lampainit.js`), уже включён.
|
||
|
||
⚠️ **Связки kp ↔ tmdb в данных нет.** В `.md` — 68 ссылок `kinopoisk.ru/film/<id>/`,
|
||
в Radarr — `tmdbId`. Прямого соответствия нет ни в одном файле. **Мост — модуль
|
||
`watchlist_sync/resolver.py`** (см. ниже).
|
||
|
||
### `watchlist_sync/resolver.py` — резолвер постеров (уже написан!)
|
||
|
||
Путь: `/srv/dev-disk-by-uuid-49e8f586-3839-4c5d-a1e1-58bfc3579ade/watchlist-sync/watchlist_sync/`
|
||
|
||
Уже решает задачу постеров/ID для каталога:
|
||
- поиск в **TMDB** (`api.themoviedb.org/3`, языки `ru-RU` + `en-US`)
|
||
- поиск в **Кинопоиске** (`api.poiskkino.dev/v1.4`)
|
||
- возвращает `Candidate`: `tmdb_id`, `kp_id`, `title`, `year`, `score`, `rating`, `genres`
|
||
- `is_horror()` — ужасы по TMDB `genre_id=27` (нужно для сортировки 🧟♀️)
|
||
- кэш `.resolve_cache.json`; различает `ok` / `ambiguous` (score < 0.75) / `not_found`
|
||
|
||
### 🔴 `watchlist_sync/arr.py` — ИСТОЧНИК АВТОСКАЧКИ (в коде!)
|
||
|
||
```python
|
||
# radarr_add():
|
||
"monitored": True,
|
||
"addOptions": {"searchForMovie": True}, # ← качает СРАЗУ после добавления
|
||
|
||
# sonarr_add():
|
||
"monitored": True,
|
||
"addOptions": {"searchForMissingEpisodes": True}, # ← то же для сериалов
|
||
```
|
||
|
||
⚠️ **Даже если снять `monitored` вручную, следующий запуск добавления из списка
|
||
включит автоскачку снова** — флаг зашит в код. Фикс: `searchForMovie` → `False`,
|
||
`searchForMissingEpisodes` → `False`. **Статус: не применён, на апруве.**
|
||
|
||
### Как выключить автоскачку на HDD — ✅ ВЫПОЛНЕНО 2026-09-22
|
||
|
||
| Сервис | Очередь | `monitored` | `rssSyncInterval` |
|
||
|---|---|---|---|
|
||
| **Radarr** | 6 → **0** | 45 → **0** | 30 → **0** |
|
||
| **Sonarr** | 19 → **0** | 13 → **0** | 15 → **0** |
|
||
|
||
Метаданные **целы**: 50 фильмов, 46 с постерами, 50 с `tmdbId` и рейтингом,
|
||
24 файла на диске **не тронуты**. Бэкапы — метка `20260922-123404`.
|
||
|
||
**Проверка пассивности:** Transmission за 45 с — NET `290GB/26.7GB`, BLOCK `214GB/393kB`
|
||
не сдвинулись. Логи Radarr (`search|download|grab`) за 2 мин — пусто.
|
||
|
||
**Правильные эндпоинты (проверено):**
|
||
```bash
|
||
# отмена загрузки — файлы на диске НЕ трогаются
|
||
DELETE /api/v3/queue/<id>?removeFromClient=true&blocklist=false
|
||
|
||
# снятие monitored — КЛЮЧ ПОЛЯ РАЗНЫЙ!
|
||
PUT /api/v3/movie/editor {"movieIds": [...], "monitored": false} # Radarr
|
||
PUT /api/v3/series/editor {"seriesIds": [...], "monitored": false} # Sonarr, НЕ "ids"
|
||
|
||
# RSS off — отправлять ВЕСЬ объект конфига с id, иначе молча вернёт старое
|
||
PUT /api/v3/config/indexer {"rssSyncInterval": 0, "id": 1, ...остальное}
|
||
```
|
||
|
||
**Откат:**
|
||
```bash
|
||
curl -sL -X PUT ".../api/v3/movie/editor" -d '{"movieIds":[...],"monitored":true}'
|
||
curl -sL -X PUT ".../api/v3/series/editor" -d '{"seriesIds":[...],"monitored":true}'
|
||
curl -sL -X PUT ".../api/v3/config/indexer" -d '{"rssSyncInterval":30,"id":1,...}'
|
||
cp radarr.db.bak-20260922-123404 radarr.db && docker restart radarr
|
||
```
|
||
|
||
### 🔴 Питфолл: `urllib` не идёт по 307, `curl -sL` идёт
|
||
|
||
Симптом: **все** DELETE/PUT из Python-скриптов вернули
|
||
`HTTP Error 307: Temporary Redirect`, **ничего не изменилось**.
|
||
Штатный `urllib` на 307/308 превращает DELETE в GET и теряет тело.
|
||
|
||
**Фикс — свой redirect-хендлер:**
|
||
```python
|
||
class RedirectKeepMethod(urllib.request.HTTPRedirectHandler):
|
||
def redirect_request(self, req, fp, code, msg, headers, newurl):
|
||
if code in (307, 308):
|
||
new = urllib.request.Request(newurl, data=req.data,
|
||
method=req.get_method())
|
||
for k, v in req.headers.items():
|
||
new.add_header(k, v)
|
||
return new
|
||
return super().redirect_request(req, fp, code, msg, headers, newurl)
|
||
|
||
_OPENER = urllib.request.build_opener(RedirectKeepMethod)
|
||
# далее _OPENER.open(req) вместо urllib.request.urlopen(req)
|
||
```
|
||
|
||
Прочие грабли сессии:
|
||
- **Sonarr группирует эпизоды сезона под одним `id`** — после удаления первой записи
|
||
остальные дают `404`, это **не сбой**, они ушли с родительской.
|
||
- **Кириллица внутри inline-`jq` в `ssh '...'`** ломает команду
|
||
(`unexpected INVALID_CHARACTER`). Ключи объекта — латиницей: `total`, `monitored`, `queue`.
|
||
|
||
## TorrServer внутри Lampac — на HDD НЕ пишет (проверено 2026-09-22)
|
||
|
||
| Параметр | Значение | Смысл |
|
||
|---|---|---|
|
||
| `UseDisk` | **`false`** | 🔴 **на диск не пишет вообще** |
|
||
| `CacheSize` | 100663296 (96 МБ) | кэш в RAM |
|
||
| `TorrentsSavePath` | `""` | пути сохранения нет |
|
||
| `TorrentDisconnectTimeout` | 180 | раздача живёт 3 мин после остановки |
|
||
|
||
```bash
|
||
# конфиг TorrServer
|
||
docker exec lampac cat /lampac/data/ts/settings.json | jq '.BitTorr | {UseDisk, CacheSize, TorrentsSavePath}'
|
||
|
||
# жив ли
|
||
curl -s http://192.168.1.14:9118/ts/echo # → MatriX.135
|
||
curl -s -X POST http://192.168.1.14:9118/ts/torrents \
|
||
-H "Content-Type: application/json" -d '{"action":"list"}' # → []
|
||
```
|
||
|
||
## 🔴 Поиск торрентов: отдельного Jackett НЕТ, его роль играет Lampac
|
||
|
||
`lampainit.js` прописывает:
|
||
```js
|
||
Lampa.Storage.set('parser_torrent_type', 'jackett');
|
||
Lampa.Storage.set('jackett_url', '192.168.1.14:9118'); // ← сам Lampac!
|
||
Lampa.Storage.set('jackett_key', '1');
|
||
```
|
||
|
||
Контейнера **Jackett в системе нет**. Lampac отдаёт Jackett-совместимый API сам:
|
||
|
||
```bash
|
||
# ⚠️ на КОРНЕ, БЕЗ префикса /jackett (с ним → 404)
|
||
curl "http://192.168.1.14:9118/api/v2.0/indexers/all/results?apikey=1&Query=matrix"
|
||
# → {"Results":[{"Tracker":"rutor","Title":"...","MagnetUri":"magnet:?xt=...","Seeders":0}]}
|
||
```
|
||
✅ Проверено: вернул реальные результаты с магнит-ссылками.
|
||
**Отдельный Jackett ставить НЕ нужно** — так задумано производителем.
|
||
|
||
## Занятые порты на Кра́кене (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]].
|
||
|
||
### Общее про модуль
|
||
|
||
| Что | Как |
|
||
|---|---|
|
||
| Данные | `sites/<site>.yaml` — `host`, `menu`, `search`, `list`, `content` |
|
||
| Переопределения | `override/<site>.yaml`, `override/_.yaml` |
|
||
| Роуты | `/catalog.js`, `/catalog`, `/catalog/list`, `/catalog/card` |
|
||
| WAF | `^/catalog/` → 10 req/sec |
|
||
| Примеры | 10 файлов: `vokino`, `rezka`, `kinopub`, `aniliberty`, `eneyida`, `filmix`, `filmixapp`, `getstv`, `kinobase`, `kinoukr` |
|
||
|
||
**Обязателен HTTP:** `if (!url.StartsWith("http")) url = $"{init.host}/{url}"` — локальные файлы не читаются.
|
||
|
||
**Два режима:** `jsonPath: true` → `JToken.Parse` (JSON), иначе HtmlAgilityPack (HTML).
|
||
|
||
🔴 **Питфолл: элемент с пустым `href` ВЫБРАСЫВАЕТСЯ** —
|
||
`if (!IsNullOrWhiteSpace(name) && !IsNullOrWhiteSpace(href))` (ListController.cs).
|
||
Нужен непустой `href` у каждого элемента.
|
||
|
||
🔴 **Питфолл: `{cat}` НЕ подставляется в `nodes`** — JSONPath статичен.
|
||
Разные категории = разные JSON-файлы.
|
||
|
||
🔴 **Питфолл: кэш без версии данных** — ключ `catalog:{plugin}:{search}:{sort}:{cat}:{page}`.
|
||
После правки данных нужен `docker restart lampac`.
|
||
|
||
**Выключен в двух местах** `base.conf`/`current.conf`:
|
||
```jsonc
|
||
"BaseModule": { "SkipModules": [ "Catalog", ... ] }
|
||
"LampaWeb": { "initPlugins": { "catalog": false } }
|
||
```
|
||
|
||
Синапс модулей (всего 33): `AdminPanel, Adult, Catalog, Community, DLNA, DatabaseEditor, ExternalBind,
|
||
ForkPlayerXML, GStreamer, JacRed, Kit, LampaWeb, LampacApk, LogUserRequest-Lite, MsxNative, Music,
|
||
NextHUB, Online, OnlineAnime, OnlineENG, OnlineGEO, OnlinePaid, OnlineRUS, OnlineUKR, PidTor, Potok,
|
||
Proxy, SISI, Sync, Telemetry, Tracks, Transcoding, WebLog`.
|
||
|
||
Полный пример YAML (`vokino.yaml`): `docker exec lampac cat /lampac/module/Catalog/sites/vokino.yaml`.
|
||
|
||
Выбор порта — `docker compose config` + `sudo ss -tlnp` перед деплоем.
|
||
|
||
## Интеграция с Lampa (ТВ) — ✅ СДЕЛАНО 2026-09-22
|
||
|
||
- Плагин: `http://192.168.1.14:9118/online.js`
|
||
- TorrServer в Lampa: Настройки → TorrServer → «Использовать основную ссылку» → `http://192.168.1.14:9118`
|
||
- Буфер плеера: 50–100 МБ
|
||
- `/lg.ipk` отдаёт сам Lampac (проверено: HTTP **200**)
|
||
|
||
### Установка клиента на LG webOS — по SSH, без флешки
|
||
|
||
🔴 **`Media Station X` и `.ipk` с флешки — НЕ нужны.** ТВ имеет SSH-доступ (root), установка делается с Mac.
|
||
|
||
**ТВ:** `root@192.168.1.70`, ключ `~/.ssh/konka_webos`, webOS **5.4.2** (ядро 4.4.84, image `starfish-dvb-secured`, build 2602, `webos_build_datetime 20230405092501`).
|
||
Порты открыты: `22` (SSH), `3000`/`3001` (Luna). Из кастомного уже стоит: `org.webosbrew.hbchannel` 0.7.2, `org.webosbrew.inputhook`, `me.wouterdek.magic4pc`.
|
||
|
||
**Порядок установки:**
|
||
|
||
```bash
|
||
# 1. Скачать .ipk от Lampac прямо на ТВ
|
||
ssh root@192.168.1.70 'curl -sS --max-time 60 -o /tmp/lampa.ipk "http://192.168.1.14:9118/lg.ipk"'
|
||
# → 6 896 874 байт, формат ar (!<arch>), НЕ tar/gzip
|
||
|
||
# 2. Установить (обязательна обёртка script — см. питфолл ниже)
|
||
ssh root@192.168.1.70 'rm -f /tmp/inst.txt; script -q -c \
|
||
"luna-send -n 1 -f luna://com.webos.appInstallService/dev/install \
|
||
{\"id\":\"org.lampa.tv\",\"ipkUrl\":\"/tmp/lampa.ipk\",\"subscribe\":true}" \
|
||
/tmp/inst.txt >/dev/null 2>&1; cat /tmp/inst.txt'
|
||
# → {"subscribed":true,"returnValue":true}
|
||
|
||
# 3. Проверить, что установилось
|
||
ssh root@192.168.1.70 'ls /media/developer/apps/usr/palm/applications/'
|
||
# → com.lampac.tv ← имя приложения Lampa, НЕ org.lampa.tv
|
||
|
||
# 4. Запустить
|
||
ssh root@192.168.1.70 'rm -f /tmp/l.txt; script -q -c \
|
||
"luna-send -n 1 -f luna://com.webos.applicationManager/launch {\"id\":\"com.lampac.tv\"}" /tmp/l.txt'
|
||
|
||
# 5. Убедиться, что открылось
|
||
ssh root@192.168.1.70 'rm -f /tmp/f.txt; script -q -c \
|
||
"luna-send -n 1 -f luna://com.webos.applicationManager/getForegroundAppInfo {}" /tmp/f.txt; grep appId /tmp/f.txt'
|
||
# → "appId": "com.lampac.tv"
|
||
```
|
||
|
||
**Фактический ID приложения — `com.lampac.tv`** (vendor Lampac, version 1.0.0, type web).
|
||
⚠️ В `luna-send ... dev/install` поле `"id"` — **произвольная метка**; реальный appId берётся из `appinfo.json` внутри ipk. Ошибиться здесь не страшно, но искать приложение надо по фактическому ID.
|
||
|
||
### 🔴 Питфолл: `luna-send` по SSH молчит
|
||
|
||
**Симптом:** любой вызов `luna-send` через `ssh root@TV "luna-send ..."` печатает **хелп-экран**, а не результат. С `-t` (PTY) — тоже. С `-a '{"json"}'` — тоже.
|
||
|
||
**Причина:** `luna-send` детектирует TTY и отказывается писать в pipe.
|
||
|
||
**Решение:** обернуть в `script(1)`, который аллоцирует псевдо-TTY, и прочитать временный файл:
|
||
```bash
|
||
ssh root@TV 'script -q -c "luna-send -n 1 -f luna://service/method {json}" /tmp/o.txt; cat /tmp/o.txt'
|
||
```
|
||
|
||
Готовый враппер: `~/Automation/tv-luna-send.sh` (`TV_HOST` переопределяет таргет).
|
||
Доки: [[family/how-to/tv-luna-send]], [[family/how-to/htpc-webos-luna]].
|
||
|
||
⚠️ **Установка идёт через `com.webos.appInstallService/dev/install`**, а НЕ через
|
||
`org.webosbrew.hbchannel.service/install` (последний в образе есть, но `luna-send` его не дёрнул чисто).
|
||
|
||
⚠️ `luna-send -i` (subscribe, бесконечный) через враппер **не работает** — нужен polling.
|
||
|
||
### Первый просмотр — проверено 2026-09-22
|
||
|
||
Фильм запущен, **не дёргается**. Alex: «Вроде стабильно, не делается».
|
||
|
||
| Факт | Значение |
|
||
|---|---|
|
||
| Соединения ТВ → Lampac | 3 × ESTABLISHED `192.168.1.70 → 192.168.1.14:9118` |
|
||
| Нагрузка контейнера | `lampac` CPU 57%, NET 168 МБ ↓ / 132 МБ ↑ |
|
||
| Битрейт на eth0 | **~3–4 Мбит/с** |
|
||
|
||
⚠️ **Почему всего 3–4 Мбит, а не 15:** выбран источник **«Смотреть онлайн (lampac 1.18…)»** — встроенный
|
||
плагин `online.js`, HLS-поток. Lampac отдаёт **ссылку**, ТВ тянет видео напрямую из CDN (в `/proc/net/tcp`
|
||
ТВ видны внешние адреса на `:443`/`:8443`). Тяжёлый remux с торрента не участвует — поэтому и не дёргается.
|
||
|
||
🔴 **Следствие:** этот просмотр **не проверяет**, держит ли сеть remux 60–80 Мбит.
|
||
Тест функциональности, не полосы. Полосу проверять на торрент-источнике.
|
||
|
||
**Как убрать выбор источника:** 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`.
|
||
|
||
### 🔴 БАГ Lampac: источник не виден в панели (`enumerable: false`)
|
||
|
||
**Найдено 2026-09-22** диагностикой через Chrome DevTools ТВ. Симптом Alex:
|
||
«Ни на главной ни в Фильмах нет! Там только Сейчас смотрят, рекомендуем итд».
|
||
|
||
**Факты с живого ТВ:**
|
||
|
||
| Замер | Значение |
|
||
|---|---|
|
||
| `Lampa.Storage.field('source')` | `'Мой список'` — источник **уже выбран** |
|
||
| `Object.keys(Lampa.Api.sources)` | `'tmdb|cub'` — ❌ источника нет в перечислении |
|
||
| `Lampa.Api.sources['Мой список'].getCatalog()` | `search, movie, cartoons, anime, menu, main` — ✅ работает |
|
||
| `Object.getOwnPropertyDescriptor(Lampa.Api.sources,'Мой список')` | `{"enumerable":false,"configurable":false}` ← корень |
|
||
|
||
**Корень — в `/lampac/module/Catalog/plugin.js`** (строка 59, `loadCatalogs()`, **два вхождения**):
|
||
|
||
```js
|
||
// БЫЛО (баг)
|
||
Object.defineProperty(Lampa.Api.sources, key, { get: function(){ return Api; } });
|
||
// НАДО
|
||
Object.defineProperty(Lampa.Api.sources, key,
|
||
{ get: function(){ return Api; }, enumerable: true, configurable: true });
|
||
```
|
||
|
||
Не-enumerable свойство не попадает в `Object.keys()` → Lampa не рисует источник в панели
|
||
выбора. **Баг Lampac, не нашей настройки.**
|
||
|
||
🔴 **`plugin.js` живёт в ОБРАЗЕ, не на HDD.** `docker inspect` показывает монтирования
|
||
только на `catalog/sites` и `catalog/override`. Правка через `docker exec` **исчезнет
|
||
при обновлении образа** — нужен bind-mount:
|
||
|
||
```yaml
|
||
# docker-compose.yml
|
||
- ./catalog/plugin.js:/lampac/module/Catalog/plugin.js:ro
|
||
```
|
||
|
||
```bash
|
||
ssh kraken 'docker exec lampac cat /lampac/module/Catalog/plugin.js' > /tmp/catalog-plugin.js
|
||
cp /tmp/catalog-plugin.js /tmp/catalog-plugin.js.bak-$(date +%Y%m%d-%H%M%S)
|
||
# правка двух вхождений defineProperty (только через patch, не sed)
|
||
node --check /tmp/catalog-plugin.js # проверить синтаксис ДО заливки
|
||
scp /tmp/catalog-plugin.js kraken:/srv/.../lampac/catalog/plugin.js
|
||
ssh kraken 'cd /srv/.../lampac && docker compose up -d'
|
||
```
|
||
|
||
**Статус: фикс НЕ применён**, ждёт апрува Alex (2026-09-22).
|
||
Полный разбор — [[personal/plans/lampac-watchlist-plugin]], раздел «ГЛАВНЫЙ ПИТФОЛЛ».
|
||
|
||
### 🛠 Диагностика ТВ через Chrome DevTools — порт 9998
|
||
|
||
**Главный инструмент для отладки UI Lampa.** webOS отдаёт Chrome DevTools Protocol:
|
||
у процессов `WebAppMgr` есть `--remote-debugging-port=9998`. Даёт **чтение состояния
|
||
живой Lampa** — ни логи, ни tcpdump этого не дают.
|
||
|
||
```bash
|
||
# цель отладки + URL приложения
|
||
curl -s --max-time 8 "http://192.168.1.70:9998/json" | /usr/bin/jq -r '.[] | "\(.type): \(.url)"'
|
||
# → page: file:///media/developer/apps/usr/palm/applications/com.lampac.tv/index.html?...
|
||
```
|
||
|
||
Чтение переменных — `websocket-client` + `Runtime.evaluate`:
|
||
|
||
```python
|
||
pages = json.load(urllib.request.urlopen("http://192.168.1.70:9998/json", timeout=8))
|
||
target = next(p for p in pages if "com.lampac.tv" in p.get("url",""))
|
||
ws = websocket.create_connection(target["webSocketDebuggerUrl"], timeout=10)
|
||
# Runtime.evaluate: Lampa.Storage.field('source')
|
||
# Object.keys(Lampa.Api.sources)
|
||
# Object.getOwnPropertyDescriptor(Lampa.Api.sources,'Мой список')
|
||
```
|
||
|
||
Готовые скрипты: `/tmp/lampa_probe.py` (состояние источника),
|
||
`/tmp/lampa_probe3.py` (асинхронный вызов `menu()` каталога).
|
||
|
||
**Ловушки:**
|
||
|
||
⚠️ **Замер соединений — на ТВ, не на сервере.** `sudo ss -tn | grep :9118` на Кра́кене
|
||
сразу после старта Lampa даёт **0** (ложный вывод «не ходит»). Через ~30 с:
|
||
`ssh root@192.168.1.70 'netstat -tn | grep 9118'` → **1 ESTABLISHED + 6 TIME_WAIT**.
|
||
|
||
⚠️ **`launch` через luna требует экранированного JSON в двойных кавычках**, иначе
|
||
`errorCode: 2, invalid parameters`. `getForegroundAppInfo {}` работает без кавычек.
|
||
|
||
⚠️ **`tcpdump` на Кра́кене нет** — не ставили, DevTools дал больше.
|
||
|
||
⚠️ **`luna://com.webos.service.capture/takeScreenShot` не существует** на этом ТВ
|
||
(`Unknown method`) — скриншот так не снять.
|
||
|
||
### Диагностика «каталога нет в 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 root@192.168.1.70 'curl -s -o /dev/null -w "%{http_code}" http://192.168.1.14:9118/catalog'` | 200 |
|
||
| ТВ реально ходит | `ssh root@192.168.1.70 'netstat -tn \| grep 9118'` | ESTABLISHED <br>ноль = Lampa не стартовала |
|
||
| Источник в списке | DevTools: `Object.keys(Lampa.Api.sources)` | **все** каталоги, вкл. «Мой список» |
|
||
|
||
Порядок разбора: сначала сеть с ТВ → потом `netstat` на ТВ → потом `/catalog` на сервере →
|
||
потом DevTools (состояние JS). **Если источник есть в `Api.sources` напрямую, но нет в
|
||
`Object.keys()` — это баг `enumerable` в `plugin.js`, а не проблема настроек.**
|
||
|
||
⚠️ `docker logs lampac` **HTTP-запросы не пишет** — по логам факт обращения ТВ не проверить.
|
||
|
||
## Внутреннее устройство Lampac (разведка 2026-09-22)
|
||
|
||
**33 модуля** в образе (`/lampac/module/`):
|
||
`AdminPanel`, `Adult`, **`Catalog`**, `Community`, **`DLNA`**, `DatabaseEditor`, `ExternalBind`,
|
||
`ForkPlayerXML`, `GStreamer`, `JacRed`, `Kit`, `LampaWeb`, `LampacApk`, `LogUserRequest-Lite`,
|
||
`MsxNative`, `Music`, `NextHUB`, **`Online`**, `OnlineAnime`, `OnlineENG`, `OnlineGEO`, `OnlinePaid`,
|
||
`OnlineRUS`, `OnlineUKR`, `PidTor`, `Potok`, `Proxy`, `SISI`, `Sync`, `Telemetry` (+ остальные).
|
||
|
||
**Конфиг — `current.conf`** внутри образа (`/lampac/current.conf`, 157 КБ, генерируется из `base.conf` +
|
||
`init.conf`). Рабочий каталог `/lampac`, файлы читаются **из корня**, не из `config/`.
|
||
|
||
Выключение модуля — двумя механизмами:
|
||
1. **`SkipModules`** в `init.conf` / `current.conf`
|
||
2. **`manifest.json`** в каталоге модуля (`"enable": true|false`)
|
||
|
||
⚠️ **`init.conf` НЕ в образе по умолчанию** — его читают из `/lampac/init.conf`, файл перекрывает
|
||
`base.conf`. Правка через `docker exec` **теряется при пересоздании контейнера**, поэтому
|
||
смонтирован с HDD (`./config-module/init.conf:/lampac/init.conf:ro`). См. раздел docker-compose выше.
|
||
|
||
⚠️ `current.conf` в образе (157 КБ) — **сгенерированный** результат (`guid`, `listen`, полный конфиг).
|
||
Это **не** входной файл, править его бессмысленно.
|
||
|
||
### Полезные роуты (проверены curl'ом)
|
||
|
||
| Роут | Код | Что |
|
||
|---|---|---|
|
||
| `/` | 200 | LampaWeb (UI, `<base href="/lampa-main/">`) |
|
||
| `/online.js` | 200 | плагин VOD — 70+ онлайн-источников |
|
||
| `/lg.ipk` | 200 | установщик клиента для LG (6.9 МБ) |
|
||
| `/sisi` | 200 | JSON-список платформ 18+ |
|
||
| `/dlna` | 200 | DLNA-модуль |
|
||
| `/ts/echo` | 200 | TorrServer (отдаёт версию, напр. `MatriX.135`) |
|
||
| `/catalog.js` | **200** | плагин каталогов (включён 2026-09-22) — см. раздел Catalog |
|
||
| `/catalog` | **200** | JSON каналов каталогов |
|
||
| `/watchlist.json`, `/watchlist-<code>.json` | **200** | наш JSON-каталог watchlist |
|
||
| `/cub`, `/api`, `/lampac.js` | 404/500 | — |
|
||
|
||
⚠️ `wwwroot` отдаётся статикой: **любой** файл, положенный туда, доступен по HTTP
|
||
от корня (`http://<host>:9118/<файл>`). Проверено записью пробного файла.
|
||
|
||
## Radarr/Sonarr как источник метаданных для каталога (2026-09-22)
|
||
|
||
**Зачем:** каталог watchlist нуждается в **TMDB ID и постерах** для элементов.
|
||
Список `movies-watchlist.md` — просто текст, там этого нет. Но фильмы добавлялись
|
||
в **Radarr**, который уже держит метаданные (тянет из TMDB при добавлении).
|
||
|
||
### Что отдаёт Radarr API
|
||
|
||
```bash
|
||
KEY=$(ssh kraken 'grep -oE "<ApiKey>[^<]+</ApiKey>" \
|
||
/srv/...6194539b.../docker/radarr/config/config.xml' | sed 's/<[^>]*>//g')
|
||
|
||
curl -sL "http://localhost:7878/api/v3/movie?apikey=$KEY" | jq .
|
||
```
|
||
|
||
```json
|
||
{
|
||
"tmdbId": 1292695,
|
||
"title": "They Will Kill You",
|
||
"year": 2026,
|
||
"hasFile": true,
|
||
"monitored": true,
|
||
"images": [{"coverType": "poster",
|
||
"remoteUrl": "https://image.tmdb.org/t/p/original/6oI4oQKTWMVUlr8Ivqydp28R"}]
|
||
}
|
||
```
|
||
|
||
Маппинг в формат каталога: `tools.tmdbId` → `id`/`href`, `images[].remoteUrl` → `img`,
|
||
`title`+`year` → `title`, `hasFile` → признак «уже скачан».
|
||
|
||
### 🔴 Питфолл: `curl -sL`, без `-L` Radarr отдаёт 307
|
||
|
||
```bash
|
||
curl -s "http://localhost:7878/api/v3/movie?apikey=$KEY" | jq length # ❌ 0 байт
|
||
curl -sL "http://localhost:7878/api/v3/movie?apikey=$KEY" | jq length # ✅ 50
|
||
```
|
||
|
||
### Окружение arr-стека на Кра́кене
|
||
|
||
| Сервис | Порт | Конфиг на HDD |
|
||
|---|---|---|
|
||
| radarr | 7878 | `/srv/...6194539b.../docker/radarr/config/` |
|
||
| sonarr | 8989 | аналогично |
|
||
| prowlarr | 9696 | аналогично |
|
||
| transmission | — | отдельный контейнер |
|
||
|
||
Постеры складываются в `/config/MediaCover/` (46 каталогов на 2026-09-22) — можно
|
||
раздавать их статикой через `wwwroot`, не дёргая CDN TMDB.
|
||
|
||
⚠️ `sqlite3` в контейнерах arr **нет** — БД (`radarr.db`) читать либо через `strings`,
|
||
либо вытащить файл на хост (там `/usr/bin/sqlite3` есть).
|
||
|
||
### Управление автоскачкой (два рычага, оба нужны)
|
||
|
||
| Рычаг | Команда | Эффект |
|
||
|---|---|---|
|
||
| `monitored` | `PUT /api/v3/movie/editor` | фильм не ищется/не качается, метаданные остаются |
|
||
| `rssSyncInterval` | `PUT /api/v3/config/indexer` | `0` = Radarr не ходит в RSS (сейчас 30 мин) |
|
||
|
||
⚠️ В Radarr **нет** состояния «источник, но не грузить» — это ровно `monitored: false`.
|
||
|
||
### Контур воспроизведения — не путать (✅ проверено 2026-09-22)
|
||
|
||
| Слой | Что делает | Пишет на HDD |
|
||
|---|---|---|
|
||
| Radarr + Sonarr + Transmission | автоскачка релизов в библиотеку | **да** |
|
||
| Lampac **TorrServer** (встроенный) | стриминг из UI Lampa по требованию | ❌ **нет — доказано** |
|
||
| Catalog «Мой список» | показ секций с постерами | ❌ ничего не качает |
|
||
|
||
Просмотр через Lampa **не пополняет библиотеку**: TorrServer отдаёт поток и выбрасывает.
|
||
`transmission` к Lampa отношения не имеет.
|
||
|
||
**Доказательство, что TorrServer не пишет на диск** — `/lampac/data/ts/settings.json`:
|
||
|
||
```bash
|
||
ssh kraken 'docker exec lampac cat /lampac/data/ts/settings.json' | jq .BitTorr
|
||
```
|
||
|
||
```json
|
||
{ "CacheSize": 100663296, // 96 МБ — RAM-кэш
|
||
"UseDisk": false, // 🔴 НА ДИСК НЕ ПИШЕТ
|
||
"TorrentsSavePath": "", // путь сохранения пуст
|
||
"TorrentDisconnectTimeout": 180, // раздача живёт 3 мин после остановки
|
||
"PreloadCache": 0, "ReaderReadAHead": 83 }
|
||
```
|
||
|
||
`UseDisk: false` — дефолт Lampac, настраивать не надо. Кэш Lampac целиком:
|
||
`/lampac/cache/` = 31 МБ (SQLite, Playwright, gstreamer-registry — **не фильмы**),
|
||
`/lampac/data/` = 44 МБ. Список торрентов пуст:
|
||
`curl -s -X POST .../ts/torrents -d '{"action":"list"}'` → `[]`.
|
||
|
||
Живость TorrServer: `curl -s "http://192.168.1.14:9118/ts/echo"` → `MatriX.135`.
|
||
|
||
### 🔴 Поиск торрентов — Jackett внутри Lampac (отдельный НЕ нужен)
|
||
|
||
**Ловушка:** в `lampainit.js` прописано `parser_torrent_type = 'jackett'`,
|
||
но **контейнера Jackett нет** в `docker ps`. Это не поломка — Lampac **сам отдаёт
|
||
Jackett-совместимый API**.
|
||
|
||
```bash
|
||
curl -s "http://192.168.1.14:9118/lampainit.js" | grep -oE "Lampa.Storage.set\('[^']+', ?'[^']*'\)"
|
||
# jackett_url = '192.168.1.14:9118' ← сам Lampac, не сторонний сервис
|
||
# jackett_key = '1'
|
||
# parser_torrent_type= 'jackett'
|
||
# parser_use = 'true'
|
||
# source = 'cub'
|
||
# torrents_use = true (lampa_settings)
|
||
```
|
||
|
||
⚠️ **API живёт на КОРНЕ, без префикса `/jackett`:**
|
||
|
||
```bash
|
||
curl -s "http://192.168.1.14:9118/api/v2.0/indexers/all/results?apikey=1&Query=matrix"
|
||
# ✅ 200 — реальные результаты: Tracker:rutor, MagnetUri, Size, Seeders, ffprobe
|
||
curl -s "http://192.168.1.14:9118/jackett/api/v2.0/indexers/all/results" # ❌ 404
|
||
```
|
||
|
||
**Вывод:** ничего поднимать не надо, поиск торрентов работает штатно.
|
||
|
||
### ⚠️ Sonarr — второй источник автоскачки (не только Radarr)
|
||
|
||
Alex упомянул его не зря. Замер 2026-09-22:
|
||
|
||
```bash
|
||
SKEY=$(ssh kraken 'grep -oE "<ApiKey>[^<]+</ApiKey>" \
|
||
/srv/...6194539b.../docker/sonarr/config/config.xml' | sed 's/<[^>]*>//g')
|
||
# → 15fbec32f1cb4b05b1c2b229ce27359b
|
||
|
||
curl -sL "http://localhost:8989/api/v3/series?apikey=$SKEY" | jq length # → 13 сериалов
|
||
curl -sL "http://localhost:8989/api/v3/series?apikey=$SKEY" \
|
||
| jq '[.[]|select(.monitored)]|length' # → 13 monitored
|
||
curl -sL "http://localhost:8989/api/v3/queue?apikey=$SKEY" | jq .totalRecords # → 19 в очереди
|
||
```
|
||
|
||
| Сервис | Объектов | monitored | Очередь |
|
||
|---|---|---|---|
|
||
| Radarr | 50 фильмов | **45** | **6** |
|
||
| Sonarr | 13 сериалов | **13** | **19** |
|
||
|
||
**Отключать надо оба** — иначе Sonarr продолжит качать сериалы.
|
||
|
||
### Transmission — замер
|
||
|
||
```bash
|
||
ssh kraken 'docker exec transmission cat /config/settings.json' > /tmp/trans-settings.json
|
||
# download-dir /downloads · rpc-port 9091 · speed-limit-down-enabled false
|
||
# /config/torrents/*.torrent = 257 файлов (накопленный список РАЗДАЧ, не активная качка)
|
||
# CPU 0.76% — простаивает. NetIO 290G↑/26.7G↓ (суммарно за жизнь контейнера)
|
||
```
|
||
|
||
Полный состав контейнеров Кра́кена:
|
||
`lampac · radarr · jellyfin · transmission · portainer · flaresolverr ·
|
||
prowlarr · sonarr · watchtower · rclone · xray-reverse-bridge · hermes-kraken · cloudflared`
|
||
|
||
## Что осталось
|
||
|
||
1. **Лимит кэша TorrServer** — сейчас дефолт (`CacheSize` 96 МБ, `UseDisk: false`).
|
||
Диск 396 ГБ свободно, на HDD TorrServer не пишет вовсе — вопрос неактуален.
|
||
2. **Шаг 7 плана — watchlist в UI Lampa** — ✅ **серверная часть сделана** 2026-09-22,
|
||
🔴 **архитектура признана неверной**, переделывается: см.
|
||
[[personal/plans/lampac-watchlist-plugin]], разделы «ПЕРЕДЕЛКА 2» и
|
||
«✅ ПРОВЕРКА "как это реализуемо"».
|
||
3. **Проверка полосы на торрент-источнике** (remux 60–80 Мбит) — не сделана.
|
||
4. **Постеры/карточка в каталоге** — не сделаны, `image` пустой. Решение — брать
|
||
из Radarr (`images[].remoteUrl`) или `MediaCover/`, см. раздел выше.
|
||
5. **Автоскачка Radarr + Sonarr** — 45 monitored / очередь 6 у Radarr,
|
||
13 monitored / очередь 19 у Sonarr. План отключения на апруве
|
||
([[personal/plans/lampac-watchlist-plugin]], «ПЕРЕДЕЛКА 2»).
|