Please visit the Support Forums for online support, installation instructions, file formats, tips and more.


NAME

album.pl - A dynamically generated web based photo album.


SYNOPSIS

There are many ways to invoke album.pl:

Normal: http://dev.bobbitt.ca/cgi-bin/album.pl

Go to a specific album: http://dev.bobbitt.ca/cgi-bin/album.pl?album=albumname

Go to a specific photo: http://dev.bobbitt.ca/cgi-bin/album.pl?photo=photoname

Go to the Configuration Management screen: http://dev.bobbitt.ca/cgi-bin/album.pl?function=config

Update titles and descriptions: http://dev.bobbitt.ca/cgi-bin/album.pl?function=enter_desc

Upload photos or movies: http://dev.bobbitt.ca/cgi-bin/album.pl?function=upload

Show the Administration Menu: http://dev.bobbitt.ca/cgi-bin/album.pl?function=admin

View photos as part of a slideshow (5 second delay): http://dev.bobbitt.ca/cgi-bin/album.pl?slideshow=5

View photos as a full screen slideshow: http://dev.bobbitt.ca/cgi-bin/album.pl?slideshow=5;fullscreen=1

Turn on debugging (highest level): http://dev.bobbitt.ca/cgi-bin/album.pl?debug=4

Generate static HTML files for each album and photo: http://dev.bobbitt.ca/cgi-bin/album.pl?static=1

View recent uploads: http://dev.bobbitt.ca/cgi-bin/album.pl?album=:recent

View 15 most recent uploads: http://dev.bobbitt.ca/cgi-bin/album.pl?album=:recent;showall=15

View the 10 most recent uploads, formatted for inclusion in other pages: http://dev.bobbitt.ca/cgi-bin/album.pl?album=:recent;ssi=10

View a randomly selected photo from the album: http://dev.bobbitt.ca/cgi-bin/album.pl?random=1

View a randomly selected photo, formatted for inclusion in other pages: http://dev.bobbitt.ca/cgi-bin/album.pl?random=1;ssi=2

View the thumbnail of a randomly selected photo, formatted for inclusion in other pages: http://dev.bobbitt.ca/cgi-bin/album.pl?random=1;ssi=1

View randomly selected photos in a slideshow (5 second delay), formatted for inclusion in other pages: http://dev.bobbitt.ca/cgi-bin/album.pl?random=1;ssi=2;slideshow=5

View the thumbnails of randomly selected photos in a slideshow (5 second delay), formatted for inclusion in other pages: http://dev.bobbitt.ca/cgi-bin/album.pl?random=1;ssi=1;slideshow=5

View a specific photo, formatted for inclusion in other pages: http://dev.bobbitt.ca/cgi-bin/album.pl?photo=photoname;ssi=1

View photos in a slideshow (5 second delay), formatted for inclusion in other pages: http://dev.bobbitt.ca/cgi-bin/album.pl?photo=photoname;slideshow=5;ssi=1

View randomly selected photo directly (no HTML, just the image itself): http://dev.bobbitt.ca/cgi-bin/album.pl?image=random

View randomly selected thumbnail directly (no HTML, just the thumbnail itself): http://dev.bobbitt.ca/cgi-bin/album.pl?image=randthumb

View most popular photos: http://dev.bobbitt.ca/cgi-bin/album.pl?popular=1

View most popular albums: http://dev.bobbitt.ca/cgi-bin/album.pl?popular=2

View thumbnails of 10 most popular photos, formatted for inclusion in other pages: http://dev.bobbitt.ca/cgi-bin/album.pl?popular=1;ssi=10

View thumbnails of 10 most popular albums, formatted for inclusion in other pages: http://dev.bobbitt.ca/cgi-bin/album.pl?popular=2;ssi=10

Use an alternate configuration file: http://dev.bobbitt.ca/cgi-bin/album.pl?configfile=/home/user/www/album.cfg

Give them a try, some are undocumented features! :)


DESCRIPTION

album.pl is a simple web based program that allows you to simply drop new photo files into a directory, and they will automatically be accessible via the web. It does this by building the photo album on the fly. album.pl uses a simple administration menu to allow you to move or delete photos and albums, as well as adding titles and long descriptions.

Users may upload photos directly into your album, if you permit it.

It can also be used to create static HTML files for certain situations. (This mode is not updated automatically, but is useful for creating a photo CD or viewing pictures without a web server.

To get a feel for all the features and functions, you should see CHANGES.txt.


INFORMATION

Author: Mike Bobbitt (Mike@Bobbitt.ca), Cipher Logic Canada Inc.

For updates, instructions and examples see http://dev.bobbitt.ca/forums on the web.


SUPPORT

There is a support forum set up for discussion of album.pl matters. I would recommend that anyone with a support question try searching the forums first. Your question may have already been answered! Otherwise, try posting your question to the forums, where you have the best chance of having it answered. That way, if I am unable to respond right away, it's entirely likely that a peer user will be able to help out. The forums are located at:

http://dev.bobbitt.ca/forums

Once registered with the forums, user are also invited to use the test album, located at http://dev.bobbitt.ca/cgi-bin/album.pl to ``test drive'' the software. Support questions sent to me by e-mail tend to get a slower response.

Please also note that this is a personal project. I work on it in my spare time, on weekends and evenings, so I'm not always able to respond questions or comments in a timely manner. Expect delays, try to be patient, and remember it's free. ;)


FAQ

For an up to date list of Frequently Asked Questions and common problems, please see the FAQ section of the support forums:

http://dev.bobbitt.ca/forums/index.php?board=3.0


TO DO

There are still bugs in this code, so please bear with me, and report any that you find. The complete list of all the things I still want to do with album.pl is located here:

http://dev.bobbitt.ca/forums/index.php?topic=352.0

Any place in the code that I've started (but not finished) a feature, I tried to mark it with a ***.


LICENSE

This program is © 1999-2004 Cipher Logic Canada Inc. All Rights Reserved.

As long as you leave this POD section and my contact info above in tact, feel free to use this as you see fit. You can pretty much do anything with this script except resell it. :)

If you come up with any good modifications to it, please let me know. I'd love to fold your mod into the public version (with credit, of course).

Good luck!


APOLOGIES

Here goes:


SUBROUTINES

photoAlbum()

 photoAlbum($manual_override);
 $manual_override - Start in this album or with this photo (optional)

Does the majority of the processing for the photo album

error()

 error($line,$error,$extra_info,$module);
 $line - Line number, where error occurred.
 $error - Pre-defined error code that prints a canned message.
 $extra_info - Additional information that can be passed in
 $module - Module that threw the error

Displayes the error message associated with $error along with the $extra_info. Then halts execution.

debug()

 debug($debug_message,$debug_level,$line);
 $debug_message - String to print if debugging is on
 $debug_level - Only pring string if current debug level is $debug_level or higher (current debug level is set by $debug)
 $line - The line number of the debug statement.
 $module - Module name (optional).

Prints a message, if $::debug has a value.

setDate()

 $datestr=setDate($convtime,$return_seconds);
 $datestr        - date and time
 $convtime       - unixtime value which is used to set $datestr (optional)
 $return_seconds - 1=YYYY/MM/DD HH:MM:SS, 0=YYYY/MM/DD HH:MM

Converts $convtime into a human readable format and returns it as $datestring. If $convtime is not provided, the current time is returned. If $return_seconds has a value, then the time includes seconds.

sanityTest()

 sanityTest();

Runs some basic tests to make sure the environment is clean and secure before the script starts.

readDirectory()

 @myfile_list=readDirectory($scan_directory);
 @myfile_list - Returned list of files in this directory
 $scan_directory - Directory to read all values from

Reads all entries in specified directory, returns as list

recursiveScan()

 recursiveScan($scan_directory,$already_scanned);
 $scan_directory - Directory to search recursively
 $already_scanned - Path of directories above this one (optional)

Walks the directory tree recursively

isAPhoto()

 isAPhoto($photo_name);
 $photo_name - name of picture file

Returns 1 if the filename passed in is that of a valid ``photo'', 2 if it is a link to a photo, or 0 otherwise.

isAThumb()

 isAThumb($photo_name);
 $photo_name - name of picture file

Returns 1 if the filename passed in is a thumbnail, or 0 otherwise.

isAMovie()

 isAMovie($movie_name);
 $movie_name - name of movie file

Returns 1 if the filename passed in is that of a valid ``movie'', 0 otherwise.

getLinkURL()

 $linkurl=getLinkURL($linkfile);
 $linkurl - Returns the actual location of the photo (relative to $::album_dir) given it's link file location.
 $linkfile - Location of the link file, either absolite file path or relative to $::album_dir.

Opens the specified link file and extracts the actual location of the image, which is returned.

Authenticate()

 $authenticated=Authenticate($mode);
 $authenticated - Returns 1 if the user was successfully authenticated, otherwise zero.
 $mode - Alternate authentication mode. For UBB, this means Junior Members are not permitted, and will always return zero. (Used to prohibit junior members from uploading).

Authenticates the global variables $::username and $::password, using the specified method. Returns 1 for a successful authentication, otherwise 0. Populates $::mem_level, the membership level assigned when authentication type is 5

checkPassword()

 $goodpass=checkPassword($mypassword,$storedpass);
 $goodpass - The password that matched, if found. (Otherwise, the stored password ($storedpass) is returned).
 $mypassword - The password that the user has entered.
 $storedpass - The password on file for that user.

Checks $mypassword against $storedpass using all known encryption methods, and returns a copy of the ``good'' (clear) password, if found

loginStatus()

 $login_html=loginStatus();
 $login_html = The user's login status, as HTML.

Returns the user's login status as either a URL to the login page (if the user is not logged in) or as as ``Welcome [username]'' message (if the user is logged in).

cookieLogin()

 $status=cookieLogin();
 $status - 1 if login info was found, otherwise 0

Retrieves login information from the cookie (if found) and passes it back as $::username, $::password, $::usernumber (UBB) and $::displayname.

openDescfile()

 openDescfile($descfilename);
 $descfilename - The full, filesystem path to the album you want to read descriptions from.

Opens up $descfilename so that photo/album titles/descriptions can be loaded.

getDescription()

 getDescription($desctoget,$mode);
 $desctoget - Photo or album to get description of
 $mode - 0 = Normal; 1 = Searching

Retrieves the title, description and owner of the provided object. Puts the title in $::shortdesc, the description in $::longdesc (if present) and the owner in $::owner (if present) and the view permission level in $::this_level (if present).

buildDescFooter()

 $add_desc_footer=buildDescFooter($status);
 $add_desc_footer - The HTML code for adding a description, which is returned.
 $status - 0 if building the whole form, 1 if building it as part of another form (like the create album form, for example).

Creates $directory in $basedir, and updates the description with $::shortdesc and $::longdesc.

getPhotoDimensions()

 ($height,$width)=getPhotoDimensions($filepath);
 $height - Height of photo.
 $width - Width of photo.
 $filepath - Full filesystem path to the photo to check.

Uses Imagemagick to determine the size of a photo.

showFooter()

 $footer=showFooter($show);
 $footer - HTML footer, if returned.
 $show - If set to 0, the footer simply returned, if set to 1, it is displayed and returned.

Rerturns or displays the HTML footer for all pages.

buildTemplate()

 $template=buildTemplate();
 $template = variable to pass the template back into

Builds the object template, and returns it.

buildNavFooter()

 $nav_footer=buildNavFooter($mode);
 $mode - 0 = Build entire Nav footer; 1 = Build "Previous" section only; 2 = Build "Up" section only; 3 = Build "Next" section only; 4 = Jump station only

Builds the navigaction footer, and returns it. (The navigation footer is the buttons/links that allow you to visit the next/previous photo or album.)

passVars()

 $vars=passVars($format);
 $vars = variable to pass the formed variables back into
 $format = 0: pass in web URL format (&debug=1&configfile=file, etc); 1: pass in button format (<input type="hidden"...); 2: same as zero, but no function code

Sees which variables must be passed (configfile, debug, static, etc), builds the string containing the data, and passes the value back.

printHeader()

 $header=printHeader($mode);
 $header - The formed header, with style sheet or body colour tags, is returned.
 $mode - 0 = Return all header HTML; 1 = Return just style sheet tag

Prints out either the style sheet or a generic body tag.

trackView()

 $current_views=trackView($currentphoto,$mode;$newcount);
 $current_views - Returns a string containing the number of views and the last viewed date.
 $currentphoto - Photo to update views for.
 $mode - 0 = Update views; 1 = Don't update views; 2 = Reset count to zero; 3 = set count to passed number
 $newcount - Set counter to this number if passed and mode 3.

Updates the number of views and the last viewed date for the current photo in $::viewfile.

findTemplate()

 $template_path=findTemplate($template_name);
 $template_path - The full path to the appropriate template (local or global).
 $template_path - The filename of the template.

Replaces all the tags in the data passed in, and returns the updated string.

substituteData()

 $output_data=substituteData($input_data);
 $input_data - Data that is passed in. Each of the "####TAGS####" tags are replaced with actual data. See the file format section of this document for details on the tags.
 $output_data - After substitutions, the data that is returned.

Replaces all the tags in the data passed in, and returns the updated string.

buildObject()

 $output_data=buildObject();
 $output_data - The HTML for displaying the object is build and returned.

Builds the ``object'' to be displayed. For a photo, it builds the HTML to display the photo, and for an album, it builts the list of objects in that album (photos and sub-albums).

sortObjects()

 @sorted=sortObjects($mode);
 @sorted - The @::file_list, sorted according to the configuration
 $mode - 0 = Sorting for album view; 1 = Sorting for navigation bar (cuts off photo filename)

Sorts @::file_list, according to configuration settings, and returns the sorted array.

buildAlbum()

 $return_html=buildAlbum($mode);
 $return_html - The built HTML for the current object
 $mode - 1 = Display this group on every page (albums); 0 = Display as per usual (photos and movies)

Builds the HTML for a photo, album or movie, as it appears in it's album (called when building an album page, for each ``thimbnail'' object on that page).

parseLinks()

 $template=parseLinks($template);
 $template - Data is passed in, made web safe, and passed out.

Checks the data passed and converts special characters within any links into web safe characters.

showThumb()

 $thumbnail_html=showThumb($myobject,$mode);
 $myobject - Path/filename to object to search for thumbnail of, relative to album_dir.
 $thumbnail_html - HTML for the thumbnail.
 $mode - 1 = return just the URL to the thumb, not the HTML for the thumb

Returns the proper HTML for the thumbnail of the passed object, honouring all configfile settings. If configured to do so, will also call genThumb for photos that do not already have a thumbnail.

readConfig()

 readConfig($confile,$mode);
 $confile - path and filename of the config file
 $mode - 0 = Reading primary config; 1 = Reading local config (per album config)

Reads configuration information from the specified config file.

getRatings()

 $ratings=getRatings($mode,$rating_file_loc);
 $ratings - The string of rating information to insert into the template.
 $mode - 0 = Add a link to submit a rating to the returned data; 1 = Do not return the link to add a rating; 2 = Perform search; 3 = Show rating only, not comments; 4 = It's a popularity contest! Populate @poplist with info on photo ratings.
 $rating_file_loc - Location of ratings file (optional, only used if mode=1).

Returns the ratings information for the current photo/movie.

webifyLinks()

 $output=webifyLinks($input);
 $input - The string to webify (make web safe).
 $output - Web safe version returned.

Returns the ``websafe'' version of the passed filename/path.

isAdmin()

 $status=isAdmin();
 $status - 0 = Not an admin; 1 = Yep, they're an admin!; 2 = They're a user, but they own this album.

Checks to see if the current user is an authenticated admin.

isGuest()

 $status=isGuest();
 $status - 0 = Not a guest, 1 = Yep, they're a guest!

Checks to see if the current user is an authenticated guest.

getCookie()

 getCookie();

Gets cookie from browser, and puts it into %cookie hash.

splitCookie()

 splitCookie($param);
 $param = parameter to split

Splits a multi-valued chip into a list of parameters.

showCookie()

 showCookie();

Displays the contents of a cookie in debug level 2.

genThumb()

 $status=genThumb($myobject,$image_thumb,$mode);
 $status - 0 = Success, 1 = Failure
 $myobject - The full file system path to the object to generate a thumbnail for
 $image_thumb - The full file system path to the thumbnail to create for this image
 $mode - 0 = Generate thumbnails for pictures; 1 = Resize pictures on upload; 2 = Resize pictures on upload by file size (not dimensions)

Generates a thumbnail for $object, according to the current rules for thumbnails. This subroutine requires ImageMagick to be installed in order to work.

showBreadCrumbs()

 $breadcrumbs=showBreadCrumbs();
 $breadcrumbs - The HTML for the breadcrumb trail.

Builds an HTML ``breadcrumb'' trail so the user can navigate upwards in their album. $::bread_style defines the format to be used:

 0 = Use folder heirarchy
 1 = use » single » line » breadcrumbs

shroudPic()

 $imgcode=shroudPic($image);
 $imgcode - The actual content of the image, to display
 $image - The full file path to the image to display back

Displays the image pointed to by $image, even if it is not under the web root.

showObject()

 $html=showObject($myobject,$mode,$uploaduser,$uploadtime);
 $html - The object, as seen in "album view," including thumbnail, ratings, etc. Formatted in HTML.
 $myobject - The path to the object (relative to $::album_dir) to display.
 $mode - 0 = Display object normally; 1 = Display object for Recent Uploads; 2 = Display for Popular List
 $uploaduser - Username that uploaded this file (recent uploads only)
 $uploadtime - Time/date that the file was uploaded (recent uploads only)

Displays $object using the current settings of the album.

updateComment()

 $retcode=updateComment($myobject,$comment);
 $retcode - Return value: 0 = Success; 1 = Failure.
 $myobject - The path to the photo, relative to album_dir.
 $comment - The comment to add to the photo.

Adds/Updates the comment in $myobject to be $comment. Uses jhead to actually insert the comments into the photo.

detectBrowser()

 $type=detectBrowser();
 $type - The browser type: 0 = IE variant; 1 = Mozilla (Opera, Netscape, Phoenix, etc) variant

Detects the browser type, and returns the appropriate value

printHTMLHeader()

 printHTMLHeader();

Prints the HTML header if it hasn't already been printed.

DBICheck()

 $dbi_fail=DBICheck();
 $dbi_fail - 0 = DBI package was found, 1 = DBI package not found

Checks to see if the DBI Perl package was installed and returns a status accordingly.

upgradeCfg()

 upgradeCfg();

Upgrade the album.pl configuration, if possible.

checkFile()

 checkFile($filename);
 $filename - File name to check.

Confirms that the file name does not contain spaces or slashes. Used to keep upgradeCfg filenames clean.

isViewable() isViewable($viewdir,$viewfile,$mode);

  $viewdir - directory where we are checking permissions
  $viewfile - file on which to ckeck permissions

Checks the user level needed to view this an album/photo/movie against permissions of user who is logged in. If building static pages, all objects are viewable. =cut

sub isViewable { my $flag=0; my $viewdir=shift; my $viewfile=shift; my $mode=shift; my $pic_lev; my $user_lev;

        debug("Entering subroutine isViewable for $viewdir/$viewfile...\$mode=$mode",4,__LINE__);
        if ($create_html_flag ge 1 || $authentication_type lt 1 || isAdmin() eq 1)
        {
                $flag=1;
                return $flag;
        }
        else
        {
                close(INFO);
                if($mode eq "1")
                {
                        $infofilename=$viewdir."/".$::descname;
                }
                elsif ($mode eq "2")
                {
                        $infofilename=$::album_dir."/".$viewdir.$::descname;
                }
                else
                {
                        $infofilename=$::album_dir."/".$viewdir."/".$::descname;
                }
                debug("Looking for InfoFile: [$infofilename]<p>",3,__LINE__);
                if (-r $infofilename)
                {
                        $::useinfo=1;
                        open(INFO,"$infofilename");
                        debug("Using InfoFile: [$infofilename]<p>",3,__LINE__);
                }
                # Get Viewlevel
                getViewlevel($viewfile);
                close(INFO);
                if (!$::info_level || $::info_level eq "anyone" || $::info_level eq 0)
                {
                        $flag=1;
                        debug("Anyone has permission $flag.",4,__LINE__);
                }
                else
                {
                        if (!$::authenticated)
                        {
                                $flag="";
                                debug("No one has permission, not logged in. flag is \"$flag\" ",4,__LINE__);
                        }
                        else
                        {
                                if ($::mem_level eq 0 || $::mem_level eq 1)
                                {
                                        $user_lev=1;
                                }
                                else
                                {
                                        $user_lev=2;
                                }
                                if ($::info_level eq "Family" || $::info_level eq 1)
                                {
                                        $pic_lev=1;
                                }
                                elsif ($::info_level eq "Friend" || $::info_level eq 2)
                                {
                                        $pic_lev=2;
                                }
                                elsif ($::info_level eq "owner" || $::info_level eq 3)
                                {
                                        $pic_lev=3;
                                }
                                if (($user_lev ge $pic_lev) || ($pic_lev eq 3 && $::owner eq $::loggedin))
                                {
                                        $flag=1;
                                        debug("Permission granted on pic_lev $pic_lev with user_lev $user_lev flag $flag.",4,__LINE__);
                                }
                        }
                }
                return($flag);
        }
        debug("Leaving subroutine isViewable for $viewdir/$viewfile...\$mode=$mode...\$flag=$flag",4,__LINE__);
 }

##########################################################################

getViewlevel()

 getViewlevel($leveltoget);
 $leveltoget - Photo or album to get view level for

Retrieves the view permission level in $::info_level (if present).