6.9 KiB
title, namespace, created, updated, last_synced, type, tags, confidence
| title | namespace | created | updated | last_synced | type | tags | confidence | ||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Media Pipeline — Pitfalls & Debug Notes | work | 2026-05-16 | 2026-05-20 | 2026-05-20 | entity |
|
high |
Media Pipeline — Pitfalls & Debug Notes
Операционные заметки по Swift media-pipeline (media_files_db / media-toolbox) на Кракене. Связано: personal-os-architecture, tech/kraken-network
§9.x Score Engine — Критические питфолы
§9.9 Year tiebreak:
if count > 1only — НИКОГДА не штрафовать единственного кандидата- Если кандидат один — year mismatch не является причиной для снижения score
§9.6 Subset floor:
- Floor 0.35 когда queryToks ⊆ candidateToks (запрос является подмножеством кандидата)
- Это нормально — не считать subset-матч за слабый результат
False resolves:
- Проверять поле
title:— если в title шум из имени файла =hasBestEffortResultjunk, не настоящий resolve - Пример:
2001 Космическая одиссея.mkv→ title:2001 Космическая одиссея.mkv= junk
Транслитерация
transliteratedToLatinдля кириллических названий генерирует мусорные запросы — TMDb не находитMigratsiya- Решение: не эмитить lat-запросы когда источник уже кириллица
transliteratedToCyrillicиз латинских имён — полезен (Osnovnoi→Основной Инстинкт→ TMDb находит)
KP (Кинопоиск) Rate Limit
- KP — настоящий fallback, дёргается только если TMDb не дал winner
- 40 KP-запросов vs 8428 TMDb в типичном прогоне
- Лимит исчерпывается только после очистки кеша когда весь TMDb идёт заново
- Проблема не в архитектуре — это нормально
- KP API URL смена домена (Баг 8):
api.kinopoisk.dev→api.poiskkino.dev. Swift URLSession при редиректе теряетX-API-KEY→ пустые ответы кешируются. Фикс: обновить URL, добавитьshouldCache: ((Data) -> Bool)?— не кешировать пустойdocs.
Docker Deploy — Kraken (обязательный порядок)
После каждого деплоя обязательно чистить dangling images, иначе диск забивается (~1-2GB за прогон):
# Mac (после docker build)
docker image prune -f
# Kraken (после docker load)
ssh kraken "docker image prune -f"
Полная последовательность деплоя:
# 1. Собрать
docker build -f Dockerfile.kraken -t media-pipeline:kraken .
# 2. Перенести
docker save media-pipeline:kraken -o /tmp/mp.tar
scp /tmp/mp.tar kraken:/tmp/
ssh kraken "docker load -i /tmp/mp.tar && rm /tmp/mp.tar && docker image prune -f"
rm /tmp/mp.tar
# 3. Почистить локально
docker image prune -f
Docker Run — Kraken
Всегда монтировать unresolved.json явно:
docker run \
-v "$(pwd)/config.json:/config/config.json:ro" \
-v "/media:/media" \
-v "$(pwd)/cache:/cache" \
-v "$(pwd)/unresolved.json:/config/unresolved.json" \
media-pipeline
Без явного маунта unresolved.json пишется внутри контейнера и теряется.
Пофикшенные баги (сессии 2026-05)
Code=516 EEXISTв ApplyPhase — исправлен- Episode regex
\bboundary — исправлен - BBC prefix strip + trim — исправлен
- Yoficator Linux path — исправлен
- Backtick в TitleParser (
/[^'\p{L}\p{N}]+/→ strip apostrophes first) — исправлен - §9.6 subset floor 0.35 — добавлен
- §9.9 year tiebreak
count>1only — исправлен - Year-miss retry в TMDb/KP providers — добавлен
- KP API URL (
api.poiskkino.dev) + пустой-docs no-cache — исправлен - Leet-speak в транслите (
4=ч):String.decodeLeetSpeak()— исправлен - Год
2023г(кириллическоег):(19|20)\d\d)г\bпаттерн — исправлен TitleParser _year_underscore boundary:\b→(?<![0-9])..(?![0-9])— исправлен (Баг 12)OutputConfigcartoons/documentariesне optional в JSON:decodeIfPresent— исправленxvid/divxне в quality markers list — исправлен- TitleParser: год как название фильма (1984, 2001) → safety guard ≥2 букв перед — исправлен
Трекер-парсеры (Steps A-C, 2026-05-17)
TrackerPageParserRegistry — dispatch по url.host:
RutrackerPageParser— CP1251/iconv, SwiftSoup, жанры из заголовка, KP/IMDb IDsRutorPageParser,NNMClubPageParser— структура реализована, требует fixture тестовTrackerMediaKindenum: movie/series/cartoon/documentary/music/audiobook/game/book/unknownextractMediaKind— детект поBB.catId/FORUM_IDна странице (100+ forum IDs)
DirectoryPolicy / MatchPolicy / MoveStrategy:
FileAction.transmissionMove(torrentId:, from:, to:)— CodablebuildMovieActionsчитает policy,needsSymlink,needsNFO,effectiveOutputDirtransmissionMoveкогда естьtorrentId, иначеmove
⚠️ transmissionMove генерируется только если scanner создал регион (нужен video файл).
Музыка/книги/игры из downloads не перекладываются — нет videoExtensions для аудио (Шаг D, pending).
Agent/Sync Pitfall — Duplicate unresolved
Проблема: agent пишет canonical dir в /media/library/, но sync при следующем запуске снова добавляет файл в unresolved (нет source marker).
Фикс: updateUnresolvedStore проверяет allOutputDirs на существующий canonical dir → пропускает. Файл: PipelineRunner.swift.
QuerySnapshotGenerator
При изменениях в TitleParser/NameTokenization/QueryBuilder снапшоты в тестах устаревают.
Регенерация: swift run QuerySnapshotGenerator из корня репо.
НЕ использовать SNAPSHOT_TESTING_RECORD=all — крашит при 364 concurrent writes (SIGSEGV).