#!/usr/bin/perl -w # makeIndexes.pl # # copyright (c) 2005 by philo vivero # # released under the terms of the GPL. if you do not understand # what those terms are, please discontinue use of this program # until you do. use strict; my $convertCommand = "nice convert -limit Memory 8388608 -quality 85"; my $bigThumbSize = "250x250"; my $minWidth = "75"; my $tinyThumbSize = "${minWidth}x${minWidth}"; my $bgColour = "#ffffff"; my $normalColour = "#020202"; my $highlightColour = "#305830"; my $titleColour = "#a0c0a0"; my $cellColour = "#e0e8e0"; my $numFilesName = "00-numFilesInThisDir.txt"; my $indexFileName = "index.html"; my $cssFileName = "pv-makeIndexes.css"; my $indexTemplateFileName = ""; my $recurseOption = ""; my @dirsToDo; my $dirToDo; my $tinyThumb; my $intermediateSize = 0; my $setIntermediateToThis = 0; # no args passed? tell how to use it and quit if (scalar @ARGV == 0) { doUsage(); } # parse arguments my $inArg; while ($inArg = shift) { if ($inArg eq '-h' || $inArg eq '--help') { doUsage(); } elsif ($inArg eq '--recurse' || $inArg eq '-r') { $recurseOption = "y"; } elsif ($inArg eq '--index-template') { $indexTemplateFileName = shift; } elsif ($inArg eq '--create-template') { my $html = doInitHtmlTemplate(); open (OFILE, "> index.template.html"); print OFILE $html; close OFILE; open (OFILE, "> $cssFileName"); print OFILE &getDefaultCSS(); close OFILE; print "Created index.template.html and $cssFileName. You might want to edit them.\n"; exit 0; } elsif ($inArg eq '--intermediate-size') { $setIntermediateToThis = shift; } else { # the final argument becomes $dirToDo $dirToDo = $inArg; } } # if we're recursing, we'll overwrite the previous push # into @dirsToDo, because the find will find the argument # passed to this script if ($recurseOption) { my $dirsToDo = `find "$dirToDo" -type d`; my @dirsForward = split (/\n/, $dirsToDo); # put the directories in reverse order (leaf-level first) foreach my $dirToDo (@dirsForward) { push (@dirsToDo, $dirToDo); } } else { @dirsToDo = ($dirToDo); } foreach $dirToDo (@dirsToDo) { my $htmlTemplate = ""; $htmlTemplate = doInitHtmlTemplate(); my $oldwd=`pwd`; chomp ($oldwd); # which dir to do if ($dirToDo) { print " . chdir'ing to \"$dirToDo\" from \"$oldwd\"\n"; chdir "$dirToDo"; } else { print " . Doing `pwd`\n"; $dirToDo = `pwd`; } # get rid of " in any filenames my $numQuote = `ls -al *\\"* 2>/dev/null | wc -l`; while ($numQuote > 0) { doSystem ('rename \\" \"\" *'); $numQuote = `ls -al *\\"* 2>/dev/null | wc -l`; } # list the gallery name, try to be nice about how it's displayed $htmlTemplate = doGalleryName ($dirToDo, $htmlTemplate); # get rid of existing tiny thumbnails doSystem ("rm tinythumb-*.thumb.jpg 2>/dev/null"); # find out if we need to create an intermediate-sized image my $intermediateSizeFile = `ls -1 00-size-* 2>/dev/null`; chomp ($intermediateSizeFile); if ($intermediateSizeFile =~ /00-size-(\d+)/) { $intermediateSize = $1; } else { $intermediateSize = $setIntermediateToThis; } print " . Determined intermediateSize = $intermediateSize\n"; # foreach jpg, create thumbnail & deal with $indexFileName my $fileList = `find . -mindepth 1 -maxdepth 1 -name '*.jpg' | egrep -v 'thumb|\\.${intermediateSize}\\.jpg' | sort`; my @fileList = split (/\n/, $fileList); my $bigGallery = ""; foreach my $i (@fileList) { print " . . Working on $i\n"; # create a big thumbnail & get its style info doBigThumb ($i); $bigGallery .= insertBigGallery ($i); } $htmlTemplate =~ s/__bigGallery__/$bigGallery/gm; # now put thumbnails of subdirs into the $indexFileName #my $thumbListToDo = `( find */ -mindepth 1 -maxdepth 1 -type d ; find */ -mindepth 1 -maxdepth 1 -type l ) | sort`; my $thumbListToDo = `find . -mindepth 1 -maxdepth 1 -type d | sort`; my @thumbListToDo = split (/\n/, $thumbListToDo); my $numFiles = scalar (@fileList); my $tinyGallery = ""; foreach my $dir (@thumbListToDo) { if (getRandomThumbnail ($dir)) { $tinyGallery .= insertTinyGallery ($dir); $numFiles++; } else { print " . Found no thumbs in $oldwd/$dir\n"; } } $htmlTemplate =~ s/__tinyGallery__/$tinyGallery/gm; open (OFILE, ">$numFilesName"); print OFILE $numFiles; close OFILE; #print " . Creating $indexFileName for $dirToDo\n"; open (HTMLFILE, "> $indexFileName"); print HTMLFILE $htmlTemplate; close HTMLFILE; # go back from whence we came chdir "$oldwd"; } exit 0; # --------------------------------------------------------------------------- # --------------------------------------------------------------------------- # --------------------------------------------------------------------------- # Subroutines follow # --------------------------------------------------------------------------- # --------------------------------------------------------------------------- # --------------------------------------------------------------------------- # create HTML for the large thumbnail sub doBigThumb { my $i = shift; my $singleFixed = doSingleQuoteFix ($i); if ($intermediateSize > 0 && ! -e "$i.${intermediateSize}.jpg") { doSystem ("$convertCommand -resize \\>${intermediateSize}x${intermediateSize} '$singleFixed' '$singleFixed'.${intermediateSize}.jpg"); if (! -e "$i.thumb.jpg") { doSystem ("$convertCommand -resize \\>$bigThumbSize '$singleFixed'.${intermediateSize}.jpg '$singleFixed'.thumb.jpg"); } } elsif (! -e "$i.thumb.jpg") { doSystem ("$convertCommand -resize \\>$bigThumbSize '$singleFixed' '$singleFixed'.thumb.jpg"); } } # do a system call, optionally print what you're doing sub doSystem { my $cmd = shift; #print " . doSystem ($cmd)\n"; system ($cmd); } # from the image properties, determine style text # width is useful, but height is impossible to determine # without knowing font height sub getStyleText { my $file = shift; my $styleTxt = ""; my $identify; # too slow. ### # determine the width of the
  • ### $identify = `identify $file`; # not as slow... if ($file =~ /^tinythumb-/) { $identify = $tinyThumbSize . "+0+0"; } elsif ($file =~ /\.thumb\./) { $identify = $bigThumbSize . "+0+0"; } if ($identify =~ /(\d+)x(\d+)\+\d+\+\d+/) { my $x = $1; my $y = $2; if ($x < $minWidth) { $x = $minWidth; }; $x = int ($x * 1.1 + 24); #$y = int ($x * 1.5); #$styleTxt = " style='width: $x; height: $y;'"; $styleTxt = " style='width: $x;'"; } else { $styleTxt = ""; } return $styleTxt; } # get any text out of a .txt file corresponding to the current file/dir sub getPossibleText { my $whichSide = shift; my $possibleFile = shift; my $textToInsert = ""; my $possibleTextFile = $whichSide . "-" . $possibleFile . ".txt"; if (-e $possibleTextFile) { open (IFILE, $possibleTextFile); my $inline; while ($inline = ) { $textToInsert .= $inline; } close IFILE; } return $textToInsert; } # convert _ and - into spaces for display and remove JPG/PNG # extensions sub makeDisplay { my $dispName = shift; $dispName =~ s/-/ /gs; $dispName =~ s/_/ /gs; $dispName =~ s/\.jpg//gs; $dispName =~ s/\.png//gs; $dispName =~ s/([a-z]{1})([A-Z]{1})/$1 $2/gs; $dispName =~ s/([A-Z]{1})([A-Z]{1})/$1 $2/gs; $dispName =~ s/ A / a /gs; $dispName =~ s/ An / an /gs; $dispName =~ s/ And / and /gs; $dispName =~ s/ The / the /gs; $dispName =~ s/ Of / of /gs; $dispName =~ s/ Or / or /gs; return $dispName; } # since we will single-quote this argument, we can convert # any single quotes inside to '\'' (ie: end the single quote, # add an escaped single quote, then re-open the single quote) sub doSingleQuoteFix { my $inStr = shift; $inStr =~ s/'/'\\''/g; return $inStr; } # show usage and exit sub doUsage { print "Usage: $0 [--recurse|-r] [--index-template ] [--intermediate-size ] \n"; print " or: $0 [--help|-h] [--create-template]\n"; print "Try this for instant gratification: \"$0 -r .\"\n"; print "\n"; print "--recurse Do all subdirectories, too\n"; print "--index-template Use this HTML file as template for index.html\n"; print "--intermediate-size Create smaller images of this size as well as thumbnails\n"; print "--create-template Create an index.template.html to be used for --index-template\n"; print "\n"; print "Just getting started? Here's what you should do:\n"; print "\n"; print " 1. $0 --create-template\n"; print " 2. Edit the index.template.html file -- format as you like\n"; print " 3. Edit the $cssFileName file and put it in your docroot (or where template specifies)\n"; print " 4. $0 -r --index-template index.template.html .\n"; print "\n"; print "Any file named \"before-.txt\" will be put before the JPEG in question. Any\n"; print "file named \"after-.txt\" will be put after the JPEG in question. Any file\n"; print "named \"before-anything.txt\" will be the title of the page for that directory.\n"; exit 1; } # the name of the gallery, and any special text sub doGalleryName { my $dirToDo = shift; my $htmlTemplate = shift; if ($dirToDo ne '.' && $dirToDo ne './') { my $displayDir = makeDisplay ($dirToDo); $htmlTemplate =~ s/__pwd__/$displayDir/gm; } else { my $dirParse = `pwd`; chomp ($dirParse); if ($dirParse =~ /^.+\/(.+)$/) { my $i = makeDisplay ($1); $htmlTemplate =~ s/__pwd__/$i/gm; } else { my $displayDir = makeDisplay ($dirParse); $htmlTemplate =~ s/__pwd__/$displayDir/gm; } } if (-e 'before-anything.txt') { my $txt = `cat before-anything.txt`; $htmlTemplate =~ s/__beforeAnything__/

    $txt<\/p>/gm; } else { $htmlTemplate =~ s/__beforeAnything__//gm; } return $htmlTemplate; } # insert a thumbnail into the large gallery (of regular # thumbnails) sub insertBigGallery { my $i = shift; my $bigGallery = ""; # get rid of any beginning ./ -- it'll just cause problems $i =~ s/^\.\///; # any text to go before a series of pics/dirs my $txt = getPossibleText('before', $i); if ($txt) { $bigGallery .= "

    $txt

    \n"; } #print " . Insert to $indexFileName\n"; my $dispName = makeDisplay($i); my $styleTxt = getStyleText($i . ".thumb.jpg"); if ($intermediateSize > 0) { my $alink = ""; my $fullAlink = "Fullsize: $dispName"; $bigGallery .= "
    $alink
    $fullAlink
    \n"; } else { my $alink = ""; $bigGallery .= "
    $alink
    $dispName
    \n"; } # any text to go after a series of pics/dirs $txt = getPossibleText('after', $i); if ($txt) { $bigGallery .= "

    $txt

    \n"; } return $bigGallery; } # insert a thumbnail into the tiny gallery (of directories) sub insertTinyGallery { my $i = shift; my $tinyGallery = ""; # get rid of any beginning ./ -- it'll just cause problems $i =~ s/^\.\///; # any text to go before a series of pics/dirs my $txt = getPossibleText('before', $i); if ($txt) { $tinyGallery .= "

    $txt

    \n"; } my $styleTxt = getStyleText($tinyThumb); my $dispName = makeDisplay($i); my $numPicsVerbiage = ""; if (-f "$i/$numFilesName") { open (IFILE, "< $i/$numFilesName"); my $num = ; close IFILE; $numPicsVerbiage = " ($num item"; if ($num != 1) { $numPicsVerbiage .= "s)"; } else { $numPicsVerbiage .= ")"; } } $tinyGallery .= "\n"; # any text to go after a series of pics/dirs $txt = getPossibleText('after', $i); if ($txt) { $tinyGallery .= "

    $txt

    \n"; } return $tinyGallery; } # given a directory, get a list of thumbnails, and pick one # at random, then convert it into a tiny thumbnail sub getRandomThumbnail { my $dir = shift; # pick a random image for thumbnail my $oldwd = `pwd`; chomp ($oldwd); chdir "$dir"; my $thumbList = `ls -1 *.thumb.jpg 2>/dev/null`; chomp ($thumbList); chdir "$oldwd"; if ($thumbList) { my @thumbList = split (/\n/,$thumbList); my $thumbNum = int (rand (@thumbList)); my $thumbFile = $thumbList[$thumbNum]; print " . Tinythumb :: $dir/$thumbFile\n"; $tinyThumb = "tinythumb-$thumbFile"; my $sanitised1 = doSingleQuoteFix("$dir/$thumbFile"); my $sanitised2 = doSingleQuoteFix($tinyThumb); -e $tinyThumb || doSystem ("$convertCommand -geometry $tinyThumbSize '$sanitised1' '$sanitised2'"); return 1; } else { return 0; } } # initialise the HTML template sub doInitHtmlTemplate { my $html = " __pwd__
    __pwd__
    __beforeAnything__ __tinyGallery__
    __bigGallery__
    Created with makeIndexes.pl by Philo Vivero.
    "; # if there's a template indexfile, use it rather if ($indexTemplateFileName && -e $indexTemplateFileName) { $html = `cat $indexTemplateFileName`; } return $html; } sub getDefaultCSS { my $css = " "; return $css; }