Files
obsidian-vault/wiki/tech/media-pipeline-pitfalls.md
T

6.9 KiB
Raw Blame History

title, created, updated, type, tags, confidence
title created updated type tags confidence
Media Pipeline — Pitfalls & Debug Notes 2026-05-16 2026-05-18 entity
media-pipeline
swift
pitfalls
debugging
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 > 1 only — НИКОГДА не штрафовать единственного кандидата
  • Если кандидат один — year mismatch не является причиной для снижения score

§9.6 Subset floor:

  • Floor 0.35 когда queryToks ⊆ candidateToks (запрос является подмножеством кандидата)
  • Это нормально — не считать subset-матч за слабый результат

False resolves:

  • Проверять поле title: — если в title шум из имени файла = hasBestEffortResult junk, не настоящий 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.devapi.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 \b boundary — исправлен
  • 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>1 only — исправлен
  • 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)
  • OutputConfig cartoons/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 IDs
  • RutorPageParser, NNMClubPageParser — структура реализована, требует fixture тестов
  • TrackerMediaKind enum: movie/series/cartoon/documentary/music/audiobook/game/book/unknown
  • extractMediaKind — детект по BB.catId/FORUM_ID на странице (100+ forum IDs)

DirectoryPolicy / MatchPolicy / MoveStrategy:

  • FileAction.transmissionMove(torrentId:, from:, to:) — Codable
  • buildMovieActions читает policy, needsSymlink, needsNFO, effectiveOutputDir
  • transmissionMove когда есть 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).

Связанные заметки