#!/usr/local/bin/perl # kphoto.cgi - build virtual photoalbums from directories of images # # by Kirk Israel # This script is offered as e-mail-me-ware: if you use it, send # e-mail to kisrael@alienbill.com . Enhancements/Suggestions welcome. # # # When placed in a directory (either literally or as a symbolic link) # makes a clickthrough slideshow for all the # *gif, *jpg, *jpeg (case insensitive), with the options of viewing # all images on a page. # # HINT: CALL THIS SYMLINK "index.cgi" AND ON MANY SERVERS IT WILL ACT # AS THE DEFAULT "index.html" FOR THE DIRECTORY # # There is a related editkphoto.cgi script that allows you to # edit captions for each images, as well as a title for the photoalbum # and text for the album's "splash page". Simply (temporarily?) put # that script (or symlink it) in the same directory as the photos # and this script and make sure it the script has permission to write # to a file "kphoto.info" in the directory # # Also, if you have a directory "full/" in that directory, and it has # files to larger versions of the image files with the same name, # it will make links to the big versoin print "Content-type: text/html\n\n"; chugCGI(*input); #read in all the image files, sort opendir(READ,"."); while($nextfile=readdir(READ)){ if($nextfile =~ /\.(jpg|jpeg|gif)$/i) { push @pixname, $nextfile; } } closedir READ; @sortpix = sort @pixname; #load captions, title, etc readInfo(); $view = $input{"view"}; $title = $info{"title"}; $splashpage = $info{"splashpage"}; if($title eq ""){ $title = "k/photo"; } print<<__EOQ__; <head><title>$title</title></head> __EOQ__ #if we don't know wich pic to view, show splashpage if($view eq ""){ if($splashpage eq ""){ $splashpage = qq(<div align="center"><font size=5><b>$title</b></font><br></div>); } print qq(<div align="center">$splashpage</div>); print qq(<div align="center"><br>); printPrevNext(); print qq(</div>); #start with the first pic if we have absolutely no info to make a title page if($splashpage eq "" && $title eq ""){ $view = "1"; } else { print<<__EOQ__; <div align="center"><B> <I> Click ALL to see all the photos on one page<BR> Click NEXT to start with the first image (recommended for slower connections)<br> Click on an Image or NEXT to advance through the images</I> __EOQ__ print qq(<div align="center">); printJumper(); print qq(</div>); } } #see if we print all the images if($view eq "all"){ print qq(<div align="center">\n); $i = 1; foreach $thispix (@sortpix) { showPix($thispix, $i); print "<br>"; $i++; } } #if we have a number, show just that image if($view =~ /\d/){ print qq(<div align="center">); #print links to prev/all/next printPrevNext($view); print "<br>"; $offset = $view - 1; $thispix = $sortpix[$offset]; $nextnum = $view + 1; #we;re going to make the image a link to the next one so it's easier to click if($nextnum > $#sortpix + 1){ $nextnum = 1; } showPix($thispix, $nextnum); printJumper(); print qq(</div>); } sub printPrevNext { my($current)=@_; print "<b>"; $lastpix = $#sortpix+1; if($current ne ""){ print "Viewing $view of $lastpix "; } else { print "$lastpix Images "; } print " "; $prev = $current - 1; $next = $current + 1; if($prev > 0){ print qq(<a href="?view=$prev"><<PREV</a>); } print qq( <a href="?view=all">ALL</a> ); if($next <= $lastpix){ print qq(<a href="?view=$next">NEXT>></a>); } print "</b>"; } sub showPix { my($thispix,$linkto) = @_; $safepix = $thispix ; $safepix =~ s/ /%20/g; print qq(<a href="?view=$linkto"><img src="$safepix" border=0></a><br>\n); $caption = $info{"caption:".$thispix}; if($caption eq ""){ $caption = $thispix; } print "<b>$caption</b>"; #print zoom version link if available if(-e "full/$thispix"){ print <<__EOQ__; <font size=-1><a href="full/$safepix" TARGET="fullsize_$safepix">[fullsize]</a></font> __EOQ__ } print "<br>\n"; } #print select box with links to all the images sub printJumper { $i = 1; print qq(<form><select name="view">\n<option>Jump To Image...\n); foreach $pix(@sortpix){ $thiscaption = $info{"caption:".$pix}; if($thiscaption eq "") { $thiscaption = $pix; } if($current == $i) { $selected = "SELECTED";} else { $selected="";} #only show first 40 characters $thiscaption = substr($thiscaption,0,40); print qq(<option value="$i" $selected>$thiscaption\n); $i++; } print qq(</select><input type="submit" value="GO"></form>\n); } #replace values of info for this key based on input sub updateInfo { my($key) = @_; if($input{$key} ne ""){ $info{$key} = $input{$key}; } else { delete($info{$key}); } } #read .info file, put key=value pairs into hash sub readInfo { %info = (); open(READ,"< kphoto.info"); flock(READ,1); #lock for reading while(defined($nextline=<READ>)){ chomp $nextline; ($key,@rest)=split(/=/,$nextline); #break on first = $val=join("=",@rest); #glue the value together in case it also had =s $val =~ s/\\n/\n/g; $info{$key} = $val; } close READ; } sub chugCGI { local (*in) = @_ if @_; local ($i, $key, $val); if($ENV{'REQUEST_METHOD'}eq"POST") { read(STDIN,$in,$ENV{'CONTENT_LENGTH'}); }else {$in = $ENV{'QUERY_STRING'};} @in = split(/&/,$in); foreach $i (0 .. $#in) { $in[$i] =~ s/\+/ /g; ($key, $val) = split(/=/,$in[$i],2);$key =~ s/%(..)/pack("c",hex($1))/ge; $val =~ s/%(..)/pack("c",hex($1))/ge; $in{$key}.= $val;}return length($in);}