#!/usr/bin/perl $VERSION = '1.02'; # XPhotoAlbum - XML Photo Album Script # Version 1.02 # # Get docs and newest version from # http://www.neystadt.org/XPhotoAlbum/ # # Copyright (c) 2002-2005, John Neystadt # You may install this script on your site for free # To obtain permision for redistribution or any other usage # contact john@neystadt.org. # # Drop me a line if you deploy this script on your site. =head1 NAME XPhotoAlbum.pl v1.02 - XML Photo Album Script =cut use XML::DOM; use URI::Escape; $UrlBase = '/cgi-bin/XPhotoAlbum.pl'; # Script error handling block binmode STDOUT, ":utf8"; print "Content-Type: text/html\n\n"; BEGIN { sub _perlerror { my $message = $_[0]; print <Sorry, CGI internal perl error -- $message EOR exit (1); } $SIG{'__WARN__'}=\&_perlerror; $SIG{'__DIE__'}=\&_perlerror; } # end of script error handling my $Parm = $ENV {QUERY_STRING}; $Parm =~ s/=\++/=/go; $Parm =~ s/\++/ /go; my %Params = split (/[=&]/, $Parm); if ($Params {'index'}) { $IndexFile = $Params {'index'}; } else { $IndexFile = '/john/album/index.xml'; } my $parser = new XML::DOM::Parser; my $doc = $parser->parsefile ('..' . $IndexFile); my $album = $doc->getChildNodes ()->item (0); my $PicturePath = $album->getAttribute ('PATH'); $PicturePath =~ s|[\\/]$||go; $PicturePath .= '/' if $PicturePath; print ' ', $album->getAttribute ('TITLE'), ' '; if ($Params {'type'} eq 'plain') { PrintPlainAlbum ($album); } elsif ($Params {'type'} eq 'IE') { PrintIEAlbum ($album); } elsif ($Params {'type'} eq 'thumb') { PrintThumbAlbum ($album); } else { PrintPic ($album, $Params {'id'}); } print ""; # ***** sub PrintPic { my ($album, $id) = @_; print ' '; my $folder = $album->getChildNodes ()->item (1); my $children = $folder->getChildNodes (); my $picIndex = 0; my $prevId, $nextId, $lastId, $thePic; for (0..$children->getLength ()-1) { my $pic = $children->item ($_); next if $pic->getNodeName () ne 'PICTURE'; my $picId = $pic->getAttribute ('id'); next if !$picId; if ($thePic && $id == $lastId) { $nextId = $picId; last; } if ($picId == $id) { $prevId = $lastId; $thePic = $pic; } $lastId = $picId; } my $Url = $UrlBase . '?index=' . $IndexFile . '&type='; print "
\n"; print '[ << ]', "\n" if $prevId; print '[ Index ]', "\n"; print '[ >> ]', "\n" if $nextId; print "
\n"; my $text = $thePic->getFirstChild (); if (defined ($text)) { $text = $text->getData (); } else { $text = ''; } print "", $text, "
"; print '', $thePic->getAttribute ('HREF'), '
'; PrintPlainFooter ($album); print "\n"; } # *** sub PrintThumbAlbum { my ($album) = @_; print '

', $album->getAttribute ('TITLE'), '


'; my $Columns = $album->getAttribute ('COLUMNS'); $Columns = 8 if $Columns < 1; my $folder = $album->getChildNodes ()->item (1); my $children = $folder->getChildNodes (); my $picIndex = 0; for (0..$children->getLength ()-1) { my $pic = $children->item ($_); next if $pic->getNodeName () ne 'PICTURE'; if ($picIndex % $Columns == 0) { if ($picIndex != 0) { print "\n"; } print "\n"; } my $Thumb = $PicturePath . 'thumb/' . $pic->getAttribute ('HREF'); $Thumb =~ s/(\....)$/_thumb\1/o; print ' '; $picIndex++; } print "
'; my $text = $pic->getFirstChild (); if (defined ($text)) { $text = $text->getData (); } else { $text = ''; } print '
', $pic->getAttribute ('HREF'), '
', $text, '
' if !$pic->getAttribute ('SKIP'); print '
\n\n"; PrintPlainFooter ($album); print "\n"; } # ***** sub PrintPlainAlbum { my ($album) = @_; print "\n"; PrintPlainFolders ($album, 0); PrintPlainFooter ($album); print "\n"; } sub PrintPlainFolders { my ($folder, $level) = @_; my $title = $folder->getAttribute ('TITLE'); if (!$level) { print '

'; } else { print '
'; } print $title; if (!$level) { print '

'; } else { print '
'; } # Any annotation? my $children = $folder->getChildNodes (); for (0..$children->getLength ()-1) { my $child = $children->item ($_); print "\n", $child->getFirstChild ()->getData (), "\n" if $child->getNodeName eq 'ANNOTATION'; } print "\n" if $TagOpened; # Now the pictures PrintPlainPictures ($folder); # Now the sub folders my $TagOpened = 0; for (0..$children->getLength ()-1) { my $child = $children->item ($_); next if $child->getNodeName ne 'FOLDER'; print "
\n" if !$TagOpened; $TagOpened = 1; PrintPlainFolders ($child, $level+1); } print "
\n" if $TagOpened; print "
" if $level; } sub PrintPlainPictures { my ($folder) = @_; my $children = $folder->getChildNodes (); my $TagOpened = 0; for (0..$children->getLength ()-1) { my $child = $children->item ($_); next if $child->getNodeName () ne 'PICTURE'; print "\n" if $TagOpened; } sub PrintPlainFooter { my ($album) = @_; print "
\n"; if (open (fhFooter, $album->getAttribute ('FOOTER'))) { print ; close fhFooter; } else { print "Can't open footer file (", $album->getAttribute ('FOOTER'), ")!"; } } # ***** sub PrintIEAlbum { my ($album) = @_; print <<"EOF"; This will be set from JavaScript
[ ShowImage (""); return false; <<] [ ShowImage (""); return false; >>]
:


EOF PrintDivFolders ($album); PrintDivPictures ($album); PrintDivImage ($album); PrintDivFooter ($album); print "\n\n"; } # ******* my $FolderNum = 0; sub PrintDivFolders { my ($album) = @_; print '', "\n"; } sub PrintDivPictures { my ($album) = @_; print ''; } sub PrintDivImage { my ($album) = @_; print '', "\n"; } sub PrintDivFooter { my ($album) = @_; print '"; } # ******* sub PrintFolders { my ($folder, $level) = @_; my $title = $folder->getAttribute ('TITLE'); print "\t" x $level, '
', ' ' x (($level-1)*5), '$title
\n" if ++$level; my $children = $folder->getChildNodes (); for (0..$children->getLength ()-1) { my $child = $children->item ($_); PrintFolders ($child, $level) if $child->getNodeName eq 'FOLDER'; } } $Pic = 0; sub PrintPictures { my ($folder) = @_; my $children = $folder->getChildNodes (); # expand sub-folders for (0..$children->getLength ()-1) { my $child = $children->item ($_); PrintPictures ($child) if $child->getNodeName eq 'FOLDER'; } # Now print the pictures print '\n"; } __END__ =head1 DESCRIPTION This simple script can be used for organizing web photo album. The script can be used for online or Off-Line photo album generation. It does not provides web interface for picture uploading, thumbnail generation or web authoring of the album. Those tasks you will have to do using standard image processing tools and ftp. However it generates rather nice browsable photo album. Those are XPhotoAlbum features: =over =item * Support threee different alum viewing modes: =over =item 1 Three pane DHTML (client side) browsing. =item 2 Thumbnail based album. =item 3 Plain text outline for outdated browsers. =back =item * Generate album dynamically from index XML file =item * Support dynamic clients side album =item * For the 1st two modes are supported only with Internet Explorer. =item * Plain text album is supported on all browsers. =item * Support international (Unicode based) text within album. =back =head1 USAGE =over =item 1 Put the script in your cgi-bin directory. =item 2 Edit the script to set script parameters to your configuration =over =item * $UrlBase = '/cgi-bin/XPhotoAlbum.pl'; # path to the album script from web server root. =back =item 3 Refer to the script as: I&type=B> to be translated. =over =item * B - is relative url to the XML file with the album index. =item * B - is one of the three album types: =over =item a. B - Three pane DHTML (client side) browsing (Internet Explorer only). =item b. B - Thumbnail based album (Internet Explorer only). =item c. B - Plain text outline (all browsers). =back =back =back =head1 XML Index File Format Please see the examples below to understand the format of the files. However one nuance must be noticed regarding the thumbnail image files. Thumbnails shiuld be placed in the directory B under image path. Thumbnail image names are derrived from regular images names appending B<_thumb> before file extension. For example for file B<~john/Image.JPG> thumbnils is sought under B<~john/thumb/Image_thumb.JPG>. =head1 CAVEATS Send your feedback... =head1 TIPS AND TRICKS Send your feedback... =head1 EXAMPLES Please see http://www.neystadt.org/ for three instances of the albums using this technology. Particulary examples of the XML index files are located at: http://www.neystadt.org/gal/birth/index.xml http://www.neystadt.org/john/album/index.xml http://www.neystadt.org/leonid/album.xml =head1 PREREQUISITES This script requires the C, C modules available from CPAN (http://www.cpan.org) =pod OSNAMES All UNIXes, Windows NT =pod SCRIPT CATEGORIES Web =pod README This simple script can be used for organizing web photo album. The script can be used for online or Off-Line photo album generation. It does not provides web interface for picture uploading, thumbnail generation or web authoring of the album. Those tasks you will have to do using standard image processing tools and ftp. However it generates rather nice browsable photo album. =cut