#!/bin/bash #============================================================================== # Модуль основной логики: поиск файлов, сопоставление, генерация имён #============================================================================== # Глобальная переменная для хранения подготовленных данных # Формат: "видео_файл\tаудио_файл\tвыходной_файл" для каждой строки declare -a FILE_TRIPLETS # Основная функция, которая находит и сопоставляет файлы # Возвращает 0 в случае успеха, 1 в случае ошибки logic_prepare_file_lists() { # Очищаем предыдущие результаты FILE_TRIPLETS=() # Проверка, заданы ли все необходимые пути if [[ -z "$VIDEO_SRC_DIR" || -z "$AUDIO_SRC_DIR" || -z "$OUTPUT_BASE_DIR" || -z "$OUTPUT_SERIES_NAME" ]]; then ui_show_message "Ошибка" "Не все обязательные параметры заданы (каталоги видео, аудио, вывода и имя сериала)." return 1 fi # 1. Найти видеофайлы # Использование `find ... -print0` и `mapfile` для безопасной обработки имён с пробелами local video_list_raw mapfile -d '' video_list_raw < <(find "$VIDEO_SRC_DIR" -maxdepth 1 -name "$VIDEO_FILE_PATTERN" -print0 | sort -z) if [ ${#video_list_raw[@]} -eq 0 ]; then ui_show_message "Ошибка" "Видеофайлы по шаблону '$VIDEO_FILE_PATTERN' в каталоге '$VIDEO_SRC_DIR' не найдены." return 1 fi # 2. Найти аудиофайлы # maxdepth не используется, чтобы искать в подкаталогах, как в примерах local audio_list_raw mapfile -d '' audio_list_raw < <(find "$AUDIO_SRC_DIR" -name "$AUDIO_FILE_PATTERN" -print0 | sort -z) if [ ${#audio_list_raw[@]} -eq 0 ]; then ui_show_message "Ошибка" "Аудиофайлы по шаблону '$AUDIO_FILE_PATTERN' в каталоге '$AUDIO_SRC_DIR' не найдены." return 1 fi # 3. Проверить совпадение количества файлов if [ ${#video_list_raw[@]} -ne ${#audio_list_raw[@]} ]; then local msg="Количество найденных файлов не совпадает!\n\n" msg+="Видео: ${#video_list_raw[@]}\n" msg+="Аудио: ${#audio_list_raw[@]}\n\n" msg+="Проверьте каталоги и шаблоны поиска." ui_show_message "Ошибка сопоставления" "$msg" return 1 fi # 4. Сгенерировать выходные имена и собрать триплеты local i for i in "${!video_list_raw[@]}"; do local video_file="${video_list_raw[$i]}" local audio_file="${audio_list_raw[$i]}" local video_basename video_basename=$(basename "$video_file") # Извлекаем номер эпизода с помощью regex if [[ "$video_basename" =~ $EPISODE_NUMBER_REGEX ]]; then local episode_num="${BASH_REMATCH[1]}" # Приводим к формату с ведущим нулём, если нужно (например, 1 -> 01) episode_num=$(printf "%02d" "$((10#$episode_num))") else ui_show_message "Ошибка Regex" "Не удалось извлечь номер эпизода из файла:\n$video_basename\n\nС помощью регулярного выражения:\n$EPISODE_NUMBER_REGEX" return 1 fi # Собираем имя выходного файла из шаблона local output_name="$OUTPUT_FILENAME_TEMPLATE" output_name="${output_name/\{SERIES_NAME\}/$OUTPUT_SERIES_NAME}" output_name="${output_name/\{SEASON\}/$SEASON_NUMBER}" output_name="${output_name/\{EPISODE\}/$episode_num}" local output_path="${OUTPUT_BASE_DIR}/${output_name}" # Сохраняем триплет в массив FILE_TRIPLETS+=("$video_file"$'\t'"$audio_file"$'\t'"$output_path") done return 0 } # Функция для отображения предпросмотра logic_show_preview() { if ! logic_prepare_file_lists; then # Сообщение об ошибке уже было показано внутри logic_prepare_file_lists return 1 fi if [ ${#FILE_TRIPLETS[@]} -eq 0 ]; then ui_show_message "Предпросмотр" "Нет файлов для обработки." return fi local preview_text="Будут обработаны следующие файлы (${#FILE_TRIPLETS[@]} шт.):\n\n" local count=1 for triplet in "${FILE_TRIPLETS[@]}"; do IFS=$'\t' read -r video audio output <<< "$triplet" preview_text+="$(printf "%02d" $count). \n" preview_text+=" \ZbВИДЕО:\Zn $(basename "$video")\n" preview_text+=" \ZbАУДИО:\Zn $(basename "$audio")\n" preview_text+=" \Zb-> ВЫВОД:\Zn $(basename "$output")\n\n" ((count++)) done ui_show_message "Предпросмотр" "$preview_text" }