#!/bin/bash ## a photo-uploader relying on Apache-protection/authentication -- Eugene Reimer 2010-12; ## consists of 2 parts: an HTML page with photo-upload-FORM, and a CGI program to receive data + file from that form, and store the file in its rightful place; ## but implemented with only this bash CGI-program; it produces an HTML-page with the uploader-form; ## the HTML-page also contains Javascript for field-level validation of form data; ## ## PREREQ: convert identify -- from Imagemagick ## ## Copyright © 2010 Eugene Reimer; can be modified and/or distributed under the terms of the GPL; see http://www.gnu.org/licenses/gpl.html. fix () { echo "$@" |sed "s|['\"]||g; s|[:=]\+|--|g; s|[()_:/ \t]\+|~|g"; } ##function to eliminate chars that are troublesome in filenames nbr () { echo "$@" |sed -n 's|[^0-9]*\([0-9]\{2,8\}\).*|\1-|p'; } ##function returns the first (2-to-8-digit) numeric-substring, and a hyphen if nonempty MSGS=$(csplit -k --prefix=tmpPart$$. - /^--/ "{100}" 2>&1) ##split stdin at "--" lines into tempfiles named tmpPart$$.NN if [[ -e tmpPart$$.05 ]];then ##==tmpPart$$.05 exists, means we're doing an upload ONM=$(cat tmpPart$$.05 |sed -n 's|.*filename="\([^"]*\).*|\1|p') ##remember user-filename from IMGFILE section for F in tmpPart$$.??;do sed -i '/^--/d; /^Content-/d; /^\r$/d' $F; done ##fixup tmpPart$$.NN tmpfiles, discarding --DLM Content-.* and empty lines F=tmpPart$$.05; head --bytes=-2 $F >$F.rev; mv -f $F.rev $F ##fixup tmpPart$$.05 tmpfile, removing last 2 bytes LOC=$( cat tmpPart$$.01 |tr '\r\n' ' ' |sed 's| \+$||' ) ##remember the text in LOC DATE=$( cat tmpPart$$.02 |tr '\r\n' ' ' |sed 's| \+$||' ) ##remember the text in DATE PHOTOG=$( cat tmpPart$$.03 |tr '\r\n' ' ' |sed 's| \+$||' ) ##remember the text in PHOTOG CAPTION=$(cat tmpPart$$.04 |tr '\r\n' ' ' |sed 's| \+$||' ) ##remember the text in CAPTION OTY=$(file -b -i $F|sed 's|;.*||'); OFS=$(stat -c%s $F) ##get mime-type (eg: image/jpeg) and filesize of image-file OSZ=$(identify -format "%wx%h" $F); W=${OSZ%x*}; H=${OSZ#*x} ##get image-size in pixels as W, H if ((W*H>3030000));then convert $F -resize "3000000@" -quality 85 $F.rev ##more than 3.03-megapixels: scale down to 3-megapixel qual:85 JPEG; "@"=>area-units elif [[ $OTY != *jpeg* ]];then convert $F -quality 85 $F.rev ##non-JPEG: convert to same-size qual:85 JPEG elif ((OFS>900000));then convert $F -quality 85 $F.rev ##JPEG at excessively high qual: convert to same-size qual:85 JPEG fi [[ -e $F.rev ]] && [[ $(stat -c%s $F.rev) -gt $OFS ]] && rm -f $F.rev ##discard converted file if bigger than original; note: can mean keeping a non-JPEG [[ -e $F.rev ]] && CVTED=1 ##remember that conversion done, for msg to be shown later [[ -e $F.rev ]] && mv -f $F.rev $F ##converted file replaces $F NTY=$(file -b -i $F|sed 's|;.*||'); NFS=$(stat -c%s $F) ##get post-conversion mime-type and filesize NSZ=$(identify -format "%wx%h" $F) ##get post-conversion image-size [[ $DATE == "" ]] && DATE=$(identify -format "%[EXIF:DateTimeOriginal]]" $F |sed 's| .*||; s|:||g') ##omitted DATE indicates use-EXIF-date; beware: "]" for omitted [[ $DATE != [0-9]* ]] && DATE=$(date -r$F +%Y%m%d) ##with fallback to file-timestamp-date NNM=$(nbr $ONM)$(fix $CAPTION)_$(fix $LOC)_$(fix $DATE)_$(fix $PHOTOG) ##form new-filename from numeric-part-of-user-filename, CAPTION, LOC, DATE, PHOTOG NNM=$NNM.$(echo "${NTY#image/}" |sed 's|jpeg|jpg|; s|tiff|tif|') ##add suffix for image-type derived from post-conversion mime-type else ##==tmpPart$$.05 does not exist: this is initial invocation just to supply the form PHOTOG=$REMOTE_USER ##default PHOTOG from $REMOTE_USER fi UPLOADER="$REMOTE_USER"; [[ $UPLOADER == "" ]] && UPLOADER=$(cat tmpPart$$.06 |tr '\r\n' ' ' |sed 's| \+$||') ##workaround for unreliable $REMOTE_USER var [[ $UPLOADER != "" ]] && SIGNEDIN="
You are signed in as:$UPLOADER" ##signed-in-as msg when $UPLOADER available echo "Content-type: text/html" echo "" cat ../nav1-head.txt echo "
Instructions:
Enter Date as YYYYMMDD, that is as 8-digits consisting of 4-digit Year, 2-digit Month, 2-digit Day-of-month; note: if your camera's clock is set correctly and the image contains the camera's EXIF-data then omit the Date here for the best result; omitting Date may work even if the image lacks EXIF-data as in that case the image-file's timestamp will be used.
Enter Photographer as zz if name of photographer is unknown; please do not upload annotated photos, however if you must then so indicate by supplying zz or zzNAME as Photographer where NAME is the name of photographer.
Please supply a Caption that identifies the species; when species is identified by more than one name use an equal-sign to separate names; use a colon to separate species-name(s) from rest-of-caption; for a people-picture, please identify persons by name if possible (in which case there's no need to identify the species); for a plant-picture, please indicate whether a Habitat, Clump, Plant, Flower-spike, Flower, Foliage, Fruit/Seed-capsule view.
Use the Browse... button to select the image-file to be uploaded (some browsers show it as a Choose... button); uploading the full-sized image produced by your camera is fine, although we'll save it as at most a 3-megapixel JPEG; almost any image type is supported, JPEG, PNG, TIFF, etc, however if your camera uses a RAW format then you use its software to convert to JPEG before uploading; if converting to JPEG yourself we recommend a quality-setting that will reduce a typical 3-megapixel photo to roughly 500KB.
Use the Submit button once you're ready to do the upload. " if F=tmpPart$$.05; [[ -e $F ]];then ##tell user about the actions -- will do them after producing DEBUG-INFO echo "
ACTIONS:"
[[ $CVTED ]] && echo "
$OTY size:$OSZ filesize:$OFS converted due to size or type"
echo "
$ONM saved as $NNM; size:$NSZ filesize:$NFS"
fi
echo "