#!/bin/bash
###############################################################
#
# The MIT License
#
# Copyright (c) 2005, 2006 Olof Holmgren
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation
# files (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software,
# and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
###############################################################
###############################################################
#
# Changelog:
#
# v2.4 (2006-01-09)
# Added a comment in the generated HTML code stating
# that the album was created with Fotofix.
#
# Removed the tempfile that were used to store fileType info.
# This should lead to minimal performance improvements.
#
# v2.3
# ImageMagick 2.3.4 did something to it's identify command
# that broke the exif functionality of the script. Fixed that.
#
# Fotofix v2.3 works with ImageMagick 2.3.4 but might be broken
# for earlier versions.
#
# v2.2
# Removed jhead dependency.
#
# A little EXIF information is now added to the HTML
# output along with a javascript allowing the user
# to choose whether he/she wants to see this info or not.
#
# Title changed to "dir1/dir2/.../dirN" instead of "dir"
#
# v2.1
# Added a slideshow feature. (using javascript & query vars)
#
# The generated html is now valid HTML 4.01 Transitional.
#
# Movie files can be handled. The first frame will be
# grabbed, scaled and thumbnailified.
#
# All files that can be handled by ImageMagick will now
# get nice little thumbnails. All other files will also
# end up in the album. They will get a black box as a
# thumbnail and a bigger black box as a scaled image.
#
# Scaled images will never be upscaled to a size larger
# than the original.
#
# Added startup option --rebuild. This causes the
# script to rescale all pictures. The default behaviour
# have been changed to only scale images if they haven't
# been scaled before, making it A LOT faster.
#
# Empty dirs will show up in the album and get an index.html.
#
# v2.0
# The script is now recursive and can build and connect
# several folders into one large album consisting of
# many smaller.
#
# v1.0
# Initial version. Builds galleries with thumbnails
# and individual pages for each pic.
#
#############################################################
##############################################
# Settings:
#############################################
# Look & Feel
thumbSize="120x120"
thumbQuality="70"
scaledSize="750x750"
scaledQuality="75"
cols=4
rows=4
slideshowSpeed=5000 # Milliseconds spent on each page in slideshow mode
scaledFormat="jpg"
thumbFormat="jpg"
# Set the look & feel finer by editing the stylesheet below
# Filenames and such
albDir="album"
thumbDir="thumbs"
scaledDir="scaled"
fileSuffix=".html"
htmlPageName="index"
cssFileName="style.css"
##############################################
insertStyleSheet()
{
echo "
BODY { background-color: white;
color: black; }
H1 { color: blue;
font-size: xx-large;
font-weight: bold;
text-align: center;
margin-top: 0.8em;
margin-bottom: 0.5em; }
H2 { color: black;
font-size: large;
font-weight: bold;
margin-bottom: 0em;
margin-top: 0em;
text-align: center; }
H2.filename { margin-top: 1em;
margin-bottom: 0.5em; }
A { text-decoration: none;
font-weight: bold; }
A:hover { color: red ! important; }
A:visited { color: blue; }
TD { vertical-align: top;
padding: 0.5em; }
TABLE { margin-left: auto;
margin-right: auto;
margin-top: 0em;
padding: 0em; }
TABLE.comment { margin-left: auto;
margin-right: auto;
margin-top: 0em;
width: 35em; }
TABLE.index { padding: 2em; }
TABLE.subgallery { margin-top: 2em;
margin-bottom: 1em; }
TD.index { vertical-align: middle;
text-align: center; }
IMG { border: 0; }
FONT.ahref { font-weight: bold; }
DIV.backtoalbum { margin-top: 0.3em;
margin-bottom: 0.5em; }
DIV { text-align: center; }
TABLE.extraInfo { background-color: e1e1ff;
margin-top: 0.5em;
font-size: small; }
TD.extraInfo { padding: 0.1em; }" > "$albDir/$cssFileName"
}
insertIndexTable()
{
echo "
$javaLink" >> "$albDir/$index"
}
# $1 = page to link to $2 = text in link
generateJavascriptLink()
{
javaLink=""
}
# $1 = pic to show
insertPicPage()
{
# /home/user/dirToAlbumify/subAlbum -> /subAlbum
local pathToPic="${PWD##$origPWD}"
# subAlbum -> subAlbum/picToShow (if subAlbum = "" we get "" -> /picToShow)
local pathToPic="$pathToPic/$1"
# /picToShow -> picToShow (if we had subAlbum = "" above. else nothing happens)
local pathToPic="${pathToPic#/}"
# subAlbum/picToShow -> ../subAlbum/picToShow (ie we've got a relative link to the pic!)
local pathToPic="$pathToAlbumRoot$pathToPic"
echo "
$title
$realTitle
[$javaLink]
" >> "$albDir/$currentPicNr$fileSuffix"
if [[ $currentPicNr -eq 1 ]]
then
generateJavascriptLink "$nrOfPics$fileSuffix" "<<Prev"
echo "$javaLink" >> "$albDir/$currentPicNr$fileSuffix"
else
generateJavascriptLink "$prevPicNr$fileSuffix" "<<Prev"
echo "$javaLink" >> "$albDir/$currentPicNr$fileSuffix"
fi
echo "
Pic $currentPicNr of $nrOfPics
" >> "$albDir/$currentPicNr$fileSuffix"
if [[ $currentPicNr -eq $nrOfPics ]]
then
generateJavascriptLink "1$fileSuffix" "Next>>"
echo "$javaLink" >> "$albDir/$currentPicNr$fileSuffix"
else
generateJavascriptLink "$nextPicNr$fileSuffix" "Next>>"
echo "$javaLink" >> "$albDir/$currentPicNr$fileSuffix"
fi
echo "
" >> "$albDir/$currentPicNr$fileSuffix"
# HTML part of the JavaScript/HTML that controls the slideshow
echo "
$1
" >> "$albDir/$currentPicNr$fileSuffix"
# insert comments and exif data
local fileType=`identify -format "%m" "$1[0]"` # %m = magic number
if [[ "$fileType" == "JPEG" ]]
then
echo "
" >> "$albDir/$currentPicNr$fileSuffix"
identify -format "" "$1" >> "$albDir/$currentPicNr$fileSuffix"
fi
echo "
" >> "$albDir/$currentPicNr$fileSuffix"
}
insertNewPage()
{
local prevIndex="$index"
index="$htmlPageName$pageNum$fileSuffix"
let pageNum=$pageNum+1 # See to it that we get index1, index2, ...
local nextIndex="$htmlPageName$pageNum$fileSuffix"
local picsOnPage=`expr $cols \* $rows`
if [[ $nrOfPics -eq 0 ]]
then
pagesNeeded=1
else
# Bash doesn't do floating point arithmetics
# so we'll have to do this workaround
pagesNeeded=0
tmp=$nrOfPics
while [[ $tmp -gt 0 ]]
do
let pagesNeeded=$pagesNeeded+1
let tmp=$tmp-$picsOnPage
done
fi
echo "
$title
$realTitle${title[$level]}
" > "$albDir/$index"
if [[ "$PWD" != "$origPWD" ]] # We came from another directory!
then
generateJavascriptLink "../$htmlPageName$fileSuffix" "Back to $oldTitle"
echo "
[$javaLink]" >> "$albDir/$index"
fi
echo "
" >> "$albDir/$index"
if [[ $pageNum -ne 1 ]] # not first page -> prev link needed
then
insertPageEnd "$prevIndex"
generateJavascriptLink "$prevIndex" "<<Prev"
echo "$javaLink" >> "$albDir/$index"
else
echo "<<Prev" >> "$albDir/$index"
fi
echo "
Page $pageNum of $pagesNeeded
" >> "$albDir/$index"
if [[ $pageNum -lt $pagesNeeded ]] # More pics than can fit on this page -> Include next link
then
generateJavascriptLink "$nextIndex" "Next>>" "$albDir/$index"
echo "$javaLink" >> "$albDir/$index"
else
echo "Next>>" >> "$albDir/$index"
fi
echo "
" >> "$albDir/$index"
if [[ $pagesNeeded -gt 1 ]]
then
i=""
while [[ $i -lt $pagesNeeded ]]
do
let ii=$i+1
if [[ $ii -eq $pageNum ]]
then
echo "[$ii] " >> "$albDir/$index"
else
generateJavascriptLink "$htmlPageName$i$fileSuffix" "$ii"
echo "[$javaLink]" >> "$albDir/$index"
fi
let i=$i+1
done
fi
echo "
" >> "$albDir/$index"
}
# $1 = name of page to be ended
insertPageEnd()
{
# We won't have an open table to close if there's no pics
# (ie just album links) on the page.
if [[ $nrOfPics -ne 0 ]]
then
echo "
" >> "$albDir/$1"
fi
echo "
" >> "$albDir/$1"
}
# $1 = dir to link to
insertDirLink()
{
generateJavascriptLink "$1/$htmlPageName$fileSuffix" "$1"
echo "$javaLink " >> "$albDir/$index"
}
createDirs()
{
# Create the albDir
if [[ ! -e "$albDir" ]]
then
mkdir "$albDir"
elif [[ ! -d "$albDir" ]]
then
echo ">>"
echo ">> ERROR: There is already a file $PWD/$albDir so I can't create that directory"
echo ">> Rename it or change the variables in the script."
exit
fi
# Create the thumbDir
if [[ ! -e "$albDir/$thumbDir" ]]
then
mkdir "$albDir/$thumbDir"
elif [[ ! -d "$albDir/$thumbDir" ]]
then
echo ">>"
echo ">> ERROR: There is already a file $PWD/$thumbDir so I can't create that directory"
echo ">> Rename it or change the variables in the script."
exit
fi
# Create the scaledDir
if [[ ! -e "$albDir/$scaledDir" ]]
then
mkdir "$albDir/$scaledDir"
elif [[ ! -d "$albDir/$scaledDir" ]]
then
echo ">>"
echo ">> ERROR: There is already a file $PWD/$scaledDir so I can't create that directory"
echo ">> Rename it or change the variables in the script."
exit
fi
# Create the css
insertStyleSheet
}
countPics()
{
nrOfPics=0
for file in *
do
if [[ ! -d "$file" ]]
then
let nrOfPics=$nrOfPics+1
fi
done
}
findAlbums()
{
pageNum=""
pageStarted=0
for dir in *
do
if [[ -d "$dir" ]] && [[ "$PWD/$dir" != "$albDir" ]]
then
if [[ $pageStarted -eq 0 ]] # Should we create a new page?
then
insertNewPage
echo "
Subgalleries:
" >> "$albDir/$index"
pageStarted=1
fi
insertDirLink "$dir"
fi
done
if [[ $pageStarted -eq 1 ]]
then
echo "
" >> "$albDir/$index"
fi
}
genGallery()
{
currentPicNr=0
for pic in *
do
if [[ ! -d "$pic" ]]
then
if !(($currentPicNr % (($cols * $rows)))) # Have we filled a page?
then
# Do we need a new page?
if [[ $currentPicNr -eq 0 ]]
then
if [[ $pageStarted -eq 0 ]]
then
insertNewPage
fi
insertIndexTable
else #currentPicNr != 0
insertNewPage
insertIndexTable
fi
fi
# Do we need a new row?
if !(($currentPicNr % $cols))
then
insertRow
fi
let prevPicNr=$currentPicNr
let currentPicNr=$currentPicNr+1
let nextPicNr=$currentPicNr+1
echo ">> Adding pic $currentPicNr of $nrOfPics in ${title[level]} ($pic)"
# scale the image, but only if it hasn't been done already
if [[ "$pic" -nt "$albDir/$scaledDir/$pic.$scaledFormat" ]] || [[ "$rebuild" == "true" ]]
then
convert -format $scaledFormat -size $scaledSize -quality $scaledQuality -thumbnail "$scaledSize>" "$pic[0]" "$albDir/$scaledDir/$pic.$scaledFormat"
fi
# Thumbnail the scaled version, but only if it hasn't been done before
if [[ "$pic" -nt "$albDir/$thumbDir/$pic.$thumbFormat" ]] || [[ "$rebuild" == "true" ]]
then
convert -format $thumbFormat -size $thumbSize -quality $thumbQuality -thumbnail $thumbSize "$albDir/$scaledDir/$pic.$scaledFormat" "$albDir/$thumbDir/$pic.$thumbFormat"
fi
insertPicPage "$pic" # $pic = pic to show
insertIndexTd "$currentPicNr$fileSuffix" "$pic.$thumbFormat" # "page to link to" "thumb to show"
fi
done
# Include an index without pics if we found an empty dir.
if [[ $nrOfPics -eq 0 ]] && [[ $pageStarted -eq 0 ]]
then
insertNewPage
fi
insertPageEnd "$index" # remember to close the last page
}
recurse()
{
# see to it that we get enough ../ when we insert the relative links
pathToAlbumRoot="../$pathToAlbumRoot"
# The chunk below takes care of generating headers with correct links
index="$htmlPageName$fileSuffix"
realTitle=""
countPics
createDirs
findAlbums
genGallery
for dir in *
do
if [[ -d "$dir" ]] && [[ "$PWD/$dir" != "$albDir" ]]
then
albDir="$albDir/$dir"
oldTitle="${PWD##*/}" # oldTitle -> current dir
cd "$dir"
let "level=$level+1"
title[$level]="$dir"
recurse
let "level=$level-1"
cd "../"
#title="${title%/*}" # dir1/dir2 -> dir1
pathToAlbumRoot="${pathToAlbumRoot%../}" # Strip last ../
albDir="${albDir%/*}" # albDir/anotherDir -> albDir
fi
done
}
# $x = args
echo ">>"
echo ">> Creating a gallery from $PWD"
if [[ "$1" == "--rebuild" ]]
then
echo ">>"
echo ">> Doing complete rebuild of album"
rebuild="true"
fi
albDir="$PWD/$albDir"
# These are used to generate headers with relative links
level=0
title[$level]="${PWD##*/}" # title = last part of $PWD
origPWD="$PWD"
# Used when inserting relative links
pathToAlbumRoot=""
echo ">>"
echo ">> Creating album"
recurse
echo ">> Album done!"
exit