Perl Photo Tools - Part 3.
Apr 28 2009 Programming

Final entry for my photo tools.
The browser frontend. Using CGI, and DBI.  

Here's the landing page. It uses some of the code from my first script that collected stats. Only this time the output is tabulated html. I decided to access the files directly rather than through the database so I could simply use permissions for controlling access without dead links.


#!/usr/bin/perl

# e dziewa july 2008

use strict;
use warnings;
use CGI qw(:standard -no_xhtml);
use CGI::Carp qw(carpout);
$CGI::POST_MAX=1024 * 100;  # max 100K posts
$CGI::DISABLE_UPLOADS = 1;  # no uploads

my ($char_count, $word_count) = 0;
my ($filename, @who, @when, @what, $people, $when, $place);
my (@filename_array_split, $name, $year, $what);
my (%names_hash, %years_hash, %what_hash);
my @words;
my ($where, @where, %where_hash);
my $pathname = "/absolutepath/photos";
my ($i, $j) = 0;

opendir (DIRHANDLE, $pathname) or die "couldn't open $pathname:\n$!";

while (defined($filename = readdir(DIRHANDLE))) {
    next if $filename =~ /^\.\.?$/;
    ($people, $what, $when, $where) = split / - /, $filename;
    @who = split / \& /, $people;
    @when = $when;
    @what = split / /, $what;
    chop $where; chop $where; chop $where; chop $where;
    @where = $where;
    @filename_array_split = split //, $filename;
    $char_count += $#filename_array_split;
    @words = split /\b/, $filename;
    $word_count += $#words; $j++;

    foreach $name (@who) { $names_hash{$name}++ }
    foreach $year (@when) { $years_hash{$year}++ }
    foreach $what (@what) { $what_hash{$what}++ }
    foreach $place (@where) { $where_hash{$where}++ }
}

my $doc = new CGI;
my $favicon = '<link rel="Shortcut Icon" type="image/x-icon" src=img/favicon.ico" />';
print $doc->header,
    $doc->start_html( -head => $favicon,
            -title=> 'the dziewa\'s photo collection',
            -meta=>{ 'author' => 'eric dziewa', 'keywords' => 'some \'KEY\' words', 'description' => 'descriptive text' },
            -style=>{ 'src' => 'validcss.css' }
    );

print '
<div id="container">
    <div>
        <div style="text-align: right"><span class="header">
            We have ', $j, ' photos, containing ',$char_count, ' characters, within ', $word_count, ' words.<br>
            You can <a href="picture.pl" target="blank">View them all</a>, or thumb through the<br>
            years, people, places, and titles with the links below.</span>
        </div>
    </div>
</div>
<br><br>';

print '<br><table width="100%"><tr><td>&nbsp;<td>&nbsp;<td>&nbsp;<td>&nbsp;<td>&nbsp;<td>&nbsp;
        <td>&nbsp;<td>&nbsp;<th class="borderline" colspan="2">Years';

my %ENV; $ENV{'SCRIPT_NAME'} = 'search.pl';

foreach my $sorted_dates (sort keys %years_hash) {
    if ($i % 10) { print "<td class=\"borderlblue\" width=\"10%\">" }
    else { print "<tr><td class=\"borderlblue\" width=\"10%\">" }
    print "<a href=\"$ENV{SCRIPT_NAME}?year=$sorted_dates\" target=\"blank\"><b>$sorted_dates</b><br>
        $years_hash{$sorted_dates}</a>";
    $i++;
}
print '</table>';
$i = 0;

my @k = sort { $a cmp $b } keys %names_hash;
printf("<br><br><table width=\"100%%\"><tr><td>&nbsp;<td>&nbsp;<td>&nbsp;<td>&nbsp;
    <th class=\"borderline\">%d People", $#k +1);

foreach my $k (@k) {
    if ($i % 5) { print "<td class=\"borderlblue\" width=\"20%\">" }
    else { print "<tr><td class=\"borderlblue\" width=\"20%\">" }
    print "<a href=\"$ENV{SCRIPT_NAME}?people=$k\" target=\"blank\"><b>$k</b><br>$names_hash{$k}</a>";
    $i++;
}
print '</table>';
$i = 0;

my @m = sort { $where_hash{$b} <=> $where_hash{$a} } keys %where_hash;
printf("<br><br><table width=\"100%%\"><tr><td>&nbsp;<td>&nbsp;<td>&nbsp;<td>&nbsp;
    <th class=\"borderline\">%d Places", $#m +1);

foreach my $m ( sort @m ) {
    if ($i % 5) { print "<td class=\"borderlblue\" width=\"20%\">" }
    else { print "<tr><td class=\"borderlblue\" width=\"20%\">" }
    print "<a href=\"$ENV{SCRIPT_NAME}?places=$m\" target=\"blank\"><b>$m</b><br>$where_hash{$m}</a>";
    $i++;
}
print '</table>';
$i = 0;

my @w = sort { $a cmp $b } keys %what_hash;
printf("<br><br><table width=\"100%%\"><tr><td>&nbsp;<td>&nbsp;<td>&nbsp;<td>&nbsp;
    <th class=\"borderline\">%d Title Words", $#w +1);

    foreach my $n (@w) {
    if ($i % 5) { print "<td class=\"borderlblue\" width=\"20%\">" }
    else { print "<tr><td class=\"borderlblue\" width=\"20%\">" }
    print "<a href=\"$ENV{SCRIPT_NAME}?title=$n\" target=\"blank\"><b>$n</b><br>$what_hash{$n}</a>";
     $i++;
    }


Download
Screenshot

The next pages gather information from the database. The first is for me personally. I like to browse chronologically.


#!/usr/bin/perl

# eric dziewa july 2008

use warnings;
use strict;
use CGI qw(:standard -no_xhtml);
use CGI::Carp qw(carpout);
$CGI::POST_MAX=1024 * 100;  # max 100K posts
$CGI::DISABLE_UPLOADS = 1;  # no uploads
use DBI;
    my $database = "databasename";
    my $host = "hostname";
    my $user = "username";
    my $pass = "password";
    my $dbh = DBI->connect( "DBI:mysql:database=$database; host=$host; ", " $user", "$pass", { 'RaiseError' => 1 } );

my $doc = new CGI;

my $favicon = '<link rel="Shortcut Icon" type="image/x-icon" src="img/favicon.ico" />';

my $startpos;
if ( $ENV{QUERY_STRING} =~ /page=(\d{1,3})/ ) {
    $startpos = $1;
}
else { $startpos = 0; }

my $voidcontext = 0; ### provides an operation to supress these warnings

my $location = $startpos;
if ( $location == 0 ) { $voidcontext++ }
else { $location--; $location *= 20; }

my $numberof_statement = $dbh->prepare("select count(*) from contents;");
    $numberof_statement->execute();
my $noof = $numberof_statement->fetchrow_array;
    $numberof_statement->finish();

print
$doc->header,
$doc->start_html( -head => $favicon,
    -title => 'the dziewa\'s photo collection',
    -meta => { 'author' => 'eric dziewa', 'keywords' => 'some \'KEY\' words', 'description' => 'descriptive text' },
    -style=>{ 'src' => 'validcss.css' }
);

print '
<div id="container">
    <div>
        <div class="caps" style="text-align: right"><h4>Hi '.$ENV{'REMOTE_ADDR'}.'</h4>
        </div>
        <div style="text-align: right">&nbsp; </div>
    </div>
</div>
<br><br>';

if ( $noof < $startpos ) {
    print "Silly rabbit, tricks are for kids!<br>
    the maximum query string is ", int($noof/20), " not ", $startpos * 20, " </html>"; return }
else { $voidcontext++ }

my $statement = $dbh->prepare("select
    two_filename, two_width, two_height,
    four_filename, four_width,  four_height,
    filename, width, height, webname
    from contents limit $location,20;
");

$statement->execute();

print '<table cellpadding="4" cellspacing="4">';

my $rowcount = 0;
while ( my @row = $statement->fetchrow_array ) {
    if ( $rowcount == 0 or $rowcount == 4 or $rowcount == 8 or $rowcount == 12 or $rowcount == 16 ) {
        print '<tr>'; $rowcount++
    }
    else { $rowcount++ }

    print "<td valign=\"top\" width=\"25%\" align=\"center\">
    <img src=\"picture_thumb/$row[0]\" alt=\"$row[0]\" width=\"$row[1]\" height=\"$row[2]\" 
    style=\"padding-top: 15px; padding-bottom: 15px\"><br>
    $row[9]<br>
    <a href=\"picture_mid/$row[3]\" target=\"blank\">$row[4] x $row[5]</a><br>
    <a href=\"picture/$row[6]\" target=\"blank\">$row[7] x $row[8]</a>
    ";
}

$statement->finish();
$dbh->disconnect();
print '</table><br>';

my $morelinks;
if ( ( $noof / 20 ) =~ /\./ ) { $morelinks = ( int( $noof / 20 ) + 1 ); }
else { $morelinks = int($noof / 20); }

my ( $more_iterator, $linkscount, $start_is_zero ) = 0;

print '<table width="100%">';
print '<tr>', '<td width="5%">&nbsp;' x16, '<th class="borderline" colspan="4">Pages in Set';

while ( $morelinks > 0 ) {
    if ( $linkscount == 0 ) { print '<tr>'; $linkscount++; }
    elsif ( ( $linkscount / 20 ) =~ /\.\d/ ) { $linkscount++ }
    else { print '<tr>'; $linkscount++ }

    if ( $startpos == 0 and $start_is_zero == 0 or $linkscount == $startpos ) {
        print "<td class=\"borderline\" width=\"5%\">",$more_iterator+1; $morelinks--; $more_iterator++;
        $start_is_zero++;
    }
    else {
        print "<td class=\"borderlblue\" width=\"5%\"><a href=\"$ENV{SCRIPT_NAME}?page=",$more_iterator+1,"\">", $more_iterator+1, "</a>";
        $morelinks--; $more_iterator++;
    }
}
print '</table>';
print '</body></html>';


Download
Screenshot

Twenty 200x200 images per page. With descriptive links to medium and full size images.

Finally the last page which gives access to searching. I decided to spell out all the possible search terms because the users didn't use the search button even with big letters pointing to it. Not everybody is computer savvy.


#!/usr/bin/perl

# eric dziewa july 2008

use warnings;
use strict;
use CGI qw(:standard -no_xhtml);
use CGI::Carp qw(carpout);
$CGI::POST_MAX=1024 * 100;  # max 100K posts
$CGI::DISABLE_UPLOADS = 1;  # no uploads
my $voidcontext = 0;
$Apache::DBI::Debug = 2;

use DBI;
    my $database = "databasename";
    my $host = "hostname";
    my $user = "username";
    my $pass = "password";
    my $dbh = DBI->connect( "DBI:mysql:database=$database; host=$host;" , "$user", "$pass", { 'RaiseError' => 1 } );

my $doc = new CGI;

my $favicon = '<link rel="Shortcut Icon" type="image/x-icon" src="img/favicon.ico" />';

my ( $searchfield, $searchstring );

if ( $ENV{QUERY_STRING} =~ /^year=(\d{4})=?/ ) {
    $searchstring = $1; $searchfield = 'year=';
}
elsif ( $ENV{QUERY_STRING} =~ /^title=([\w\(\)'&!-]+)=?/ ) {
    $searchstring = $1; $searchfield = 'title=';
}
elsif ( $ENV{QUERY_STRING} =~ /^people=([\w %20\(\)]+)=?/ ) {
    $searchstring = $1;
    ( $searchstring = $searchstring ) =~ s/%20/\ /g;
    ( $searchstring = $searchstring ) =~ s/([()])/\\$1/g;
    $searchfield = 'people=';
}
elsif ( $ENV{QUERY_STRING} =~ /^places=([\w %20\(\)'&-]+)=?/ ) {
    $searchstring = $1;
    ( $searchstring = $searchstring ) =~ s/%20/\ /g;
    ( $searchstring = $searchstring ) =~ s/([()])/\\$1/g;
    $searchfield = 'places=';
}
else { $searchstring = "llamma"; }

print $doc->header,
      $doc->start_html( -head =>  $favicon,
            -title=>"Search results for $searchstring",
            -meta=>{'author'=>'eric dziewa','keywords'=>'some \'KEY\' words','description'=>'descriptive text'},
            -style=>{'src'=>'validcss.css'}
    );

my $noof;
my $numberof_statement = $dbh->prepare("select count(*) from contents where filename regexp ?;");
$numberof_statement->execute($searchstring);
$noof = $numberof_statement->fetchrow_array;
$numberof_statement->finish();
$dbh->disconnect();

print '
<div id="container">
    <div>
        <div class="caps" style="text-align: right"><h4>Hi '.$ENV{'REMOTE_ADDR'}.'</h4>
        </div>
        <div style="text-align: right"><h4>', $noof, ' Results for \'', $searchstring, '\'</h4>
        </div>
    </div>
</div>
<br><br>';

my $searchposition;
if ( $ENV{QUERY_STRING} =~ /^.+=.+=(\d+)$/ ) {
    $searchposition = $1;
}
else { $searchposition = 0; }

my $morelinks;
if ( ( $noof / 20 ) =~ /\./ ) {
    $morelinks = ( int($noof / 20) + 1 );
}
else {
    $morelinks = int($noof / 20);
}

if ( $morelinks < $searchposition ) {
    print "Silly rabbit, tricks are for kids!<br>
    the maximum query string is $morelinks not $searchposition </html>";
    return
}
else { $voidcontext++ }

my $location = $searchposition;

if ( $location == 0 ) { $voidcontext++ }
else { $location--; $location *= 20; }

my $statement = $dbh->prepare("select
    two_filename, two_width, two_height,
    four_filename, four_width,  four_height,
    filename, width, height, webname
    from contents where filename regexp ? limit $location,20;
");
    $statement->execute($searchstring);

print '<table cellpadding="4" cellspacing="4">';

my $rowcount = 0;
while ( my @row = $statement->fetchrow_array ) {
    if ( $rowcount == 0 or $rowcount == 4 or $rowcount == 8 or $rowcount == 12 or $rowcount == 16 ) {
        print '<tr>'; $rowcount++;
    }
    else { $rowcount++ }

    print "<td valign=\"top\" width=\"25%\" align=\"center\">
    <img src=\"picture_thumb/$row[0]\" alt=\"$row[0]\" width=\"$row[1]\" height=\"$row[2]\" 
    style=\"padding-top: 15px; padding-bottom: 15px\"><br>
    $row[9]<br>
    <a href=\"picture_mid/$row[3]\" target=\"blank\">$row[4] x $row[5]</a><br>
    <a href=\"picture/$row[6]\" target=\"blank\">$row[7] x $row[8]</a>
    ";
}
$statement->finish();
$dbh->disconnect();

print '</table><br><br>';

my $more_iterator = 0; my $linkscount = 0; my $start_is_zero = 0;

print '<table width="100%">';
print '<tr>', '<td width="5%">&nbsp;' x16, '<th class="borderline" colspan="4">Pages in Set';

my ( $spacer, $toggle );
if ( $morelinks < 20 ) {
    $spacer = 20 - $morelinks;
    $toggle = 0;
}

while ( $morelinks > 0 ) {
    if ( $linkscount == 0 ) { print '<tr>'; $linkscount++; }
    elsif ( ( $linkscount / 20 ) =~ /\.\d/ ) { $linkscount++ }
    else { print '<tr>'; $linkscount++ }

    if ( ($spacer) and $toggle == 0 ) {
        print '<td width="5%">&nbsp;' x $spacer; $toggle = 1
    }
    else { $voidcontext++ }

    if ( $searchposition == 0 and $start_is_zero == 0 or $linkscount == $searchposition ) {
        print "<td class=\"borderline\" width=\"5%\">",$more_iterator+1; $morelinks--; $more_iterator++;
        $start_is_zero++;
    }
    else {
        print "<td class=\"borderlblue\" width=\"5%\"><a href=\"$ENV{SCRIPT_NAME}?$searchfield$searchstring\=",
        $more_iterator+1,"\">", $more_iterator+1,"</a>";
        $morelinks--; $more_iterator++;
    }
}
print '</table>
</body></html>';


Download

One day I might modify these to list items instead of tables.

   
Comments
Jun 11 2014
Comment #1 posted by Ricen at 11:52 am

Hello...

Comments for this entry available via RSS.
Comment Area
Your Name
Your Email (will not be published)
Your Website
Your Comment
Profanity is Prohibited
eric.dziewa.com is running WordPress.
WhiteSpace theme designed by E. Dziewa.
All content © E. Dziewa.
Thanks for stopping by.