#!/usr/bin/env perl ######################################################### # # the Minimally Sufficient Gallery (MSG) # # v0.9 2004-05-30 msittig@wubi.org (draft original script) # v1.0 2004-05-31 msittig@wubi.org (fix markup for validation) # v1.1 2004-05-31 msittig@wubi.org (add welcome, documentation) # v1.2 2004-06-01 msittig@wubi.org (img width/height) # v1.2.1 2004-06-04 msittig@wubi.org (don't resize small thumbs) # v1.2.2 2004-06-26 msittig@wubi.org (simplify LINK_BACK, change # default image html)) # v1.2.3 2004-07-18 msittig@wubi.org (img pages link to image) # v1.3 2004-08-25 msittig@wubi.org (custom pic labels) my $version = "1.3" ; ########################################################## # # Simple instructions: # # CLI: ./msg.cgi # ./msg.cgi --regen # # WWW: http://example.com/dir/msg.cgi # http://example.com/dir/msg.cgi?regen=1 # # Further: http://wubi.org/code/msg/ # ########################################################## # # Customize: # # WELCOME_MESSAGE: A short message on the blank first page. # This can include html markup, but please # remember to make it well-formed :) my $WELCOME_MESSAGE = qq{

Image Gallery

Back }; # DATA_DIR: The directory where thumbnails and stuff is stored. # There's not much reason to change this. my $DATA_DIR = "msg_data" ; # THUMB_WIDTH: Thumbnails are all sized to this same width, and # proportions are maintained. (in pixels) my $THUMB_WIDTH = "80" ; # LINK_BACK: Where do you want to "Back" link to point to? # This can be relative ("../../") or absolute # ("http://example.com"). Keep in mind that the # link will originate within the data directory, # which is inside the image directory. my $LINK_BACK = "../../" ; # Additionally, a customizable stylesheet is located at the end # of the script. # ################################################################ use strict; use Image::Size; use CGI qw{ :standard } ; my $WEB_BUILD = 1 if defined $ENV{'REQUEST_METHOD'} ; print header, begin_html( "Building MSG...", "strict" ), h1( "Generating MSGallery..." ) if $WEB_BUILD ; # Initial environment set-up. if( ! -d "$DATA_DIR" ) { system( "mkdir $DATA_DIR" ); unless( -d $DATA_DIR ) { er( "Couldn\'t create the data directory. Try \'chmod 777 ./\'." ) ; exit; } } my $regen_thumbnails = $ARGV[0]; $regen_thumbnails = ( $regen_thumbnails eq "--regen" or param('regen') ) ? 1 : 0 ; er( "You've requested to regenerate the thumbnails.") if $regen_thumbnails; # Begin processing. my( @menu ); foreach( sort( glob( "*.jpg" ), glob( "*.JPG" ), glob( "*.gif" ), glob( "*.png" ) ) ) { my( $filename, $tb_filename, $x, $y, $kb, $ext, $x_tb, $y_tb ); $filename = $tb_filename = $_ ; er( "Working with $filename" ) ; $tb_filename =~ s/\.(jpg|gif|png)/-tb\.$1/i; ($x, $y, $ext, $kb) = ( imgsize( $filename ), int( ( stat( $filename ) )[7] / 1024 + .5 ), ) ; $x_tb = ( $x > 80 ) ? $THUMB_WIDTH : $x ; $y_tb = ( $x != 0 ) ? int( $y * ( $x_tb / $x ) + .5 ) : die "oops, this thumbnail has 0 width!" ; if( ! -e "$DATA_DIR/$tb_filename" or $regen_thumbnails ) { my $create_thumbnail = ( $x_tb == 80 ) ? qq[convert "$filename" -resize $x_tb "$DATA_DIR/$tb_filename"] : qq[cp "$filename" "$DATA_DIR/$tb_filename"] ; er( "Next, $create_thumbnail" ) ; system( "$create_thumbnail" ) ; } unless( open( IND, ">$DATA_DIR/$filename.html" ) ) { er( "Couldn't open $DATA_DIR/$filename.html: $!" ); er( "This was probably a permissions problem. Try 'chmod 777 ./'." ); exit; }; my( $pic_label ) ; $pic_label = $filename ; # Print individual image documents. er( "Printing individual document for $filename." ); print IND begin_html( "$filename", "transitional" ), table( { -width=>'100%', }, Tr( td( { -valign=>'middle', -align=>'center', }, img( { -src=>"../$filename", -alt=>' ' } ) , a( { -href=>"../$filename", -title=>"Direct link to the image", -class=>'direct', }, p( $pic_label ) ) ) ) ), end_html; close IND; my $i = 0; push( @menu, p( a( { -href=>"$filename.html", -target=>"main", }, img( { -src=>"$tb_filename", -alt=>' ', -width=>"$x_tb", -height=>"$y_tb", -title=>"$ext ${x}x${y}pixels, ${kb}K", } ), ), br, $filename, ) ) ; er( "Image info: $ext ${x}x${y}pixels, ${kb}K" ); } # End of individual picture processing. # Print menu document. er( "Printing menu document" ); open( MENU, ">$DATA_DIR/menu.html" ) or er( "Couldn't open menu.html: $!" ) && exit ; print MENU begin_html( "Menu for /".`basename \`pwd\``." gallery", "transitional" ), h1( a( { -href=>"welcome.html", -target=>'main', }, "/".`basename \`pwd\`` ), ), "@menu", p( a( { -href=>"$LINK_BACK", -target=>'_top' }, "Back" ) ), address( a( { -href=>'http://wubi.org/code/msg/', -title=>'Minimally Sufficient Gallery', -target=>'_top', }, "MSG" ), "$version", br, "micah\@earthling.net", ), end_html; close MENU; # Print frameset document er( "Printing main frameset document." ); my $menu_width = $THUMB_WIDTH + 60; open( MAIN, ">index.html" ) or er( "Couldn't open index.html: $!" ) && exit; print MAIN begin_html( "Gallery of /".`basename \`pwd\``, "frameset" ) ; print MAIN qq{ <body>@menu</body> } ; print MAIN ""; close MAIN; # Print welcome page if( ! -e "$DATA_DIR/welcome.html" ) { er( "Printing welcome page." ); open( BLANK, ">$DATA_DIR/welcome.html" ) ; print BLANK begin_html( "Welcome", "transitional" ), table( { -width=>'100%', -class=>"welcome", }, Tr( td( { -valign=>'middle', -align=>'center', }, "$WELCOME_MESSAGE", ) ) ), end_html; } # Print stylesheet # But only if it doesn't exist - allow users to upgrade MSG or edit # the CSS without losing it on next regen. if( ! -e "$DATA_DIR/msg.css" ) { er( "Printing stylesheet" ); my( $stylesheet ); while( ) { $stylesheet .= $_ } ; open( CSS, ">$DATA_DIR/msg.css" ) ; print CSS $stylesheet ; close CSS ; } print h1( "Done." ), p( 'I now present you with the ', a( { -href=>'./', -title=>'Back to main gallery page.', }, 'finished result' ), '.', ) if $WEB_BUILD ; ### SUBROUTINES ########################################### sub begin_html { my( $title, $dtd, %dtd_string, $out ) = @_; # Start_html's dtd key can take a two item array ref # http://stein.cshl.org/WWW/software/CGI/CGI.pm # List of valid DTDs # http://www.w3.org/QA/2002/04/valid-dtd-list.html %dtd_string = ( strict => [ '-//W3C//DTD XHTML 1.0 Strict//EN', 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd', ], transitional => [ '-//W3C//DTD XHTML 1.0 Transitional//EN', 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd', ], frameset => [ '-//W3C//DTD XHTML 1.0 Frameset//EN', 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd', ], ); my $css_path = ( $dtd eq "frameset" ) ? "$DATA_DIR/msg.css" : "msg.css" ; # er( "The dtd \"$dtd\" value is ".$dtd_string{$dtd}->[0] ) ; $out .= start_html( -title => "$title", -style => { -src=>"$css_path" }, -dtd => $dtd_string{ $dtd }, -encoding => 'utf-8', ); $out =~ s###i if $dtd eq "frameset"; # CGI.pm sometimes sticks in an "encoding" attr, which is not valid xhtml $out =~ s###i; return $out; } sub er { $_ = shift; print "er: $_\n" if defined $ENV{'SHELL'} ; print "$_", br if defined $ENV{'REQUEST_METHOD'} ; } __END__ body { background-color: black; color: white; } h1 { font-size: 1em; } h1 a { color: white; } img { border-color: white; } p { text-align: center; font-size: .7em; font-family: arial, helvetica; } address { font-size: .5em; font-style: normal; padding: 1.5em 0; } address a { color: cornflowerblue; } html, body, table { height: 95%; } table.welcome { width: 60%; margin: 0 auto; } table.welcome p { text-align: left; } table.welcome a { font-variant: small-caps; } a.direct { color: white; }