#!/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" # --- Переменные состояния --- # ... (все переменные состояния остаются без изменений) 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