|
|
#!/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
|