[2026-09-23] eagle: family/projects/watchlist-automation.md personal/plans/lampac-watched-to-watchlist.md personal/tech/home-network-config.md
This commit is contained in:
1 parent
ec49b14ac3
commit
8b87784327
3 files changed
+255
-44
No files matched your search
@@ -12,6 +12,62 @@ tags:
|
||||
|
||||
Полная цепочка: как `family/documents/movies-watchlist.md` превращается в скачанный контент.
|
||||
|
||||
## 🔴 2026-09-23: канал «Lampa → `[x]`» найден; фиксы сирот закоммичены
|
||||
|
||||
### Коммит `ffe7974` — закрыт должок по грязному дереву
|
||||
|
||||
В рабочем дереве `watchlist-sync` висели **незакоммиченные** правки, которые уже
|
||||
работали боевым прогоном (ночной 02:30 использовал именно их):
|
||||
|
||||
| Файл | Δ | Что |
|
||||
|---|---|---|
|
||||
| `watchlist_sync/parser.py` | +65 | фикс «ОСИРОТЕВШИЕ СТРОКИ» в `process_thumbs()`: `watched_titles`/`watched_kp` по всем секциям кроме Новинок, `_norm_title()`, вырезание сирот из `keep`, флаг `_patch_dropped` в раннем выходе |
|
||||
| `watchlist_sync/cli.py` | +7 | явные ветки вывода `👍 / 👎 / [x] / [drop]` (было обобщённое `else`) |
|
||||
|
||||
Закоммичены **отдельным** коммитом, не смешаны с новым кодом.
|
||||
Предыдущий HEAD был `a131208` (2026-09-21).
|
||||
|
||||
`sync_up._mark_watched` **уже содержит** фикс эмодзи-префикса — `_PREFIX` поглощает
|
||||
эмодзи с обеих сторон `⬇️`. Работает, правок не требует, переиспользуется.
|
||||
|
||||
### Найден реальный канал просмотров — модуль Lampac `TimeCode`
|
||||
|
||||
`sync_up` читает **Jellyfin**, но Jellyfin больше не источник: `BaseItems` — 53,
|
||||
`movie` — **0**, `UserData.IsPlayed=true` — **0**. Смотреть стали через Lampa+TorrServer.
|
||||
|
||||
**Фактический источник просмотров — Lampa**, и она уже пишет их на сервер в
|
||||
SQLite-БД модуля `TimeCode`:
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| БД | `$H/lampac/database/TimeCode.sql` (таблица `timecodes`) |
|
||||
| Модуль | `/lampac/module/Sync/TimeCode/` (`Controller.cs`, `plugin.js`, `README.md`) |
|
||||
| Ключ | `identity` = TMDB-ID (`movie-1758655` / `1758655_movie`) |
|
||||
| Прогресс | `percent` (флага «просмотрено» нет — политика клиента, см. README) |
|
||||
|
||||
🔴 **`watched_at` — НЕ признак досмотра.** Живая запись: `watched_at = 1790053739498`
|
||||
при **`percent = 18`**. Значит любое обновление таймкода пишет `watched_at`.
|
||||
Порог ставить **только по `percent`**.
|
||||
|
||||
План реализации синка `timecodes` → `[x]`:
|
||||
[[personal/plans/lampac-watched-to-watchlist]].
|
||||
|
||||
### 🔴 `ssh kraken` резолвится в мёртвый `.15` — работать через `.14`
|
||||
|
||||
Все обрывы этой сессии — маршрут ssh, не сервисы. Детали и обход:
|
||||
[[personal/tech/home-network-config]] → «Питфоллы доступа».
|
||||
|
||||
### Состояние стека после ребута (замер 2026-09-23)
|
||||
|
||||
14/14 контейнеров поднялись сами. Radarr/Sonarr queue `0`, Transmission 9 торрентов
|
||||
всё `Done/Idle` (Sum down `0.0`). Диск **31%** (539G/1.8T). Lampac `:9118` → 200,
|
||||
Jellyfin `:8096` → 302. Ночные скрипты отработали: cleanup 02:00, nightly 01:00,
|
||||
catalog 02:30–02:32 (каналов 4, позиций 392; `.md` 708 строк / 615 позиций).
|
||||
|
||||
🟡 **Лог `nightly` пишется в `/tmp/watchlist-nightly.log`** → умирает при ребуте,
|
||||
след прогона не сохраняется. Остальные логи уже в `~/logs/`. Фикс предложен,
|
||||
ждёт команды Alex.
|
||||
|
||||
## 🔴 2026-09-22: АВТОСКАЧКА НА HDD ВЫКЛЮЧЕНА (по требованию Alex)
|
||||
|
||||
**Контекст.** Задача — Lampa на ТВ показывает каталог из `movies-watchlist.md` и играет
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
title: Отметка «просмотрено» из Lampa → watchlist.md
|
||||
type: plan
|
||||
status: awaiting-approval
|
||||
status: planned-not-implemented
|
||||
namespace: personal
|
||||
created: 2026-09-23
|
||||
updated: 2026-09-23
|
||||
@@ -44,17 +44,35 @@ related:
|
||||
| Читает | `GET /timecode/all?card_id=...` |
|
||||
| Ключ личности | `identity` = `{tmdb_id}_movie` — **ровно то, что нужно для матча со списком** |
|
||||
|
||||
**Живая запись на 2026-09-23:**
|
||||
🔴 **ФОРМАТ `identity` — ОБЕ ФОРМЫ СУЩЕСТВУЮТ.** В README описана `movie-674`
|
||||
(дефис, префикс), но `card` выводится как `674_movie`. Живая запись показала
|
||||
именно дефисную форму. Regex должен принимать обе:
|
||||
|
||||
```python
|
||||
m = re.match(r'^(?:(movie|tv)-)?(\d+)', str(identity))
|
||||
```
|
||||
identity = 1758655_movie card = movie-1758655
|
||||
position = 1222.0 duration = 6898.0 percent = 18.0
|
||||
watched_at = 0 deleted = 0
|
||||
|
||||
⚠️ **Живая запись 2026-09-23 (снята дважды, значения менялись):**
|
||||
```
|
||||
`percent` уже считается Lampa/TorrServer. Отметка «просмотрено» в UI Lampa
|
||||
кладёт `percent ≈ 100` (либо `watched_at > 0` — обе колонки проверять).
|
||||
снимок 1: identity=1758655_movie card=movie-1758655
|
||||
position=1222.0 duration=6898.0 percent=18.0
|
||||
watched_at=0 deleted=0
|
||||
|
||||
снимок 2: identity=movie-1758655 card=1758655_movie
|
||||
position=1222.0 duration=6898.0 percent=18.0
|
||||
watched_at=1790053739498 deleted=0
|
||||
```
|
||||
🔴 **Вывод из снимка 2: `watched_at > 0` при `percent = 18`.** Значит `watched_at`
|
||||
ставится при **любой** записи таймкода, а не только при досмотре. Критерий
|
||||
«`watched_at > 0` = просмотрено» — **НЕНАДЁЖЕН**. Порог должен быть по `percent`.
|
||||
|
||||
⚠️ **Фильм `1758655` НЕ найден в `watchlist.json`** (368 позиций с TMDB-ID).
|
||||
Это не watchlist-позиция — смотрится в Lampa из другого источника. Планируемое
|
||||
поведение: не найдено в json → тихо пропустить, не ошибка.
|
||||
|
||||
⚠️ **`sqlite3` в контейнере НЕТ** (обычный случай у Alex) — БД читать через
|
||||
`docker cp lampac:/lampac/database/TimeCode.sql /tmp/` + `python3 -c "import sqlite3 ..."`.
|
||||
`docker cp lampac:/lampac/database/TimeCode.sql /tmp/` + `python3` **файлом-скриптом**
|
||||
(не `-c`, каждый inline = апрув). Готовые пробы: `/tmp/probe_cache.py`, `/tmp/probe_match.py`.
|
||||
На хосте Кра́кена `python3` есть.
|
||||
|
||||
### 1.4 Порог «просмотрено» — ответ из документации модуля
|
||||
@@ -72,32 +90,97 @@ README модуля (`/lampac/module/Sync/TimeCode/README.md`), раздел «
|
||||
| `updated_at` | сервер, мс | Когда приняли строку. Курсор дельт `?since=` |
|
||||
| `percent` | клиент | Прогресс; флага «просмотрено» отдельно нет |
|
||||
|
||||
**Отсюда критерий отбора строки:**
|
||||
**Отсюда критерий отбора строки — 🔴 ПЕРЕСМОТРЕН по факту (см. выше):**
|
||||
```
|
||||
deleted = 0 И percent > 0 И watched_at > 0
|
||||
deleted = 0 И percent >= ПОРОГ
|
||||
```
|
||||
⚠️ `deleted=1` — это **снятая** отметка (надгробие), `position`/`percent` обнулены,
|
||||
`duration` сохранён. Такие строки **не** считать просмотром.
|
||||
⚠️ Состояние `percent=18, watched_at=0` (живая запись сейчас) = **начал смотреть,
|
||||
не досмотрел** → `[x]` НЕ ставить.
|
||||
🔴 **`watched_at` в критерий НЕ ВХОДИТ** — доказано живой записью: `watched_at > 0`
|
||||
при `percent = 18`. Это просто «когда последний раз писали строку», ставится
|
||||
любым апдейтом таймкода.
|
||||
|
||||
**Порог по `percent`** — единственное надёжное. `percent = 18` = начал смотреть,
|
||||
не досмотрел → `[x]` НЕ ставить. Точное значение порога (`90`? `95`?) снять
|
||||
с живого досмотра: досмотреть фильм в Lampa, вычитать `percent`, записать факт сюда.
|
||||
|
||||
### 1.5 Что уже есть в `watchlist.json` — `tmdb_id` готов к матчу
|
||||
|
||||
`$H/lampac/wwwroot/watchlist.json` → `channels.*.items[]`, у **346/346** films есть `tmdb_id`.
|
||||
Матч делается по TMDB-ID, **без** хрупкого сравнения названий.
|
||||
`$H/lampac/wwwroot/watchlist.json` → `channels.{films,new,cartoons,anime}.items[]`.
|
||||
|
||||
**Поля позиции (ВСЕ, проверено):**
|
||||
```json
|
||||
{"name":"Простите за беспокойство","original":"Sorry to Bother You","year":2018,
|
||||
"rating":0,"image":"https://image.tmdb.org/t/p/w500/2QoxL3MMH8fvlHG7etFKfqLLnAe.jpg",
|
||||
"href":"https://www.themoviedb.org/movie/424781"}
|
||||
```
|
||||
|
||||
🔴 **TMDB-ID живёт ТОЛЬКО в `href`** (`.../movie/424781`). Отдельного поля `tmdb_id`
|
||||
в json позиции НЕТ — это описание парсера каталога, а не json-схемы.
|
||||
|
||||
🔴 **Поля с оригинальной строкой из `.md` в json НЕТ.** Alex предположил, что оно
|
||||
есть — проверено, отсутствует. Значит матч json↔`.md` идёт по `name` + `year`,
|
||||
и **обязан** использовать ту же нормализацию, что `parser._norm_title()`
|
||||
(срезает markdown-ссылку, `(2025)`, `IMDb 7.1 KP 6.6`, приводит к `[0-9a-zа-яё]`).
|
||||
Сырое имя не сравнивать — в `.md` строка выглядит так:
|
||||
```
|
||||
- [ ] ⬇️ [Под огнём](https://www.kinopoisk.ru/film/5455250/) (2025) IMDb 7.1 KP 6.6
|
||||
```
|
||||
|
||||
### 1.6 Мост TMDB ↔ KP через `.resolve_cache.json` — НЕ РАБОТАЕТ
|
||||
|
||||
Кэш резолвера: **483 записи, все не-null**. Структура:
|
||||
```json
|
||||
{"status":"ok","candidate":{"tmdb_id":412656,"kp_id":null,"title":"Поступь хаоса",
|
||||
"year":2021,"media_type":"movie","score":1.0,"rating":6.548,"genres":[14,878,12]}}
|
||||
```
|
||||
🔴 **`kp_id` = `null` у всех записей.** Ключ существует, значение пустое. Моста
|
||||
TMDB↔KP в кэше **нет**.
|
||||
|
||||
**Но он и не нужен.** `.md` хранит KP-ссылки (`kinopoisk.ru/film/`, 68 штук),
|
||||
`timecodes` — TMDB-ID. Прямого моста действительно нет, **однако цепочка замкнута
|
||||
через TMDB-ID**, который есть с обеих сторон:
|
||||
```
|
||||
timecodes.identity (TMDB) → watchlist.json.href (TMDB) → name+year → строка .md
|
||||
```
|
||||
KP в этой цепочке не участвует вообще.
|
||||
|
||||
⚠️ **Питфолл разведки:** поиск «есть ли kp_id» по подстроке в JSON-блобе дал
|
||||
ложное «458 записей с kp-полем» — потому что строка `"kp_id"` присутствует
|
||||
с `null`. Проверять **значение**, а не наличие ключа.
|
||||
|
||||
---
|
||||
|
||||
## 2. Решение
|
||||
|
||||
**Новый модуль в `watchlist-sync`: `sync_from_lampac.py`.**
|
||||
Читает `timecodes` → сопоставляет по `tmdb_id` → ставит `[x]` в `.md` (тем же
|
||||
`sync_up._mark_watched`, что уже работает для Jellyfin). Вызывается в конце
|
||||
`watchlist-nightly.sh` — после `sync-up`, перед `sync-vault (push)`.
|
||||
Читает `timecodes` → сопоставляет с `watchlist.json` по TMDB-ID из `href` →
|
||||
берёт `name` + `year` → находит строку `.md` по нормализованному названию →
|
||||
ставит `[x]` тем же `sync_up._mark_watched`, что уже работает для Jellyfin.
|
||||
Вызывается в конце `watchlist-nightly.sh` — после `sync-up`, перед `sync-vault (push)`.
|
||||
|
||||
**Цепочка матча (единственная рабочая):**
|
||||
```
|
||||
timecodes.identity "movie-1758655" / "1758655_movie"
|
||||
│ regex ^(?:(movie|tv)-)?(\d+)
|
||||
▼
|
||||
tmdb_id = 1758655
|
||||
│ watchlist.json: href = ".../movie/1758655"
|
||||
▼
|
||||
{name, year} → нормализация + год
|
||||
▼
|
||||
строка movies-watchlist.md → [x]
|
||||
```
|
||||
KP-ID (`kinopoisk.ru/film/`, 68 штук в `.md`) в цепочке **не участвует** —
|
||||
моста TMDB↔KP нет и не требуется.
|
||||
|
||||
Почему так, а не «писать в Jellyfin»: Jellyfin не источник просмотров и не имеет
|
||||
файлов для большинства позиций. Единственный честный источник — Lampa.
|
||||
|
||||
**Статус на конец сессии:** план готов, код **не написан**. Разведка закрыта
|
||||
(цепочка проверена, одна живая запись прогнана — матч дал 0, потому что фильм
|
||||
вне вотчлиста; это ожидаемо, не баг).
|
||||
|
||||
---
|
||||
|
||||
## 3. Шаги
|
||||
@@ -123,13 +206,16 @@ deleted = 0 И percent > 0 И watched_at > 0
|
||||
5. **Крон.** В `~/scripts/watchlist-nightly.sh` — новый вызов **после** `sync-up`,
|
||||
**до** `sync-vault (push)`. Правка через `sudo cp` (`~/scripts/` — `root:root 755`).
|
||||
Бэкап скрипта до правки. Сумма новой версии зафиксировать в доке.
|
||||
6. **Порог.** Критерий — `watched_at > 0` (документация: «просмотрено» — это
|
||||
`watched_at`, а не `percent`). Живая запись сейчас `percent=18, watched_at=0` —
|
||||
проходить не должна. Если в логе увидим `watched_at > 0` при `percent` ~20-40 —
|
||||
значит Lampa помечает как просмотренное раньше конца; тогда добавить нижний порог
|
||||
`percent >= 50` и перепроверить.
|
||||
6. **Порог.** 🔴 **По `percent`, НЕ по `watched_at`** — пересмотрено по факту
|
||||
(см. 1.4): `watched_at > 0` встречается при `percent = 18`. Стартовое значение
|
||||
`percent >= 90`. Уточнить с живого досмотра: досмотреть в Lampa, вычитать
|
||||
`percent`, вписать факт сюда. `percent = 18` проходить не должен.
|
||||
7. **Документировать** в `family/projects/watchlist-automation.md` (раздел про синк)
|
||||
+ ссылка из `personal/plans/lampac-watchlist-plugin.md`.
|
||||
8. **Проверка матча — обязательна до записи.** Прогнать `/tmp/probe_match.py`
|
||||
(цепочка `timecodes` → `watchlist.json` → `.md`) и **убедиться, что хоть одна
|
||||
позиция находится**. Если находится 0 — матч сломан, `--apply` не запускать.
|
||||
Сейчас: `1758655` в json не найден (вне watchlist) → 0 совпадений ожидаемо.
|
||||
|
||||
---
|
||||
|
||||
@@ -137,14 +223,19 @@ deleted = 0 И percent > 0 И watched_at > 0
|
||||
|
||||
| # | Граблю | Обход |
|
||||
|---|---|---|
|
||||
| 1 | `sqlite3` в контейнерах НЕТ | `docker cp` + `python3 -c "import sqlite3"` на хосте |
|
||||
| 1 | `sqlite3` в контейнерах НЕТ | `docker cp` + **файл-скрипт** `python3 /tmp/x.py` на хосте |
|
||||
| 2 | `~/scripts/` на Кра́кене `root:root 755` — `scp` даёт `Permission denied` | только `sudo cp` |
|
||||
| 3 | Кириллица в inline-ssh | **BLOCKED** tirith — писать скрипт файлом (`write_file`), не heredoc |
|
||||
| 4 | `identity` для сериалов = `{tmdb}_tv` + серия неизвестна | этап 1 — только фильмы; сериалы отдельно |
|
||||
| 4 | `identity` для сериалов = `tv-1851-s1e2`, серия в `card` | этап 1 — только фильмы; сериалы отдельно |
|
||||
| 5 | `percent` сбрасывается в `0` при `deleted` | фильтровать `deleted = 0` |
|
||||
| 6 | Матч по названию ломается на год/рейтингах | матч **только** по `tmdb_id`, строгий |
|
||||
| 7 | `timecodes` пишу сам `TimeCode`, при рестарте лампака не теряется (SQLite на хосте) | ок |
|
||||
| 6 | Матч по названию ломается на год/рейтингах | нормализация `_norm_title()` + год как второй ключ |
|
||||
| 7 | `timecodes` переживает рестарт лампака (SQLite на хосте, не в контейнере) | ок |
|
||||
| 8 | Крон-файлы возвращать только `crontab /tmp/файл`; бэкап `crontab -l > f` обязателен | — |
|
||||
| 9 | 🔴 **`identity` бывает в ДВУХ формах** (`movie-674` и `674_movie`) | regex `^(?:(movie\|tv)-)?(\d+)` |
|
||||
| 10 | 🔴 **`watched_at` не признак досмотра** — бывает `>0` при `percent=18` | порог только по `percent` |
|
||||
| 11 | 🔴 **inline `python3 -c` уходит на апрув и истекает** | все пробы — файлами |
|
||||
| 12 | **`ssh kraken` резолвится в мёртвый `.15`** | работать через `kraken@192.168.1.14` |
|
||||
| 13 | Длинные `ssh` + тяжёлый `jq` рвут соединение («banner exchange») | разбивать на короткие команды, тяжёлое — файлом |
|
||||
|
||||
---
|
||||
|
||||
@@ -168,27 +259,78 @@ deleted = 0 И percent > 0 И watched_at > 0
|
||||
|
||||
---
|
||||
|
||||
## 7. Открытый вопрос (задан Alex 2026-09-23, ответа нет)
|
||||
## 7. Открытый вопрос — ЗАКРЫТ документацией ✅
|
||||
|
||||
Как именно в Lampa ставится «просмотрено» — **вручную кнопкой** или **автоматически
|
||||
при досмотре до конца**? От этого зависит порог в шаге 6:
|
||||
Alex сказал «в душе не ебу как она там ставится, ищи документацию» — и был прав.
|
||||
Ответ найден в README модуля, вопрос задавать не следовало.
|
||||
|
||||
| Как ставится | Какая колонка сработает |
|
||||
|---|---|
|
||||
| Вручную кнопкой | `watched_at > 0` (Lampa кладёт `updated` в `watched_at`) |
|
||||
| Автодосмотр до конца | `percent >= 90` |
|
||||
**README `TimeCode`, раздел «Нативные клиенты»:**
|
||||
|
||||
В плане заложены **оба условия одновременно** (`percent >= 90` **ИЛИ** `watched_at > 0`) —
|
||||
работает в любом случае, но при ответе Alex можно сузить и убрать ложные срабатывания.
|
||||
> **«Отдельного флага "просмотрено" нет: это `percent`. road Lampa его не несёт
|
||||
> и не несла никогда, порог завершённости — политика клиента, а не свойство записи.»**
|
||||
|
||||
То есть порог — **политика клиента** (Lampa на ТВ), сервер его не знает и не хранит.
|
||||
Отсюда: единственный переносимый признак — `percent`, и значение порога надо
|
||||
взять у клиента, а не у сервера.
|
||||
|
||||
**Дополнительно опровергнуто фактом:** живая запись дала `watched_at > 0` при
|
||||
`percent = 18`. Значит `watched_at` — «когда последний раз писали строку»,
|
||||
а не «досмотрел». Использовать его как критерий — ошибка.
|
||||
|
||||
**Как снять точный порог (следующая сессия):**
|
||||
1. Досмотреть в Lampa фильм **из вотчлиста** (не `1758655` — его нет в json).
|
||||
2. Вычитать `percent` из `timecodes` (через `/tmp/probe_match.py`).
|
||||
3. Вписать наблюдённое значение в этот раздел и в шаг 6.
|
||||
|
||||
---
|
||||
|
||||
## 8. Связанные находки этой сессии (не часть плана, но проверено)
|
||||
|
||||
- **Стек после ребута:** 14/14 контейнеров поднялись сами, Radarr/Sonarr queue `0`,
|
||||
Transmission 9 торрентов всё `Done/Idle`, диск 31%, Lampac 200 / Jellyfin 302.
|
||||
Ночные скрипты (cleanup 02:00, nightly 01:00, catalog 02:30) отработали.
|
||||
Записано в [[family/projects/watchlist-automation]].
|
||||
- **🔴 Лог `nightly` живёт в `/tmp/watchlist-nightly.log`** → умирает при ребуте.
|
||||
Сегодняшний прогон следа не оставил. Предложен фикс (перенести в `~/logs/`),
|
||||
ждёт команды. Остальные логи уже в `~/logs/`.
|
||||
### 8.1 Стек после ребута
|
||||
|
||||
14/14 контейнеров поднялись сами, Radarr/Sonarr queue `0`, Transmission 9 торрентов
|
||||
всё `Done/Idle` (Sum down 0.0), диск 31% (539G/1.8T), Lampac `:9118` → 200,
|
||||
Jellyfin `:8096` → 302. Ночные скрипты отработали: cleanup 02:00, nightly 01:00,
|
||||
catalog 02:30–02:32 (каналов 4, позиций 392, `.md` 708 строк / 615 позиций).
|
||||
Vault git чистый. Записано в [[family/projects/watchlist-automation]].
|
||||
|
||||
### 8.2 🔴 Лог `nightly` живёт в `/tmp/` → умирает при ребуте
|
||||
|
||||
Крон: `0 1 * * * bash ~/scripts/watchlist-nightly.sh >> /tmp/watchlist-nightly.log`.
|
||||
`/tmp` чистится при перезагрузке — сегодняшний прогон следа не оставил, вывод
|
||||
восстановлен только косвенно (по mtime артефактов). Остальные логи уже
|
||||
в `~/logs/` (`watchlist-catalog.log`, `watchlist-cleanup.log`). Фикс (перенести
|
||||
в `~/logs/`) предложен, ждёт команды Alex.
|
||||
|
||||
### 8.3 🔴 `ssh kraken` резолвится в МЁРТВЫЙ адрес
|
||||
|
||||
`ssh kraken` → DNS отдаёт **`192.168.1.15`** → порт 22 открыт, но sshd рвёт
|
||||
соединение на `banner exchange`. Рабочий адрес — **`192.168.1.14`** (проверено:
|
||||
`ALIVE_14`, uptime 6:27, load 0.02).
|
||||
|
||||
Причина в `~/.ssh/config`: proxy-команда
|
||||
```
|
||||
if ifconfig | grep -q 10.99.0.2; then nc 10.99.1.2 22; else nc kraken 22; fi
|
||||
```
|
||||
На Mac интерфейса с `10.99.0.2` **нет** → уходит на `nc kraken 22` → мёртвый `.15`.
|
||||
WG-туннель до Кра́кена не поднят.
|
||||
|
||||
**Обход до восстановления WG:** всегда `ssh kraken@192.168.1.14` явно.
|
||||
**Проверка:** `nc -z -w 5 192.168.1.14 22`.
|
||||
|
||||
### 8.4 Commit незакоммиченных фиксов сирот
|
||||
|
||||
В рабочем дереве `watchlist-sync` висели незакоммиченные правки, которые **уже
|
||||
работали боевым прогоном**: `cli.py` (+7) и `parser.py` (+65) — фикс «ОСИРОТЕВШИЕ
|
||||
СТРОКИ» в `process_thumbs()` + явные ветки вывода `👍/👎/[x]/[drop]`.
|
||||
Закоммичены отдельным коммитом **`ffe7974`** (не смешаны с новым кодом).
|
||||
|
||||
`_mark_watched` в `sync_up.py` **уже содержит** фикс эмодзи-префикса (`_PREFIX`
|
||||
поглощает эмодзи с обеих сторон `⬇️`) — переиспользуется без правок.
|
||||
|
||||
### 8.5 Внешний TMDB API с Кра́кена недоступен
|
||||
|
||||
`curl https://api.themoviedb.org/3/movie/...` без ключа → `Invalid API key`.
|
||||
Ключ живёт в `$WS/.env` (`TMDB_KEY`), прямой вызов из шелла не проходит.
|
||||
Для проверки названий использовать `watched_at`-путь через `watchlist.json`,
|
||||
а не TMDB API.
|
||||
@@ -50,13 +50,26 @@ route -n get 192.168.2.197 # на Mac: какой gateway?
|
||||
|
||||
| Узел | Доступ | Статус 2026-09-23 |
|
||||
|---|---|---|
|
||||
| Кра́кен `192.168.1.15` | `ssh kraken` (через `~/.ssh/config`) | ✅ работает |
|
||||
| Кра́кен `192.168.1.15` | ~~`ssh kraken`~~ | 🔴 **СЛОМАНА**: DNS отдаёт `.15` (wlan0, metric 600) → порт 22 открыт, но sshd рвёт на `banner exchange`. Рабочий адрес — `192.168.1.14` |
|
||||
| Кра́кен `192.168.1.14` | `ssh kraken@192.168.1.14` | ✅ **работает** именно так (eth0, активный) |
|
||||
| ASUS `192.168.1.1` | ~~`ssh -i ~/.ssh/id_rsa admin@192.168.1.1`~~ | ❌ **НЕ работает**: `Permission denied` → `Connection closed`. `nc -z 192.168.1.1 22` → closed. Маршруты — только веб-UI |
|
||||
| HTPC `192.168.1.86` | `ssh -i ~/.ssh/id_rsa bazzite@192.168.1.86` | (не проверялся в этой сессии) |
|
||||
| TrueNAS | `ssh truenas_admin@mallexxx.duckdns.org` | ✅ работает |
|
||||
| OpenWrt `192.168.2.2` | `ssh root@192.168.2.2` (прямой, по ключу) | (не проверялся в этой сессии) |
|
||||
|
||||
⚠️ **У Кра́кена ДВА IP** — `.14` (eth0, активный default metric 100) и `.15` (wlan0, metric 600). `~/.ssh/config` резолвит `kraken` на `.15`. При построении маршрутов учитывать оба.
|
||||
⚠️ **У Кра́кена ДВА IP** — `.14` (eth0, активный default metric 100) и `.15` (wlan0, metric 600). **Работать через `.14`.**
|
||||
|
||||
🔴 **`ssh kraken` (голый хостнейм) НЕ РАБОТАЕТ с 2026-09-23.** Причина — proxy-команда в `~/.ssh/config`:
|
||||
```
|
||||
if ifconfig | grep -q 10.99.0.2; then nc 10.99.1.2 22; else nc kraken 22; fi
|
||||
```
|
||||
На Mac интерфейса с `10.99.0.2` **нет** (WG-туннель до Кра́кена не поднят) → ветка `else` → `nc kraken 22` → DNS отдаёт мёртвый `.15` → `kex_exchange_identification: Connection closed by remote host`.
|
||||
|
||||
**Обход:** всегда `ssh kraken@192.168.1.14` (или `ssh -o ... kraken@192.168.1.14`).
|
||||
**Проверка живости:** `nc -z -w 5 192.168.1.14 22 && echo OK`.
|
||||
**Заодно:** `ssh kraken` идёт через proxy, поэтому тяжёлые команды и длинные `jq` рвут соединение заметно чаще — дробить команды.
|
||||
|
||||
🔴 **Симптом-ловушка:** обрыв SSH выглядит как «хост упал» / «контейнеры лежат». **Сначала проверить адрес и `ping`/`nc`**, а не лезть в `docker ps`. В этой сессии так и было: хост пинговался и был жив, load 0.02, `uptime 6:27` — сломан был только маршрут ssh.
|
||||
|
||||
## Прочие заметки из skill (краткая выжимка)
|
||||
|
||||
|
||||
Reference in new issue
Block a user