diff --git a/wallpapers.sh b/wallpapers.sh new file mode 100755 index 0000000..b1a18d6 --- /dev/null +++ b/wallpapers.sh @@ -0,0 +1,87 @@ +#!/bin/bash +echo "Перекодирование изображений из каталога 'wallpapers' в каталог 'wallpapers2'." +#-----------------------------------------------------------------------------------------------; +prompt="Подтверждение (да/нет): " && read -erp "$prompt" line && echo -ne "\033[1A$prompt\033[K" +case "${line,,}" in y | yes | д | да) echo "ПОДТВЕРЖДЕНИЕ" ;; *) echo "ОТМЕНА" && exit 0 ;; esac +#-----------------------------------------------------------------------------------------------; +time_ms="$(date '+%s%3N')" # текущее время в миллисекундах +#-----------------------------------------------------------------------------------------------; +# файл-отчёт о завершении работы функции, удаление старого файла +export logfile="$PWD/logs/wallpapers.log" && rm -f "$logfile" +#-----------------------------------------------------------------------------------------------; +# создание структуры каталогов "wallpapers2", создание вспомогательных файлов +#-----------------------------------------------------------------------------------------------; +# переход в каталог-источник +cd "../wallpapers" || exit 1 +# создание каталога-преемника, если его нет +mkdir -p "../wallpapers2" +# удаление файлов и папок, кроме папки ".git" +find "../wallpapers2" -mindepth 1 -maxdepth 1 -type d,f -not -name ".git" -exec rm -rf {} \; +# создание каталогов "full-size" и "preview" +find . -mindepth 1 -maxdepth 1 -type d -not -name ".git" \ + -printf "%f/full-size\0%f/preview\0" | xargs -I{} -n1 -0 -P0 bash -c 'mkdir -p "../wallpapers2/{}"' +# копирование файлов ".md" и удаление суффиксов, если они есть +find . -type f -name "*.md*" \ + -printf "cp -f %h/%f ../wallpapers2/%h/@%f\n" | sed -r 's|@(.*?\.md).*$|\1|' | xargs -n1 -0 -P0 bash -c +# создание файла ".gitattributes" +attr+=("*.jpg linguist-language=JPG") +attr+=("*.png linguist-language=PNG") +attr+=("*.webp linguist-language=WEBP") +printf '%s\n' "${attr[@]}" >"../wallpapers2/.gitattributes" +#-----------------------------------------------------------------------------------------------; +# перекодирование изображений из каталога "wallpapers" в каталог "wallpapers2" +#-----------------------------------------------------------------------------------------------; +# обработка изображений +function graphics_magick { + dir="$2" && file="${3%.*}" + folder_fs="../wallpapers2/${dir//original/full-size}" + folder_pv="../wallpapers2/${dir//original/preview}" + { + # создание временного файла + case "${3##*.}" in + "bmp") tmp="bmp" && ext="png" && cp "$dir/$3" "$folder_fs/$file.tmp.$tmp" ;; + "jpg") tmp="jpg" && ext="jpg" && cp "$dir/$3" "$folder_fs/$file.tmp.$tmp" ;; + "jxl") tmp="jxl" && ext="jpg" && cp "$dir/$3" "$folder_fs/$file.tmp.$tmp" ;; + "png") tmp="png" && ext="png" && cp "$dir/$3" "$folder_fs/$file.tmp.$tmp" ;; + "svg") tmp="png" && ext="png" && rsvg-convert "$dir/$3" -o "$folder_fs/$file.tmp.$tmp" ;; + *) return ;; # пять типов изображений + esac + # полноразмерное изображение — удаление лишних профилей, качество 90% + gm convert "$folder_fs/$file.tmp.$tmp" -strip -quality 90% "$folder_fs/$file.$ext" + # уменьшенное изображение — 512 пикселей по горизонтали, удаление лишних профилей, качество 90% + gm convert "$folder_fs/$file.tmp.$tmp" -strip -resize 512!x\> -quality 90% "$folder_pv/$file.webp" + # удаление временного файла + rm "$folder_fs/$file.tmp.$tmp" + } &>>/dev/null + # отчёт о завершении выполнения функции + echo "$dir/$3" >>"$logfile" + # соответствующая строка для текущего каталога + pre="\e[${1}A" && aft="\e[K\e[${1}B\r" + # массив общего количества файлов и цвета для его отображения + read -ra array <<<"$count" && green="\e[92m" && norm="\e[0m" + # текущее значение и общее значение для текущего каталога и для всех каталогов + current_dir="$(grep -c "^$dir" "$logfile")" && total_dir="${array[$1]}" + current_all="$(grep -c "." "$logfile")" && total_all="${array[0]}" + [ "$current_dir" == "$total_dir" ] && file="${dir}" || file="${dir}/$3" + [ "$current_dir" == "$total_dir" ] && c1="$green" || c1="$norm" + [ "$current_all" == "$total_all" ] && c2="$green" || c2="$norm" + printf "${pre}Обработано: [${c1}%d/%d${norm}] %s${aft}" "$current_dir" "$total_dir" "$file" + printf "Всего обработано файлов: [${c2}%d/%d${norm}]\r" "$current_all" "$total_all" +} +export -f graphics_magick +# поиск всех каталогов "original", сортировка и добавление порядковых номеров для строк +readarray -t folders < <(find . -type d -path "*original*" -printf '%p\n' | sort -r | grep -n '\S') +# строка-массив общего количества файлов в каждом каталоге *original* для дочерних процессов +export count && count="$(printf 'find %s -type f | wc -l\0' "${folders[@]#*:}" | xargs -n1 -0 bash -c | tr '\n' ' ')" +# общее количество файлов во всех каталогах *original* +count="$(echo "$count" | numsum -r) $count" +# смещение курсора вниз на соответствующее количество строк +printf 'Каталог: %s\n' "${folders[@]#*:}" | sort +# строка замены путей для каталогов "original" на такие же с порядковыми номерами +replace="sed $(printf "%s\n" "${folders[@]}" | sed -E "s/(.+):(.+)/-e 's|\"\2\"|\"\1\" \"\2\"|g'/" | tr '\n' ' ')" +# поиск всех файлов в каталогах "original", добавление порядковых номеров и параллельный запуск функции для каждого +find . -type f -path "*original*" -printf 'graphics_magick "%h" "%f"\0' | eval "$replace" | xargs -n1 -0 -P0 bash -c +#-----------------------------------------------------------------------------------------------; +# замер продолжительности выполнения в миллисекундах, пересчёт в минуты, секунды и миллисекунды +tms="$(($(date '+%s%3N') - time_ms))" && min="$((tms / 1000 / 60))" && sec="$((tms / 1000 % 60))" +ms="$((tms % 1000))" && printf '\nОбщее время выполнения: %02d:%02d.%03d мс.\n' "$min" "$sec" "$ms"