Files
universal-merge/universal_merger.sh
T
2025-07-08 17:41:22 +07:00

141 lines
6.6 KiB
Bash
Executable File

#!/bin/bash
#==============================================================================
# Универсальный скрипт для обработки медиафайлов с TUI-интерфейсом
#==============================================================================
# --- Подключение модулей ---
SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd)
source "$SCRIPT_DIR/core_ui.sh"
source "$SCRIPT_DIR/core_logic.sh"
source "$SCRIPT_DIR/core_actions.sh"
# --- Конфигурация по умолчанию ---
DEFAULT_ROOT_PATH="/var/www/nextcloud/data/grayhook/files/"
DEFAULT_TORRENTS_DIR="${DEFAULT_ROOT_PATH}/Torrents"
DEFAULT_ARCHIVE_DIR="${DEFAULT_ROOT_PATH}/Archive/Anime"
# Путь к временному файлу для mkvmerge.
# Рекомендуется использовать путь в tmpfs (/tmp) или на быстром диске (NVMe).
TEMP_MERGE_FILE="/tmp/tmp.mkv"
# --- Переменные состояния ---
# ... (все переменные состояния остаются без изменений)
VIDEO_SRC_DIR=""
AUDIO_SRC_DIR=""
OUTPUT_BASE_DIR=""
OUTPUT_SERIES_NAME=""
SEASON_NUMBER="01"
VIDEO_FILE_PATTERN="*.mkv"
AUDIO_FILE_PATTERN="*.mka"
EPISODE_NUMBER_REGEX='.* ([0-9]{2}) .*'
OUTPUT_FILENAME_TEMPLATE="{SERIES_NAME} s{SEASON}e{EPISODE}.mkv"
CURRENT_ACTION=""
# --- НОВАЯ ВСПОМОГАТЕЛЬНАЯ ФУНКЦИЯ ---
# Обрезает путь для красивого отображения в меню, оставляя конец строки.
# $1: Полный путь
# $2: Максимальная длина отображения
# $3: Текст, если путь не задан
truncate_path_for_display() {
local full_path="$1"
local max_len="$2"
local placeholder="$3"
if [[ -z "$full_path" ]]; then
echo "$placeholder"
return
fi
if [ ${#full_path} -gt "$max_len" ]; then
# Вычисляем, сколько символов с конца нужно оставить
# -3 нужно, чтобы вместить "..." в начале
local trim_len=$((max_len - 3))
echo "...${full_path: -$trim_len}"
else
echo "$full_path"
fi
}
# --- Главный цикл программы ---
main() {
# 1. ВНЕШНИЙ ЦИКЛ: ВЫБОР ДЕЙСТВИЯ
while true; do
CURRENT_ACTION=$(ui_select_initial_action)
if [[ -z "$CURRENT_ACTION" ]]; then
clear
echo "Выход."
break
fi
# 2. ВНУТРЕННИЙ ЦИКЛ: НАСТРОЙКА И ЗАПУСК
while true; do
# --- ИЗМЕНЕНИЯ ЗДЕСЬ ---
# Готовим пути для отображения с помощью новой функции
local max_display_len=45 # Можете поменять это значение под свой экран
local display_video_path=$(truncate_path_for_display "$VIDEO_SRC_DIR" "$max_display_len" "_не задан_")
local display_audio_path=$(truncate_path_for_display "$AUDIO_SRC_DIR" "$max_display_len" "_не задан_")
local display_output_path=$(truncate_path_for_display "$OUTPUT_BASE_DIR" "$max_display_len" "_не задан_")
# Формируем пункты меню ДИНАМИЧЕСКИ
local menu_items=()
menu_items+=("V" "Видео каталог : $display_video_path")
if [ "$CURRENT_ACTION" == "MERGE" ]; then
menu_items+=("A" "Аудио каталог : $display_audio_path")
fi
menu_items+=(
"O" "Выходной каталог : $display_output_path"
"N" "Имя для Plex : ${OUTPUT_SERIES_NAME:-_не задано_}"
"S" "Номер сезона : $SEASON_NUMBER"
"" "--- Шаблоны и Regex ---"
"P" "Шаблон видеофайлов : $VIDEO_FILE_PATTERN"
)
if [ "$CURRENT_ACTION" == "MERGE" ]; then
menu_items+=("U" "Шаблон аудиофайлов : $AUDIO_FILE_PATTERN")
fi
menu_items+=(
"R" "Regex номера серии : $EPISODE_NUMBER_REGEX"
"T" "Шаблон имени вывода : $OUTPUT_FILENAME_TEMPLATE"
"" "--- Действия ---"
"VIEW" "Предпросмотр сопоставления файлов"
"RUN" "ЗАПУСТИТЬ обработку"
"BACK" "<- Назад к выбору действия"
)
choice=$(ui_main_menu "${menu_items[@]}")
# ... (остальная часть цикла main остается без изменений) ...
if [[ "$choice" == "BACK" || -z "$choice" ]]; then
break
fi
case "$choice" in
V) VIDEO_SRC_DIR=$(ui_get_directory "Выберите каталог с видеофайлами" "$VIDEO_SRC_DIR" "$DEFAULT_TORRENTS_DIR") ;;
A) AUDIO_SRC_DIR=$(ui_get_directory "Выберите каталог с аудиофайлами" "$AUDIO_SRC_DIR" "$VIDEO_SRC_DIR") ;;
O) OUTPUT_BASE_DIR=$(ui_get_directory "Выберите БАЗОВЫЙ каталог для результата" "$OUTPUT_BASE_DIR" "$DEFAULT_ARCHIVE_DIR") ;;
N) OUTPUT_SERIES_NAME=$(ui_get_input "Введите имя сериала для Plex" "$OUTPUT_SERIES_NAME") ;;
S) SEASON_NUMBER=$(ui_get_input "Введите номер сезона (например, 01, 02)" "$SEASON_NUMBER") ;;
P) VIDEO_FILE_PATTERN=$(ui_get_input "Введите шаблон для поиска видео (*.mkv, *ep*.mkv)" "$VIDEO_FILE_PATTERN") ;;
U) AUDIO_FILE_PATTERN=$(ui_get_input "Введите шаблон для поиска аудио (*.mka, *.ac3)" "$AUDIO_FILE_PATTERN") ;;
R) EPISODE_NUMBER_REGEX=$(ui_get_input "Введите ERE-regex для номера серии" "$EPISODE_NUMBER_REGEX") ;;
T) OUTPUT_FILENAME_TEMPLATE=$(ui_get_input "Введите шаблон имени выходного файла" "$OUTPUT_FILENAME_TEMPLATE") ;;
VIEW) logic_show_preview ;;
RUN) run_processing ;;
esac
done
done
}
# --- Точка входа ---
if ! command -v dialog &> /dev/null; then
echo "Команда 'dialog' не найдена. Пожалуйста, установите ее."
exit 1
fi
main