499 lines
12 KiB
Bash
Executable file
499 lines
12 KiB
Bash
Executable file
#!/bin/bash
|
|
|
|
###############################################################################
|
|
|
|
[ "$(env | /bin/sed -r -e '/^(PWD|SHLVL|_|PATH)=/d')" ] && exec -c $0
|
|
|
|
export PATH
|
|
|
|
###############################################################################
|
|
|
|
__needed_programs='convert
|
|
identify
|
|
bc'
|
|
|
|
export __fatal_error='false'
|
|
|
|
while read -r __program; do
|
|
if ! which "${__program}" &>/dev/null; then
|
|
echo "Need '${__program}'"
|
|
export __fatal_error='true'
|
|
fi
|
|
done <<<"${__needed_programs}"
|
|
|
|
###############################################################################
|
|
# Variables
|
|
###############################################################################
|
|
|
|
__ignore_variables='PWD
|
|
SHLVL
|
|
_
|
|
OLDPWD
|
|
PATH'
|
|
|
|
########################################
|
|
# Default Options
|
|
########################################
|
|
|
|
__PROCESS_JPEG=true
|
|
__depends__PROCESS_JPEG=(JPEG_RESCALE JPEG_CONVERT_LOSSLESS JPEG_TARGET_SIZE)
|
|
# false/auto
|
|
__JPEG_RESCALE=auto
|
|
__depends__JPEG_RESCALE=(JPEG_RESCALE_THRESHOLD)
|
|
# for auto, in KP
|
|
__JPEG_RESCALE_THRESHOLD=2000
|
|
__JPEG_CONVERT_LOSSLESS=false
|
|
__JPEG_TARGET_SIZE=true
|
|
__depends__JPEG_TARGET_SIZE=(JPEG_TARGET_SIZE_BYTES)
|
|
__JPEG_TARGET_SIZE_BYTES='150000'
|
|
|
|
__PROCESS_PNG=true
|
|
__depends__PROCESS_PNG=(PNG_RESCALE PNG_CONVERT_LOSSLESS)
|
|
# false/auto
|
|
__PNG_RESCALE=auto
|
|
__depends__PNG_RESCALE=(PNG_RESCALE_THRESHOLD)
|
|
# for auto, in KP
|
|
__PNG_RESCALE_THRESHOLD=2000
|
|
__PNG_CONVERT_LOSSLESS=true
|
|
|
|
__PROCESS_SCRIPT=false
|
|
|
|
__WEBP_METHOD='6'
|
|
__WEBP_QUALITY='50'
|
|
|
|
__ENVIRONMENT_LIST='PROCESS_JPEG
|
|
PROCESS_PNG
|
|
PROCESS_SCRIPT
|
|
JPEG_RESCALE
|
|
JPEG_RESCALE_THRESHOLD
|
|
JPEG_TARGET_SIZE
|
|
JPEG_TARGET_SIZE_BYTES
|
|
JPEG_CONVERT_LOSSLESS
|
|
PNG_RESCALE
|
|
PNG_RESCALE_THRESHOLD
|
|
PNG_CONVERT_LOSSLESS
|
|
WEBP_METHOD
|
|
WEBP_QUALITY'
|
|
|
|
###############################################################################
|
|
# Functions
|
|
###############################################################################
|
|
|
|
__fatal_error_handler() {
|
|
if [ "${__fatal_error}" == 'true' ]; then
|
|
echo 'Fatal Error: Exiting'
|
|
exit 1
|
|
fi || exit 1
|
|
}
|
|
|
|
########################################
|
|
# __set_env <env file>
|
|
########################################
|
|
#
|
|
# Set Environment
|
|
# Sets the environment from a file
|
|
#
|
|
########################################
|
|
|
|
__set_env() {
|
|
|
|
while read -r __line; do
|
|
__varname="$(sed 's/^/__/' <<<"${__line}")"
|
|
export "${__line}=${!__varname}"
|
|
done <<<"${__ENVIRONMENT_LIST}"
|
|
|
|
if [ "${#}" -gt 0 ]; then
|
|
set -o allexport
|
|
source "${1}"
|
|
set +o allexport
|
|
fi
|
|
|
|
while read -r __line; do
|
|
if ! [ "${__line}" == "" ]; then
|
|
unset "${__line}"
|
|
fi
|
|
done <<<"$(printenv | sed 's/^\([^=]*\)=.*/\1/' | grep -Fxv "${__ignore_variables}" | grep -Fxv "${__ENVIRONMENT_LIST}")"
|
|
|
|
__resolve_env
|
|
|
|
}
|
|
|
|
__resolve_env() {
|
|
|
|
__old_hash=""
|
|
__current_hash="$(__hash_env)"
|
|
|
|
while [ "${__old_hash}" != "${__current_hash}" ]; do
|
|
|
|
while read -r __check_set; do
|
|
if [ "${!__check_set}" == 'false' ]; then
|
|
eval "__arr=\"\${__depends__${__check_set}[@]}\""
|
|
for __item in ${__arr[@]}; do
|
|
if ! [ "${!__item}" == 'false' ]; then
|
|
export "${__item}"='false'
|
|
fi
|
|
done
|
|
fi
|
|
done < <(set | grep -e '^__depends__' | sed 's/^__depends__\([^=]*\)=.*/\1/')
|
|
__old_hash="${__current_hash}"
|
|
__current_hash="$(__hash_env)"
|
|
|
|
done
|
|
|
|
__need="$(
|
|
{
|
|
while read -r __check_set; do
|
|
if ! [ "${!__check_set}" == 'false' ]; then
|
|
eval "__arr=\"\${__depends__${__check_set}[@]}\""
|
|
for item in ${__arr[@]}; do
|
|
echo "${item}"
|
|
done
|
|
fi
|
|
done < <(set | grep -e '^__depends__' | sed 's/^__depends__\([^=]*\)=.*/\1/')
|
|
while read -r __item; do
|
|
if ! [ "${!__item}" == 'false' ]; then
|
|
echo "${__item}"
|
|
fi
|
|
done <<<"${__ENVIRONMENT_LIST}"
|
|
} | sort | uniq
|
|
)"
|
|
|
|
__does_not_exist="$(grep -Fxv "${__ENVIRONMENT_LIST}" <<<"${__need}")"
|
|
if [ "${__does_not_exist}" != "" ]; then
|
|
echo 'Error:'
|
|
echo "${__does_not_exist}"
|
|
echo 'Does not exist!
|
|
'
|
|
fi
|
|
|
|
while read -r __unset; do
|
|
if [ "${__unset}" != "" ]; then
|
|
unset "${__unset}"
|
|
fi
|
|
done < <(__print_env | sed -e 's/^\([^=]*\)=.*/\1/' | grep -Fxv "${__need}")
|
|
|
|
}
|
|
|
|
########################################
|
|
# __print_env
|
|
########################################
|
|
#
|
|
# Print Environment
|
|
# Prints the environment
|
|
#
|
|
########################################
|
|
|
|
__print_env() {
|
|
|
|
printenv | grep -xvf <(sed 's|\(.*\)|^\1=.*|' <<<"${__ignore_variables}") | sort
|
|
|
|
}
|
|
|
|
########################################
|
|
# __hash_env
|
|
########################################
|
|
#
|
|
# Hash Environment
|
|
# Hashes the environment
|
|
#
|
|
########################################
|
|
|
|
__hash_env() {
|
|
|
|
__print_env | md5sum - | sed 's/ .*//'
|
|
|
|
}
|
|
|
|
########################################
|
|
# __clear_env
|
|
########################################
|
|
#
|
|
# Clear Environment
|
|
# Clears the environment
|
|
#
|
|
########################################
|
|
|
|
__clear_env() {
|
|
|
|
while read -r __var; do
|
|
unset "${__var}"
|
|
done <<<"${__ENVIRONMENT_LIST}"
|
|
|
|
}
|
|
|
|
__unset_unused() {
|
|
while read -r __var; do
|
|
#local "${__var}"
|
|
if [ "${__var}" != "__PROCESS_${1^^}" ]; then
|
|
eval "${__var#__}"='false'
|
|
fi
|
|
done < <(set | grep -E '^__PROCESS_' | sed 's/^\([^=]*\)=.*/\1/')
|
|
|
|
__resolve_env
|
|
}
|
|
|
|
########################################
|
|
# __process <.env>
|
|
########################################
|
|
#
|
|
# Process
|
|
# Call this once situated in the correct
|
|
# directory to process
|
|
#
|
|
########################################
|
|
|
|
__process() {
|
|
|
|
if [ "${PROCESS_SCRIPT}" == 'true' ]; then
|
|
|
|
__process_scripts -r
|
|
|
|
__fatal_error_handler
|
|
|
|
__process_scripts
|
|
fi
|
|
|
|
if [ "${PROCESS_JPEG}" == 'true' ]; then
|
|
__process_generic_image jpeg
|
|
fi
|
|
|
|
if [ "${PROCESS_PNG}" == 'true' ]; then
|
|
__process_generic_image png
|
|
fi
|
|
|
|
}
|
|
|
|
__find_jpeg() {
|
|
find './src/' -type f \( -iname \*.jpg -o -iname \*.jpeg \)
|
|
}
|
|
|
|
__find_png() {
|
|
find './src/' -type f \( -iname \*.png \)
|
|
}
|
|
|
|
__process_generic_image() {
|
|
|
|
__set_env './src/.env'
|
|
|
|
__unset_unused "${1}"
|
|
|
|
"__find_${1}" | while read -r __source_file; do
|
|
|
|
export FILE_HASH="$(md5sum "${__source_file}")"
|
|
|
|
__target="$(sed -e 's|^\./src/|./|' -e 's/[^\.]*$/webp/' <<<"${__source_file}")"
|
|
|
|
if ! __check_file "${__source_file}"; then
|
|
|
|
echo "Processing: ${__target}"
|
|
|
|
echo "$(__hash_env)" >"$(__get_hash_file "${__source_file}")"
|
|
|
|
__target_dir="$(dirname "${__target}")"
|
|
|
|
mkdir -p "${__target_dir}"
|
|
|
|
if [ -e "${__target}" ]; then
|
|
rm "${__target}"
|
|
fi
|
|
|
|
__img_rescale="${1^^}_RESCALE"
|
|
__img_rescale_threshold="${1^^}_RESCALE_THRESHOLD"
|
|
__img_convert_lossless="${1^^}_CONVERT_LOSSLESS"
|
|
__img_convert_target_size="${1^^}_TARGET_SIZE"
|
|
__img_convert_target_size_bytes="${1^^}_TARGET_SIZE_BYTES"
|
|
|
|
__print_env
|
|
|
|
__convert_options=("-auto-orient" "-quality" "${__WEBP_QUALITY}" "-define" "webp:method=${__WEBP_METHOD}")
|
|
|
|
if [ "${!__img_convert_lossless}" == 'true' ]; then
|
|
__convert_options+=("-define" "webp:lossless=true")
|
|
fi
|
|
|
|
if [ "${!__img_rescale}" == 'auto' ] && [ "$(identify -format '(%w*%h)/1000\n' "${__source_file}" | bc)" -gt "${!__img_rescale_threshold}" ]; then
|
|
__convert_options+=("-resize" "$((__img_rescale_threshold * 1000))@>")
|
|
fi
|
|
|
|
convert "${__source_file}" ${__convert_options[@]} "${__target}"
|
|
|
|
if [ "${!__img_convert_target_size}" == 'true' ] && [ "$(stat -c '%s' "${__target}")" -gt "${!__img_convert_target_size_bytes}" ] && ! [ "${!__img_convert_lossless}" == 'true' ]; then
|
|
echo "File too large, resizing"
|
|
rm "${__target}"
|
|
__convert_options+=("-define" "webp:target-size=${!__img_convert_target_size_bytes}" "-define" "webp:pass=8")
|
|
convert "${__source_file}" ${__convert_options[@]} "${__target}"
|
|
fi
|
|
|
|
fi
|
|
|
|
unset FILE_HASH
|
|
|
|
done
|
|
|
|
}
|
|
|
|
########################################
|
|
# __process_scripts <-r>
|
|
########################################
|
|
#
|
|
# Process
|
|
# Call this to process scripts, or call
|
|
# with '-r' to check required programs
|
|
#
|
|
########################################
|
|
__process_scripts() {
|
|
|
|
__unset_unused SCRIPT
|
|
|
|
while read -r __source_file; do
|
|
|
|
export FILE_HASH="$(
|
|
{
|
|
md5sum "${__source_file}"
|
|
"${__source_file}" -d
|
|
"${__source_file}" -d | sort | while read -r __file; do
|
|
md5sum "${__file}"
|
|
done
|
|
} | sort | md5sum -
|
|
)"
|
|
|
|
if ! __check_file "${__source_file}" "$("${__source_file}" -t)"; then
|
|
|
|
if [ "${1}" == '-r' ]; then
|
|
|
|
while read -r __program; do
|
|
if ! which "${__program}" &>/dev/null; then
|
|
echo "$(pwd)${__source_file:1} needs '${__program}'"
|
|
export __fatal_error='true'
|
|
fi
|
|
done < <("${__source_file}" -r)
|
|
|
|
else
|
|
|
|
echo "Running: ${__source_file}"
|
|
echo "$(__hash_env)" >"$(__get_hash_file "${__source_file}")"
|
|
|
|
__target_files="$("${__source_file}" -t)"
|
|
|
|
"${__source_file}"
|
|
|
|
while read -r __file; do
|
|
if ! [ -a "${__file}" ]; then
|
|
echo "Warning: $(pwd)${__source_file:1} failed to create ${__file}"
|
|
fi
|
|
done <<<"${__target_files}"
|
|
|
|
fi
|
|
fi
|
|
|
|
unset FILE_HASH
|
|
|
|
done < <(find './src/' -type f \( -iname \*.sh \))
|
|
|
|
}
|
|
|
|
########################################
|
|
# __get_hash_file <file>
|
|
########################################
|
|
#
|
|
# Get Hash File
|
|
# Returns the hash path for a given file
|
|
#
|
|
########################################
|
|
|
|
__get_hash_file() {
|
|
echo "${1}.hash"
|
|
}
|
|
|
|
########################################
|
|
# __check_file <source> [<target> ...]
|
|
########################################
|
|
#
|
|
# Check File
|
|
# Checks if a given file is current
|
|
#
|
|
########################################
|
|
|
|
__check_file() {
|
|
|
|
__source="${1}"
|
|
|
|
shift
|
|
|
|
__hash_file="$(__get_hash_file "${__source}")"
|
|
|
|
__targets=''
|
|
|
|
if [ "${#}" == '0' ]; then
|
|
|
|
__targets="$(sed -e 's|^\./src/|./|' -e 's/\(jpeg\|jpg\|png\)$/webp/' <<<"${__source_file}")"
|
|
|
|
else
|
|
|
|
until [ "${#}" == '0' ]; do
|
|
|
|
__targets="${1}
|
|
${__targets}"
|
|
|
|
shift
|
|
|
|
done
|
|
|
|
fi
|
|
|
|
local __target
|
|
|
|
while read -r __target; do
|
|
|
|
if ! [ -e "${__target}" ]; then
|
|
return 1
|
|
fi
|
|
|
|
done < <(sed '/^$/d' <<<"${__targets}")
|
|
|
|
if [ -e "${__hash_file}" ]; then
|
|
__file_hash="$(cat "${__hash_file}")"
|
|
if [ "${__file_hash}" == "$(__hash_env)" ]; then
|
|
return 0
|
|
fi
|
|
fi
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
###############################################################################
|
|
|
|
__fatal_error_handler || exit 1
|
|
|
|
{
|
|
|
|
pushd "$(dirname "${0}")"
|
|
|
|
pushd ../
|
|
|
|
} &>/dev/null
|
|
|
|
###############################################################################
|
|
|
|
find './content/' -type f -iwholename '*/src/.env' | while read -r __file; do
|
|
|
|
__parent_directory="$(sed 's|src/.env$||' <<<"${__file}")"
|
|
|
|
__set_env "${__file}"
|
|
|
|
pushd "${__parent_directory}" &>/dev/null
|
|
|
|
__process "${__file}"
|
|
|
|
popd &>/dev/null
|
|
|
|
__clear_env
|
|
|
|
done
|
|
|
|
###############################################################################
|
|
|
|
popd &>/dev/null
|
|
|
|
exit
|