#!/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 "&nbsp;&nbsp;&nbsp;&nbsp;";
    $prev = $current - 1;
    $next = $current + 1;

    if($prev > 0){
	print qq(<a href="?view=$prev">&lt;&lt;PREV</a>);
    }
	print qq(&nbsp;&nbsp;&nbsp;&nbsp;<a href="?view=all">ALL</a>&nbsp;&nbsp;&nbsp;&nbsp;);

    if($next <= $lastpix){
	print qq(<a href="?view=$next">NEXT&gt;&gt;</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);}