Files
obsidian-vault/family/projects/media-toolbox-kraken.md
T
2026-05-29 23:00:57 +00:00

61 KiB
Executable File
Raw Blame History

created, updated, status, tags
created updated status tags
2026-05-13 2026-05-17 in-progress
kraken
media
jellyfin
transmission
swift
project

Media Toolbox на Кракене

Цель: полноценный медиасервер на Кракене (RPi 5) — перенос библиотеки с HTPC, автосортировка через media-pipeline (Swift), Jellyfin, торренты.


Архитектура (целевая)

HTPC (Bazzite 192.168.1.86)
  └── rsync → Kraken HDD /srv/.../media/

Kraken (RPi 5, 192.168.1.14)
  ├── /srv/dev-disk-by-uuid-49e8f586-3839-4c5d-a1e1-58bfc3579ade/media/
  │     ├── movies/          ← фильмы (127 папок)
  │     ├── cartoons/        ← мультфильмы (126 папок)
  │     ├── series/          ← сериалы (45 папок)
  │     ├── documentaries/   ← документальные (35 папок)
  │     └── downloads/complete ← Transmission
  ├── Docker: Transmission (128 торрентов, порт 9091)
  ├── Jellyfin native (порт 8096)
  └── Docker: media-pipeline:kraken (Swift CLI, arm64)

media-pipeline (~/Developer/media_files_db, ветка kraken-agent)
  ├── scan → resolve → apply (sync)
  ├── NFO-файлы для Jellyfin/Kodi
  ├── Transmission RPC для обновления путей
  └── unresolved.json — реестр нераспознанных

Текущий статус (2026-05-14, сессия 5)

Sync результаты (последний запуск — dry_run=false)

Категория Resolved Unresolved Статус
movies 2 (generation.p, Black Mirror dup) NFO пишутся
series 1 (Black Mirror — homonym) NFO пишутся
cartoons 6 в работе
documentaries 6 Tier 4 запускается
Итого 401 15 sync запущен

dry_run выключен (2026-05-14), запущен sync — NFO пишутся на диск.

Что работает

  • Docker образ media-pipeline:kraken задеплоен (ветка kraken-agent)
  • Фильмы: 127/127 NFO
  • Сериалы: все resolved (Black Mirror, Ну погоди!, и др. — через resolve-manual)
  • Кеш API-ответов: /config/cache, 30-дневный TTL
  • Transmission download-complete hook установлен
  • resolve-manual работает для movie/series/single-file

Открытые задачи

1. 🔴 [ОБЯЗАТЕЛЬНО К ИСПОЛНЕНИЮ] Довести media-pipeline до 0 unresolved без resolve-manual

Принцип: resolve-manual — не решение. Тул должен резолвить всё автоматически.
Текущее состояние: 32 unresolved после sync (dry_run=false). Разбивка:

Группа A — старые source-папки (scan подхватывает оригиналы после apply): apply создаёт canonical папки с симлинками, но оригинальные папки (flow.aka.straume..., bezumnyj_maks_3... и т.д.) остаются и при следующем scan снова попадают в unresolved. Это архитектурный баг.

  • Нужно: scanner должен пропускать папки, чьи файлы уже используются как цели симлинков в canonical структуре (или: хранить список resolved source-paths в unresolved.json и пропускать их при scan).

Группа B — мультики (tie/ambiguity): козленок, тигренок, нехочуха.xvid, чебурашка.m4v, котенок по имени гав.m4v, 25е - первый день, рики тики тави, приключения фунтика, незнайка, миграция

  • Причины: KP возвращает несколько кандидатов с одинаковым весом (tie), или IMDB/web search не находит по транслитерации.
  • Нужно: улучшить tie-breaking (год из папки/файла, popularity score из KP), расширить кириллические варианты запроса.

Группа C — документалки: bbc. the real jungle book bear 2012, bbc. секреты собак, penguin meet the family (2020), бегемоты - жизнь в воде, гиганты моря 2011, таинственная жизнь собак (hdtvrip 720p, 2013), тайная жизнь собак (2016г), prehistoric.planet.s02.1080p, жизнь птиц 1998, пингвины. шпион в толпе, супер белки (2018), шпион в снегах 2018

  • Tier 4 (IMDb scrape) запускается, но candidates = 0 — title matching слишком строгий для BBC-документалок.
  • Нужно: для documentaries/ добавить relaxed matching (убирать "bbc.", год, технические теги из запроса перед поиском).

7. 🟡 ROM-инфраструктура: qBittorrent + Rutracker + Эмуляторы

Цель: Eagle/Кракен могут самостоятельно искать и качать игры/ROM-ы.

qBittorrent на HTPC:

  • Установить qBittorrent (Flatpak: com.qbittorrent.qBittorrent)
  • Настроить Web UI (порт 8080, доступ с Mac/Кракена)
  • Добавить Rutracker в список трекеров

Switch эмуляция:

  • Установить EmuDeck на HTPC
  • Достать prod.keys + title.keys (Switch firmware keys) — путь: ~/.config/Ryujinx/system/
    • Источник: rutracker (поиск "nintendo switch keys prod.keys") или community
  • Скачать DKC: Tropical Freeze (.nsp или .xci) через qBittorrent

Rutracker доступ для агентов:

  • Настроить парсинг/API-доступ к Rutracker (учётка + cookie или jackett)
  • Научить Eagle/Кракена инициировать скачку через qBittorrent Web UI API
  • Документировать workflow в этом файле

Wii альтернатива (проще чем Switch):

  • Dolphin ставится через EmuDeck без BIOS
  • DKC Returns (Wii) скачать как .wbfs
  • Маппинг геймпада (нет Wiimote)

5. 🔴 Торренты: Transmission не видит 271/293 файлов

Проблема: Transmission ищет файл по downloadDir/torrent_name. После pipeline apply файлы переименованы в canonical форму (Furiosa - A Mad Max Saga (2024)/Furiosa - A Mad Max Saga (2024).mkv), а торрент ожидает оригинальное имя (Furiosa.A.Mad.Max.Saga.2024.1080p....mkv) прямо в /media/movies/. Совпадений нет → haveValid=0 у 271 торрентов.

22 торрента с файлами — только те что в /downloads/complete (свежескачанные, pipeline ещё не обработал).

Нужно: реализовать torrent-fix subcommand: для каждого торрента искать файл по имени (case-insensitive fuzzy) в source директориях /media/movies/, /media/cartoons/ и т.д., и вызывать torrent-set-location RPC.

6. 🔴 Мультфильмы в library/movies (классификационный баг)

Проблема: library/cartoons = 0 items, library/movies = 202 items из которых 106 — мультфильмы. MediaFinalizer.OutputConfig содержал только moviesDirectories + seriesDirectoriesbuildMovieActions всегда писал в movies.

Фикс (задеплоен):

  1. Config.OutputConfig + MediaFinalizer.OutputConfig расширены: добавлены cartoonsDirectories + documentariesDirectories.
  2. movieOutputDir(forGenres:) — роутинг по resolved жанрам (Animation→cartoons, Documentary→documentaries). Source path не используется.
  3. ProviderSearchStrategy.facts() теперь эмитит NFOMetadataFact с жанрами провайдера (раньше genres терялись, в граф не писались).

После деплоя: нужно переместить существующие 106 неправильных entries из library/movies в library/cartoons (отдельный скрипт). Новые sync'и будут класть правильно.

  • Настроить библиотеки в Jellyfin (http://192.168.1.14:8096)
  • NFO файлы готовы (716 шт.), Jellyfin должен их подхватить

4. 🟢 Hermes cron на Кракене

  • Периодический запуск sync (новые загрузки через Transmission)

Архитектурные принципы (важно)

Принцип Описание
NFO как evidence LocalEvidenceStrategy читает NFO только если они пришли с контентом (торрент). Pipeline-generated NFO не должны читаться как входные данные — это circular dependency. Сейчас защита через .media-pipeline-canonical маркер (FileScanner пропускает canonical dirs). Долгосрочно: добавить <generator>media-pipeline</generator> тег в generated NFO и фильтровать в LocalEvidenceStrategy.
Классификация по жанрам провайдера Роутинг в cartoons/documentaries — только по жанрам из API (TMDb/KP), через MediaSearchCandidate.genres → NFOMetadataFact → movieOutputDir(forGenres:). Source path никогда не используется для категоризации.
resolve-manual — не решение unresolved.json — очередь для автоматического резолва. resolve-manual только для экстренных случаев.
Решение Описание
Unresolved = last resort unresolved.json — НЕ мусорка. Это очередь для AI-агента (Tier 5), который по крону подбирает нераспознанные и разрешает их через LLM + web search. Для данной библиотеки цель: Tier 0-4 (TMDb → KP → IMDb scrape → web search) должны закрывать всё — в unresolved.json не должно попадать ни одного item'а из текущей библиотеки.
Web search enabled providers.webSearch.enabled=true в config.json. IMDb scrape как Tier 4 для всего, что не нашли TMDb/KP. Tier 4 должен срабатывать до того, как item уходит в unresolved.json
Документалки приоритет KP BBC/Discovery документалки плохо индексированы в TMDb. KP часто знает их под русскими названиями. Стратегия: сначала KP с русским названием из папки, потом IMDb
resolve-manual Только для экстренных случаев, не как регулярный процесс
Single-file NFO Для .mkv/.m4v файлов NFO создаётся рядом (film.nfo), не внутри

Исправленные баги

Баг 1: Двойной вызов binary (КРИТИЧЕСКИЙ)

docker run ... media-pipeline:kraken media-pipeline sync → бинарь получал media-pipeline как аргумент. Фикс: ENTRYPOINT ["media-pipeline"]

Баг 2: TitleSimilarity — симметричный Jaccard

encanto_2021_bdrip_by_dalemake vs Encanto: lengthRatio=0.2 → rejected. Фикс: Asymmetric scoring — candidate-coverage Jaccard когда query длиннее. Коммит 2704ce3

Баг 3: maxCallsPerRun = 8

8 API-вызовов → 192/200 items никогда не искались. Фикс: 8 → 500. Коммит 2704ce3

Баг 4: Series-гипотезы для одиночных файлов

Одиночные .avi/.mkv без S/E маркеров получали series-гипотезу → TMDb искал по /search/tv. Фикс: videos.count < 2 && !hasAnyEpisodeMarkers → return nil. Коммит 17c2ddc

Баг 5: HTTP кеш не персистился

cacheDirectory = /usr/local/bin/cache — удалялся при docker run --rm. Фикс: Autodetect /config mount → /config/cache. Коммит 5a1053c

Баг 7: Tier 4 (web search) не запускался для контента не в TMDb/KP

Проблема: MediaPlanner гейтил Tier 4 на hasLiveUnresolved() — но когда TMDb/KP возвращают 0 кандидатов, арбитр фаерит provider-not-found, который прунит все гипотезы. После этого hasLiveUnresolved=false → Tier 4 никогда не запускался.
Фикс:

  • MediaPlanner: Tier 4/5 теперь гейтятся на !hasWinner (нет .winning гипотезы), а не hasLiveUnresolved
  • ProviderSearchStrategy: добавлен флаг includePrunedHypotheses — когда true, поиск идёт и по .pruned ветками
  • WebSearchStrategy.webSearchDefaults: includePrunedHypotheses=true Коммит: 115f757

Баг 8: KP API URL смена домена (301 redirect)

api.kinopoisk.dev переехал на api.poiskkino.dev. Swift URLSession при редиректе теряет X-API-KEY заголовок → KP возвращает {"docs":[]} → кешируется как валидный пустой ответ → советские мультики и BBC не резолвились неделями. Фикс: (1) обновлён URL в KinopoiskAPI.swift; (2) HTTPClient.fetch получил shouldCache: ((Data) -> Bool)? — KP не кеширует ответы с пустым docs.

Баг 9: Leet-speak в именах файлов

ni4ego_horoshego, o_4em_govoryat_muzh4iny — цифра 4 = ч в русском warez-транслите. Стандартная транслитерация не покрывает. Фикс: String.decodeLeetSpeak() в StringExtensions.swift + дополнительный variant в NameTokenization.variants.

Баг 10: Год 2023г не парсился как год

Миграция. 2023г.mkv — кириллическая г (год) является word char, поэтому \b после 2023 не срабатывает → qYear=nil → TMDb ищет без фильтра года → 0 результатов. Фикс: В TitleParser.cleanupTitleAndYear добавлен паттерн (19|20)\d\d)г\b до стандартного \b regex. Коммит 770e51e.

Баг 11: Cyr→Lat query variant — мусорные запросы

NameTokenization генерировал transliteratedToLatin variant для кириллических имён → МиграцияMigratsiya → TMDb/KP не знают транслит, 0 результатов, только занимают cache-слоты. Оригинальный Go-sync делал только Latin→Cyrillic. Фикс: Убран transliteratedToLatin из query variants в NameTokenization.swift. Коммит 10d64da.

Баг 12: TitleParser _year_\b не срабатывает на underscore-границах

Проблема: bezumnyj_maks_3_pod_kupolom_groma_1985_[torrents.ru] — год 1985 окружён _, а _ является \w в Swift regex. Поэтому \b1985\b не срабатывает → year=nil, 1985 остаётся в title → TMDb запрос содержит 1985 в строке вместо year= параметра → 0 результатов.

Следствие: заголовок безумный макс 3 под куполом грома 1985 → TokenParser видит 1985 как токен → вариант обрезается по digit-граничному паттерну → появляется мусорный вариант безумный мак (truncated).

Фикс: в TitleParser.cleanupTitleAndYear заменён \b(\d{4})\b на (?<![0-9])((?:19|20)\d\d)(?![0-9]) — игнорирует _ как boundary, проверяет только цифровые границы.
Тест: NameTokenizationTests.yearInUnderscores + titleParserYearInUnderscores — оба GREEN.
Коммит: 61be066 (заодно с NFO sidecar fix, фактически в коде с TitleParser.swift line 39).

Баг 13: OutputConfigcartoons/documentaries не optional в JSON

Проблема: Старые config-файлы и тест-JSON без новых полей бросали keyNotFound при декодировании.
Фикс: Добавлен init(from: Decoder) с decodeIfPresent + дефолт []. Backward compatible. Коммит 2db0f81.

Баг 14: xvid/divx не в списке quality markers

Проблема: Nehochuha.XVid.DVDRipxvid не стрипался → попадал в title tokens → мусорный запрос.
Фикс: Добавлены xvid|divx в регекс quality markers в TitleParser.cleanupTitleAndYear. Коммит 2db0f81.

Баг 15: TitleParser — год как название фильма (1984, 2001)

Проблема: TitleParser жадно вырезал первый (19|20)\d\d — для фильмов 1984, 2001 Odyssey оставлял пустой title и ломал TMDb запрос.
Фикс: Safety guard: стрип года только если перед ним ≥2 буквенных символа. Применён в обоих year-extraction блоках.
Тесты: TitleParserExhaustiveTests.nineteenEightyFour, nineteenEightyFourBDRip, spaceOdyssey — GREEN. Коммит 2db0f81.


Инструмент: QuerySnapshotGenerator

При изменениях в TitleParser/NameTokenization/QueryBuilder снапшоты в QueryBuilderFixtureParameterizedTests.swift устаревают.
Регенерация: swift run QuerySnapshotGenerator из корня репо.
НЕ использовать SNAPSHOT_TESTING_RECORD=all — InlineSnapshotTesting 1.18.7 крашит при 364 concurrent writes (SIGSEGV).


Баг 6: resolve-manual NFO path для single-файлов

resolve-manual писал NFO внутрь файла вместо рядом. Фикс: Detect isDirectory, для файлов → deletingPathExtension().appendingPathExtension("nfo"). Коммит c0fdc59


Конфиг на Кракене

/srv/dev-disk-by-uuid-49e8f586-3839-4c5d-a1e1-58bfc3579ade/docker/media-pipeline/
├── config.json          ← TMDb/KP ключи, Transmission RPC, directories
├── unresolved.json      ← реестр нераспознанных (создаётся автоматически)
├── cache/               ← HTTP кеш 30 дней
└── on-download-complete.sh

Запуск sync:

docker run --rm \
  -v /srv/.../media:/media \
  -v /srv/.../docker/media-pipeline:/config \
  media-pipeline:kraken \
  sync --config /config/config.json

Force-resolve одного item:

docker run --rm ... media-pipeline:kraken \
  resolve-manual --config /config/config.json \
  --media-path '/media/cartoons/bremenskie.muzykanty' \
  --tmdb 14327

Технические детали

HTPC bazzite@192.168.1.86, Data: /run/media/bazzite/Data/, WoL: B0:6E:BF:60:6D:64
Кракен kraken@192.168.1.14, HDD: /srv/dev-disk-by-uuid-49e8f586-3839-4c5d-a1e1-58bfc3579ade/
Jellyfin http://192.168.1.14:8096
Transmission http://192.168.1.14:9091
Исходники ~/Developer/media_files_db/, ветка kraken-agent
Docker образ media-pipeline:kraken (arm64, Colima 24GB)
kraken ssh kraken → LAN (192.168.1.14) или VPN (10.99.1.2) через DNS-резолв
docker deploy docker save img -o /tmp/img.tar && scp /tmp/img.tar kraken:/tmp/ && ssh kraken "docker load -i /tmp/img.tar && rm /tmp/img.tar"docker save | ssh зависает через WireGuard tunnel
Transmission RPC Токен: curl -D /tmp/hdrs ... > /dev/null, затем grep X-Transmission-Session-Id /tmp/hdrs | awk '{print $2}' | tr -d '\r\n'. Payload с base64 торрента — писать в файл (-d @file), не аргументом (иначе "Argument list too long")

Источник торрентов (важно)

Торренты на Кракене (128 шт.) импортированы из Windows Transmission-daemon на HTPC:

/run/media/bazzite/Windows/windows/serviceprofiles/localservice/appdata/local/transmission-daemon/
  ├── torrents/   ← 210 .torrent файлов
  └── resume/     ← 214 resume (пути, статус)

Валидация resume (2026-05-14): 185/214 файлов есть на HTPC. 29 missing:

  • ~15 медиафайлов с утраченного диска X:/Movies/ — потеряны безвозвратно
  • ~14 игр/архивов из Downloads/Unsorted/ — не медиа, не важно

Отдельно: uTorrent (/run/media/bazzite/Windows/program files/utorrent/) — 131 .torrent файл, resume.dat с 18 записями. Из них только 6 хешей совпадают с Кракеном.

Karnavalnaya.noch.1956.BDRip.AVC.mkv — есть в uTorrent и в Transmission на Кракене (downloaded=0). Файла нет нигде — никогда не скачивался.

Router script: Sonarr/Radarr → правильная библиотека Jellyfin

Задача: после импорта Sonarr/Radarr создать symlink в нужную папку Jellyfin на основе жанра/рейтинга. Sonarr/Radarr кладут файлы в movies-radarr/ и series-sonarr/ — Jellyfin видит только эти папки. Роутер создаёт symlinks в тематические библиотеки чтобы Jellyfin показывал правильную структуру.

Логика маршрутизации

Входные папки:
  /media/movies-radarr/   → фильмы
  /media/series-sonarr/   → сериалы

Для каждого тайтла читаем NFO (или TMDb API):
  - genres[]
  - content_rating (R / 18+ / TV-MA / PG / etc.)
  - type (movie / series)

Алгоритм (приоритет сверху вниз):

  IF documentary IN genres:
    movie  → /media/documentaries/
    series → /media/documentaries-series/

  ELIF animation IN genres AND rating NOT IN [R, 18+, TV-MA]:
    movie  → /media/cartoons/
    series → /media/cartoons-series/

  ELSE (default):
    movie  → /media/movies/
    series → /media/series/

Movies и Series — финальный fallback, если не попало в другие категории.

Что делает скрипт

  1. Сканирует movies-radarr/ и series-sonarr/
  2. Для каждого тайтла читает movie.nfo / tvshow.nfo → жанры + рейтинг
  3. Если NFO нет → запрос TMDb API по имени папки
  4. Определяет целевую папку по алгоритму выше
  5. Создаёт symlink: ln -s /media/movies-radarr/X /media/movies/X
  6. Копирует NFO + постер рядом с symlink (Jellyfin не видит метадату через symlink)
  7. Тригерит Jellyfin rescan нужной библиотеки

Запуск

  • При добавлении: вызывается из Sonarr/Radarr → Settings → Connect → Custom Script
  • Полный пересчёт: router.py --rescan-all

Что НЕ делает

  • Не трогает файлы в movies-radarr/ и series-sonarr/
  • Не удаляет старые symlinks без --cleanup
  • Не переименовывает торренты

Jellyfin библиотеки (целевые)

Библиотека Тип Пути
Movies movies /media/movies + /media/movies-radarr
Series tvshows /media/series + /media/series-sonarr
Cartoons movies /media/cartoons
Cartoon Series tvshows /media/cartoons-series
Documentaries movies /media/documentaries
Documentary Series tvshows /media/documentaries-series

Порядок в Jellyfin UI: Movies → Series → Cartoons → Cartoon Series → Documentaries → Documentary Series → Music


*arr стек (Prowlarr / Radarr / Sonarr) — настройка 2026-05-17

Архитектура

Prowlarr (9696) → Radarr (7878) + Sonarr (8989) → Transmission (9091)
                                                          ↓ файлы на диск
                                                    Jellyfin (8096)

Статус контейнеров

Контейнер Порт Compose Сети
transmission 9091 docker/transmission/ media_default + media_net
radarr 7878 docker/radarr/ docker_default + media_net
sonarr 8989 docker/sonarr/ docker_default + media_net
prowlarr 9696 docker/prowlarr/ docker_default + media_net
jellyfin 8096 docker/jellyfin/ media_default (не в media_net — OK, читает диск)

Все compose-файлы обновлены: добавлена media_net (external).

API ключи

Сервис Ключ
Radarr cbcb8ec320104359920c0f611d503c7b
Sonarr 15fbec32f1cb4b05b1c2b229ce27359b
Prowlarr 134ac38a02b94d5fb3e3a6e67228b18e
Jellyfin 87af49b6ff62ea68da6abdab0d7a4fbc (eagle-script)

Конфигурация

  • Radarr root folder: /media/movies-radarr
  • Sonarr root folder: /media/series-sonarr
  • Radarr ← Transmission: настроен (host=transmission, port=9091, no auth)
  • Sonarr ← Transmission: настроен
  • Prowlarr → Radarr + Sonarr: fullSync
  • Prowlarr индексер: RuTracker (user: mallexxx), baseUrl https://rutracker.org/
  • Radarr/Sonarr NFO: включен (Kodi/Emby metadata writer)

Jellyfin библиотеки

Библиотека Пути
Movies /media/library/movies + /media/movies-radarr
Cartoons /media/library/cartoons
Series /media/library/series + /media/series-sonarr

/media/library/ — существующая библиотека с NFO/постерами от media-pipeline.
/media/movies-radarr, /media/series-sonarr — новые скачки через *arr.

Полная документация

Скилл на Кракене: ~/.hermes/skills/kraken-media-stack/SKILL.md
Покрывает: все операции, API примеры, pitfalls.


Текущий статус (2026-05-18, сессия 16)

Jellyfin библиотеки (актуально после 2026-05-18)

Библиотека Тип Пути
Movies movies /media/movies
Series tvshows /media/series
Cartoons movies /media/cartoons
Cartoon Series tvshows /media/cartoons-series
Documentaries movies /media/documentaries
Documentary Series tvshows /media/documentaries-series
Music music (пусто)

movies-radarr и series-sonarr убраны из библиотек Jellyfin. Router script создаёт symlinks в тематические папки при каждом новом импорте.

Router script: /srv/.../docker/media-pipeline/router.py

# Dry-run:
python3 /srv/dev-disk-by-uuid-49e8f586-3839-4c5d-a1e1-58bfc3579ade/docker/media-pipeline/router.py
# Apply:
python3 /srv/dev-disk-by-uuid-49e8f586-3839-4c5d-a1e1-58bfc3579ade/docker/media-pipeline/router.py --apply

Сделано сегодня

  • Love, Death & Robots → /media/series (был в cartoons)
  • Пингвины. Шпион в толпе → /media/documentaries-series (был в cartoons-series)
  • Удалены 79 дублей standalone-файлов в cartoons (папка+файл → оставлена папка)
  • Удалены standalone-дубли в documentaries: Шпион в снегах, Невероятные хищники, Таинственная жизнь собак 2013
  • Удалён LDR s01e18 lowercase-дубль
  • Исправлен NFO Чебурашки → советский 1971 (tmdb 34859)
  • Созданы NFO+постеры: В синем море в белой пене, Котёнок по имени Гав, Смешарики Новый сезон, Трям! Здравствуйте!, Тигрёнок в чайнике
  • Исправлен NFO Знакомимся с кабанами → русский заголовок + постер
  • Стрим (Flow 2024) → /media/movies/Flow (2024)/
  • Обновлены Transmission locations: ~15 торрентов (cartoons-series, documentaries-series, series, правильные подпапки)
  • Исправлена Тайна третьей планеты — удалена lowercase NFD-дублирующая папка
  • Удалена пустая папка-призрак Бременских музыкантов
  • Перемещены 5 арменфильм мультиков в отдельные папки
  • rsync "в синем море в белой пене.avi" с HTPC
  • Вокзал для двоих — movie.nfo рядом с part1/part2 (part1/part2 формат поддерживается Jellyfin нативно)
  • Написан план router script: Sonarr/Radarr → тематические библиотеки по жанру/рейтингу

Открытые задачи

  • Router scriptrouter.py реализован и запущен. Symlinks созданы, movies-radarr/series-sonarr убраны из Jellyfin библиотек.
  • 🟡 Передать Transmission locations через router script при каждом новом импорте (вместо ручного обновления)
  • 🔴 rsync невыполненных с HTPC — список в Фильмы не перенесенные с htpc на кракен.md (пункты [ ])
  • 🟡 Watchlist — добавить перенесённые фильмы в нужные разделы (кроме Знакомимся с кабанами и Нехочухи)

Текущий статус (2026-05-17, сессия 15)

rsync финальный прогон (28 файлов)

Запущен rsync 28 медиафайлов отсутствующих на Кракене (скрипт /tmp/rsync_missing28.sh, tmux сессия rsync3):

Фильмы (22): Брат 2 (4K UpScale), Вивариум, Ворон, Голодные игры Баллада, Голый пистолет, Злая, Инвалид, Как взломать экзамен, Компаньон, Кошачьи миры Луиса Уэйна, Леон, Начало, Операция С Новым Годом, Особенности охоты (1995), Особенности охоты зимний период, Особенности рыбалки, Первый день моей жизни, Пираты, Планета обезьян, Самолетом поездом машиной, Тетрис, Знакомимся с кабанами

Мультфильмы (5): Despicable Me 4, Encanto, Inside Out, Le Grand Mechant Renard, Nehochuha

Сериалы (1): Fleabag

После завершения — прогнать fix_torrent_case.py ещё раз для привязки новых файлов к торрентам.

Текущий статус (2026-05-16, сессия 14)

Регрессия 278→194 — диагноз и фикс

Причина: два бага в RegionPartitioner.shadowedFilePaths:

  1. Case-sensitive сравнение имёнThe.Iron.Giant.1999.mkv не матчился с sibling-dir the.iron.giant.1999.../ (Linux case-sensitive FS).
  2. Canonical-dir не видны партиционеруFileScanner.discover() пропускал canonical-папки (.media-pipeline-canonical маркер) но не сообщал о них. Поэтому Cloud.Atlas.BDRip-AVC.mkv не знал что рядом уже есть Cloud Atlas (2012)/.

Фиксы:

  • ScanModels.ScanResult: новое поле canonicalDirectories: [URL]
  • FileScanner.discover(): заполняет canonicalDirectories при скипе
  • RegionPartitioner: (1) case-insensitive baseName match, (2) shadow standalone если в том же каталоге есть любая canonical-dir
  • 3 новых теста в ScanPhaseRegionSelectionTests
  • Коммит: 855b806

402/402 тестов GREEN. Деплой на Кракен запущен.

Текущий статус (2026-05-16, сессия 13)

Итог прогона (новый образ, после всех фиксов сессий 10–13)

Метрика Значение
applied ~269
skipped (unresolved) 13
errors 0

Resolved в этой сессии

  • Generation П (2011) — standalone .mkv, applied
  • Mad Max Beyond Thunderdome (1985) — standalone .mkv слинкован в существующую canonical папку
  • Nehochuha — resolved (папка)

13 остатков — финальный список

# Путь Группа Причина
1 /media/cartoons/budil'nik 1984 Мультик Нет в TMDb/KP под этим названием
2 /media/cartoons/novogodn'aya_pesenka_deda_moroza Мультик Нет в TMDb/KP
3 /media/documentaries/bbc. the real jungle book bear 2012 BBC (genuinely absent) Нет в TMDb/KP
4 /media/documentaries/bbc. секреты собак BBC (genuinely absent) Нет в TMDb/KP
5 /media/documentaries/penguin meet the family (2020) BBC (genuinely absent) Нет в TMDb/KP
6 /media/documentaries/Таинственная жизнь собак (HDTVRip 720p, 2013).mkv Дубль Дубль строки 7 (разный регистр)
7 /media/documentaries/таинственная жизнь собак (hdtvrip 720p, 2013) Дока Нет в TMDb/KP
8 /media/documentaries/бегемоты - жизнь в воде BBC (genuinely absent) Нет в TMDb/KP
9 /media/documentaries/супер белки (2018) Дока Нет в TMDb/KP
10 /media/documentaries/шпион в снегах 2018 Дока Нет в TMDb/KP
11 /media/movies/Dolina.Ekho.2025.ATVP.WEB-DLRip.AVC.mkv Дубль Дубль строки 12
12 /media/movies/dolina.ekho.2025.atvp.web-dlrip.avc Папка Уже resolved как папка — дубль
13 /media/movies/Stiratel.1996.x264.BDRip.(AVC).0ptimus.mkv Фильм Транслит StiratelСтёртый (KP не находит)

По группам:

  • Дубли (3): строки 6/7 — один и тот же контент; строки 11/12 — папка уже resolved
  • Genuinely absent в TMDb/KP (8): BBC документалки + советские мультфильмы
  • Транслит mismatch (1): Stiratel → нужен русский title Стёртый для KP поиска

Sync результат (pipeline-run3, образ 738b4b7426e9)

Метрика Значение
applied 260
skipped (unresolved) 23
errors 0

Фиксы этой сессии

  • Code=516 idempotent symlink — повторный прогон больше не падает на уже существующих симлинках
  • TitleParser \b episode regexMovie 43 больше не обрезается до Movi; Movie 43 → resolved
  • BBC prefix stripbbc. the real jungle book bearthe real jungle book bear в запросах
  • Yoficatorкотёнок по имени гав и тигрёнок в чайнике resolved через е→ё
  • rsync с HTPC завершён — 303 фильма, 206 мультиков, 72 серии, 46 документалок (2.2TB)
  • unresolved.json маунтится-v $(pwd)/unresolved.json:/config/unresolved.json

⚠️ Обязательный pipeline.providers в config.json — если tmdb/kinopoisk отсутствуют в блоке → disabled → 213 skipped вместо 278+ applied!

"pipeline": {
  "providers": {
    "tmdb":       { "enabled": true, "language": "ru-RU" },
    "kinopoisk":  { "enabled": true },
    "torrent":    { "enabled": true },
    "webSearch":  { "enabled": true },
    "aiAgent":    { "enabled": false }
  }
}

Запуск pipeline (правильная команда)

cd /srv/dev-disk-by-uuid-49e8f586-3839-4c5d-a1e1-58bfc3579ade/docker/media-pipeline
docker run --rm \
  -v "$(pwd)/config.json:/config/config.json:ro" \
  -v "/srv/dev-disk-by-uuid-49e8f586-3839-4c5d-a1e1-58bfc3579ade/media:/media" \
  -v "$(pwd)/cache:/config/cache" \
  -v "$(pwd)/unresolved.json:/config/unresolved.json" \
  media-pipeline:kraken

23 оставшихся unresolved — анализ

Группа A — дубли (папка + файл, 4 пары): Папка resolv-ится (separateItems hypothesis), standalone файл нет.

  • Nehochuha.XVid.DVDRip.avi (папка nehochuha.xvid.dvdrip — resolved )
  • Bezumnyj_Maks_3_Pod_Kupolom_Groma_1985_[torrents.ru].mkv (папка resolved)
  • Dolina.Ekho.2025.ATVP.WEB-DLRip.AVC.mkv (папка resolved)
  • dolina.ekho.2025.atvp.web-dlrip.avc (дубль папки выше)

Группа B — не индексированы в KP/TMDb:

  • bbc. the real jungle book bear 2012
  • bbc. секреты собак
  • penguin meet the family (2020)
  • бегемоты - жизнь в воде
  • супер белки (2018)
  • шпион в снегах 2018
  • Таинственная жизнь собак (HDTVRip 720p, 2013).mkv
  • таинственная жизнь собак (hdtvrip 720p, 2013) (дубль выше)

Группа C — транслитные фильмы (KP находит, но support=0 из-за wrong-hypothesis):

  • Ni4ego_horoshego_v_otele_El_Royal_2018 — KP 446021|2018 находит
  • O_4em_govoryat_muzh4iny_2010О чем говорят мужчины (year filter: 2010 vs 2011)
  • Serebryanye_konki_2020
  • Generation.P.BDRip-AVC
  • Stiratel.1996 — KP знает как Стёртый, транслит неверный
  • The.Frozen.Kingdom.of.the.Snow.Leopard.(2020)

Группа D — год mismatch:

  • рики тики тави 1965 — в KP год 1976 (советский м/ф)

Группа E — 2024-2025 новинки (возможно не проиндексированы):

  • Odin.den.v.Stambule.2024
  • Prorok.Istoriya.Aleksandra.Pushkina.2025

Группа F — неопределённое:

  • 25е - первый день

Следующие шаги

  1. Группа A: удалить дубли-standalone-файлы (папки с тем же контентом есть)
  2. Группа C: разобраться с wrong-hypothesis багом в арбитраже (KP result привязывается не к той hypothesis)
  3. Группа B: rename папок на правильные названия (BBC docs не индексированы)
  4. Группа D/E: relaxed year matching или override через resolve-manual

Unresolved: Investigation List

Эти 15 позиций прошли все автоматические тиры (TMDb→KP→IMDb→WebSearch) и остались нераспознанными. Статус на 2026-05-16. Для каждого — план ручного расследования.

Группа: Дубли (удалить с диска или дедуплицировать scanner)

Путь Действие
/media/cartoons/Nehochuha.XVid.DVDRip.avi Папка nehochuha.xvid.dvdrip уже resolved. Удалить standalone файл.
/media/movies/Bezumnyj_Maks_3_Pod_Kupolom_Groma_1985_[torrents.ru].mkv Resolved в прогоне 2026-05-16 (слинкован). Удалить из unresolved.json вручную.
/media/movies/Dolina.Ekho.2025.ATVP.WEB-DLRip.AVC.mkv Папка dolina.ekho.2025... уже resolved. Это standalone дубль.
/media/movies/dolina.ekho.2025.atvp.web-dlrip.avc Та же папка что выше — в scanner попадает дважды.
/media/documentaries/Таинственная жизнь собак (HDTVRip 720p, 2013).mkv Дубль строки ниже (разный регистр).
/media/documentaries/таинственная жизнь собак (hdtvrip 720p, 2013) Основная версия — нужно искать.

Группа: Советские мультфильмы (нет под транслитом в TMDb/KP)

Путь Query для ручного поиска Примечание
/media/cartoons/budil'nik 1984 КП: «Будильник», год 1978 или 1984 Советский м/ф Союзмультфильм
/media/cartoons/novogodn'aya_pesenka_deda_moroza КП: «Новогодняя песенка Деда Мороза», год 1983

Расследование: curl "https://api.poiskkino.dev/v1.4/movie/search?query=Будильник&year=1984&type=cartoon"

Группа: Документальные (BBC/Discovery, нет в TMDb)

Путь Варианты поиска Примечание
/media/documentaries/bbc. the real jungle book bear 2012 IMDb: «The Real Jungle Book» (2012, BBC) Возможно серия BBC Natural World
/media/documentaries/bbc. секреты собак IMDb/КП: «Secrets of Your Dog», «BBC Секреты собак»
/media/documentaries/penguin meet the family (2020) IMDb: «Penguin: Meet the Family» (2020) BBC Studios
/media/documentaries/бегемоты - жизнь в воде КП/IMDb: «Hippos: Life in the Water», «BBC Бегемоты»
/media/documentaries/супер белки (2018) КП: «Супер белки», IMDb: «Super Squirrels» (2018)
/media/documentaries/шпион в снегах 2018 КП: «Шпион в снегах», IMDb: «Snow Spy», «Spy in the Snow»
/media/documentaries/таинственная жизнь собак (hdtvrip 720p, 2013) КП: «Тайная жизнь собак», IMDb: «Secret Life of Dogs» (2013, BBC)

Расследование:

  1. Поиск на IMDb: https://www.imdb.com/find?q=<title>&s=tt
  2. Если нашли — взять TMDb ID через: https://api.themoviedb.org/3/find/<imdb_id>?external_source=imdb_id

Группа: Транслит-mismatch

Путь Реальное название KP ID Действие
/media/movies/Stiratel.1996.x264.BDRip.(AVC).0ptimus.mkv «Стёртый» (1996) KP 9268 resolve-manual --tmdb <id> или добавить alias в транслит-словарь

Расследование: KP ID 9268 уже в кеше. Проблема — StiratelСтирател не совпадает с Стёртый. Нужно проверить есть ли у KP 9268 TMDb external ID: curl "https://api.poiskkino.dev/v1.4/movie/9268".


Архитектура: Agentic Flow (agent subcommand)

Записано 2026-05-16. Это главная спека media-pipeline agent subcommand.

Входные данные агента (для каждого unresolved item)

Агент получает всё что можно извлечь без баз:

  1. Файловые метаданные — имя папки/файла, набор файлов в папке (для TV show), длительность, формат, битрейт, разрешение (через ffprobe или AVFoundation)
  2. Транскрипция речиffmpeg вырезает первые 60–120 сек аудио → Whisper API → текст (речь дикторов, диалоги, announcer voice)
  3. OCR титровffmpeg захватывает 5–10 кадров из начала → tesseract или Vision API → текст с title card, студия, год
  4. Имена файлов как уже есть (query names из UnresolvedEntry)

Инструменты агента (function calling / tool use)

LLM получает инструменты и итеративно их вызывает до 10 шагов:

Tool Параметры Описание
search_tmdb title, year?, language? Поиск в TMDb API
search_kinopoisk title, year? Поиск в KP API
search_imdb title, year? IMDb full-text search
fetch_page url Фетч и возврат текста страницы (IMDb, Wikipedia, BBC, Rutracker, etc.)
search_web query Веб-поиск (DuckDuckGo / SerpAPI)

Выходные данные агента — одно из трёх

Вариант A — DB-bound resolve (нашёл в базе):

{
  "tmdb_id": 12345,
  "kp_id": 678,
  "imdb_id": "tt1234567"
}

→ Pipeline пишет NFO стандартно через TMDb/KP fetch

Вариант B — full metadata без DB binding (BBC/редкие доки):

{
  "title": "The Frozen Kingdom of the Snow Leopard",
  "original_title": "...",
  "year": 2020,
  "description": "...",
  "genres": ["Documentary"],
  "poster_url": "https://...",
  "source_url": "https://bbc.com/programmes/...",
  "duration_min": 59
}

→ Pipeline пишет custom NFO с этими данными (без tmdb/kp ID). Jellyfin подхватит.

Вариант C — manual resolve:

{
  "category": "unrecognized",
  "reason": "Не удалось идентифицировать после всех источников"
}

→ Остаётся в unresolved.json с agent_hint для ручного разбора

Выход для TV show / папки с несколькими фильмами

Агент возвращает список результатов, по одному на файл/эпизод. Структура аналогична тому что делает media sync — те же поля что и NFO.

Приоритет обработки

  1. Сначала The.Frozen.Kingdom.of.the.Snow.Leopard.(2020) — самый сложный кейс, нет в TMDb/KP
  2. Остальные BBC/Soviet docs из unresolved.json
  3. Все остальные unresolved

Реализация

Шаг 1: MediaFileInspector (новый модуль)

  • ffprobe / AVFoundation → duration, format, resolution, audio tracks
  • ffmpeg → extract frames → Vision/tesseract OCR → title card text
  • ffmpeg → extract 60s audio → Whisper API → speech transcript
  • Все результаты упакованы в MediaFileContext struct

Шаг 2: ChatGPTAPI.resolveMedia(context: MediaFileContext) (новый метод)

  • OpenAI function calling loop (max 10 iterations)
  • Системный промпт включает все данные из MediaFileContext
  • LLM итеративно вызывает tools пока не придёт к выводу
  • Возвращает AgentResolutionResult (A/B/C)

Шаг 3: Agent.swift subcommand расширен

  • Запускает MediaFileInspector для каждого unresolved item
  • Передаёт MediaFileContext в resolveMedia
  • По результату: пишет NFO (A/B) или обновляет hint (C)

Шаг 4: Tier 6 в sync pipeline (опционально)

  • После Tier 5 (AIAgentStrategy) — запускает VideoAnalysis для застрявших
  • Добавляет найденные variants как новые QueryNameFact → передаёт через Tier 0–4

Зависимости (Linux/arm64 на Кракене)

  • ffprobe / ffmpeg — уже установлен на Кракене
  • whisper-cpp или OpenAI Whisper API (через ChatGPTAPI)
  • tesseract — нужно установить (apt install tesseract-ocr tesseract-ocr-rus)
  • Vision API (macOS only) — для Linux использовать tesseract

План: CV/Whisper для Tier 6 (для оценки)

Идея: когда все тиры исчерпаны — использовать сам медиафайл как источник сигнала для идентификации.

Подход A: Whisper — транскрипция аудиодорожки начала фильма

  • ffmpeg -i film.mkv -ss 0 -t 120 -vn -acodec pcm_s16le -ar 16000 /tmp/opening.wav
  • whisper /tmp/opening.wav --language ru --model small → текст
  • Из текста: название, студия, год, авторы → уточнённый TMDb/KP запрос
  • Применимо: советские мультфильмы, документалки с русским закадровым голосом

Подход B: CV — захват кадров с титрами

  • ffmpeg -i film.mkv -ss 5 -vframes 10 /tmp/frames/frame%03d.jpg (начало)
  • ffmpeg -i film.mkv -sseof -120 -vframes 10 /tmp/frames/end%03d.jpg (конец — credits)
  • OCR через tesseract или Vision API → текст с кадров
  • Из текста: оригинальное название, год, студия
  • Применимо: советские мультфильмы всегда имеют title card в первые секунды

Подход C: Chromaprint/AcoustID — audio fingerprint

  • fpcalc film.mkv → fingerprint → https://api.acoustid.org/v2/lookup
  • Применимо: редко

Реализация (если решим делать)

  1. Новый Tier6VideoAnalysisStrategy в MediaDomain
  2. Запускается только для attempt_count >= 10
  3. На Linux: ffmpeg, whisper-cpp или OpenAI Whisper API, tesseract
  4. Вывод: дополнительные NameVariant для QueryBuilder
  5. Стоимость Whisper API: ~$0.006/мин, 120 сек = $0.01 за фильм. 13 items = $0.13
  6. Вердикт: Хорошая идея для stuck документалок. Реализовать после agentic flow.

  • 2026-05-15 сессия 10: rsync с HTPC завершён (2.2TB). Фиксы: Code=516 idempotent symlink, TitleParser \b episode regex, BBC prefix strip, Yoficator (е→ё). Результат: 260 applied, 0 errors, 23 unresolved. Movie 43 , Котёнок , Тигрёнок , Нехочуха (папка) .
  • 2026-05-13 сессия 1: HTPC разбужен, rsync запущен (~1.3TB), торрент-база импортирована (128 торрентов из Windows Transmission-daemon)
  • 2026-05-13 сессия 2: Docker build arm64, deploy на Кракен, first sync
  • 2026-05-13 сессия 3: kraken-agent ветка: UnresolvedStore, resolve-manual, agent, torrent-fix subcommands
  • 2026-05-14 сессия 4: 5 системных багов исправлены. Sync: 222/317 resolved (70%).
  • 2026-05-14 сессия 5: resolve-manual для 13 items. unresolved: 24 → 8. NFO path bug fix. kraken-ssh → WireGuard.
  • 2026-05-14 сессия 6: dry_run=false, sync запущен → 401 resolved, 32 unresolved. apply создаёт canonical папки + симлинки (оригиналы не трогает). 716 NFO написано. Валидация торрентов HTPC.
  • 2026-05-15 сессия 7: Торренты: 467 скопированы с HTPC, 323 добавлены в Transmission (294 итого после удаления 50 игр/нон-медиа). rsync: movies + мультфильмы + BBC документалки. Фиксы в коде: (1) best-effort collapse при исчерпании tierов, (2) дедупликация dir+file регионов в RegionPartitioner, (3) strip .aka./full.screen из TitleParser, (4) scanner пропускает canonical dirs по маркеру .media-pipeline-canonical, (5) Roman numerals в транслитерации (Ампир V). Финал: 19 unresolved.
  • 2026-05-16 сессия 8: Обнаружен корневой баг: KP API переехал api.kinopoisk.devapi.poiskkino.dev (301 redirect, Swift теряет X-API-KEY). Исправлен URL. Удалены 359 невалидных KP-кеш записей. Добавлен leet-speak decode (4ch: ni4ego→nichego, muzh4iny→muzhchiny). Починен кеш: KP пустые docs:[] больше не кешируются (были причиной повторных промахов после rate-limit/redirect). Текущий unresolved: 22. Завтра KP лимит сбросится → ожидаем ≤5.
  • 2026-05-16 сессия 9: Добавлен жанровый роутинг (cartoons/documentaries — только по genres из провайдера, не по source path). Фикс nfoMeta priority (provider genres > local empty NFO). Фикс парсинга года 2023г (русский суффикс). TMDb genres передаются из config. Убран Cyr→Lat query variant (не соответствует оригинальному Go-sync, TMDb не ищет по транслиту). Порядок провайдеров подтверждён: TMDb → KP → IMDb (short-circuit после каждого). KP — настоящий fallback (40 запросов vs 8428 TMDb). Текущий unresolved: 30 (ждём сброса KP rate limit).
  • 2026-05-16 сессия 10–11 (продолжение): Серия кодовых фиксов. 278 applied, 3 skipped (98.9%). Созданы ручные NFO для 11 тайтлов (нарушение принципа — удалены в сессии 12).
  • 2026-05-16 сессия 13: Integration тест BezumyjMaksIntegrationTests (8 кейсов, все шаги pipeline). Generation П resolved. Mad Max Beyond Thunderdome standalone resolved. Nehochuha . 13 unresolved — финальный список: 3 дубля, 8 genuinely absent (BBC/советские доки), 1 транслит-mismatch (Stiratel→Стёртый). Удалены 15 ручных NFO. Подтверждён и задокументирован Баг 12 (_1985_ year extraction). TitleParser регекс исправлен. Exhaustive тесты TitleParserExhaustiveTests (24 кейса) — GREEN. Баги 13 (OutputConfig backward compat), 14 (xvid/divx markers), 15 (год-как-название: 1984, 2001). QuerySnapshotGenerator executable — регенерация 364 снапшотов без racing. 391/391 тестов GREEN. Текущий unresolved на Кракене: 6. Следующий шаг: deploy → clean run → agentic flow для 3 BBC/доков.

Фиксы сессий 10–11 (код)

  • double-counting fixHypothesisArbiter: penalizedZeroProviders в HypothesisFact, только newly-zero провайдеры пенализируются за проход. Серебряные коньки resolved.
  • originalHypo scope bugcollectEvidence использовал originalHypo вне scope → compile error. Заменён на hypothesis.
  • TMDb en-US locale merge — для Latin-script запросов: dual search (ru-RU + en-US), merge (ru-RU first), лимит 40. Generation П resolved.
  • NFO reverse-prefix matchHypothesisGenerator: sidecar Generation.P.nfo теперь матчится к Generation.P.BDRip-AVC.mkv через stemPrefix проверку.
  • FileScanner sibling sidecar — для file-region (не директория) сканируются сиблинги в parent dir → NFO рядом с mkv подхватывается. Stiratel resolved.

6 оставшихся unresolved (на Кракене, актуально)

Группа A — standalone-дубли (2 шт.):
Папки с тем же контентом уже resolved. Standalone-файлы pipeline не резолвит потому что дубль.

  • /media/movies/Bezumnyj_Maks_3_Pod_Kupolom_Groma_1985_[torrents.ru].mkv
  • /media/cartoons/Nehochuha.XVid.DVDRip.avi

Группа B — genuinely absent в TMDb и KP (3 шт.):

  • /media/documentaries/bbc. the real jungle book bear 2012
  • /media/documentaries/bbc. секреты собак
  • /media/documentaries/бегемоты - жизнь в воде

Группа C — папка (дубль resolved-папки):

  • /media/movies/bezumnyj_maks_3_pod_kupolom_groma_1985_[torrents.ru]

Группы A и C — устранить через дедупликацию scanner'а (пропускать standalone если есть resolved canonical папка с тем же контентом).
Группа B — Tier 5 (agentic flow) или manual resolve как последний resort.

Следующий шаг: exhaustive tests → deploy → agentic flow

Задача: написать exhaustive тесты валидирующие каждый шаг парсинга для всех проблемных тайтлов — как незарезолвленных, так и тех, где создавались ручные NFO. Никаких ручных NFO не создавать — тул должен всё находить автоматически.

Тайтлы для exhaustive тестов:

Filename Ожидаемый title Ожидаемый year Проблема/баг
bezumnyj_maks_3_pod_kupolom_groma_1985_[torrents.ru] bezumnyj maks 3 pod kupolom groma 1985 Баг 12: _year_
Nehochuha.XVid.DVDRip.avi nehochuha nil
budil'nik 1984 budilnik 1984 апостроф soft-sign
novogodn'aya_pesenka_deda_moroza_1982 novogodnyaya pesenka deda moroza 1982 апостроф + год в underscore
таинственная жизнь собак (HDTVRip 720p, 2013) таинственная жизнь собак 2013 год в скобках со стороссей
шпион в снегах 2018 шпион в снегах 2018 год в конце
супер белки (2018) супер белки 2018 год в скобках
penguin meet the family (2020) penguin meet the family 2020 год в скобках
dolina.ekho.2025.atvp.web-dlrip.avc dolina ekho 2025 качество-маркеры
Stiratel.1996 stiratel 1996 год через точку
The.Frozen.Kingdom.of.the.Snow.Leopard.(2020) the frozen kingdom of the snow leopard 2020 точки как разделители
Generation.P.BDRip-AVC generation p nil буква как часть названия
Ni4ego_horoshego_v_otele_El_Royal_2018 nichego horoshego v otele el royal 2018 leet-speak + год
O_4em_govoryat_muzh4iny_2010 o chem govoryat muzhchiny 2010 leet-speak
Serebryanye_konki_2020 serebryanye konki 2020 год в underscore
bbc. the real jungle book bear 2012 the real jungle book bear 2012 BBC prefix + год
bbc. секреты собак секреты собак nil BBC prefix кириллица
Миграция. 2023г.mkv миграция 2023 Баг 10: кирилл. суффикс г
рики тики тави 1965 рики тики тави 1965
25е - первый день первый день nil числовой префикс