3 # Purpose: create a tiny webgallery using CSS-features
4 # Authors: Wolfgang Scheicher <worf@grml.org>
5 # Bug-Reports: see http://grml.org/bugs/
6 # License: This file is licensed under the GPL v2.
7 # Latest change: Mon Apr 25 10:38:00 CEST 2005 [worf]
8 ################################################################################
11 DISPLAY_GEOMETRY=640x480
12 THUMBNAIL_GEOMETRY=150x150
13 PREVIEW_GEOMETRY=250x250
16 PARENT_DIR="Übergeordnetes Verzeichnis"
18 PATH=$PATH:/usr/X11R6/bin:/usr/bin
27 THUMBNAILS=("$DISPLAY_GEOMETRY" "$THUMBNAIL_GEOMETRY")
28 FILE_EXTENSIONS=("jpg" "png" "gif")
29 REQUIRED=("jpegtran" "convert" "identify" "find" "tr" "sed" "awk" "grep")
31 ##############################################################
33 create_sample_config () {
34 # sample config with some default values
36 if [ -f description ] ; then
38 echo "description file allready exists!"
40 echo "creating example description file"
43 echo -e "# Gallery Config File\n#
44 # Title for this Directory
45 TITLE=\"${PWD##*/}\"\n
48 # this parameters affect the dir list in the parent directory:
50 THUMB=\"$(find_all_images | head -n 1 )\"\n
51 # Index to sort dirs by.
52 # You might want to use some date for chronological order
53 INDEX=\"$(date +%F)\"\n" > $DST
54 if [[ -z $STYLESHEET ]] ; then
56 # This will be used for all subdirs as well
57 STYLESHEET=\"stylesheet.css\"" >> $DST
61 ##############################################################
64 # create datadir and check for required apps
68 for app in "${REQUIRED[@]}" ; do
69 if which $app 2>/dev/null >/dev/null ; then
72 echo "ERROR: $app not found!"
76 if [[ -f description ]] ; then source "description"; fi
77 STYLESHEET=$( find_stylesheet )
81 # adds a "../ if it is not a absolute path or a url"
82 # otherwise returns the same string again
83 if [[ "${1::1}" == "/" ]] ; then
85 elif [[ "${1::7}" == "http://" ]] ; then
87 elif [[ ! -z $1 ]] ; then
93 # searches parent dirs recursively for a stylesheet
94 # until it reaches the root dir
95 if [[ -f description ]] ; then source "description"; fi
96 if [[ -z $STYLESHEET ]] ; then
97 if [[ ! "$PWD" == "/" ]] ; then
99 parent_dir $( find_stylesheet )
106 ##############################################################
109 # returns a list of all (supported) Images in the current dir
111 for ext in "${FILE_EXTENSIONS[@]}" ; do
112 find *.${ext} -maxdepth 0 2> /dev/null
117 # Searches all dirs and lists them,
118 # sorted by the INDEX field in the description file
120 DIRS="$(find * -maxdepth 0 -type d)"
121 for DIR in $DIRS ; do
123 if [[ -f ${DIR}/description ]] ; then source "${DIR}/description"; fi
124 echo "${INDEX} ${DIR}" )
125 done | sort | sed -e "s/^\S*\s//"
128 ##############################################################
131 # deletes old thumbnails and html files
132 # temporarily creates a filelist
134 if [[ "$RECURSIVE" == "true" ]] ; then
135 ALL_DIRS=( $(find_all_dirs) )
136 for DIR in "${ALL_DIRS[@]}"; do
137 ( IFS=$OLDIFS && cd "$DIR" && $0 $OPTS ; )
141 if [[ -d "${DATADIR}" ]] ; then
142 find_all_images > "${DATADIR}/filelist"
143 for GEOMETRY in "${THUMBNAILS[@]}"; do
145 [[ -d "${DATADIR}/${GEOMETRY}" ]] &&
146 cd "${DATADIR}/${GEOMETRY}" &&
148 awk 'NR==FNR {a[$0];next}
149 !($0 in a)' ../filelist - |
151 echo "rm ${DATADIR}/${GEOMETRY}/${line}"
158 find *.html -maxdepth 0 2> /dev/null |
159 awk 'NR==FNR {a[$0];next}
160 {sub(/\.html$/,"",$0)}
161 !($0 in a)' filelist - |
163 echo "rm ${DATADIR}/${line}.html"
167 rm "${DATADIR}/filelist"
171 ##############################################################
174 # generates thumbnails
175 # time of modification is set to that of the original and used
176 # to check if existing thumbs need updating
177 # orientation in the exif-header is used to rotate generated images
179 for GEOMETRY in "${THUMBNAILS[@]}"; do
180 mkdir -p "$DATADIR/$GEOMETRY" || exit
181 echo -ne "($GEOMETRY"
182 DST="$DATADIR/$GEOMETRY/$FILE"
184 if [[ -e $DST ]]; then
185 if [[ $(stat -c "%Y" $FILE) == $(stat -c "%Y" $DST) ]]; then
196 if [[ $SKIP == "false" ]]; then
198 ORIENTATION=$(identify -format "%[EXIF:Orientation]" "$FILE")
199 if [[ "$ORIENTATION" == "6" ]]; then
201 convert -quality $THUMBNAIL_QUALITY -rotate 90 -geometry "$GEOMETRY+0+0>" "$FILE" "$DST"
202 elif [[ "$ORIENTATION" == "8" ]]; then
204 convert -quality $THUMBNAIL_QUALITY -rotate 270 -geometry "$GEOMETRY+0+0>" "$FILE" "$DST"
207 convert -quality $THUMBNAIL_QUALITY -geometry "$GEOMETRY+0+0>" "$FILE" "$DST"
209 if [[ "${FILE##*.}" == "jpg" ]]; then
211 jpegtran -copy none -optimize -progressive "$DST" > "$DST.tmp"
212 mv -f "$DST.tmp" "$DST"
216 touch -m --reference=$FILE $DST
227 THUMBGEOMETRY=$(identify -format "%wx%h" "$DATADIR/$THUMBNAIL_GEOMETRY/${FILE}")
228 THUMBWIDTH=${THUMBGEOMETRY%x*}
229 THUMBHEIGHT=${THUMBGEOMETRY#*x}
231 THUMBT=$(((156 - $THUMBHEIGHT )/2 ))
232 THUMBB=$(((157 - $THUMBHEIGHT )/2 ))
233 THUMBL=$(((156 - $THUMBWIDTH )/2 ))
234 THUMBR=$(((157 - $THUMBWIDTH )/2 ))
237 COMMENT=$(identify -format "%c" "${FILE}" | tr '\n' ' ')
238 THUMBNAIL=$DATADIR/$THUMBNAIL_GEOMETRY/${FILE}
239 THIS_HTML=$DATADIR/${FILE}.html
241 html_header > ${THIS_HTML}
243 echo "<div class=\"gallerynav\">
244 ${FILE}
245 <a href=\"../index.html\">Index</a> <a href=\"${LAST}.html\"><<<</a> ${CURRENT}/${IMAGE_COUNT} <a href=\"${NEXT}.html\">>>></a>
250 <a href=\"../${FILE}\"><img alt=\"${DISPLAY_GEOMETRY}/${FILE}\" src=\"${DISPLAY_GEOMETRY}/${FILE}\" /></a>
254 identify -format "<table>
255 <tr><td>Auflösung:</td><td>%wx%h</td></tr>
256 <tr><td>Dateigröße:</td><td>%b</td></tr>
257 <tr><td>Camera:</td><td>%[EXIF:Model]</td></tr>
258 <tr><td>Datum/Zeit:</td><td>%[EXIF:DateTime]</td></tr>
259 <tr><td>Kommentar:</td><td>%c</td></tr>
260 </table>" ${FILE} >> $THIS_HTML
262 echo "</div>" >> $THIS_HTML
263 html_foot >> $THIS_HTML
265 echo "<a href=\"$THIS_HTML\"><img alt=\"Thumbnail\" src=\"$THUMBNAIL\" style=\"width:${THUMBWIDTH}px; height:${THUMBHEIGHT}px; margin: ${THUMBT}px ${THUMBR}px ${THUMBB}px ${THUMBL}px;\" title=\"${COMMENT}\" /><br />$FILE</a>" >> index.html
270 ##############################################################
273 # generates the upper part of the index page
274 # containing the list of subdirs
275 # which are recursively processed from here too
277 TITLE="${TITLE=${PWD##*/}}"
278 html_header > index.html
279 echo "<div class=\"cont\">" >> index.html
280 echo "<h1>${TITLE}</h1>" >> index.html
281 echo "<ul>" >> index.html
282 echo "<li class=\"back\"><b><a href=\"../index.html\">${PARENT_DIR}</a></b></li>" >> index.html
283 ALL_DIRS=( $(find_all_dirs) )
284 for DIR in "${ALL_DIRS[@]}"; do
285 ( TITLE="${DIR}"; THUMB=""; INDEX=""; COMMENT=""
286 if [[ -f ${DIR}/description ]] ; then source "${DIR}/description"; fi
287 echo "<li class=\"dir\"><a class=\"tooltip\" href=\"${DIR}/index.html\"><b>${TITLE}</b>" >> index.html
289 if [[ ! "${THUMB}${COMMENT}" == "" ]]; then
290 if [[ "${COMMENT}" == "" ]]; then
291 echo "<span><table><tr><td><img alt=\"Thumbnail\" src=\"${DIR}/${DATADIR}/thumb.${THUMB##*.}\" /></tr></table></span>" >> index.html
292 elif [[ "${THUMB}" == "" ]]; then
293 echo "<span><table><tr><td>${COMMENT}</td></tr></table></span>" >> index.html
295 echo "<span><table><tr><td><img alt=\"Thumbnail\" src=\"${DIR}/${DATADIR}/thumb.${THUMB##*.}\" /></td><td></td><td></td><td>${COMMENT}</td></tr></table></span>" >> index.html
298 echo "</a></li>" >> index.html
299 if [[ "$RECURSIVE" == "true" ]] ; then
300 ( STYLESHEET="$(parent_dir ${STYLESHEET})"
301 IFS=$OLDIFS && cd "$DIR" && $0 $OPTS ; )
308 <div class=\"gallery\">
309 <div class=\"spacer\"></div>
315 <div class=\"spacer\"></div>
319 html_foot >> index.html
322 ##############################################################
324 create_sample_stylesheet () {
325 if [ -f stylesheet.css ] ; then
326 echo "stylesheet.css allready exists!"
329 cat << EOF > stylesheet.css
330 a {text-decoration:none;}
332 div.gallery img {border: 2px inset #aaa; margin:3px;}
333 div.gallery a {color:#000; border: 2px outset #aaa; text-decoration:none; text-align:center; float:left; padding:3px; margin:4px; background-color:#ddd;}
334 div.gallery a:hover {color:#333; border: 2px outset #ccc; background-color:#eee;}
335 div.spacer {clear: both;}
336 div.gallerynav {text-align: center; margin: 0px; padding:0em 0.3em 0em 0.3em;}
338 a.tooltip, a.tooltip:link, a.tooltip:visited, a.tooltip:active { position: relative; }
339 a.tooltip span {display: none}
340 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; }
344 ##############################################################
349 <title>${TITLE}</title>
350 <link rel=\"stylesheet\" type=\"text/css\" href=\"${STYLESHEET}\" />
363 ##############################################################
366 # generates the whole thing, puts everything together
368 ALL_IMAGES=( $(find_all_images) )
369 IMAGE_COUNT=${#ALL_IMAGES[@]}
372 STYLESHEET="$(parent_dir ${STYLESHEET})"
376 for file in "${ALL_IMAGES[@]}" "../index" ; do
378 if [[ "$FILE" != "../index" ]]; then
384 CURRENT="$(( ${CURRENT} + 1 ))"
388 if [[ ! -z "${THUMB}" ]] ; then
389 echo -ne "preview thumbnail from ${THUMB}\t"
390 THUMBNAILS=("$PREVIEW_GEOMETRY")
392 [ -e "${DATADIR}/thumb.${THUMB##*.}" ] && mv "${DATADIR}/thumb.${THUMB##*.}" "${DATADIR}/${PREVIEW_GEOMETRY}/${THUMB}"
394 mv "${DATADIR}/${PREVIEW_GEOMETRY}/${THUMB}" "${DATADIR}/thumb.${THUMB##*.}"
397 ) | tee -a $LOG >> $VERBOSE
399 echo " $IMAGE_COUNT Image(s) in ${TITLE}"
402 ##############################################################
406 while getopts "vdsrp-:" OPT ; do
408 v) VERBOSE=/dev/stdout
410 d) create_sample_config
413 s) create_sample_stylesheet
422 echo -n "ERROR: Missing argument for option \"$OPTARG\". "
426 echo -n "ERROR: Unknown option \"$OPTARG\". "
431 shift $(($OPTIND -1))
433 build_gallery 2>${DATADIR}/errors
434 if [ -s ${DATADIR}/errors ]; then
435 echo -e "\nWARNING: there were errors. see .tmp/errors"
440 ## END OF FILE #################################################################