Skip to content

emildg8/MediaInboxToolkit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

39 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MediaInboxToolkit

Отдельный инструмент для входной сортировки видео (inbox → Сериалы / Фильмы / _SortReview), с русскими именами через TMDB, Blu-ray remux и отчётами CSV/TXT.

SeriesToolkit (стабильная линия 0.2.2) остаётся продуктом нормализации уже разложенных библиотек сериалов. Этот пакет — расширяемый конвейер «до библиотеки»; дальнейшая полировка имён эпизодов — отдельным запуском SeriesToolkit по целевым папкам.

Требования

  • Репозиторий Script_Rename_ALLVideo: рядом с каталогом MediaInboxToolkit в корне лежит Fetch-VideoMetadata.ps1.
  • Для TMDB: переменная окружения TMDB_API_KEY (или см. Fetch-VideoMetadata.ps1).

Быстрый запуск

cd <корень репозитория>\MediaInboxToolkit
powershell -NoProfile -ExecutionPolicy Bypass -File .\MediaInboxToolkit.ps1 -UseTmdb -DryRun

Минимальный GUI (WinForms):

powershell -NoProfile -ExecutionPolicy Bypass -File .\Start-MediaInboxToolkitGui.ps1

Политика по умолчанию: .\sort-inbox.example.json (нейтральные пути). Пример разнесённой библиотеки с папками «Сериалы / Фильмы / Аниме / …»: .\sort-inbox.library-layout-advanced.example.json — скопируйте и замените nasShareRoot на свой UNC; лишние ключи в destinations можно удалить. При -Apply и folders.createDestinationRootsOnApply: true целевые корни из политики создаются, если их ещё нет.

Обезличенный старт (для любого пользователя)

Ни один скрипт не требует персонального UNC. Используйте один из вариантов:

  • Сетевой NAS/SMB: \\NAS\media\Video\Sort
  • Локальный диск: D:\Media\Video\Sort
  • Внешний диск: E:\Video\Sort

Для оркестрационных скриптов можно не передавать -SortRoot/-InboxPath, а задать переменную окружения:

$env:MIT_INBOX_ROOT = 'D:\Media\Video\Sort'

Локальный layout-конфиг для спецвыпусков: скопируйте media-library-layout.local.example.json в media-library-layout.local.json и заполните своими путями. Этот файл не должен попадать в git.

После проверки CSV в LOGS\: добавьте -Apply.

Оркестратор (inbox → SeriesToolkit)

powershell -NoProfile -ExecutionPolicy Bypass -File .\MediaInboxToolkit.Orchestrate.ps1 `
  -InboxPath '\\NAS\share\Video\Sort' -UseTmdb -DryRun

С -Apply и -RunSeriesToolkitAfter вторым шагом вызывается SeriesToolkit\SeriesToolkit.Engine.ps1. Корни можно задать вручную (-SeriesToolkitRoots) и/или взять из последнего sort-inbox-*.csv шага 1: -SeriesToolkitRootsFromLastCsv (или явный -SeriesToolkitCsvPath).

Публикация в отдельный репозиторий GitHub

Из корня монорепо при настроенном remote media-inbox (ваш standalone-репозиторий MediaInboxToolkit) :

powershell -NoProfile -ExecutionPolicy Bypass -File .\MediaInboxToolkit\Publish-MediaInboxStandalone.ps1 -ForceWithLease

-ForceWithLease нужен, если на GitHub в main уже есть коммиты вне текущего subtree (типично после ручных правок).

После успешного push скрипт создаёт и отправляет тег v<version> из version.json, если такого тега ещё нет на media-inbox. На GitHub срабатывает workflow Release (.github/workflows/release.yml): оформленное описание из CHANGELOG.md + ZIP с дистрибутивом и SHA-256.

Связка с SeriesToolkit

MediaInboxToolkit раскладывает файлы по структуре; SeriesToolkit (стабильная линия 0.2.2) полирует имена эпизодов уже в целевых папках. Общий модуль метаданных — Fetch-VideoMetadata.ps1.

Пакетное RU-переименование в Sort (до MediaInbox)

Для ручной партии или узкого инбокса без полного MIT/ffprobe:

cd <repo>\MediaInboxToolkit\Scripts
# sort-rename.batch.example.json → sort-rename.local.json (sortRoot, списки фильмов/сериалов)
powershell -NoProfile -ExecutionPolicy Bypass -File .\Apply-SortRussianRename.ps1 -ConfigPath .\sort-rename.local.json -Apply
powershell -NoProfile -ExecutionPolicy Bypass -File .\Update-SortEpisodeRuTitles.ps1 -SortRoot '\\NAS\share\Video\Sort' -Apply

После ошибочного SeriesToolkit или дублей сезонов:

powershell -NoProfile -ExecutionPolicy Bypass -File .\Repair-SortInboxLayout.ps1 -Apply
powershell -NoProfile -ExecutionPolicy Bypass -File .\Sync-SortEpisodeTitlesFromTmdb.ps1 -Apply
powershell -NoProfile -ExecutionPolicy Bypass -File .\Export-SortInboxAudit.ps1

Пример политики раскладки в основную библиотеку TNAS: sort-inbox.emilian-tnas.example.json. Конвейер NAS + qBittorrent: docs/TERRAMASTER-QBIT-PIPELINE.md.

Плоские эпизоды в папке мультсериала

Если в каталоге шоу лежат отдельные файлы без SxxEyy (только название выпуска), их можно разнести по подпапкам Сезон N и переименовать по данным TMDB:

  • Скрипт: Scripts/Resolve-LooseCartoonEpisodesFromTmdb.ps1
  • Конфиг UTF-8: Scripts/Resolve-LooseCartoonEpisodesFromTmdb.config.json (cartoonsRoot, список шоу с tvId, опционально torrentScanRoots и блок qbittorrent)
  • Ключ TMDB: TMDB_API_KEY (или см. Fetch-VideoMetadata.ps1)

Проверяйте tvId на themoviedb.org. Пример: Robot Chicken709; число 1433 там — American Dad!, для «Робоцыпа» оно не подходит.

Пример из корня монорепозитория:

powershell -NoProfile -ExecutionPolicy Bypass -File .\MediaInboxToolkit\Scripts\Resolve-LooseCartoonEpisodesFromTmdb.ps1 -WhatIf

Уберите -WhatIf, когда результат устраивает.

Политика (расширения)

  • destinations — любые именованные корни (не только series / cartoons / movies / review): например animeSeries, animeMovies; пути относительно nasShareRoot.
  • destinationsByKind — карта вида контента (MediaInboxToolkit.ContentKinds.ps1) → имя ключа из destinations.
  • destinationsByKindMinConfidence — минимальная уверенность эвристики (0–100), иначе используется прежняя логика (preferCartoonsSubfolder / сериал vs фильм).
  • safetyrequireSourceUnderInbox, skipSourceIfUnderLibrary + libraryRootRelatives, чтобы не трогать файлы уже в библиотеке.
  • tmdbKindRefinement — уточнение «аниме vs мульт» по TMDB (жанр Animation + регион).
  • folders.createDestinationRootsOnApply — перед переносом создать все каталоги из destinations, если отсутствуют.
  • classificationfolderSeasonContext (папка Season N / N season + файл NN.; опционально orphanSeasonFolderSeriesMap для одиночной папки сезона без родителя-шоу), tvSpecialFilenameBoost (Robot Chicken Star Wars Episode I→TV), movies.allowMissingYearIfTmdbMatched, cartoonMovieBasenameRegexes (массив regex по имени файла: при совпадении и эвристике «фильм» вид контента принудительно cartoon_moviedestinationsByKind.cartoon_movie, до TMDB; узкие шаблоны, чтобы не задеть живые фильмы). seriesQueryRewrites — до поиска TMDB: массив { "pattern": "<regex>", "seriesGuess": "<строка для поиска TMDB>", "matchField": "<опционально>" }; правила идут по порядку, при совпадении текущий SeriesGuess подменяется значением поля seriesGuess, затем применяется следующее правило. matchField (по умолчанию seriesGuess): basename — regex к stem имени файла (без расширения); relativePath — к пути файла относительно инбокса (\); seriesGuessOrBasename — сначала SeriesGuess, иначе stem. Примеры: Wednesday / Peacemaker из basename, Invincible.2021 в имени файла→Invincible, китайский заголовок папки только в SeriesGuess, путь с «Подозрительная сова»→точное имя шоу. seriesFolderByTmdbTvId — после матча TMDB: объект "<tmdb tv id>": "Имя папки" переопределяет SeriesFolder (например Invincible 95557Непобедимый); в CSV в заметках появится folder_tv_id_policy.

Документация

Архитектура vNext (каркас)

MediaInboxToolkit теперь содержит каркас Toolkits/:

  • Toolkits/SeriesToolkit/ — legacy-слот для поэтапной интеграции существующего SeriesToolkit;
  • Toolkits/VideoMetaToolkit/ — отдельный слот под новый модуль описаний/постеров/актёров (VideoMetaToolkit.ps1 — заготовка launcher).

Текущие рабочие скрипты пока остаются на прежних путях; перенос кода выполняется постепенно.

Версии и журнал

  • version.json, CHANGELOG.md, Bump-Version.ps1 — как в SeriesToolkit.
  • Ветка Git: master.

Логи

По умолчанию .\LOGS\ (каталог в .gitignore). Для полного текстового транскрипта прогона (включая ошибки TMDB в консоли) и блока POST-RUN SUMMARY в конце файла: .\Run-DryRunTranscript-Example.ps1 (параметры -InboxPath / -PolicyPath при необходимости).

Разложение только внутри Sort (подкаталог Sort\_Workspace\…, затем SeriesToolkit по сериалам): .\Organize-SortInPlace.ps1 и политика sort-inbox.workspace-inside-sort.json (scope.excludeDirectoryNames: _Workspace). Под _Workspace в политике используются ASCII-имена (series, movies, …), чтобы лаунчер не ломался на кодировке консоли; русские имена шоу/эпизодов задаёт TMDB.

Тот же сценарий, но папка Video вместо _Workspace: политика sort-inbox.video-under-sort.example.json (исключение сканирования: Video). В folders заданы skeletonProfile: ascii, workspaceSeriesToolkitSubfolders и skeletonExtraRelatives — дополнительные пустые каталоги (документалистика, концерты и т.д.); их создаёт .\New-MediaInboxDestinationSkeleton.ps1 (движок сортировки их не использует, пока не добавите ключи в destinations / destinationsByKind). Доп. вариант скелета — зонт «Время приключений» (один корень и три подшоу: Финн и Джейк / Далёкие земли / Фионна и Кейк): готовый массив skeletonExtraRelatives в sort-inbox.skeleton-extras-adventure-time-umbrella.example.json (ветка под …\Video\cartoons\…); для кириллических корней библиотеки — sort-inbox.skeleton-extras-adventure-time-umbrella.cyrillic.example.json (…\Video\Мультсериалы\…). Скопируйте элементы в folders.skeletonExtraRelatives своего sort-inbox.*.local.json. Кириллический обезличенный вариант тех же правил: sort-inbox.video-under-sort.cyrillic.example.json (nasShareRoot в примере нейтральный — скопируйте в sort-inbox.*.local.json и пропишите свой UNC). Этап «скелет + DryRun»: .\Invoke-MediaInboxSortStage1.ps1 или -SkeletonProfile Cyrillic; ожидание нового CSV после долгого DryRun: .\Watch-MediaInboxToolkitCsv.ps1. Перенос: .\Invoke-MediaInboxSortStage3Apply.ps1 (введите YES; -Force без паузы). Полный in-place + SeriesToolkit: .\Organize-SortVideoUnderSort.ps1 (имена подпапок под Sort\Video берутся из политики). GUI: пресет политики + кнопка «Создать скелет». Локальные пути — sort-inbox.<имя>.local.json.gitignore).

Ручная валидация CSV перед переносом

Быстрый конвейер

  1. DryRun → sort-inbox-*.csv
  2. .\New-MediaInboxReviewCsv.ps1 -CsvPath <csv>*.review.csv (колонки HumanOverride / HumanComment / HumanDestOverride уже пустые). По умолчанию APPLY только при Confidence >= 70. Для сериалов с уже собранным путём в DestFullPath (фрагмент - SxxEyy -) дополнительно разрешается APPLY при Confidence >= 55 (параметры -ApplyMinConfidence / -SeriesEpisodeStructuredMinConfidence, 0 отключает льготу для сериалов).
  3. .\Update-MediaInboxReviewCsvAutoDecide.ps1 -CsvPath <review.csv> -TorrentDirectory "C:\Users\<user>\Downloads"*.auto.csv
    Логика торрентов: совпадение rutracker-… в пути и в имени .torrent; разбор метаданных .torrent (имена файлов внутри раздачи) — если имя видеофайла в CSV встречается ровно в одной локальной раздаче, применяется эта раздача (в т.ч. номер темы из имени .torrent, без id в пути). При одинаковом счёте совпадения слов у нескольких раздач: совпадение имени файла с листом в .torrent, затем SxxEyy / Exx в именах файлов раздачи, затем topic id в пути; при двух кандидатах и совпадении mit_dur_s из CSV с ffprobe по файлу — предпочтение раздаче с одним видео-листом.
    Опционально qBittorrent Web UI (если полный путь SourceFullPath в CSV совпадает с путём, который отдаёт клиент в save_path + файлы раздачи): тот же базовый URL, что в браузере, без завершающего слэша, например https://хост:порт/qbittorrent. Если логина нет — учётку не указывайте; при самоподписанном HTTPS: -QbittorrentSkipCertificateCheck. Переменные: MIT_QBIT_WEBUI, при необходимости MIT_QBIT_USER / MIT_QBIT_PASS.
    Если qBittorrent качает в один UNC (например \\NAS\qBittorrent\...\downloads), а в CSV уже пути после переноса в сортировку (\\NAS\media\Video\Sort\...), задайте пару префиксов: -QbittorrentCsvSourcePrefix (корень, как в CSV) и -QbittorrentDownloadRootPrefix (корень каталога загрузок qBittorrent). Относительный хвост пути тогда подставляется под каталог загрузок для поиска в индексе API. То же через MIT_QBIT_CSV_PREFIX и MIT_QBIT_DOWNLOAD_ROOT. Либо блок qbittorrent в media-library-layout.local.json (webUiUrl, csvSourcePrefix, downloadRootPrefix) — подхватывается, если параметры и env пустые. У других пользователей клиент не обязателен — достаточно папки с .torrent. Спецвыпуски (без SxxEyy в имени файла): media-library-layout.example.jsonmedia-library-layout.local.json.gitignore). Если лежит рядом со скриптом и не заданы -MediaLibraryLayoutJson / MIT_MEDIA_LIBRARY_JSON, он подхватывается сам. В JSON: videoLibraryRoot (UNC до Video), scanRoots (подкаталоги с сериалами: Мультсериалы, Сериалы, Анимесериалы и т.д.). Иначе корень: MIT_VIDEO_LIBRARY_ROOT или -MediaLibraryVideoRoot. При запуске строится индекс подпапок; для строк REVIEW без эпизода срабатывают explicitRules (regex имени файла + имени папки + libraryRoot). Для Анимесериалов при совпадении с ovaFilenameRegex путь ведёт в подпапку ovaSubfolderName (например OVA). Опциональный fuzzy по Notes (fuzzyEnabled, fuzzyUniqueMinScore) — только один явный победитель. Отключить весь блок «плоско в корень сериала»: -SkipCartoonSeriesRootFlat. В консоли смотрите MediaLibraryRoot и SeriesIndexEntries (должно быть > 0, если NAS доступен).
  4. .\Prepare-MediaInboxReviewForHuman.ps1 -CsvPath <*.auto.csv>*.for-human.csv + *.for-human.html
    Откройте HTML в браузере: цветные блоки REVIEW (жёлтый) / APPLY (зелёный) / SKIP (серый), таблицы по разделам.
  5. Правки в *.for-human.csv (Excel / LibreOffice):
    • HumanOverride — пусто = брать Decision; иначе APPLY, SKIP, REVIEW (перекрывает Decision при переносе).
    • HumanDestOverride — полный путь файла назначения, если нужно не то, что в DestFullPath.
    • HumanComment — заметка для себя (на перенос не влияет).
    • Цвет заливки в Excel необязателен; достаточно колонок.
  6. .\Invoke-MediaInboxApplyReviewedCsv.ps1 -CsvPath <ваш исправленный csv>-WhatIf для проверки). Корень инбокса: -InboxRoot (по умолчанию \\…\Video\Sort). Цели в библиотеке (\\…\Video\Мультсериалы, …\Фильмы и т.д.) разрешены, если задан -MediaLibraryVideoRoot, переменная MIT_VIDEO_LIBRARY_ROOT или videoLibraryRoot в media-library-layout.local.json.

Отдельно только HTML из любого CSV

.\Export-MediaInboxReviewHtml.ps1 -CsvPath <csv>

Сводка цифр

.\Get-MediaInboxReviewedCsvSummary.ps1 -CsvPath <csv>

About

MediaInboxToolkit: inbox → библиотека (видео, TMDB, BD-remux)

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors