From scottbertin@y... Mon Apr 10 20:00:46 2006 From: scottbertin@y... (Scott J. Bertin) Date: Thu Dec 21 19:59:34 2006 Subject: [Album] [PATCH] Use the full path to find files instead of assuming where they are v2 Message-ID: <443B1BDE.70102@yahoo.com> The following patch to album 3.11 uses the full path to find files in case a plugin puts them in an unexpected place. I posted a similar patch to 3.10 in November. This patch is required for full functionality of the reorganizer plugin I am also sending today. Scott J. Bertin scottbertin@yahoo.com -------------- next part -------------- Index: album =================================================================== RCS file: /Users/scottbertin/.cvsroot/album/album,v retrieving revision 1.1.1.2 retrieving revision 1.8 diff -u -r1.1.1.2 -r1.8 --- album 10 Apr 2006 12:51:00 -0000 1.1.1.2 +++ album 10 Apr 2006 13:18:00 -0000 1.8 @@ -2771,7 +2772,9 @@ return if !$opt->{jhead}; # Saw a jhead error.. return unless $pic =~ /\.jpe?g$/i; - my $exif = get_exif_info($opt,$data,"$dir/$pic"); + my $pic_file = $data->{obj}{$pic}{full}{path} || "$data->{paths}{dir}/$pic"; + + my $exif = get_exif_info($opt,$data,$pic_file); return unless $exif; $data->{obj}{$pic}{exif} .= exif_replace($exif, @{$opt->{exif}}) @@ -2990,8 +3001,8 @@ # Final obj is a hash of hashes: full, medium, thumb # Each hash contains: file, x, y and possibly filesize and path foreach my $pic ( @{$data->{pics}} ) { - $data->{obj}{$pic}{full}{file} = $pic; - $data->{obj}{$pic}{full}{path} = "$dir/$pic"; + $data->{obj}{$pic}{full}{file} = $pic unless $data->{obj}{$pic}{full}{file}; + $data->{obj}{$pic}{full}{path} = "$dir/$pic" unless $data->{obj}{$pic}{full}{path}; } # Links to sub-albums @@ -4642,11 +4653,11 @@ # Paths my $dir = $data->{paths}{dir}; - my $path = "$dir/$pic"; my $obj = $data->{obj}{$pic}; + my $path = $obj->{full}{path}; # Figure out type - $obj->{is_movie} = is_movie($opt,$pic); + $obj->{is_movie} = is_movie($opt,$path); my $can_embed = $obj->{is_movie}; $can_embed = 1 if $pic =~ /\.(pdf|ps)$/i; my $tag = 'img'; @@ -4719,12 +4730,15 @@ # -no_embed USED to mean that movie pages didn't have image pages.. #$use_image_pages = 0 if $obj->{is_movie} && !$opt->{embed}; + my $image_dir = "$opt->{dir}/" if $opt->{dir}; + my $image_path = "$dir/$image_dir"; if ($use_image_pages) { my $image_page = "$pic$data->{paths}{page_post_url}"; - $obj->{URL}{album_page}{image} = url_quote($opt, "$opt->{dir}/$image_page"); + $obj->{URL}{album_page}{image} = url_quote($opt, "$image_dir$image_page"); # Kludge - the number of ".." should be equal to the pathsize of $opt->{dir} my $image = ($opt->{just_medium} && $obj->{thumb}) - ? $obj->{medium}{file} : "../$pic"; + ? $obj->{medium}{path} : $obj->{full}{path}; + $image = diff_path($opt, $image_path, $image); $obj->{URL}{image_page}{image} = url_quote($opt, $image); $obj->{URL}{image_page}{image_page} = url_quote($opt, $image_page); @@ -4732,28 +4746,35 @@ # -embed: pic or medium, but pic if movie (../$pic) # -noembed and -medium: medium # -noembed and -nomedium: snapshot - my $image_src = $obj->{medium}{file} || "../$pic"; + my $image_src = $obj->{medium}{path} || $obj->{full}{path}; if ($obj->{snapshot}{file}) { - $image_src = $opt->{embed} ? "../$pic" : - ($obj->{medium}{file} || $obj->{snapshot}{file}); + $image_src = $opt->{embed} ? $obj->{full}{path} : + ($obj->{medium}{path} || $obj->{snapshot}{path}); } + $image_src = diff_path($opt, $image_path, $image_src); $obj->{URL}{image_page}{image_src} = url_quote($opt, $image_src); # Thumbnail - $obj->{URL}{album_page}{thumb} = url_quote($opt, "$opt->{dir}/$obj->{thumb}{file}"); - $obj->{URL}{image_page}{thumb} = url_quote($opt, $obj->{thumb}{file}); + $obj->{URL}{album_page}{thumb} = + url_quote($opt, diff_path($opt, $dir, $obj->{thumb}{path})); + $obj->{URL}{image_page}{thumb} = + url_quote($opt, diff_path($opt, $image_path, $obj->{thumb}{path})); } else { - $obj->{URL}{album_page}{image} = url_quote($opt, $pic); - $obj->{URL}{album_page}{thumb} = url_quote($opt, "$opt->{dir}/$obj->{thumb}{file}"); + $obj->{URL}{album_page}{image} = + url_quote($opt, diff_path($opt, $dir, $obj->{full}{path})); + $obj->{URL}{album_page}{thumb} = + url_quote($opt, diff_path($opt, $dir, $obj->{thumb}{path})); # We might normally have image pages, just not for this non-image - $obj->{URL}{image_page}{image_page} = url_quote($opt, "../$pic") + $obj->{URL}{image_page}{image_page} = + url_quote($opt, diff_path($opt, $image_path, $obj->{full}{path})) if $opt->{image_pages}; } # -transform_url if ($opt->{transform_url}) { $obj->{URL}{album_page}{image} = $opt->{transform_url}; - $obj->{URL}{album_page}{image} =~ s/%S/$pic/g; + my $pic_path = diff_path($opt, $dir, $obj->{full}{path}); + $obj->{URL}{album_page}{image} =~ s/%S/$pic_path/g; my $s = $pic; $s =~ s/\.[^\.]+$//; $obj->{URL}{album_page}{image} =~ s/%s/$s/g; } @@ -4834,7 +4866,8 @@ get_size($opt,'thumb',$obj); # URL to find the thumbnail - $obj->{URL}{album_page}{thumb} = url_quote($opt, "$url/$opt->{dir}/$obj->{thumb}{file}"); + my $thumb_path = diff_path($opt, $data->{paths}{dir}, $obj->{thumb}{path}); + $obj->{URL}{album_page}{thumb} = url_quote($opt, $thumb_path); } # Should caption be done here? From scottbertin@y... Mon Apr 10 20:01:21 2006 From: scottbertin@y... (Scott J. Bertin) Date: Thu Dec 21 19:59:34 2006 Subject: [Album] [PLUGIN]reorganizer.alp - a plugin to allow images to be outside the album directory Message-ID: <443B1C01.4030606@yahoo.com> Have images stored in one place appear in albums elsewhere. I use this plugin to allow an image to be in multiple albums with only a single copy of the image and thumbnail. It will also handle most of the other reorganization tasks that people have mentioned on the list that they would like album to do. This plugin requires the full path patch that I am also sending today for full functionality. This plugin has been fairly well tested, but is rather complex. Feel free to contact me with any questions or problems you may have. This plugin, and the others I have sent in the past, should not be considered as entries in the contest. I have no desire to relinquish ownership of the code. Scott J. Bertin scottbertin@yahoo.com DESCRIPTION: For the most basic usage, reorganizer will recursively copy the contents of the specified source directory to the directory being processed by album. It will copy images, captions, and thumbnails. Normally, this copying will be done using hard links to reduce disk usage. If any images have a .albums file (for example image.jpg and image.albums), that file will be read and interpreted as a list of additional directories (relative to the album directory) where the image should appear. If the reorganizer:albums_only option is set, the recursive copy will be skipped, and only .albums files will be consulted for where the images should end up. If the no_reorganizer:copy_images option is used, the images will be accessed from the original location with no duplication. In this case, an image in multiple albums will only have the thumbnail generated once (unless the no_reorganizer:common_thumbnails option is used). It is mandatory to supply at least one source, or reorganizer will not do anything. If a source directory (or subdirectory) contains a .hide_album file, it will not be duplicated, but it will still be processed for .albums files. If a source directory (or subdirectory) contains a .no_album file, it will not be processed at all. Images with a .no_img or .hide_album file will be ignored even if there is a .albums file for that image. No files will be overwritten unless the -force option is used. This plugin uses many hooks, and modifies album's internal data structures. Not all hooks are used for their intended purpose, so it should be loaded as the first plugin if possible. EXAMPLES: The following examples assume that the original images are in a directory called pics, and that the directory all the html will be produced in is web. Duplicating an existing directory of images, leaving the original directory unchanged: album -plugin utils/reorganizer -reorganizer:source=pics web Create an album with only medium and thumbnail images in the directory: album -medium 600x400 -just_medium -plugin utils/reorganizer \ -reorganizer:source=pics -no_reorganizer:copy_images \ -no_reorganizer:common_thumbnails web Create an album based on .albums files, leaving the images in pics, and thumbnails in pics/tn. web will only contain html files: album -plugin utils/reorganizer -reorganizer:source=pics \ -reorganizer:albums_only -no_reorganizer:copy_images web -------------- next part -------------- # Album Plugin: utils/reorganizer # For info: 'album -plugin_info utils/reorganizer' # For usage: 'album -plugin_usage utils/reorganizer' # For license: 'album -utils/reorganizer:show_license' use strict; use File::Copy; use File::Path; my $LICENSE = << 'LICENSE'; Copyright (c) 2005-2006 Scott J. Bertin Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. LICENSE my $DESCRIPTION = << 'DESCRIPTION'; Have images stored in one place appear in albums elsewhere. For the most basic usage, reorganizer will recursively copy the contents of the specified source directory to the directory being processed by album. It will copy images, captions, and thumbnails. Normally, this copying will be done using hard links to reduce disk usage. If any images have a .albums file (for example image.jpg and image.albums), that file will be read and interpreted as a list of additional directories (relative to the album directory) where the image should appear. If the reorganizer:albums_only option is set, the recursive copy will be skipped, and only .albums files will be consulted for where the images should end up. If the no_reorganizer:copy_images option is used, the images will be accessed from the original location with no duplication. In this case, an image in multiple albums will only have the thumbnail generated once (unless the no_reorganizer:common_thumbnails option is used). It is mandatory to supply at least one source, or reorganizer will not do anything. If a source directory (or subdirectory) contains a .hide_album file, it will not be duplicated, but it will still be processed for .albums files. If a source directory (or subdirectory) contains a .no_album file, it will not be processed at all. Images with a .no_img or .hide_album file will be ignored even if there is a .albums file for that image. No files will be overwritten unless the -force option is used. This plugin uses many hooks, and modifies album's internal data structures. Not all hooks are used for their intended purpose, so it should be loaded as the first plugin if possible. DESCRIPTION my $EXAMPLES = << 'EXAMPLES'; The following examples assume that the original images are in a directory called pics, and that the directory all the html will be produced in is web. Duplicating an existing directory of images, leaving the original directory unchanged: album -plugin utils/reorganizer -reorganizer:source=pics web Create an album with only medium and thumbnail images in the directory: album -medium 600x400 -just_medium -plugin utils/reorganizer \ -reorganizer:source=pics -no_reorganizer:copy_images \ -no_reorganizer:common_thumbnails web Create an album based on .albums files, leaving the images in pics, and thumbnails in pics/tn. web will only contain html files: album -plugin utils/reorganizer -reorganizer:source=pics \ -reorganizer:albums_only -no_reorganizer:copy_images web EXAMPLES my @dir_info; my $init_dir; my @saved_sources; sub start_plugin { my ($opt) = @_; # Setup the options album::add_option(1, 'show_license', \&show_license, one_time=>1, usage=>'Show the license for this plugin.'); album::add_option(1, 'examples', \&show_examples, one_time=>1, usage=>'Show examples of how to use this plugin.'); album::add_option(1, 'source', album::OPTION_ARR, args=>'', usage=>'Source directories for images, may use wildcards.'); album::add_option(1, 'copy_images', album::OPTION_BOOL, default=>1, usage=>'Copy images to new directories.'); album::add_option(1, 'use_albums', album::OPTION_BOOL, default=>1, usage=>'Use .albums files to determine additional directories for images.'); album::add_option(2, 'albums_only', album::OPTION_BOOL, usage=>"Don't replicate source directories, just use .albums files."); album::add_option(2, 'hard_link', album::OPTION_BOOL, default=>1, usage=>'Attempt to use hard links instead of copying.'); album::add_option(2, 'never_overwrite', album::OPTION_BOOL, usage=>'Never overwrite anything while copying (even if -force).'); album::add_option(2, 'common_thumbnails', album::OPTION_BOOL, default=>1, usage=>'All albums will share the same thumbnail (only if -no_copy_images).'); album::add_option(10, 'albums', album::OPTION_STR, default=>'.albums', usage=>'Extension for the file listing albums for an image.'); # Setup the hooks album::hook($opt, 'gather_contents', \&gather_contents); album::hook($opt, 'end_album', \&cleanup); album::hook($opt, 'get_exif_caption', \&set_image_path); album::hook($opt, 'new_image_path', \&new_image_path); return { author => 'Scott J. Bertin', href => 'mailto://scottbertin@yahoo.com', version => '1.1', description => $DESCRIPTION, }; } sub cleanup { my ($opt, $data, $hookname, $dir, $album) = @_; return unless $init_dir eq $dir; $#dir_info = -1; $#saved_sources = -1; undef $init_dir; } sub gather_contents { my($opt, $data, $hookname, $path, $album) = @_; do_init($opt, $data, $path); # Are we tracking anything in this directory? my $dir_index = find_dir_info($path); return if $dir_index < 0; # Add to the list of pics my $dir = $dir_info[$dir_index]; foreach my $image (@{$dir->{images}}) { # Run the gather_contents_item plugin to be consistent with the normal # gather_contents procedure next if album::do_hook($opt,$data,'gather_contents_item', $dir, $image->{name}); push @{$data->{pics}}, $image->{name}; } if (album::option($opt, 'image_pages')) { # Make sure the directory exists for the image pages my $slash = album::option($opt, 'slash'); my $tndir = album::option($opt, 'dir'); my $tn = $path.$slash.$tndir; mkpath($tn) if ! -d $tn; } # Don't return 1, normal gather_contents code should still run. return; } # This needs to be done after read_captions, or it may be clobbered. # This needs to be done before get_exif_caption, or exif info won't be found. sub set_image_path { my ($opt, $data, $hookname, $pic) = @_; # Are we tracking anything in this directory? my $dir_index = find_dir_info($data->{paths}{dir}); return undef if $dir_index < 0; # Add the new image info foreach my $image (@{$dir_info[$dir_index]->{images}}) { if ($image->{name} eq $pic) { $data->{obj}{$pic}{full}{file} = $pic; $data->{obj}{$pic}{full}{path} = $image->{path}; } } return undef; } sub new_image_path { my ($opt, $hookname, $dir, $pic, $type, $postfix) = @_; return undef unless album::option($opt, 'common_thumbnails'); # Are we tracking anything in this directory? my $dir_index = find_dir_info($dir); return undef if $dir_index < 0; # Add the postfix and possibly new extension my $basename = $pic; my $ext = ""; my $dot_index = rindex($pic, "."); if ($dot_index) { $basename = substr($pic,0,$dot_index); $ext = substr($pic, $dot_index+1); } my $file = "$basename.$postfix$ext"; $file .= ".$type" if $type && lc($type) ne lc($ext); # Find where the image should be created foreach my $image (@{$dir_info[$dir_index]->{images}}) { return ($file, $image->{tn}.$file) if $image->{name} eq $pic; } return undef; } sub do_init { my($opt, $data, $dir) = @_; $init_dir = $dir unless $init_dir; # Check the options my $sources = get_new_sources($opt, $dir); my $albums_only = album::option($opt, 'albums_only'); # Gather the image and directory information foreach my $source (@$sources) { dup_dir($opt, $dir, $source, "", $albums_only, 1); } } sub get_new_sources { my ($opt, $dir) = @_; my $all_sources = album::option($opt, 'source'); my @new_sources; my $new_seen; for(my $i=0; $i<=$#$all_sources; $i++) { $new_seen ||= $i>$#saved_sources || $$all_sources[$i] ne $saved_sources[$i]; push(@new_sources, $$all_sources[$i]) if $new_seen; } @saved_sources = @$all_sources; return glob_paths($opt, $dir, \@new_sources); } sub read_file { my ($f) = @_; return undef unless $f; return undef unless (-r $f); return undef unless (open(FILE,"<$f")); my @contents; while() { # Strip leading and trailing whitespace s/^\s+//; s/\s+$//; # Skip blank lines push(@contents,$_) unless length($_) == 0; } close FILE; return @contents; } sub write_file { my ($f, $lines) = @_; return unless $f; return unless (open(FILE,">$f")); foreach (@$lines) { print FILE "$_\n"; } close FILE; } sub get_files { my ($dir) = @_; return undef unless $dir; return undef unless (-d $dir); return undef unless opendir(DIR,"$dir"); my @dir = readdir(DIR); closedir(DIR); return @dir; } sub find_image_file { my ($opt, $all_files, $albums_file, $captions) = @_; # Get the base name of the image file my $albums = album::option($opt, 'albums'); my $base = $albums_file; $base =~ s/\Q$albums\E$//; # Find any matching files my @matches = grep(/^$base\.[^\.]*$/, @$all_files); # Check if this file should be skipped foreach my $skip_opt ('not_img', 'no_album', 'hide_album') { my $skip_ext = album::option($opt, $skip_opt); return undef if $skip_ext && grep(/^\Q$base\E.*\Q$skip_ext\E$/, @$all_files); } # Find matching images @matches = grep(album::is_image($opt, $_), @matches); return undef if scalar(@matches) == 0; # Find the shortest match. This should eliminate the possibility of # matching the wrong file. my $match_found = $matches[0]; for(my $i=1; $i<=$#matches; $i++) { $match_found = $matches[$i] if length($matches[$i]) < length($match_found); } # Does captions file say to ignore this image? return undef if $match_found && grep(/^#\s*\Q$match_found\E\s/, @$captions); return $match_found; } sub find_dir_info { my ($dir) = @_; for my $i (0..$#dir_info) { return $i if $dir_info[$i]->{dir} eq $dir; } return -1; } # Get an absolute path even if it doesn't exist yet sub normalize_path { my ($opt, $path) = @_; my $slash = album::option($opt, 'slash'); # Make sure we're starting with an absolute path, not a relative path my $drive = ""; if (album::option($opt, 'windows') && !album::option($opt, 'cygwin') && substr($path,1,1) eq ":") { $drive = substr($path,0,2); $path = substr($path,2); if (index($path, $slash) != 0) { $path = album::port_abs_path($opt,$drive.".").$slash.$path; } } elsif (index($path, $slash) != 0) { $path = album::port_abs_path($opt,".").$slash.$path; } # Handle any . or .. components in the path my @parts; foreach my $orig_part (split $slash, $path) { if ($orig_part eq "..") { pop @parts; next; } next if $orig_part eq "."; next if $orig_part eq ""; push @parts, $orig_part; } $parts[0] = $drive.$slash.$parts[0]; return join album::option($opt, 'slash'), @parts; } # Copy, link, or ignore a file as appropriate sub do_copy { my ($opt, $source, $target) = @_; my $hard_link = album::option($opt, 'hard_link'); my $overwrite = album::option($opt, 'force') && !album::option($opt, 'never_overwrite'); return unless -r $source; return if -e $target && !$overwrite; unlink $target if -e $target; return if $hard_link && link($source, $target); copy($source, $target); } # Copy a caption from one caption file to another sub caption_copy { my ($opt, $image, $src, $dest, $captions) = @_; # Check the options my $slash = album::option($opt, 'slash'); my $caption_file_name = album::option($opt, 'captions'); mkpath($dest); $src .= $slash; $dest .= $slash; # Copy the entry in the captions file my @caption_lines = grep(/^\Q$image\E *(\t|::|$)/, @$captions); my $caption_line = $caption_lines[0]; if ($caption_line) { my $overwrite = album::option($opt, 'force') && !album::option($opt, 'never_overwrite'); # Check for an existing line in the caption file @caption_lines = read_file($dest.$caption_file_name); my $found = 0; for (my $i=0; !$found && $i<=$#caption_lines; $i++) { $found = $caption_lines[$i] =~ /^\Q$image\E *(\t|::|$)/; $caption_lines[$i] = $caption_line if $found; } # Add the caption if it didn't already exist push @caption_lines, $caption_line if !$found; # Write the replacement caption file write_file($dest.$caption_file_name, \@caption_lines) if !$found || $overwrite; } } # Copy the thumbnail and medium image files sub thumbnail_copy { my ($opt, $image, $src, $dest) = @_; # Check the options my $slash = album::option($opt, 'slash'); mkpath($dest); $src .= $slash; $dest .= $slash; # Copy the thumbnail my $is_movie = album::is_movie($opt, $image); my $type = album::option($opt, 'type'); my @post = $is_movie ? ('snap.','snap.') : ('tn.',''); my ($srcfile, $srcpath) = album::new_image_path($opt, $src, $image, $type, @post); my ($destfile, $destpath) = album::new_image_path($opt, $dest, $image, $type, @post); do_copy($opt, $srcpath, $destpath); # Copy the medium image if (album::option($opt, 'medium')) { $type = album::option($opt, 'medium_type'); $type = album::option($opt, 'type') if $is_movie && !$type; ($srcfile, $srcpath) = album::new_image_path($opt, $src, $image, $type, 'med.', 'med.'); ($destfile, $destpath) = album::new_image_path($opt, $dest, $image, $type, 'med.', 'med.'); do_copy($opt, $srcpath, $destpath); } } # Copy the image, associated files, and caption sub image_copy { my ($opt, $image, $src, $dest, $captions) = @_; # Check the options my $slash = album::option($opt, 'slash'); mkpath($dest); $src .= $slash; $dest .= $slash; my $basename = $image; $basename =~ s/^(.+)\.[^\.]+$/\1/; # Copy the image and any associated files my @files = grep(/^$basename\.[^\.]+$/, get_files($src)); foreach my $file (@files) { do_copy($opt, "$src$file", "$dest$file"); } thumbnail_copy($opt, $image, $src, $dest); caption_copy($opt, $image, $src, $dest, $captions); } # Perform filename globbing on paths (possible relative to $dir). # Returns a list of full paths for valid directories found. sub glob_paths { my ($opt, $dir, $paths) = @_; my $slash = album::option($opt, 'slash'); my @globbed_paths; foreach my $path (@$paths) { my $found = 0; foreach my $gp (glob($path)) { $found = 1 if -e $gp; push @globbed_paths, album::port_abs_path($opt, $gp) if -d $gp; } if (!$found) { foreach my $gp (glob($dir.$slash.$path)) { push @globbed_paths, album::port_abs_path($opt, $gp) if -d $gp; } } } return \@globbed_paths; } sub image_track { my ($opt, $image, $src, $dest, $captions) = @_; # Check the options my $slash = album::option($opt, 'slash'); my $tndir = album::option($opt, 'dir'); my $common_thumbnails = album::option($opt, 'common_thumbnails') && !album::option($opt, 'copy_images'); # If this already exists in the target directory, don't mess with it. return if -e $dest.$slash.$image; # Setup the info for this image my $image_info = {name=>$image, path=>$src.$slash.$image}; my $tn = normalize_path($opt, $src.$slash.$tndir).$slash; $image_info->{tn} = $tn if $common_thumbnails; # Find the directory for tracking my $dir_index = find_dir_info($dest); if ($dir_index < 0) { mkpath($dest); push @dir_info, {dir=>$dest, images=>()}; $dir_index = $#dir_info; } else { # Make sure this image isn't already tracked in this directory return if grep($_->{name} eq $image, @{$dir_info[$dir_index]->{images}}); } # Add this image to the list push @{$dir_info[$dir_index]->{images}}, $image_info; # Copy the caption caption_copy($opt, $image, $src, $dest, $captions); # Copy the thumbnail image if necessary mkpath($tn) if $common_thumbnails && ! -d $tn; thumbnail_copy($opt, $image, $src, $dest) if !$common_thumbnails; } sub copy_or_track_image { my ($opt, $image, $src, $dest, $captions) = @_; if (album::option($opt, 'copy_images')) { image_copy($opt, $image, $src, $dest, $captions); } else { image_track($opt, $image, $src, $dest, $captions); } } sub dup_dir { my($opt, $top_dir, $source_top, $subdir, $albums_only, $depth) = @_; # Check the options my $max_depth = album::option($opt, 'depth'); my $slash = album::option($opt, 'slash'); my $caption_file = album::option($opt, 'captions'); my $use_albums = album::option($opt, 'use_albums'); my $hide_album = album::option($opt, 'hide_album'); my $no_album = album::option($opt, 'no_album'); my $tndir = album::option($opt, 'dir'); my $albums = album::option($opt, 'albums'); return if $max_depth > 0 && $depth > $max_depth; # Gather the image and directory information my $source = $source_top.$subdir; my @files = get_files($source); return unless scalar(@files) > 0; return if grep(/^\Q$no_album\E$/, @files); if (!$albums_only && grep(/^\Q$hide_album\E$/, @files)) { $albums_only = 1; return if !$use_albums; } my $dir = $init_dir.$subdir; my @captions = read_file($source.$slash.$caption_file) if $caption_file; # Process each .albums file foreach my $file (@files) { next if $file =~ /^\./; my $file_path = $source.$slash.$file; if (-d $file_path) { dup_dir($opt, $top_dir, $source_top, $subdir.$slash.$file, $albums_only, $depth+1) if $file ne $tndir; next; } if (!$albums_only && album::is_image($opt, $file_path)) { copy_or_track_image($opt, $file, $source, $dir, \@captions); next; } next unless $use_albums; next unless $file =~ /.\Q$albums\E$/; my $image = find_image_file($opt, \@files, $file, \@captions); next unless $image; my $image_path = $source.$slash.$image; my @lines = read_file($source.$slash.$file); next unless scalar(@lines); # Handle additional albums foreach my $line (@lines) { copy_or_track_image($opt, $image, $source, normalize_path($opt, $top_dir.$slash.$line), \@captions); } } } sub show_license { my ($opt) = @_; print "The following license applies ONLY to the ", $opt->{_curr_plugin}, " plugin, and should not be construed ", "to apply to album, or any other plugin.\n\n", $LICENSE; exit; } sub show_examples { my ($opt) = @_; print $EXAMPLES; exit; } # Plugins always end with: 1; From dave@s... Mon May 22 18:13:54 2006 From: dave@s... (Dave Hansen) Date: Thu Dec 21 19:59:34 2006 Subject: [Album] [PATCH 1/6] add a "global footer" Message-ID: <20060523011354.85EE1FA861@blackbird.sr71.net> In addition to the nice "Marginal Hacks", etc... footer, I also like to have a little blurb with my email address on each page. This option makes that a little bit easier. You can see an example here: http://www.sr71.net/pictures/test/ --- diff -puN album~global-footer-option album --- bin/album~global-footer-option 2006-05-22 18:09:23.000000000 -0700 +++ bin-dave/album 2006-05-22 18:09:23.000000000 -0700 @@ -133,6 +133,7 @@ add_option(2,'index', OPTION_STR, args=> add_option(2,'default_index', OPTION_STR, args=>'', default=>'index.html', usage=>["The file the webserver accesses when", "when no file is specified."]); add_option(3,'html', OPTION_STR, args=>'', default=>'.html', usage=>"Default postfix for HTML files"); +add_option(10,'global_footer', OPTION_STR, usage=>"text to insert at the end of each page"); # Thumbnail Options: add_option(1,'Thumbnail Options:',OPTION_SEP); @@ -3985,7 +3986,7 @@ sub Credit { \$from =~ s/{mh}/\$mh.\$mh[int(rand(\$#mh+1))]/e; \$from =~ s/{tool}/\$tool.\$tool[int(rand(\$#tool+1))]/e; - print "\$start \$album \$from"; + print "\$opt->{global_footer} \$album \$from"; \$${derc}=1; } @@ -4170,6 +4171,9 @@ sub footer { while(