diff --git a/family/projects/watchlist-automation.md b/family/projects/watchlist-automation.md index 4ab9e19a..d8d63ead 100644 --- a/family/projects/watchlist-automation.md +++ b/family/projects/watchlist-automation.md @@ -513,28 +513,44 @@ Docker: 29.4.3, Debian 12 bookworm, **arch `aarch64`**, 25 контейнеро **Корень:** захардкоженный `qualityProfileId: 1` (профиль `Any`) в `arr.py` — починен только 2026-09-04. Всё, что качалось до этого, брало remux'ы по 60–98 ГБ. -### 🔴 Метки `⬇️` на 4 из 5 remux'ов В watchlist НЕТ +### ✅ ИСПРАВЛЕНО 2026-09-21: ВСЕ 5 фильмов ЕСТЬ в watchlist -Проверено грепом по `family/documents/movies-watchlist.md`: +> ⚠️ **Ранее в этой доке стояло ошибочное «Schindler's List не найден в файле».** Это был **ложный вывод +> из одностороннего грепа**: фильм записан **по-русски** — «Список Шиндлера» (строка 396), +> а искали по латинице. Alex поправил. +> **Правило: искать и ru, и en — `grep -i "schindler\|шиндлер\|список"` — ПРЕЖДЕ чем утверждать «нет в списке».** -| Фильм | Строка в watchlist | Метка | +| Фильм | Строка в watchlist | Метка `⬇️` | |---|---|---| | Неистовый (Unhinged) | **107**: `- [x] ⬇️ Неистовый` | ✅ есть (и `[x]`) | -| Babylon (2022) | **83**: `- [ ] Babylon (2022)` | ❌ нет | -| Midsommar | **81**: `- [ ] 🧟♀️ midsommar 2019` | ❌ нет | -| Triangle of Sadness | **82**: `- [ ] Triangle of Sadness 2022` | ❌ нет | -| Schindler's List | **не найден в файле** | ❌ нет | +| Список Шиндлера | **396**: `- [ ] ⬇️ Список Шиндлера` | ✅ есть | +| Babylon (2022) | **83**: `- [ ] Babylon (2022)` | ❌ **потеряна** (баг `mark_queued`) | +| Midsommar | **81**: `- [ ] 🧟‍♀️ midsommar 2019` | ❌ **потеряна** | +| Triangle of Sadness | **82**: `- [ ] Triangle of Sadness 2022` | ❌ **потеряна** | -**Вывод:** `sync-down` помечает `⬇️` только то, что добавил сам. Эти 4 попали в Radarr другим путём (вручную / до появления меток). Снимать метку не с чего — кроме Неистового. +**Корень потери 3 меток — баг `mark_queued` (`parser.py:77`):** regex требует название **сразу** после `- [ ]`, +но перед ним бывает эмодзи (`- [ ] 🧟‍♀️ midsommar 2019`) → не матчит; при провале функция **молча ничего не пишет** +(`if new_text != text`), а `sync_down.py` её результат **не проверяет**. Детали — [[family/plans/watchlist-disk-overflow-fix]], Фаза 1. -### Порядок работ, согласованный с Alex +### ❌ «Восстановить потерянные `⬇️`» — отменено (неверная постановка) -1. **Удалить 5 remux-файлов** (403.4 ГБ) → диск оживает → Radarr API заработает. -2. **Снять `⬇️` у Неистового** (строка 107). `[x]` — **не трогать** (это отметка просмотра). -3. **Добавить `MIN_FREE_GB` в скрипт** — стоп-кран перед добавлением в Radarr. -4. ⚠️ Лимит качества Alex считает уже настроенным (`WEB-4K (no remux)`, id 7) — **новый лимит не делаем**. +`⬇️` = «добавлен в Radarr / качается». После удаления файлов метка должна быть **снята**, а не восстановлена. +У Babylon/Midsommar/Triangle метки и не было → **ничего не делать** (консистентно: файла нет, метки нет). +Снять `⬇️` нужно у **Списка Шиндлера** (396 → `[ ]`) и **Неистового** (107 → `[x]`, `[x]` не трогать). +⚠️ Функции `unmark_queued()` в коде **НЕТ** — писать в рамках Фазы 1. -⚠️ Удаление **напрямую файлами**, не через Radarr API — API лежит на заполненном диске. Radarr пересканирует и увидит `hasFile=false`. +### ✅ Порядок работ — Фазы 0 и 0b ВЫПОЛНЕНЫ (2026-09-21) + +1. ✅ **Удалены 5 remux-файлов** (403 ГБ) → `df` 100% → **77%**, свободно 404 ГБ → Radarr API ожил (49 фильмов). + Удаление — **файлами напрямую** (`rm` по точным путям), не через Radarr API (тот лежал). Папки с `.nfo`/постерами не тронуты. +2. ✅ **Radarr: `RescanMovie` + снятие `monitored`** у id 4/18/35/36/37 → все `monitored=false`, `hasFile=false`. + ⚠️ **Без этого Radarr перекачал бы все 403 ГБ.** Порядок: `monitored=false` через PUT **до** любого поиска. +3. ⏸ **Снять `⬇️`** у Шиндлера (396) и Неистового (107) — ждёт `unmark_queued()`. +4. ⏸ **`MIN_FREE_GB` в `sync-down`** — стоп-кран. Порог (предложение 100 ГБ) **не согласован с Alex**. +5. ⚠️ Лимит качества Alex считает уже настроенным (`WEB-4K (no remux)`, id 7) — **новый лимит не делаем**. + +**Бэкапы:** `~/backup-movies-watchlist-20260921-150759.md`, `~/backup-radarr-unmonitor-20260921-151117.json`, +`~/crontab-backup-20260921.txt`. Скрипты: `/tmp/rm_remux.sh`, `/tmp/unmonitor_remux.sh`. ### Остановка крона (сделано 2026-09-21) @@ -691,9 +707,11 @@ Jellyfin library mapping: Movies → `movies`, Cartoons → `mixed` (movies + ep - 🟡 **[2026-09-20] Логи крона в `/tmp/`** — теряются при перезагрузке. Перенести в постоянное место (`~/logs/` или на диск), если нужна история прогонов. - ✅ **[2026-09-21] Удаление просмотренных фильмов при заполнении диска >90% — ЗАКРЫТО И В КРОНЕ.** Обёртка `~/scripts/watchlist-cleanup.sh` (была в `/tmp` — перенесена через `sudo install`, у kraken sudo **без пароля**), cron `0 2 * * * ... --apply`, лог `/home/kraken/logs/watchlist-cleanup.log`. **Корзина Radarr (`recycleBin`) — решено НЕ настраивать** (контейнерный/хостовый пути расходятся; Alex больше не переспрашивать). Обёртка по умолчанию делает **dry-run** — без `--apply` в кроне был бы вечный холостой ход. Полные детали — [[family/plans/watchlist-cleanup]]. ⚠️ Питфолл: `/media` — **не медиа-диск**, а пустая папка на SD-карте (`/dev/mmcblk0p2`), отдаёт 33.9%. Реальный диск `/dev/sda1` в `/srv/dev-disk-by-uuid-6194539b-.../`. Использовать `os.statvfs`, не `shutil.disk_usage("/media")`. -- 🔴 **[2026-09-21] ДИСК ЗАПОЛНЕН 100% (0 байт свободно). `nightly` + `discover` ОСТАНОВЛЕНЫ.** Работал `sync-down --batch 5` ежедневно без проверки места. Radarr лёг с `disk I/O error` (SQLite не может писать). Полный разбор — в секции «🔴 2026-09-21: ДИСК ЗАПОЛНЕН 100%» выше. Бэкап crontab: `~/crontab-backup-20260921.txt`. -- 🔴 **[2026-09-21] ЖДЁТ АПРУВА ALEX: удаление 5 remux-файлов = 403.4 ГБ.** Babylon 92.0 / Schindler's List 89.4 / Midsommar 85.6 / Triangle of Sadness 79.7 / Unhinged 56.7 ГБ. Удалять **файлами напрямую** (Radarr API лежит). Затем снять `⬇️` у Неистового (строка 107), `[x]` не трогать. ⚠️ У 4 из 5 метки `⬇️` в watchlist нет; Schindler's List в файле отсутствует вовсе. -- 🔴 **[2026-09-21] ФАЗА 1 РЕМОНТА: добавить `MIN_FREE_GB` в `sync-down`.** Стоп-кран: если свободно < порога — не добавлять в Radarr. **Главный фикс**, без него возврат крона бессмыслен. Лимит качества Alex считает уже настроенным — **новый не делать**. +- ✅ **[2026-09-21] ДИСК ОСВОБОЖДЁН: 100% → 77%, свободно 404 ГБ.** Удалены 5 remux-файлов (403 ГБ); в Radarr снят `monitored` у id 4/18/35/36/37 (`hasFile=false`) — иначе он перекачал бы всё заново. Radarr API ожил (49 фильмов). Бэкапы: `~/backup-movies-watchlist-20260921-150759.md`, `~/backup-radarr-unmonitor-20260921-151117.json`. +- ⏹ **[2026-09-21] `watchlist-nightly` + `watchlist-discover` ОСТАНОВЛЕНЫ** (диск был 100%, `sync-down --batch 5` без проверки места). Бэкап crontab: `~/crontab-backup-20260921.txt`. **Вернуть только после Фаз 1–2, с `--batch 2`.** Активен пока только `watchlist-cleanup` (02:00). +- 🔴 **[2026-09-21] ФАЗА 2 РЕМОНТА (главный фикс): `MIN_FREE_GB` в `sync-down`.** Стоп-кран: если свободно < порога — не добавлять в Radarr. Порог **не согласован** (предложение 100 ГБ, свободно 404). Без этого возврат крона бессмыслен. Лимит качества Alex считает уже настроенным — **новый не делать**. +- 🔴 **[2026-09-21] ФАЗА 1 (не начата): фикс `mark_queued` + `unmark_queued`.** `parser.py:77` — regex не учитывает эмодзи-префикс (`- [ ] 🧟‍♀️ midsommar 2019`), при провале **молча не пишет**. Нужно: опциональные маркеры в паттерне, возврат `bool`, проверка результата в `sync_down.py` (строки 98/104/113/122). Плюс `unmark_queued()` для снятия `⬇️` (у Шиндлера 396 и Неистового 107). +- 🔴 **[2026-09-21] ФАЗА 3 (не начата): фильтр ужасов + `⭐ > 🧟`.** Точка правки — `sync_down.py:54` (расширить существующий фильтр рейтинга). Правило Alex: ужас + `⭐` → качаем; ужас без `⭐` → пропускаем. ⚠️ **Под фильтр попадает 41 строка `🧟‍♀️`** (включая свежие релизы 2025–2026) — масштаб подтверждён Alex. - 🔴 **[2026-09-21] КОРЕНЬ: `[x]` не проставляется на новые закачки.** `sync-up` (Jellyfin watched → `[x]`) видит только 6 старых фильмов из `/media/movies`, ни одного из `/media/movies-radarr`. Пока это не починено, cleanup бесполезен, а диск будет заполняться. - 🔴 **[2026-09-21] ДИСК КРИТИЧЕН: 94.7% / свободно 4.8 ГБ (замер до полного заполнения).** Порог 90% пройден, cleanup реально запускается, но **удаляет 0 файлов**: пересечение `[x]` ∩ Radarr-библиотека = **пусто** (177 просмотренных vs 28 фильмов с файлами). - 🟡 **[2026-09-21] Cleanup не видит `/media/movies`** — смотрит только Radarr-библиотеку, поэтому просмотренное из папки ручных торрентов не удаляется. Расширять — отдельно и осторожно (удаление файлов). diff --git a/personal/tech/inter-site-throughput-taiga-to-mac.md b/personal/tech/inter-site-throughput-taiga-to-mac.md index c43793e2..6ddf4393 100644 --- a/personal/tech/inter-site-throughput-taiga-to-mac.md +++ b/personal/tech/inter-site-throughput-taiga-to-mac.md @@ -169,3 +169,111 @@ Moonfin/Breezyfin **НЕ дадут 120 Мбит** — они не распар 5. По результату: сеть → лимит битрейта или prefetch-proxy; кодек → подбор профиля. **Статус: план предложен, Alex решения не дал. Ничего не менялось — ни на TrueNAS, ни на ТВ, ни в туннелях.** + +--- + +## ❌ «Поднять несколько xray-туннелей» — почему НЕ поможет (разобрано 2026-09-21) + +**Прямой вопрос Alex:** *«что помешает поднять несколько xray tunnels и использовать их? в тесте speedtest 120mbit показывало через наш реверс туннель»* + +**Ответ: ничего не помешает поднять, но скорости это не даст.** + +`speedtest` = **8 параллельных TCP-сессий**, каждая со своим congestion window → 8 × ~15 Мбит = 120. +Это доказывает, что **канал** пропускает 120 Мбит. НЕ доказывает, что **одна** сессия их возьмёт. + +**Скорость одной TCP-сессии ≈ окно / RTT.** Для 120 Мбит при RTT 104 мс нужно ~1.5 МБ неподтверждённых данных «в полёте». +Одна сессия так разгоняется только при отсутствии потерь; на межоператорском стыке потери есть → окно режется вдвое → +стабилизируется на 28–45 Мбит (наши замеры 2026-09-02). Jellyfin отдаёт видео **одним потоком** → упирается в это. + +| Подход | Независимых окон | Даст 120 Мбит? | +|---|---|---| +| speedtest (8 сессий) | ✅ 8 | ✅ | +| **Клиент с Range-запросами / prefetch-proxy** | ✅ N | ✅ **правильный путь** | +| Jellyfin webOS штатный | ❌ 1 | ❌ ~28–45 | +| **8 xray-туннелей + mux** | ❌ одно логическое окно | ❌ head-of-line blocking | +| MPTCP по одному физическому пути | ❌ | ❌ | + +**MPTCP/bonding агрегируют РАЗНЫЕ физические пути.** У нас путь один: ТТК → Ростелеком (хоп 8, +50 мс). +N туннелей по одному пути делят один congestion window → суммарно **не больше одного**, плюс оверхед инкапсуляции. +**Единственный честный путь к реальной агрегации — второй независимый ISP.** + +### ⚠️ Питфолл объяснения: аналогия «узкая труба» НЕ работает +Первое объяснение было через метафору трубы — Alex: *«ниче не понял в твоей аналогии с трубой»*. +Метафора прятала механизм. **Рабочая формулировка — через ЧИСЛО СЕССИЙ:** +«канал пропускает 120 Мбит, но только если запрашивать 8 потоками ОДНОВРЕМЕННО; одна сессия возьмёт ~28–45, потому что +не может разогнать своё окно на 104 мс RTT». Объяснять механизмом, не метафорой. + +### 🔴 Многопоточный HLS в Jellyfin / hls.js — есть в планах, НЕ реализован + +| Где | Статус | Факт | +|---|---|---| +| **Jellyfin** feature request #2171, 230 голосов | ✅ **Planned** (maintainer Joshua M. Boniface) | *«Jellyfin currently streams using only one connection»*. Но issue #3206 (2020) закрыт как **stale**, #6724 — как feature request. **За 5 лет кода нет.** | +| **hls.js** issue #6753 (окт 2024) | milestone 1.8.0, «Top priorities», **PR отсутствует** | Предлагает префетч **2–5 сегментов одновременно** («Concurrent Loading»). Ровно наш механизм — но не сделано | +| **ExoPlayer** issue #5978 | proposal | Параллельные DASH/HLS-сегменты. Android, не webOS | +| **webOS-клиенты** | ❌ невозможно | Нативный video element = чёрный ящик, число соединений не настраивается. Moonfin/Breezyfin/официальный — все однопоточны | + +**Вывод: ждать нечего.** Ни от обновления Jellyfin, ни от новых клиентов. Реальные многопоточные решения — +только **внешние прокси/префетчеры** (см. «Готовые инструменты для prefetch-proxy»). + +--- + +## 🆕 Lampac — самохостируемый backend для Lampa (рассмотрен 2026-09-21, НЕ внедрён) + +**`lampac-nextgen/lampac`** (форк `immisterio/Lampac`) — ASP.NET Core (.NET 10), MIT, `linux/amd64`+`linux/arm64`. +Порт по умолчанию **9118**. Ставится **одним контейнером** и отдаёт плагины самой Lampa. + +**Закрывает сразу всё, что разбиралось по частям:** + +| Компонент | Что даёт | +|---|---| +| **TorrServer** | встроен как subprocess — отдельный контейнер не нужен | +| **JacRed** | агрегатор торрент-индексаторов, **Jackett-совместимый** | +| **GStreamer** | **HLS/fMP4 транскод** (заменяет legacy FFmpeg, плагин `/gst.js`) — решает MKV/HEVC-проблему webOS | +| **LampaWeb** | хостит саму Lampa UI + собирает widgets: `/lg.ipk` для LG webOS, `/samsung.wgt` для Tizen | +| **TmdbProxy** | локальный кэш TMDB API | +| **DLNA/UPnP**, Tracks, Sync, TimeCode, Playwright, WAF, GeoIP | прочее | + +**Установка (Docker):** +```bash +git clone https://github.com/lampac-nextgen/lampac.git && cd lampac +mkdir -p lampac-docker/config lampac-docker/plugins +cp config/example.init.conf lampac-docker/config/init.conf +printf '%s' 'пароль_root' > lampac-docker/config/passwd +# раскомментировать volumes в docker-compose.yaml +docker compose up -d +curl -fsS "http://localhost:9118/version?type=hash" # проверка +# плагин для Lampa: http://:9118/online.js +``` +⚠️ В контейнере рабочий каталог `/lampac`, файлы читаются **из корня**, не из `config/`. Volumes по умолчанию закомментированы. + +### 🔴 Главное ограничение — Lampac НЕ решает проблему узкого канала сам по себе + +TorrServer внутри Lampac работает **на том же хосте, что и Lampac**. + +``` +Lampac на Кра́кене: пиры → Кра́кен → [УЗКИЙ КАНАЛ, 1 TCP] → ТВ ← лимит остаётся +Lampac в Бишкеке: пиры → Mac → [быстрая локалка] → ТВ ← лимит обойдён +``` + +Alex **отверг вариант с Mac**: *«нахуя нам блядь на маке что-то! на кракене блядь бэкенд»*. +Значит Lampac на Кра́кене решает только участок «пиры → Кра́кен». + +**Но у Lampac есть то, чего не было в других вариантах:** встроенный **GStreamer HLS-транскод** → +можно отдать ТВ поток 10–15 Мбит одним потоком, и он пройдёт. Это **не «обойти лимит», а «сделать поток лёгким»** — +другое решение той же проблемы. + +### 🚧 Блокер на момент рассмотрения (снят 2026-09-21) +Диск Кра́кена был **100%** (0 байт) → Lampac не поставить, TorrServer некуда кэшировать. +Плюс `/` (SD-карта) — всего 8.4 ГБ свободно, кэш торрентов туда не влезет. +**Диск освобождён до 77% / 404 ГБ** (см. [[family/plans/watchlist-disk-overflow-fix]]) — блокер снят, +но решение по Lampac **ещё не принято**. + +### Альтернатива: TorrServer прямо на ТВ +**`6ebeng/torrserver-webos`** — TorrServer как webOS-приложение (.ipk), webOS 4.x–9.x, rooted и unrooted. +Управление с любого устройства на `http://:8090`. Бинарник зашит в .ipk (32-bit ARM), работает offline. +⚠️ **Плеер — встроенный HTML5 `