#!/usr/local/bin/perl ############################################################################## $VERSION='GTindex v1.2'; # 2 April 1997 Dale Bewley #$VERSION='GTindex v1.121'; # 18 Oct. 1996 Dale Bewley #VERSION='GTindex v1.12'; # 03 Oct. 1996 Dale Bewley #v1.11b1 08-16-96, v1.10 08-12-96, v1.09 07-25-96, v1.05 06-23-96 #----------------------------------------------------------------------------- # This script was written for a specific site and may be less than portable. # Others like it found at http://www.bewley.net/perl/ # # Note: the web documentation is a little out of date. I'm working on pulling # it all into some POD at the bottom of this file. # # New in 1.2: # o -b and -l now take "none" as an option to not print bullets or lines. # o width and height tags added to thumbnail pages. this needs to be using # Image::Size instead of the subs below. I imagine most people may # not have that installed though. # New in 1.12: # o last index has a next link at the bottom. now that points to the first # index instead of a non existant one. # # Notes: # o this script requires perl5 (barely) and has been testing in win95 # and UNIX # o to run it in win95 type: # "c:\pro\perl5\bin\perl c:\pro\perl5\scripts\gtindex.pl -v *.jpg" # or something like that. # o Thumbnails should be in a subdir of the dir containing your pics. # They must have the SAME NAME as their full sized versions!! # o Say you have a dir called gfx filled full of graphics and you are in # win95. Create a subdir called gfx\thumbs and copy all the graphics # into there. Now get thumbsplus and convert all the graphics in # thumbs into thumbnails overwriting them with the same name. Set # $THUMB_DIR to "thumbs" and finally, cd to your gfx dir and run me. # o This thing is a little messy. I'll clean it up as I find time. # If you see obvious room for improvment drop me a line. # o This version has some new command line switches. # # # Copyright (C) 1995, 1996, 1997 Dale Bewley # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # ############################################################################## #- User Configurable Variables ----------------------------------------------# $ALINK = "#EE0033"; # active link color $BGCOLOR = "#000000"; # index background color $LINK = "#00FF00"; # link color $TEXT = "#FFFFFF"; # index normal text color $VLINK = "#FF1CAE"; # visited link color $BULLET = "../bullet.gif"; # image URL or blank, "", if none. $LINE = "../line.gif"; # grphical HR $MAX_ON_PAGE = 9; # maximum images on a page $MAX_ROWS = 3; # maximum number of images down a column # this means number of columns on page is # ($MAX_ON_PAGE / $MAX_ROWS) $SITE_NAME = "Dale's Images - "; # printed in title. prefixes $TITLE $HOME_URL = "http://www.bewley.net/perl/"; # home link on indexes $THUMB_DIR = "thumbs"; # directory containing optional thumbnails of images # it is assumed this will be within the current directory $TITLE = "GTindex"; # default title and header on each index page. #----------------------------------------------------------------------------# #- Help! --------------------------------------------------------------------# sub help { print <<"END_OF_HELP"; $VERSION Dale Bewley http://www.bewley.net/perl/ Description: This script will create an HTML index of all the graphics specified on the command line. And create parallel indexes with thumbnails if you have them. Usage: $0 [] Options (Defaults inside [] below): -b Bullet graphic. To appear to the left of image titles. [$BULLET] "none" to do away with bullets. -d Destructive. Overwrite old indexes with new ones. -f Baseref. URL to prepend all IMG SRC's. [$BASEREF] -h This message. -l Line graphic. To appear at the at top and bottom of indexes. [$LINE] "none" to do away with line graphics. -m Location of thumbnail images. [$THUMB_DIR] -r Maximum rows of images in a table cell. [$MAX_ROWS] -s Print size of graphic file in index next to link. -t "Title of page." Don't forget the quotes! [$TITLE] -v Verbose. Examples: $0 -vdst "Tons of Pictures!" *.jpg *.gif END_OF_HELP 1; } #----------------------------------------------------------------------------# #- Main Program -------------------------------------------------------------# require('getopt.pl'); # helps handle cmd line opts. comes with Perl &getOpts; # get commandline options if ($opt_h || !@ARGV) { &help && exit; } if (! -f $LINE) { print STDERR "Warning: $LINE does not exist (unless it is a URL)!\n"; } if (! -f $BULLET) { print STDERR "Warning: $BULLET does not exist (unless it is a URL)!\n"; } @FILES = @ARGV; # files left on the command line # extract dirs from file list foreach $i (0 .. $#FILES) { push(@DIRS,splice(@FILES,$i)) if (-d $FILES[$i]); } @thumbnails = &getThumbs($THUMB_DIR); # get thumbnails from $THUMB_DIR $numFiles = @FILES; $numDirs = @DIRS; $numIndexes = int($numFiles / $MAX_ON_PAGE); # plus remainder $numIndexes++ if (($numFiles % $MAX_ON_PAGE) != 0); # if so then 1 incomplete &giveVerbose if $opt_v; $iCount=1; # initialize index count while(@FILES) { # account for the thumb dir!! if ($iCount == 1) { $INDEX = "index.html"; } else { $INDEX = "index$iCount.html"; } *INDEX = &openIndex("INDEX", $INDEX); &printHeader(*INDEX, "$TITLE"); $shiftNum = &printIndex(*INDEX); # print links to other indexes &printIndexBar(*INDEX); &printFooter(*INDEX); if (@thumbnails) { *TINDEX = &openIndex("TINDEX", "t$INDEX"); &printHeader(*TINDEX, "$TITLE"); # pass "anything" as second parameter so it will include thumbnails # on the index $shiftNum = &printIndex(*TINDEX, "with_thumbnails"); # print links to other indexes &printIndexBar(*TINDEX, "with_thumbnails"); &printFooter(*TINDEX, "with_thumbnails"); } splice(@FILES,0,$shiftNum); close INDEX; close TINDEX; $iCount++; # debug ??? hu } #----------------------------------------------------------------------------# #- Get command line options -------------------------------------------------# sub getOpts { &Getopt('bflmrt'); # these options accept commandline values # if indexes are in the same dir w/ images then you don't need a baseref $BULLET = $opt_b if ($opt_b); undef $BULLET if ($BULLET =~ /none/i); $BASEREF = $opt_f if ($opt_f); $LINE = $opt_l if ($opt_l); undef $LINE if ($LINE =~ /none/i); $THUMB_DIR = $opt_m if ($opt_m); $MAX_ROWS = $opt_r if ($opt_r); $TITLE = $opt_t if ($opt_t); } #----------------------------------------------------------------------------# #- Read thumbnails in thumbdir ----------------------------------------------# sub getThumbs { local($dir) = shift @_; local(@thumbnails); opendir(DIR,"$dir") || return; @thumbnails = grep(/[^.]+$/, readdir(DIR)); #reading everything not .* close(DIR); return @thumbnails; } #----------------------------------------------------------------------------# #- Open next index for printing ---------------------------------------------# sub openIndex { #this needs tweaking, but it seems to work local($FH) = shift @_; # filehandle name local($INDEX) = shift @_; # filename local($i)=0; # if non destructive, let's save existing indexes if (!$opt_d) { if (-e $INDEX) { $INDEXbak = $INDEX; while (( -e $INDEXbak ) && ($i++ <= 1000)) { $INDEXbak = "$INDEX$i"; } rename("$INDEX", "$INDEXbak") || die "Can't rename $INDEX to $INDEXbak"; print "saving $INDEX to $INDEXbak\n" if ($opt_v); } } open($FH, ">$INDEX") || die "Can't open $INDEX for output $! "; print " opened $INDEX for output... " if ($opt_v); return $FH; } #----------------------------------------------------------------------------# #- Print html header on index -----------------------------------------------# sub printHeader { # you may carefully modify this HTML # pass filehandle as arg later local($FH) = shift @_; # filehandle to index local($TITLE) = shift @_; $BASEREF |= "./"; print $FH <<"E_O_HTML"; $SITE_NAME $TITLE
$TITLE

E_O_HTML print $FH "


\n" if ($LINE); } #----------------------------------------------------------------------------# #- Print an index -----------------------------------------------------------# sub printIndex { # print the actual links to graphics in the index # this will totally change with template support (if i ever add it) # for now just pass it a file handle and if this call is to include # thumbnails then pass anything as a second argument local($FH) = shift @_; # filehandle to write index to local($tindex) = shift @_; # set $tindex if printing thumbnails local($pCount) = 0; # picture count local($rCount) = 0; # row count (num pictures in a column) local($cCount) = 1; # column count print $FH "
\n\n\n"; print $FH "\t\n\t\n"; print $FH "\n
\n\t
\n"; for ($pCount=0; $pCount < $MAX_ON_PAGE; $pCount++) { ($pic = @FILES[$pCount]) || next; if ($rCount == $MAX_ROWS) { $rCount = 0; $cCount++; # no check for cols? # end the table column and start the next print $FH "\t
\n\t
\n"; } $rCount++; # list an image print $FH "\t\t
"; # no bullet on thumbnail ver. of index print $FH "" if ($BULLET && !$tindex); if ($tindex) { # should have width and height tags! get fiximg.pl print $FH ""; #if ( grep(/$pic/, @thumbnails) > 0) { #debug $thumbnail = "$THUMB_DIR/$pic"; if ( -e "$thumbnail" ) { print $FH " "; } else { print STDERR "WARNING! $thumbnail missing! "; print $FH "" if ($BULLET); } print $FH "$pic "; } else { print $FH "$pic "; } if ($opt_s) { # display size in kilobytes $size = (-s $pic); $size /= 1024; $size += .5; $size = int($size); print $FH "(", $size,"kb)"; } print $FH "

\n"; } # end index print $FH "\t\n\t

\n
\n"; print "Added $pCount files.\n" if ($opt_v); return $pCount; # debug } #----------------------------------------------------------------------------# #- Print html footer on index -----------------------------------------------# sub printFooter { local($FH) = shift @_; # filehandle to index if ($LINE) { print $FH "
"; print $FH "

\n"; } print $FH <<"E_O_HTML";
Created with $VERSION written by Bewley Internet Solutions.
E_O_HTML } #----------------------------------------------------------------------------# #- Give some verbose info ---------------------------------------------------# sub giveVerbose { # print some verbose info print "$VERSION\n"; print "$numDirs directories to ignore for now (no recursion)\n"; print scalar(@thumbnails), " thumbnails in $THUMB_DIR\n" if (@thumbnails); print "$numFiles graphics specified\n"; print "$numIndexes indexes to create\n"; } #----------------------------------------------------------------------------# #- Print Links to Other Indexes ---------------------------------------------# sub printIndexBar { local($FH) = shift @_; local($tindex) = shift @_; print $FH "
"; # print link to thumbnail or no thumbnails version if (@thumbnails) { if ($tindex) { print $FH "[No Thumbnails]\n"; } else { print $FH "[Thumbnails]\n"; } } print $FH "[Home]\n" if ($HOME_URL); $prev = $iCount; if ($iCount == 1) { # nothing } elsif ($iCount == 2) { # this is a kludge? fix it later. debug if ($tindex) { print $FH "[Previous]\n"; } else { print $FH "[Previous]\n"; } } else { if ($tindex) { print $FH "[Previous]\n"; } else { print $FH "[Previous]\n"; } } # print link to all the indexes for this batch foreach $i (1..$numIndexes) { if ($i == $iCount) { if ($tindex) { print TINDEX "$i\n"; } else { print INDEX "$i\n"; } } elsif ($i == 1) { # this is a kludge if ($tindex) { print $FH "1\n" if (@thumbnails); } else { print $FH "1\n"; } } else { if ($tindex) { print $FH "$i\n" if (@thumbnails); } else { print $FH "$i\n"; } } } #$iCount++; $next = ($iCount+1); undef $next if ($next > $numIndexes); if ($tindex) { print $FH "[Next]" if ($FILES[0]); } else { print $FH "[Next]" if ($FILES[0]); } print $FH "\n
\n"; } #----------------------------------------------------------------------------# #----------------------------------------------------------------------------# sub hwTags { my ($file) = @_ ; open(GRAPHIC, "$file") || die "Can't open graphic $file $!"; binmode(GRAPHIC); # necessary for non UNIX perl if ($file =~ /\.gif$/i) { $tags = &gifSize(GRAPHIC); } elsif ($file =~ /\.jpg$|.jpeg$/i) { $tags = &jpegSize(GRAPHIC); } close (GRAPHIC); return $tags; } #----------------------------------------------------------------------------# #- Size Gifs ----------------------------------------------------------------# sub gifSize { # return a string of height and width tags for a gif. # this code "adapted" from: # http://rajiv.org/programming/gifsize.txt my ($GIF) = @_; my ($w, $w2, $h, $h2, $gifwidth, $gifsize, $type) = () ; read ($GIF, $type, 3); seek ($GIF, 6, 0); read ($GIF, $w, 1); read ($GIF, $w2, 1); read ($GIF, $h, 1); read ($GIF, $h2, 1); $width = ord ($w) + ord ($w2) * 256; $height = ord ($h) + ord ($h2) * 256; return ("WIDTH=\"$width\" HEIGHT=\"$height\""); } #----------------------------------------------------------------------------# #----------------------------------------------------------------------------# # jpegsize : gets the width and height (in pixels) of a jpeg file # Andrew Tong, werdna@ugcs.caltech.edu February 14, 1995 # modified slightly by alex@ed.ac.uk sub jpegSize { my ($JPEG) = @_; my ($done) = 0; my ($size) = ""; read($JPEG, $c1, 1); read($JPEG, $c2, 1); if( !((ord($c1) == 0xFF) && (ord($c2) == 0xD8))){ print "This is not a JPEG!"; $done=1; } while (ord($ch) != 0xDA && !$done) { # Find next marker (JPEG markers begin with 0xFF) # This can hang the program!! while (ord($ch) != 0xFF) { read($JPEG, $ch, 1); } # JPEG markers can be padded with unlimited 0xFF's while (ord($ch) == 0xFF) { read($JPEG, $ch, 1); } # Now, $ch contains the value of the marker. if ((ord($ch) >= 0xC0) && (ord($ch) <= 0xC3)) { read ($JPEG, $junk, 3); read($JPEG, $s, 4); ($a,$b,$c,$d)=unpack("C"x4,$s); $size=join("", 'HEIGHT=',$a<<8|$b,' WIDTH=',$c<<8|$d ); $done=1; } else { # We **MUST** skip variables, since FF's within variable names are # NOT valid JPEG markers read ($JPEG, $s, 2); ($c1, $c2) = unpack("C"x2,$s); $length = $c1<<8|$c2; if( ($length < 2) ){ print "Erroneous JPEG marker length"; $done=1; } else { read($JPEG, $junk, $length-2); } } } return $size; } #----------------------------------------------------------------------------# __END__ =pod =head1 NAME gtindex.pl - Graphics and Thumbnail indexer. V1.2 - http://www.bewley.net/perl/gtindex.pl =head1 SYNOPSIS gtindex.pl [ C<-b> F ] [ C<-d> ] [ C<-f> F ] [ C<-h> ] [ C<-l> F ] [ C<-m> F ] [ C<-r> F ] [ C<-s> ] [ C<-t> F ] [ C<-v> ] Examples: gtindex.pl *.jpg gtindex.pl -vdt "Dale's Police Brutality Imagery" -b "none" *.gif gtindex.pl -v -l "none" -r 3 -t "graphics" *.gif *.jpg =head1 DESCRIPTION In case you are confused... This is a command line program only, not a CGI app, for now. This script requires perl5 (barely) and has been testing in win95 and UNIX. Well, it hasn't been tested on win95 lately. I. Use this if you have many many graphics that you would like to be able to browse easily with a web browser. Say you have a dir called gfx filled full of graphics. Create a subdir called gfx/thumbnails and place thumbnail sized copies of each graphic in there. How do you make the thumbnails? That depends on your platform. I would reccomend C for win95 and C for UNIX. Convert is a part of the Imagemagik package. Now cd to your gfx dir and run this little gem. Thumbnails must be in a subdir of the dir containing your pictures. They must also have the SAME NAME as their full sized versions!! Of course you don't need thumbnails at all if you don't have any. Just don't create the thumbnail dir and gtindex.pl will still work normally. Well, almost... =head2 Example Output =over 4 =item Dale's Images http://www.bewley.net/photos/tindex.html =item Jeremy Stafford-Deitsch's Shark Photos http://www.wattcom.com/sharks/photo/tindex.html =item Marisa Tomei Pictures http://espsun.space.swri.edu/~joey/pics/marisa/tindex.html =back =head1 OPTIONS =over 4 =item B<-b> URL Bullet graphic URL. To appear to the left of image titles. Use -b "none" if you prefer no bullets. =item B<-d> Destructive. Overwrite old indexes. =item B<-f> URL Baseref. URL to prepend all IMG SRC's. =item B<-h> Help! =item B<-l> URL Line graphic. To appear at the at top and bottom of indexes. Use -l "none" if you prefer no line graphics. =item B<-m> dir Directory (relative to current dir) which contains thumbnail images. =item B<-r> number Maximum rows or images in table cell. =item B<-s> Print size of file in index. =item B<-t> "page title" Title of page. Don't forget the quotes! =item B<-v> Verbose. =back =head2 Variables You may modify these variables to your heart's content. =over 4 =item B<$ALINK> = "#ee0033"; Index active link color. =item B<$BGCOLOR> = "#ffffff"; Index background color. =item B<$LINK> = "#6600ff"; Index link color. =item B<$TEXT> = "#000000"; Index normal text color. =item B<$VLINK> = "#ee0000"; Index visited link color. =item B<$BULLET> = "../images/ball.gif"; Default bullet next to index entry. "" if none. =item B<$MAX_ON_PAGE> = "12"; Maximum images on a page. i won't explain this because it is part of the hard coding and may just confuse things. =item B<$MAX_ROWS> = "4"; Maximum number of images down a column. this means you will have $MAX_ON_PAGE / $MAX_ROWS columns (3) =item B<$SITE_NAME> = "Dale's Image Gallery - "; Printed in title. Change this before you run it. =item B<$HOME_URL> = "http://www.bewley.net/perl/"; Home link on indexes. Change this too. =item B<$THUMB_DIR> = "thumbnails"; Directory containing optional thumbnails of images. it is assumed this will be within the current directory and thumbnails will have same names as full sized versions. =item B<$TITLE> = ""; Default title on each index page. =back =head1 TODO =over 4 =item Make more portable. The format of the index is not very flexible right now. I'm sure it will be eventually. I'd like to use the template process I use on http://www.bewley.net/perl/gif2html.html =item Add recursion? Support subdirectories of images. Sometime.. =item use Image::Size Instead of the subs within use this module for getting thubmnail dimensions. =item make CGIable. Shouldn't be much I just don't have time. =item make less ugly!! =back =head1 AUTHOR Dale Bewley, Bewley Internet Solutions Inc, mailto:sales@bewley.net