[2026-09-22] eagle: family/projects/watchlist-automation.md personal/plans/lampac-watchlist-plugin.md personal/tech/lampac-deployment.md
This commit is contained in:
1 parent
128152fc6e
commit
1aeb42f4b8
3 files changed
+472
-20
No files matched your search
@@ -240,21 +240,173 @@ volumes:
|
||||
Проверка синтаксиса ПЕРЕД заливкой: `node --check /tmp/catalog-plugin.js`.
|
||||
Статус: **не применено**, ждёт апрува Alex.
|
||||
|
||||
### Radarr как источник данных (постеры, TMDB ID)
|
||||
### Radarr как источник данных (постеры, TMDB ID) — ✅ ПРОВЕРЕНО 2026-09-22
|
||||
|
||||
Фильмы уже резолвлены в Radarr — там есть TMDB ID и постеры. Это **правильный
|
||||
источник** для каталога; `.md` их не содержит.
|
||||
|
||||
```bash
|
||||
# API-ключ
|
||||
grep -oE "<ApiKey>[^<]+</ApiKey>" /srv/dev-disk-by-uuid-6194539b-.../docker/radarr/config.xml
|
||||
# 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
|
||||
```
|
||||
|
||||
Поля ответа: `tmdbId`, `title`, `year`, `hasFile`, `images[].remoteUrl` (постер TMDB),
|
||||
`images[].coverType == "poster"`. Кэш постеров на диске: Radarr `/config/MediaCover/`.
|
||||
**Поля ответа 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 ·
|
||||
|
||||
Reference in new issue
Block a user