#!/bin/bash # Filename: twebgal # Purpose: create a tiny webgallery using CSS-features # Authors: Wolfgang Scheicher # Bug-Reports: see http://grml.org/bugs/ # License: This file is licensed under the GPL v2. # Latest change: Mon Apr 25 10:38:00 CEST 2005 [worf] ################################################################################ # Defaults DISPLAY_GEOMETRY=640x480 THUMBNAIL_GEOMETRY=150x150 PREVIEW_GEOMETRY=250x250 THUMBNAIL_QUALITY=75 PARENT_DIR="Übergeordnetes Verzeichnis" PATH=$PATH:/usr/X11R6/bin:/usr/bin DATADIR=".tmp" LOG=".tmp/log" VERBOSE="/dev/null" OPTS=$* OLDIFS=$IFS IFS=" " THUMBNAILS=("$DISPLAY_GEOMETRY" "$THUMBNAIL_GEOMETRY") FILE_EXTENSIONS=("jpg" "png" "gif") REQUIRED=("jpegtran" "convert" "identify" "find" "tr" "sed" "awk" "grep") ############################################################## create_sample_config () { # sample config with some default values # if [ -f description ] ; then DST=/dev/stdout echo "description file allready exists!" else echo "creating example description file" DST="./description" fi echo -e "# Gallery Config File\n# # Title for this Directory TITLE=\"${PWD##*/}\"\n # Optional Comment COMMENT=\"\"\n # this parameters affect the dir list in the parent directory: # thumbnail to show THUMB=\"$(find_all_images | head -n 1 )\"\n # Index to sort dirs by. # You might want to use some date for chronological order INDEX=\"$(date +%F)\"\n" > $DST if [[ -z $STYLESHEET ]] ; then echo -e "# Stylesheet # This will be used for all subdirs as well STYLESHEET=\"stylesheet.css\"" >> $DST fi } ############################################################## init_gallery () { # create datadir and check for required apps # mkdir -p ${DATADIR} echo -n "" > ${LOG} for app in "${REQUIRED[@]}" ; do if which $app 2>/dev/null >/dev/null ; then true else echo "ERROR: $app not found!" exit; fi done if [[ -f description ]] ; then source "description"; fi STYLESHEET=$( find_stylesheet ) } parent_dir () { # adds a "../ if it is not a absolute path or a url" # otherwise returns the same string again if [[ "${1::1}" == "/" ]] ; then echo "$1" elif [[ "${1::7}" == "http://" ]] ; then echo "$1" elif [[ ! -z $1 ]] ; then echo "../${1}" fi } find_stylesheet () { # searches parent dirs recursively for a stylesheet # until it reaches the root dir if [[ -f description ]] ; then source "description"; fi if [[ -z $STYLESHEET ]] ; then if [[ ! "$PWD" == "/" ]] ; then cd .. parent_dir $( find_stylesheet ) fi else echo $STYLESHEET fi } ############################################################## find_all_images() { # returns a list of all (supported) Images in the current dir # for ext in "${FILE_EXTENSIONS[@]}" ; do find *.${ext} -maxdepth 0 2> /dev/null done } find_all_dirs() { # Searches all dirs and lists them, # sorted by the INDEX field in the description file # DIRS="$(find * -maxdepth 0 -type d)" for DIR in $DIRS ; do ( INDEX="_" if [[ -f ${DIR}/description ]] ; then source "${DIR}/description"; fi echo "${INDEX} ${DIR}" ) done | sort | sed -e "s/^\S*\s//" } ############################################################## prune() { # deletes old thumbnails and html files # temporarily creates a filelist # if [[ "$RECURSIVE" == "true" ]] ; then ALL_DIRS=( $(find_all_dirs) ) for DIR in "${ALL_DIRS[@]}"; do ( IFS=$OLDIFS && cd "$DIR" && $0 $OPTS ; ) done fi echo "-> ${PWD}" if [[ -d "${DATADIR}" ]] ; then find_all_images > "${DATADIR}/filelist" for GEOMETRY in "${THUMBNAILS[@]}"; do ( [[ -d "${DATADIR}/${GEOMETRY}" ]] && cd "${DATADIR}/${GEOMETRY}" && find_all_images | awk 'NR==FNR {a[$0];next} !($0 in a)' ../filelist - | while read line ; do echo "rm ${DATADIR}/${GEOMETRY}/${line}" rm "${line}" done ) done ( cd "${DATADIR}/" && find *.html -maxdepth 0 2> /dev/null | awk 'NR==FNR {a[$0];next} {sub(/\.html$/,"",$0)} !($0 in a)' filelist - | while read line ; do echo "rm ${DATADIR}/${line}.html" rm "${line}.html" done ) rm "${DATADIR}/filelist" fi } ############################################################## build_thumbnail() { # generates thumbnails # time of modification is set to that of the original and used # to check if existing thumbs need updating # orientation in the exif-header is used to rotate generated images # for GEOMETRY in "${THUMBNAILS[@]}"; do mkdir -p "$DATADIR/$GEOMETRY" || exit echo -ne "($GEOMETRY" DST="$DATADIR/$GEOMETRY/$FILE" SKIP=false if [[ -e $DST ]]; then if [[ $(stat -c "%Y" $FILE) == $(stat -c "%Y" $DST) ]]; then SKIP=true echo -n " skip" else echo -n " D" rm $DST fi else echo -n " " fi if [[ $SKIP == "false" ]]; then ORIENTATION="" ORIENTATION=$(identify -format "%[EXIF:Orientation]" "$FILE") if [[ "$ORIENTATION" == "6" ]]; then echo -n "TR" convert -quality $THUMBNAIL_QUALITY -rotate 90 -geometry "$GEOMETRY+0+0>" "$FILE" "$DST" elif [[ "$ORIENTATION" == "8" ]]; then echo -n "TL" convert -quality $THUMBNAIL_QUALITY -rotate 270 -geometry "$GEOMETRY+0+0>" "$FILE" "$DST" else echo -n "T " convert -quality $THUMBNAIL_QUALITY -geometry "$GEOMETRY+0+0>" "$FILE" "$DST" fi if [[ "${FILE##*.}" == "jpg" ]]; then echo -n "O" jpegtran -copy none -optimize -progressive "$DST" > "$DST.tmp" mv -f "$DST.tmp" "$DST" else echo -n " " fi touch -m --reference=$FILE $DST fi echo -n ") " done } build_html() { # generates the HTML echo -n "(html" THUMBGEOMETRY=$(identify -format "%wx%h" "$DATADIR/$THUMBNAIL_GEOMETRY/${FILE}") THUMBWIDTH=${THUMBGEOMETRY%x*} THUMBHEIGHT=${THUMBGEOMETRY#*x} THUMBT=$(((156 - $THUMBHEIGHT )/2 )) THUMBB=$(((157 - $THUMBHEIGHT )/2 )) THUMBL=$(((156 - $THUMBWIDTH )/2 )) THUMBR=$(((157 - $THUMBWIDTH )/2 )) TITLE=$FILE COMMENT=$(identify -format "%c" "${FILE}" | tr '\n' ' ') THUMBNAIL=$DATADIR/$THUMBNAIL_GEOMETRY/${FILE} THIS_HTML=$DATADIR/${FILE}.html html_header > ${THIS_HTML} echo "
${FILE}     Index    <<< ${CURRENT}/${IMAGE_COUNT} >>>
\"${DISPLAY_GEOMETRY}/${FILE}\"

" >> $THIS_HTML identify -format "
Auflösung:%wx%h
Dateigröße:%b
Camera:%[EXIF:Model]
Datum/Zeit:%[EXIF:DateTime]
Kommentar:%c
" ${FILE} >> $THIS_HTML echo "
" >> $THIS_HTML html_foot >> $THIS_HTML echo "\"Thumbnail\"
$FILE
" >> index.html echo -en ")" } ############################################################## start_index () { # generates the upper part of the index page # containing the list of subdirs # which are recursively processed from here too # TITLE="${TITLE=${PWD##*/}}" html_header > index.html echo "
" >> index.html echo "

${TITLE}

" >> index.html echo " ${COMMENT}
" >> index.html } finish_index () { echo "
" >> index.html html_foot >> index.html } ############################################################## create_sample_stylesheet () { if [ -f stylesheet.css ] ; then echo "stylesheet.css allready exists!" exit 1 fi cat << EOF > stylesheet.css a {text-decoration:none;} div.gallery img {border: 2px inset #aaa; margin:3px;} div.gallery a {color:#000; border: 2px outset #aaa; text-decoration:none; text-align:center; float:left; padding:3px; margin:4px; background-color:#ddd;} div.gallery a:hover {color:#333; border: 2px outset #ccc; background-color:#eee;} div.spacer {clear: both;} div.gallerynav {text-align: center; margin: 0px; padding:0em 0.3em 0em 0.3em;} a.tooltip, a.tooltip:link, a.tooltip:visited, a.tooltip:active { position: relative; } a.tooltip span {display: none} a:hover.tooltip span {display: block; position: absolute; top: 2.5em; left: 1.5em; z-index: 100; color: #000; padding: 3px; border:1px solid #000; background: #ffc; } EOF } ############################################################## html_header () { echo " ${TITLE} " } html_foot () { echo " " } ############################################################## build_gallery() { # generates the whole thing, puts everything together # ALL_IMAGES=( $(find_all_images) ) IMAGE_COUNT=${#ALL_IMAGES[@]} start_index ( STYLESHEET="$(parent_dir ${STYLESHEET})" echo "-> ${TITLE}" CURRENT="0" FILE="../index" for file in "${ALL_IMAGES[@]}" "../index" ; do NEXT="$file" if [[ "$FILE" != "../index" ]]; then echo -ne "$FILE\t" build_thumbnail build_html echo "" fi CURRENT="$(( ${CURRENT} + 1 ))" LAST="$FILE" FILE="$file" done if [[ ! -z "${THUMB}" ]] ; then echo -ne "preview thumbnail from ${THUMB}\t" THUMBNAILS=("$PREVIEW_GEOMETRY") FILE="${THUMB}" [ -e "${DATADIR}/thumb.${THUMB##*.}" ] && mv "${DATADIR}/thumb.${THUMB##*.}" "${DATADIR}/${PREVIEW_GEOMETRY}/${THUMB}" build_thumbnail && mv "${DATADIR}/${PREVIEW_GEOMETRY}/${THUMB}" "${DATADIR}/thumb.${THUMB##*.}" echo fi ) | tee -a $LOG >> $VERBOSE finish_index echo " $IMAGE_COUNT Image(s) in ${TITLE}" } ############################################################## init_gallery while getopts "vdsrp-:" OPT ; do case $OPT in v) VERBOSE=/dev/stdout ;; d) create_sample_config exit 0 ;; s) create_sample_stylesheet exit 0 ;; r) RECURSIVE="true" ;; p) prune exit 0 ;; ?) # wrong argument echo -n "ERROR: Missing argument for option \"$OPTARG\". " exit 1 ;; *) # wrong option echo -n "ERROR: Unknown option \"$OPTARG\". " exit 1 ;; esac done shift $(($OPTIND -1)) build_gallery 2>${DATADIR}/errors if [ -s ${DATADIR}/errors ]; then echo -e "\nWARNING: there were errors. see .tmp/errors" else rm .tmp/errors fi ## END OF FILE #################################################################