#!/usr/pkg/bin/perl # Simple Photo Gallery 1.5 # # Authors: # Dan Fraser (primary) # Andrew Kilpatrick # # This software is Public Domain. # Use it however you wish. # required modules/pragma use CGI; use CGI::Carp qw( fatalsToBrowser); use URI::Escape; use Image::Info qw( image_info ); use strict; # configuration variables ######################### my $page_header = ".header.html"; # page header html my $page_footer = ".footer.html"; # page footer html my $thumbs = ".thumbs"; # thumbnail directory name my $lowres = ".lowres"; # low res directory name my $descriptions = ".descriptions"; # descriptions file my $startatlast = ".startatlast"; # begin thumbs with the last page my $display_filename = 1; # display filename if no description? my $page_size = 20; # number of thumbnails per page my $number_columns = 5; # how many columns of thumbnails my $custom_sort_enable = "YES"; # uses a custom sort algorithm $ENV{PATH} .= ':/usr/pkg/bin'; ############################ # end configuration section my $version = "1.5"; # we set a cookie for each gallery to hold the last visited date # and the last page # .startatlast overrides the last page cookie behaviour my $query; $query = new CGI; # if d is empty, we're showing the gallery index # otherwise, if id is empty, we're viewing thumbnails # otherwise, we're viewing a single picture if (!defined $query->param('d')) { show_gallery_index(); } elsif ($query->param('id')) { display_single_image($query); } else { # viewing a page of thumbnails display_thumbnail_page($query); } exit(0); sub display_thumbnail_page() { my $dir = $query->param('d'); my $safe_dir = uri_escape($dir); cleanDir($dir); my @images = get_images(); my $query = shift; my $number_of_pages = int(@images / $page_size)+1; if (@images % $page_size == 0) { $number_of_pages--; } my $current_page_number = $query->param('pg'); if(!defined($current_page_number)) { $current_page_number = 0; } print $query->header(); display_header(); # allow entry to the last page if($current_page_number eq "last") { $current_page_number = $number_of_pages; } # disallow silly values if ($current_page_number > $number_of_pages-1) { $current_page_number = $number_of_pages - 1; } if ($current_page_number < 0) { $current_page_number = 0; } my $next_page; my $previous_page; my $image_offset = $current_page_number * $page_size; # figure out the next and previous page numbers $next_page = ($current_page_number+1) % $number_of_pages; $previous_page = abs(($current_page_number-1) % $number_of_pages); # check if images need to be created # makeThumbnails($safe_dir); # print the image tags and links my $current_image = $image_offset; print "
"; print "\n"; while ($current_image < $image_offset+$page_size and $current_image < @images) { makeThumbnail($dir, $images[$current_image]); print "\n"; print "\n" if ((($current_image-$image_offset+1) % $number_columns) == 0 and $current_image+1 < $image_offset+$page_size); $current_image++; } print "
"; # print the page navigator print "
"; print "
"; if ($current_page_number == 0) { print "Previous "; } else { print "Previous "; } print ""; for (my $i = 0; $i < $number_of_pages; $i++) { if ($current_page_number == $i) { print "$i "; } else { print "$i "; } } print ""; if ($current_page_number == $number_of_pages-1) { print "Next"; } else { print "Next"; } print "
"; print "
"; print "

Back to Gallery Index

"; display_footer(); } sub display_single_image() { # get the current directory my $dir = $query->param('d'); my $safe_dir = uri_escape($dir); cleanDir($dir); my @images = get_images(); # load the description database my %desc; if ( -r "$dir/$descriptions" ) { open DESC, "$dir/$descriptions"; my $line; while (defined ($line = )) { chomp($line); my ($filename, $description); ($filename, $description) = split(/ /,$line,2); $desc{$filename} = $description; } } my $image = $query->param('id'); my $thumbs_page = $query->param('pg'); my $imgnum; for (my $i = 0; $i < @images; $i++) { if ($image eq $images[$i]) { $imgnum = $i; last; } } my $res = $query->param('res'); my $delay; if ($delay = $query->param('delay')) { print $query->header(-refresh=>"$delay; URL=index.cgi?d=$safe_dir&id=$images[$imgnum+1]&print=1&res=$res&delay=$delay"); } else { print $query->header; } display_header(); if (!defined($imgnum)) { print "

Image not found! Id is probably invalid.

"; print "Back to thumbnails"; return; } $thumbs_page = int($imgnum / $page_size); makeLowres($dir,$image); print "
"; if ($res eq 'high') { print "
"; } else { if ($imgnum+1 < @images) { print ""; } print "
"; if ($imgnum+1 < @images) { print "
"; } } # display the image controls ############################ if (!$query->param('print')) { if ($res eq 'high') { print "Preview Size"; } else { print "Full Size"; } print " * Printable"; print " * Start Slideshow"; if ($desc{$images[$imgnum]}) { print "

".$desc{$images[$imgnum]}."

"; } # display the navigation ########################## print '

'; print ""; print ""; print ""; print "
"; if ($imgnum-1 >= 0) { makeThumbnail($dir,$images[$imgnum-1]); print "
Previous"; } print "
 Image #$imgnum of ". ( @images-1) ." 
"; } my $info = image_info("$dir/$images[$imgnum]"); if (!defined $info->{error}) { print ""; print "Taken ".$info->{DateTime}."
"; print "Exposure: ".$info->{ExposureTime}; print " F".eval($info->{FNumber})."
"; print " Flash: ".$info->{Flash}."
"; print " Focal Length: ".eval($info->{FocalLength})."mm
"; print " ".$info->{Model}; print "
"; } if (!$query->param('print')) { print "
"; if ($imgnum+1 < @images) { makeThumbnail($dir,$images[$imgnum+1]); print "
Next" } print "
"; print "Back to thumbnails"; } print "
"; display_footer(); } sub display_header() { open HEADER, "$page_header" or die "couldn't open header html file: $!\n"; my $line; while (defined ($line =
)) { print $line; } close HEADER; } sub show_gallery_index() { my $oldCookie = $query->cookie("simple_photo_gallery"); my ($lastvisit, $oldafter) = split(/ /,$oldCookie); if ($oldafter <= time) { my $newfor = 60*60*2; # 2 hours $lastvisit = $oldafter-$newfor; $oldafter = time + $newfor; } my $newCookie = $query->cookie(-name=>'simple_photo_gallery', -value=>int($lastvisit)." ".int($oldafter)); print $query->header(-cookie=>$newCookie); display_header(); print CGI::h1("Available Galleries"); my $dirs = find_dirs(); print ""; my $dir; my @sortedDirs = sort {uc($a) cmp uc($b)} @$dirs; foreach $dir ( @sortedDirs ) { my $safe_dir = uri_escape($dir); opendir GALLERY, $dir; my @images = grep { /\.[jJ][pP][eE]?[gG]$/ } readdir(GALLERY); close GALLERY; my ($last_modified_time, $total_dir_size); my $image; my $new = 0; foreach $image (@images) { if ( -r "$dir/$image" ) { my ($size, $mtime); ($size, $mtime) = (stat("$dir/$image"))[7,9]; if ($mtime > $last_modified_time) { $last_modified_time = $mtime; } if ($last_modified_time > $lastvisit) { $new++; } $total_dir_size += $size; } } if (@images > 0) { if(-f "$safe_dir/$startatlast") { print ""; } else { print ""; } print ""; my $total_megs = sprintf("%2.1f",($total_dir_size / 1048576)); print ""; } } print "
$dir
$dir".localtime($last_modified_time)."".@images." photos, ${total_megs}MB"; print " ($new new)" if ($new); print "
"; print "
Simple Photo Gallery $version"; } sub find_dirs() { opendir DIR, "."; my @files = readdir DIR; close DIR; my @dirs = grep { $_ ne '.' and $_ ne '..' and -d $_ } @files; return \@dirs; } sub display_footer() { open FOOTER, "$page_footer" or die "couldn't open footer html file: $!\n"; my $line; while (defined ($line =