mirror of
https://gh.wpcy.net/https://github.com/CaptainCore/do.git
synced 2026-04-17 21:52:19 +08:00
145 lines
No EOL
5.1 KiB
Bash
145 lines
No EOL
5.1 KiB
Bash
# ----------------------------------------------------
|
|
# Finds large images and converts them to the
|
|
# WebP format.
|
|
# ----------------------------------------------------
|
|
function convert_to_webp() {
|
|
# The target directory is the first positional argument.
|
|
# The --all flag is passed as the second argument from main.
|
|
local target_dir_arg="$1"
|
|
local all_files_flag="$2"
|
|
echo "🚀 Starting WebP Conversion Process 🚀"
|
|
|
|
# --- Pre-flight Checks ---
|
|
if ! setup_cwebp; then
|
|
echo "Aborting conversion: cwebp setup failed." >&2
|
|
return 1
|
|
fi
|
|
|
|
# --- Initialize and Report Identify Method ---
|
|
# Prime the _is_webp function to determine the method and export the choice.
|
|
_is_webp ""
|
|
# Now that IDENTIFY_METHOD is set, report the choice to the user once.
|
|
if [[ "$IDENTIFY_METHOD" == "identify" ]]; then
|
|
echo "Using 'identify' command for image type checking."
|
|
else
|
|
echo "Warning: 'identify' command not found. Falling back to PHP check."
|
|
fi
|
|
|
|
# --- Determine target directory ---
|
|
local target_dir="wp-content/uploads"
|
|
if [ -n "$target_dir_arg" ]; then
|
|
target_dir="$target_dir_arg"
|
|
echo "Targeting custom directory: $target_dir"
|
|
else
|
|
echo "Targeting default directory: $target_dir"
|
|
fi
|
|
|
|
if [ ! -d "$target_dir" ]; then
|
|
echo "❌ Error: Cannot find '$target_dir' directory." >&2
|
|
return 1
|
|
fi
|
|
|
|
# --- Size and File Discovery ---
|
|
local before_size
|
|
before_size="$(du -sh "$target_dir" | awk '{print $1}')"
|
|
echo "Current directory size: $before_size"
|
|
|
|
local size_limit_mb=1
|
|
local message="larger than ${size_limit_mb}MB"
|
|
local find_args=("$target_dir" -type f)
|
|
|
|
if [[ "$all_files_flag" == "true" ]]; then
|
|
message="of all sizes"
|
|
else
|
|
find_args+=(-size "+${size_limit_mb}M")
|
|
fi
|
|
find_args+=(\( -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" -o -iname "*.webp" \))
|
|
|
|
local files
|
|
files=$(find "${find_args[@]}")
|
|
|
|
if [[ -z "$files" ]]; then
|
|
echo "✅ No images ${message} found to convert."
|
|
return 0
|
|
fi
|
|
local count
|
|
count=$(echo "$files" | wc -l | xargs)
|
|
echo "Found $count image(s) ${message} to process using up to 5 concurrent threads..."
|
|
echo ""
|
|
|
|
# --- Helper function for processing a single image ---
|
|
# This function will be run in the background for each image.
|
|
_process_single_image() {
|
|
local file="$1"
|
|
local current_num="$2"
|
|
local total_num="$3"
|
|
|
|
# The _is_webp function checks if the file is already in WebP format.
|
|
if _is_webp "$file"; then
|
|
echo "⚪️ Skipping ${current_num}/${total_num} (already WebP): $file"
|
|
return
|
|
fi
|
|
|
|
local temp_file="${file}.temp.webp"
|
|
local before_file_size
|
|
before_file_size=$(ls -lh "$file" | awk '{print $5}')
|
|
|
|
# The actual conversion command, output is suppressed for a cleaner log.
|
|
"$CWEBP_CMD" -q 80 "$file" -o "$temp_file" > /dev/null 2>&1
|
|
|
|
# Check if the conversion was successful and the new file has content.
|
|
if [ -s "$temp_file" ]; then
|
|
mv "$temp_file" "$file"
|
|
local after_file_size
|
|
after_file_size=$(ls -lh "$file" | awk '{print $5}')
|
|
echo "✅ Converted ${current_num}/${total_num} ($before_file_size -> $after_file_size): $file"
|
|
else
|
|
# Cleanup failed temporary file and report the failure.
|
|
rm -f "$temp_file"
|
|
echo "❌ Failed ${current_num}/${total_num}: $file"
|
|
fi
|
|
}
|
|
|
|
# Export the helper function and its dependencies so they are available to the subshells.
|
|
export -f _process_single_image
|
|
export -f _is_webp
|
|
export -f _is_webp_php
|
|
export -f setup_wp_cli
|
|
|
|
# --- Concurrent Processing Loop ---
|
|
local max_jobs=5
|
|
local job_count=0
|
|
local processed_count=0
|
|
|
|
# Use process substitution to avoid creating a subshell for the while loop.
|
|
# This ensures the main script's 'wait' command can see all background jobs.
|
|
while IFS= read -r file; do
|
|
processed_count=$((processed_count + 1))
|
|
|
|
# Run the processing function in the background.
|
|
_process_single_image "$file" "$processed_count" "$count" &
|
|
|
|
# On Linux, use 'wait -n' for a sliding window of jobs.
|
|
# On macOS, bash doesn't support 'wait -n', so we skip this
|
|
# and let the final 'wait' handle all jobs at once.
|
|
if [[ "$(uname)" != "Darwin" ]]; then
|
|
job_count=$((job_count + 1))
|
|
if (( job_count >= max_jobs )); then
|
|
wait -n
|
|
job_count=$((job_count - 1))
|
|
fi
|
|
fi
|
|
done < <(echo "$files")
|
|
|
|
# Wait for all remaining background jobs to complete before proceeding.
|
|
wait
|
|
|
|
# --- Final Summary ---
|
|
echo ""
|
|
local after_size
|
|
after_size="$(du -sh "$target_dir" | awk '{print $1}')"
|
|
echo "✅ Bulk conversion complete!"
|
|
echo "-----------------------------------------------------"
|
|
echo " Directory size reduced from $before_size to $after_size."
|
|
echo "-----------------------------------------------------"
|
|
} |