[2026-05-22] taiga sync: .obsidian/community-plugins.json .obsidian/graph.json .obsidian/hotkeys.json .obsidian/plugins/obsidian-git/data.json .obsidian/plugins/obsidian-git/main.js
This commit is contained in:
@@ -1,137 +0,0 @@
|
||||
---
|
||||
title: Media Pipeline — Pitfalls & Debug Notes
|
||||
namespace: work
|
||||
created: '2026-05-16'
|
||||
updated: '2026-05-20'
|
||||
last_synced: '2026-05-20'
|
||||
type: entity
|
||||
tags:
|
||||
- media-pipeline
|
||||
- swift
|
||||
- pitfalls
|
||||
- debugging
|
||||
confidence: 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.dev` → `api.poiskkino.dev`. Swift URLSession при редиректе теряет `X-API-KEY` → пустые ответы кешируются. Фикс: обновить URL, добавить `shouldCache: ((Data) -> Bool)?` — не кешировать пустой `docs`.
|
||||
|
||||
## Docker Deploy — Kraken (обязательный порядок)
|
||||
|
||||
После каждого деплоя **обязательно** чистить dangling images, иначе диск забивается (~1-2GB за прогон):
|
||||
|
||||
```bash
|
||||
# Mac (после docker build)
|
||||
docker image prune -f
|
||||
|
||||
# Kraken (после docker load)
|
||||
ssh kraken "docker image prune -f"
|
||||
```
|
||||
|
||||
Полная последовательность деплоя:
|
||||
```bash
|
||||
# 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` явно:
|
||||
```bash
|
||||
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).
|
||||
|
||||
## Связанные заметки
|
||||
|
||||
- [[personal-os-architecture]]
|
||||
- [[tech/kraken-network]]
|
||||
Reference in New Issue
Block a user