--- created: '2026-05-13' updated: '2026-05-13' status: planning tags: - kraken - media - jellyfin - transmission - swift - project --- # Media Toolbox на Кракене > Создано: 2026-05-13. Цель: полноценный медиасервер на Кракене (RPi 5) — перенос библиотеки с HTPC, автосортировка через kodi-media-sync, Jellyfin, торренты. --- ## Архитектура (целевая) ``` HTPC (Bazzite 192.168.1.86) └── /run/media/bazzite/Data/{Мультфильмы,Сериалы,movies,...} └─── rsync ──→ Kraken HDD /srv/.../media/ Kraken (RPi 5, 192.168.1.14) ├── /srv/dev-disk-by-uuid-.../media/ │ ├── movies/ ← фильмы │ ├── cartoons/ ← мультфильмы │ ├── series/ ← сериалы │ ├── documentaries/ ← документальные │ └── downloads/ ← папка Transmission (входящие) ├── Docker: Transmission (скачка торрентов) ├── Docker: Jellyfin (стриминг на TV/телефоны) └── Docker: kodi-media-sync (сортировщик + метаданные) kodi-media-sync (Swift CLI, cross-compile Mac → Linux ARM64) ├── Читает downloads/ + необработанные папки ├── Идентифицирует через Transmission RPC (если торрент) или поиск по имени ├── Создаёт NFO-файлы (Kodi/Jellyfin-совместимые) ├── Раскладывает по категориям (movies/cartoons/series/docs) ├── Обновляет пути скачки в Transmission через RPC API └── Запускается как download-complete скрипт Transmission Hermes cron (Кракен, 1-2x/day) └── kodi-media-sync --dry-run → лог → manual confirm / auto-apply TrueNAS (Taiga) └── Transmission → миграция на Крaken (или оставить для seed, скопировать БД торрентов) ``` --- ## Статус по шагам | Шаг | Статус | Заметки | |-----|--------|---------| | 1 — Исследование (Kodi lib на HTPC) | ✅ | Data: мультфильмы(229G) сериалы(116G) movies(673G) bbc(284G). kodi/movies/ — NFO+симлинки уже есть | | 2 — Wake HTPC + prevent sleep | ✅ | sleep/suspend/hibernate masked (systemctl mask). loginctl linger=yes. Процессы выживают после SSH | | 3 — Копирование медиа HTPC → Kraken | 🔄 | 4x rsync via systemd-run --user, активны. ~1.3TB total | | 4 — Transmission на Кракене | 🔲 | уже есть контейнер в /home/kraken/media/ | | 5 — Перенос torrent-базы с HTPC | ✅ | 7 торрентов Windows Transmission добавлены в Крaken Transmission (paused), пути обновить после rsync | | 6 — MediaFilesScraper: изучить + настроить | ✅ | Полный Swift 6 SPM. media-pipeline CLI. Пропатчен для Linux (AVFoundation stub, Swift 6 existential fix) | | 7 — Cross-compile Mac → Linux ARM64 | 🔲 | Swift toolchain для aarch64 | | 8 — Docker-образ kodi-media-sync на Кракене | 🔲 | | | 9 — Config: пути, Transmission, категории | 🔲 | | | 10 — Dry run: проверка сортировки | 🔲 | | | 11 — Jellyfin: настройка библиотек | 🔲 | уже есть контейнер | | 12 — Transmission download-complete hook | 🔲 | | | 13 — Hermes cron на Кракене | 🔲 | | | 14 — Руtracker-скилл (поиск/закачка) | 🔲 | | | 15 — Музыка: скачка + sync с TrueNAS | 🔲 | | --- ## Шаг 1 — Исследование: Kodi lib на HTPC **Цель:** найти реальную структуру медиабиблиотеки, где симлинки, куда ведут. ```bash ssh -i ~/.ssh/id_rsa bazzite@192.168.1.86 # Kodi userdata (может быть в двух местах) ls ~/.kodi/userdata/ ls ~/.kodi/userdata/sources.xml # список медиаисточников # Если Kodi с Windows раздела мигрировал ls /run/media/bazzite/Data/AppData/Roaming/Kodi/ 2>/dev/null # Найти симлинки в home find ~ -type l 2>/dev/null | head -30 # Медиа на Data разделе ls /run/media/bazzite/Data/ | grep -iE "film|movie|кино|мульт|serial|сери|doc" ``` **Ожидаемые пути на Data:** - `/run/media/bazzite/Data/Мультфильмы/` - `/run/media/bazzite/Data/Сериалы/` - `/run/media/bazzite/Data/movies/` - `/run/media/bazzite/Data/документальные/` (или аналог) --- ## Шаг 2 — Wake HTPC + предотвращение сна ### Wake on LAN ```bash # С Mac или Кракена: wakeonlan B0:6E:BF:60:6D:64 # или python3 ~/Automation/wake-on-lan.py ``` ### Предотвратить сон во время SSH / копирования **Вариант A — systemd-inhibit (рекомендуется):** ```bash # Запустить на HTPC в отдельной SSH-сессии, оставить висеть пока идёт копирование: systemd-inhibit --what=sleep:idle --who="media-copy" \ --why="Copying media to Kraken" --mode=block \ sleep infinity ``` Закрыть эту сессию = сон разрешён снова. **Вариант B — через systemd сервис-lockfile (долгосрочно):** Если SSH-сессия падает, нужен более надёжный способ. Создать временный `inhibit.service` который поднимается на время rsync. **Вариант C — xdg-screensaver (только экран):** ```bash # Только блокирует screensaver, не suspend while true; do xdg-screensaver reset; sleep 60; done & ``` **Рекомендация:** вариант A (systemd-inhibit). Запускать в tmux, чтобы сессия жила независимо от SSH: ```bash ssh bazzite@192.168.1.86 "tmux new-session -d -s inhibit 'systemd-inhibit --what=sleep:idle --who=media-copy --why=Copying --mode=block sleep 86400'" ``` --- ## Шаг 3 — Копирование медиа HTPC → Kraken ### Целевая структура на Кракене ``` /srv/dev-disk-by-uuid-49e8f586-3839-4c5d-a1e1-58bfc3579ade/media/ ├── movies/ ├── cartoons/ ├── series/ ├── documentaries/ └── downloads/ ← Transmission download dir └── complete/ ← сюда Transmission кладёт готовые ``` ### Создать директории ```bash ssh kraken@192.168.1.14 "mkdir -p /srv/dev-disk-by-uuid-49e8f586-3839-4c5d-a1e1-58bfc3579ade/media/{movies,cartoons,series,documentaries,downloads/complete,downloads/incomplete}" ``` ### rsync HTPC → Kraken (прямо с Кракена) ```bash # Запустить на Кракене (pull с HTPC): HDD=/srv/dev-disk-by-uuid-49e8f586-3839-4c5d-a1e1-58bfc3579ade # Мультфильмы rsync -avh --progress --no-links \ bazzite@192.168.1.86:"/run/media/bazzite/Data/Мультфильмы/" \ "$HDD/media/cartoons/" # Сериалы rsync -avh --progress --no-links \ bazzite@192.168.1.86:"/run/media/bazzite/Data/Сериалы/" \ "$HDD/media/series/" # Фильмы (уточнить точное имя папки) rsync -avh --progress --no-links \ bazzite@192.168.1.86:"/run/media/bazzite/Data/movies/" \ "$HDD/media/movies/" # Документальные (если есть) rsync -avh --progress --no-links \ bazzite@192.168.1.86:"/run/media/bazzite/Data/документальные/" \ "$HDD/media/documentaries/" 2>/dev/null || true ``` > ⚠️ `--no-links` — не копировать симлинки как симлинки, следовать им. > ⚠️ Для SSH без пароля с Кракена нужен ключ: `ssh-copy-id -i ~/.ssh/id_rsa bazzite@192.168.1.86` ### Альтернатива — пушить с HTPC через SSH: ```bash # На HTPC: rsync -avh --progress /run/media/bazzite/Data/Мультфильмы/ \ kraken@192.168.1.14:/srv/.../media/cartoons/ ``` --- ## Шаг 4 — Transmission на Кракене Transmission уже задеплоен вместе с Jellyfin в `/home/kraken/media/docker-compose.yml`. **Проверить конфиг:** ```bash cat /home/kraken/media/docker-compose.yml ``` **Download dir** должен быть смонтирован как HDD/media/downloads. **Порты:** 9091 (RPC), 51413 (peers) **Если Transmission ещё не настроен** — проверить и обновить docker-compose, добавить volume: ```yaml volumes: - /srv/dev-disk-by-uuid-.../media/downloads:/downloads - /srv/dev-disk-by-uuid-.../docker/transmission:/config ``` --- ## Шаг 5 — Перенос torrent-базы с HTPC ### Найти торрент-клиент на HTPC ```bash ssh bazzite@192.168.1.86 # Что стоит? which transmission-daemon qbittorrent-nox rtorrent 2>/dev/null systemctl list-units | grep -iE "torrent|transmission|qbit" # Transmission (если есть): ls ~/.config/transmission/torrents/ | head -10 ls ~/.config/transmission/resume/ | head -10 # qBittorrent: ls ~/.local/share/data/qBittorrent/BT_backup/ | head -10 ``` ### Если Transmission на Bazzite: ```bash # Скопировать на Кракен: rsync -avh bazzite@192.168.1.86:~/.config/transmission/ \ kraken@192.168.1.14:/tmp/htpc-transmission/ ``` ### Если торрент-клиент был на Windows (TrueNAS Transmission): Торрентная БД TrueNAS уже работает. Нужно решить: - **Вариант A:** Перенести TrueNAS Transmission на Крaken (один клиент) - **Вариант B:** Оставить TrueNAS для seed, Крaken для новых загрузок **Миграция `.torrent` + `.resume` файлов:** ```bash # Скопировать с TrueNAS (через duckdns): rsync -avh -e "ssh -i ~/.ssh/id_rsa" \ truenas_admin@mallexxx.duckdns.org:/mnt/RED_2TB/docker/transmission/ \ /tmp/taiga-transmission/ # Поправить пути в .resume файлах: # Старый путь TrueNAS: /mnt/storage/Downloads/... # Новый путь Кракена: /downloads/complete/... for f in /tmp/taiga-transmission/resume/*.resume; do # .resume это bencoded файл — нужен python с bencode или transmission-edit echo "$f" done ``` > ⚠️ Файлы `.resume` — бинарный bencode-формат. Для правки путей использовать: > `pip install bencoder.pyx` или `transmission-remote --torrent N --find /new/path` > Проще: после импорта торрентов запустить media-sync с --fix-paths флагом через RPC API. ### Исправление путей через Transmission RPC: ```bash # Transmission RPC: изменить путь для конкретного торрента curl -s -u user:pass http://kraken:9091/transmission/rpc \ -H "X-Transmission-Session-Id: TOKEN" \ -d '{"method":"torrent-set-location","arguments":{"ids":[N],"location":"/downloads/complete/FolderName","move":false}}' ``` **kodi-media-sync должен уметь это автоматически** (см. шаг 6). --- ## Шаг 6 — kodi-media-sync: функциональность ### Текущее состояние проекта Проект `~/Developer/kodi-media-sync` (Swift): - `Config.swift` — читает config.json: `transmission` URL, `directories[]`, `output.{movies,series}` - `MediaSync.swift` — scaffold: сканирует директории, вызывает `updateMetadata` (пустая) - `Path.swift` — утилиты для файловой системы **Нужно реализовать:** ### 6.1 Transmission RPC клиент ```swift // Sources/TransmissionClient.swift struct TransmissionClient { let url: URL // Получить все торренты func getTorrents() async throws -> [Torrent] // Найти торрент по имени файла / папке func findTorrent(forPath path: Path) async throws -> Torrent? // Обновить путь торрента func setLocation(torrentId: Int, location: Path) async throws } ``` ### 6.2 Идентификация медиа ```swift // Sources/MediaIdentifier.swift enum MediaType { case movie(title: String, year: Int?) case series(title: String, season: Int?, episode: Int?) case cartoon(title: String, year: Int?) case documentary(title: String, year: Int?) case unknown } struct MediaIdentifier { // Из имени папки/файла → тип медиа + нормализованное название func identify(path: Path, torrent: Torrent?) -> MediaType // Поиск метаданных (TMDB/OMDB/локальный поиск) func fetchMetadata(for media: MediaType) async throws -> MediaMetadata } ``` **Алгоритм идентификации:** 1. Если есть торрент в Transmission — взять имя торрента, категорию 2. Парсить имя файла/папки: регексы для `S01E01`, год `(2024)`, качество `1080p` 3. Для документалок типа "знакомимся с кабанами" — поиск по названию (TMDB API) 4. Маппинг исходной папки → тип: `Мультфильмы/` → cartoon, `Сериалы/` → series ### 6.3 NFO-файлы (Kodi/Jellyfin) ```swift // Sources/NFOWriter.swift // Формат Kodi NFO: https://kodi.wiki/view/NFO_files/Movies struct NFOWriter { func writeMovieNFO(_ metadata: MediaMetadata, to path: Path) throws func writeSeriesNFO(_ metadata: MediaMetadata, to path: Path) throws func writeTVShowNFO(_ metadata: MediaMetadata, to path: Path) throws } ``` ### 6.4 Config расширение ```json { "transmission": "http://user:pass@192.168.1.14:9091/transmission/rpc", "tmdb_api_key": "...", "directories": [ "/media/downloads/complete", "/media/movies", "/media/cartoons" ], "output": { "movies": "/media/movies", "series": "/media/series", "cartoons": "/media/cartoons", "documentaries": "/media/documentaries" }, "dry_run": false, "category_hints": { "/media/cartoons": "cartoon", "/media/series": "series", "/media/documentaries": "documentary" } } ``` ### 6.5 CLI флаги ``` kodi-media-sync [--config path] [--dry-run] [--path ] [--fix-paths] --dry-run Показать что будет сделано, не двигать файлы --path PATH Обработать только конкретную папку/файл --fix-paths Обновить пути в Transmission для уже существующих файлов ``` --- ## Шаг 7 — Cross-compilation Mac → Linux ARM64 **Swift на Mac имеет встроенный cross-compiler для Linux.** ### Установить Swift toolchain для Linux (если не стоит): ```bash # На Mac: swiftly install latest # или скачать Linux ARM toolchain: # https://www.swift.org/install/linux/ ``` ### Build для aarch64-linux: ```bash cd ~/Developer/kodi-media-sync # Вариант A — через Docker buildx (рекомендуется): docker buildx build --platform linux/arm64 \ -f Dockerfile.linux \ -t kodi-media-sync:arm64 \ --output type=local,dest=./build-arm64 . # Вариант B — swift cross-compile (нужен SDK): swift build --triple aarch64-unknown-linux-gnu \ --sdk /path/to/linux-arm64-sdk ``` ### Dockerfile.linux для Крaken: ```dockerfile FROM swift:5.9-jammy AS builder WORKDIR /build COPY . . RUN swift build -c release FROM ubuntu:22.04 RUN apt-get update && apt-get install -y libstdc++6 libgcc-s1 && rm -rf /var/lib/apt/lists/* COPY --from=builder /build/.build/release/kodi-media-sync /usr/local/bin/ COPY config.json /etc/kodi-media-sync/config.json ENTRYPOINT ["kodi-media-sync"] CMD ["--config", "/etc/kodi-media-sync/config.json"] ``` > ⚠️ Собирать образ на Mac через buildx с эмуляцией QEMU — не на RPi5 (undervoltage под нагрузкой)! ### Deploy на Кракен: ```bash # Сохранить образ и скопировать: docker save kodi-media-sync:arm64 | gzip | ssh kraken@192.168.1.14 "docker load" ``` --- ## Шаг 8 — Docker-образ на Кракене ### `/home/kraken/media-sync/docker-compose.yml`: ```yaml version: '3.8' services: kodi-media-sync: image: kodi-media-sync:arm64 container_name: kodi-media-sync restart: "no" # запускается по требованию, не автостарт volumes: - /srv/dev-disk-by-uuid-.../media:/media - /srv/dev-disk-by-uuid-.../docker/media-sync:/config environment: - CONFIG=/config/config.json network_mode: host # доступ к Transmission на localhost ``` ### Запуск (разовый): ```bash cd /home/kraken/media-sync sudo docker compose run --rm kodi-media-sync --dry-run sudo docker compose run --rm kodi-media-sync ``` --- ## Шаг 9 — Config для Кракена ```json { "transmission": "http://admin:pass@192.168.1.14:9091/transmission/rpc", "tmdb_api_key": "КЛЮЧ_ИЗ_TMDB", "directories": [ "/media/downloads/complete" ], "category_hints": { "/media/cartoons": "cartoon", "/media/series": "series", "/media/documentaries": "documentary", "/media/movies": "movie" }, "output": { "movies": "/media/movies", "series": "/media/series", "cartoons": "/media/cartoons", "documentaries": "/media/documentaries" }, "dry_run": false } ``` > TMDB API key: получить на https://www.themoviedb.org/settings/api (бесплатно) --- ## Шаг 10 — Dry run и ручная проверка ```bash # Dry run — показывает что будет сделано sudo docker run --rm \ -v /srv/.../media:/media \ -v /srv/.../docker/media-sync:/config \ kodi-media-sync:arm64 --dry-run # Проверить проблемные документалки sudo docker run --rm ... kodi-media-sync:arm64 --dry-run \ --path "/media/downloads/complete/знакомимся с кабанами" # Проверить NFO файлы cat /srv/.../media/movies/SomeMovie/SomeMovie.nfo ``` **Что проверить:** - [ ] Фильмы попали в movies/, мультфильмы в cartoons/ и т.д. - [ ] NFO-файлы созданы и содержат правильные title/year/plot - [ ] Документалки с нестандартными названиями найдены через TMDB - [ ] Торренты в Transmission показывают правильные пути --- ## Шаг 11 — Jellyfin: настройка библиотек Jellyfin уже работает на Кракене: http://192.168.1.14:8096 ### Категории библиотек: | Библиотека | Тип | Путь | Язык | |------------|-----|------|------| | Детские мультфильмы | Animated Movies | /media/cartoons | ru | | Детские сериалы | Series | /media/cartoons-series | ru | | Документальные | Movies | /media/documentaries | ru | | Сериалы | TV Shows | /media/series | ru | | Фильмы | Movies | /media/movies | ru | ### Настройки библиотеки: - **Metadata Language:** Russian (или auto-detect) - **NFO reading:** включить (Kodi-compatible NFO) - **Sort by:** Date Added (поле из NFO), Rating, Title ### Сортировка и фильтрация в UI (Jellyfin): - Детские: отдельная коллекция "Детям" → мультфильмы + детские сериалы - Можно использовать **Collections** для кастомных подборок - **Recently Added** — показывает по дате скачки (metadata: dateadded в NFO) - Рейтинг: IMDB/TMDB — парсится из NFO `` тег --- ## Шаг 12 — Transmission download-complete hook Transmission вызывает скрипт при завершении скачки: ```bash # settings.json Transmission (в /config/): # "script-torrent-done-enabled": true, # "script-torrent-done-filename": "/usr/local/bin/on-download-complete.sh" ``` ### `/usr/local/bin/on-download-complete.sh` (внутри контейнера): ```bash #!/bin/bash # Transmission передаёт переменные: # TR_TORRENT_NAME, TR_TORRENT_DIR, TR_TORRENT_ID, TR_APP_VERSION logger "Transmission: download complete: $TR_TORRENT_NAME" # Запустить media-sync для этой конкретной папки docker run --rm \ -v /srv/.../media:/media \ -v /srv/.../docker/media-sync:/config \ kodi-media-sync:arm64 \ --path "$TR_TORRENT_DIR/$TR_TORRENT_NAME" ``` > ⚠️ Скрипт должен быть доступен изнутри контейнера Transmission, или монтируется туда. > Альтернатива: Transmission вызывает скрипт на хосте → хост запускает docker run. --- ## Шаг 13 — Hermes cron на Кракене **Добавить через Hermes на Кракене:** ``` Крон: каждые 12 часов Задача: запустить kodi-media-sync --dry-run на папке downloads, прислать отчёт в Telegram ``` ### Cron job (добавить в Hermes Кракена): ``` Schedule: 0 */12 * * * Prompt: Запусти kodi-media-sync на Кракене: sudo docker run --rm \ -v /srv/.../media:/media \ -v /srv/.../docker/media-sync:/config \ kodi-media-sync:arm64 --dry-run Пришли отчёт: что было распознано, что нет. ``` --- ## Шаг 14 — Rutracker / торрент-поиск скилл **Добавить скилл Кракену:** - Поиск по Rutracker (может требовать авторизацию) - Альтернативы: Jackett (агрегатор) + Prowlarr - Добавление торрента в Transmission через RPC API **Jackett** (рекомендуется как агрегатор): ```yaml # docker-compose для Jackett: services: jackett: image: linuxserver/jackett ports: - "9117:9117" volumes: - /srv/.../docker/jackett:/config ``` Jackett поддерживает Rutracker + сотни других tracker-ов, отдаёт unified API. --- ## Шаг 15 — Музыка: скачка + sync с TrueNAS ### Структура: ``` Kraken: /media/music/ ├── [Artist]/ │ └── [Album]/ │ └── *.mp3 TrueNAS: /mnt/RED_2TB/storage/Music/ (master copy) ``` ### kodi-media-sync — расширение для музыки: - Идентификация: MusicBrainz / Beets - Тегирование через `beets` (python tool) - Sync Kraken → TrueNAS через rsync ### Jellyfin музыкальная библиотека: - Тип: Music - Путь: /media/music - Плеер: Jellyfin + Finamp на Android --- ## Технические детали ### HTPC - IP: 192.168.1.86 - SSH: `ssh -i ~/.ssh/id_rsa bazzite@192.168.1.86` - Data mount: `/run/media/bazzite/Data/` - WoL MAC: `B0:6E:BF:60:6D:64` ### Крaken - IP: 192.168.1.14 - SSH: `ssh -i ~/.ssh/id_rsa 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 ### kodi-media-sync - Исходники: `~/Developer/kodi-media-sync/` (Mac) - Язык: Swift 5.9+ - Зависимости: swift-argument-parser - Target: Linux ARM64 (aarch64) ### TrueNAS (Taiga) - SSH: `truenas_admin@mallexxx.duckdns.org` - Transmission config: `/mnt/RED_2TB/docker/transmission/` - Downloads: `/mnt/RED_2TB/storage/Downloads/` --- ## Журнал выполнения ### 2026-05-13 — Активная работа - Разбужен HTPC, сон заблокирован: `systemctl mask` sleep/suspend + `loginctl enable-linger bazzite` - 4x rsync запущены через `systemd-run --user` (выживают без SSH): ~1.3TB - Torrent-база Windows найдена (7 торрентов, `D:/Movies`), скопирована в `/tmp/transmission-backup/` - Изучен MediaFilesScraper: полный Swift 6.0 SPM, бинарь `media-pipeline`, команды scan/resolve/apply/sync - Пропатчен AVFoundationMediaMetadataReader для Linux (`#if canImport(AVFoundation)` + stub) - `Package.swift`: платформа понижена до macOS(.v14) для совместимости - `Dockerfile.kraken` + `docker-compose.kraken.yml` написаны - `config.kraken.json` готов: Transmission RPC, TMDB/KP, все провайдеры, `dry_run=true` - macOS build запущен в фоне для проверки компиляции ### 2026-05-13 — Сессия 2 (Docker build + resolve) **Docker build `media-pipeline:kraken`** - `.dockerignore` добавлен — исключает `.build/` (6.7GB), OOM устранён - Colima: 24GB RAM, 8 CPU; `--memory=20g -j 1` - Linux-фиксы: `#if os(Linux)` для CF-encoding (RutrackerAPI), `FoundationNetworking` в 3 файлах - Образ `media-pipeline:kraken` (78MB) собран и задеплоен на Кракен ✅ **Resolve dry run (первый)** - 6 region'ов; **1 resolved**: Black Mirror S06E01 → `seriesEpisodesNumbered`, support=0.90 ✅ - Проблема: `ProviderSearchStrategy.aggregateCandidates` — `originalVariant` выбирался по non-ASCII (кириллица), которая давала 0 результатов от TMDB - **Фикс**: `originalVariant` → первый вариант с реальными результатами; high-confidence (≥0.85) single-variant принимается без unique-result требования - Все 6 ProviderSearchStrategy тестов прошли, образ пересобран и задеплоен - `on-download-complete.sh` установлен, прописан в Transmission settings ✅ **Текущее состояние** - rsync идёт (~19-20GB из сотен GB по категориям) - Следующий dry run — когда rsync скопирует больше файлов с правильной структурой подпапок ### Что осталось - [ ] Дождаться rsync (~1.3TB), прогнать полный dry run - [ ] torrent-set-location для 7 перенесённых торрентов (после rsync) - [ ] Настроить Jellyfin библиотеки (шаг 11) - [ ] Hermes cron на Кракене (шаг 13) - [ ] Rutracker-скилл (шаг 14)