#!/bin/bash id=$1 ext=$2 set_size=$3 server=cdmr@digitalmycology.com:images.digitalmycology.com images=public/images db_config=config/database.yml username=`grep -A 20 production: $db_config | grep username: | head -1 | sed 's/.*: *//'` database=`grep -A 20 production: $db_config | grep database: | head -1 | sed 's/.*: *//'` password=`grep -A 20 production: $db_config | grep password: | head -1 | sed 's/.*: *//'` orig=$images/orig/$id.$ext orig_layers=$images/orig/$id-'*'.jpg full=$images/orig/$id.jpg huge=$images/1280/$id.jpg large=$images/960/$id.jpg medium=$images/640/$id.jpg small=$images/320/$id.jpg thumb=$images/thumb/$id.jpg log=log/process_image.$$ log2=log/process_image.log email=webmaster@mushroomobserver.org path=(. /bin /usr/bin /usr/local/bin) errors=0 if [[ $RAILS_ENV == 'production' ]]; then production=1 else production=0 fi # ---------------------------- # Help message. # ---------------------------- if [[ $1 == '-h' || $1 == '--help' ]]; then cat <<-EOH; exit -1 USAGE: script/process_image <0|1> DESCRIPTION: This is used by the webserver to resize and transfer uploaded images to the image server. It is intended to run asynchronously. One of these jobs is spwaned for each image uploaded. Each process first creates temporary soft links to a place-holder image so that the user sees at least something while waiting for the images to be processed. Then it runs convert (from ImageMagick suite) to downsize the image, first checking that no one else is running convert. If another process is running convert, it sleeps a few seconds and tries again. After images are resized, it transfers them to the image server using scp, again waiting for other scp jobs to finish first. It emails the webmaster if there are any errors. FILES: webmaster $email image server $server error log $log2 EOH fi # -------------------------------------------------- # Run a command, logging both command and result. # Sets errors to true if anything fails. # -------------------------------------------------- function run() { echo "`date`>" $* >> $log if !($* >> $log 2>&1); then errors=1 echo '**** FAILED ****' >> $log fi } # ---------------------------- # Resize images. # ---------------------------- # Wait for other conversions to finish first. while (ps -e | grep ' convert$' > /dev/null); do sleep 5; done # Do we need to convert the original to a JPEG? if [[ $orig != $full ]]; then run convert -quality 90 $orig $full # If there are multiple layers, ImageMagick saves them as 1234-N.jpg. # Take the first one, and delete the rest. if [[ ! -e $full ]]; then biggest_layer=`ls -rS $orig_layers | tail -1` if [[ -e $biggest_layer ]]; then run mv $biggest_layer $full run rm $orig_layers fi fi fi # Do we need to report the image size back to Rails? if (( $set_size )); then run script/jpegsize --set $id $full fi # Create the other sizes now. Image processing theory says that reducing # images by no more than 50% at a time is optimal. # run convert -thumbnail '1280x1280>' -quality 70 $full $huge # run convert -thumbnail '960x960>' -quality 70 $huge $large # run convert -thumbnail '640x640>' -quality 70 $huge $medium # run convert -thumbnail '320x320>' -quality 80 $medium $small # run convert -thumbnail '160x160>' -quality 90 $small $thumb run jpegresize 1280x1280 -q 70 --max-size $full $huge run jpegresize 960x960 -q 70 --max-size $huge $large run jpegresize 640x640 -q 70 --max-size $huge $medium run jpegresize 320x320 -q 80 --max-size $medium $small run jpegresize 160x160 -q 90 --max-size $small $thumb # ---------------------------- # Transfer images. # ---------------------------- # Wait for other transfers to finish first. while (ps -e | grep ' scp$' > /dev/null); do sleep 5; done # Careful! Don't do this in test mode! if (( $production )); then run scp $thumb $server/thumb/$id.jpg run scp $small $server/320/$id.jpg run scp $medium $server/640/$id.jpg run scp $large $server/960/$id.jpg run scp $huge $server/1280/$id.jpg run scp $full $server/orig/$id.jpg if [[ $orig != $full ]]; then run scp $orig $server/orig/$id.$ext fi fi # ------------------------------ # Report errors to webmaster. # ------------------------------ cat $log >> $log2 if (( $production )); then if (( $errors )); then mutt -s '[MO] process_image' $email < $log else mysql -q -u "$username" -p"$password" "$database" -e "UPDATE images SET transferred=TRUE WHERE id=$id;" fi fi rm -f $log exit $errors