Rev 4 | Blame | Compare with Previous | Last modification | View Log | RSS feed
#!/usr/bin/perl -wuse strict;use HTML::Tiny;#use CGI qw(:standard escape escapeHTML);use CGI qw/param cookie header start_html url/;my $h = HTML::Tiny->new( mode => 'html' );my $pageTitle = "CC Manage Roaster";my $homeURL = "/";my %FIELDS = (roaster => [qw(Roaster 1 text required)],url => [qw(URL 2 text required)],location => ['Location (City, State)', 3, 'text', 'required'],note => [qw(Notes 4 textarea)],logo => [qw(Logo 5 image)]);my %fieldDisplayName = map { $_ => $FIELDS{$_}->[0] } keys %FIELDS;my %fieldType = map { $_ => $FIELDS{$_}->[2] } keys %FIELDS;my @requiredFields = sort fieldOrder grep { defined $FIELDS{$_}->[3] } keys %FIELDS;#my @requiredFields = grep { $FIELDS{$_}->[2] eq 'required' } keys %FIELDS;sub fieldOrder {$FIELDS{$a}->[1] <=> $FIELDS{$b}->[1];}print header (),start_html (-title => "Add / Update Roaster", -style => {'src' => "style.css"} );print $h->div ({ class => "accent pageheader" }, [$h->h1 ($pageTitle),$h->div ({ class=>"sp0" }, [$h->div ({ class=>"spLeft" }, []),$h->div ({ class=>"spRight" }, [$h->input ({ type=>"button", value=>"Home", onClick=>"window.location.href='$homeURL'" }),]),]),]);my $choice = param ("choice") // "";if ($choice eq "Save") {process_form ();} elsif (defined (param ("roaster"))) {my $roaster = param ("roaster");display_form ($roaster, $choice);} else {display_form (); # blank form}print $h->close ("html");sub display_form {my $R = shift;my $view = shift // "";my $hiddenR = "";my $actionbutton;my ($U, $L, $I, $N, $logo);if ($R) {# we're updating an existing roaster. Get the current values out of the DB...use WebDB;my $dbh = WebDB::connect ();($U, $L, $N) = $dbh->selectrow_array ("SELECT url, location, note FROM roasters WHERE roaster = ?",undef, $R);$dbh->disconnect ();my $i = "serve_image.pl" . sprintf ("?name=%s", $h->url_encode ($R));$I = $h->img ({ src => "$i;thumbnail=1", alt => $R });# did we find a record?error ("Cannot find Roaster named $R") unless defined ($L);if ($view eq "Update") {print $h->p ("Updating Roaster $R...");$R = formField ('roaster', $R);$U = formField ('url', $U);$L = formField ('location', $L);$N = formField ('note', $N);$logo = $I.' ' . formField ('logo');$actionbutton = formField ("choice", "Save");$actionbutton .= formField ("choice", "Cancel");} else {print $h->p ("Viewing Roaster $R...");$logo = $I;$hiddenR = $h->input ({ type=>"hidden", name=>"roaster", value=> "$R" });$actionbutton = formField ("choice", "Update");}} else {print $h->p ("Adding a new Roaster...");$R = formField ('roaster');$U = formField ('url');$L = formField ('location');$N = formField ('note');$logo = formField ('logo');$actionbutton = formField ("choice", "Save");}print $h->open ("form", { action => url (), method=>"POST", enctype=>"multipart/form-data" });print $h->div ({ class=>"rTable" }, [$h->div ({ class=>"rTableRow" }, [$h->div ({ class=>"rTableCell right" }, "$fieldDisplayName{'roaster'}: "),$h->div ({ class=>"rTableCell" }, [ $hiddenR, $R ])]),$h->div ({ class=>"rTableRow" }, [$h->div ({ class=>"rTableCell right" }, "$fieldDisplayName{'url'}: "),$h->div ({ class=>"rTableCell" }, $U)]),$h->div ({ class=>"rTableRow" }, [$h->div ({ class=>"rTableCell right" }, "$fieldDisplayName{'location'}: "),$h->div ({ class=>"rTableCell" }, $L)]),$h->div ({ class=>"rTableRow" }, [$h->div ({ class=>"rTableCell right top" }, "$fieldDisplayName{'note'}: "),$h->div ({ class=>"rTableCell" }, $N)]),$h->div ({ class=>"rTableRow" }, [$h->div ({ class=>"rTableCell right top" }, "$fieldDisplayName{'logo'}: "),$h->div ({ class=>"rTableCell" }, $logo)]),]);print $actionbutton;print $h->close ("form");printJavascript ();}sub process_form {use WebDB;my %FORM;foreach (keys %FIELDS) {if ($fieldType{$_} =~ /^text/) {$FORM{$_} = WebDB::trim param ($_) // "";} else {$FORM{$_} = param ($_) // "";}}my $dbh;my ($full, $thumb, $mime_type);my $serve_url;# check for required fieldsmy @errors = ();foreach (@requiredFields) {push @errors, "$fieldDisplayName{$_} is missing." if $FORM{$_} eq "";}if (@errors) {print $h->div ({ class=>"error" }, [$h->p ("The following errors occurred:"),$h->ul ($h->li (@errors)),$h->p ("Please click your Browser's Back button to\n". "return to the previous page and correct the problem.")]);return;} # Form was okay; get image type and contents and create new record.# Use REPLACE to clobber any old image with the same name.$dbh = WebDB::connect ();if ($FORM{logo}) {$mime_type = uploadInfo ($FORM{logo})->{'Content-Type'};($full, $thumb) = read_image_file ($FORM{logo});$dbh->do ("REPLACE INTO roasters(roaster,url,logo,thumbnail,location,note,mime_type)VALUES(?,?,?,?,?,?,?)",undef,$FORM{roaster}, $FORM{url}, $full, $thumb, $FORM{location}, $FORM{note}, $mime_type);} else {$dbh->do ("INSERT INTO roasters(roaster,url,location,note)VALUES(?,?,?,?)ON DUPLICATE KEY UPDATE url = ?, location = ?, note = ?",undef,$FORM{roaster}, $FORM{url}, $FORM{location}, $FORM{note}, $FORM{url}, $FORM{location}, $FORM{note});}$dbh->disconnect (); # Image was stored into database successfully. Present confirmation# page that displays both the full size and thumbnail images.print $h->p ({ class=>"success" }, "Roaster successfully saved.");display_form ($FORM{roaster});}use Image::Magick;sub read_image_file {my $fh = shift; # filename/file handlemy $img = new Image::Magick;my ($full, $thumb);my $err;# read full-size image directly from upload file(read ($fh, $full, (stat ($fh))[7]) == (stat ($fh))[7])or error ("Can't read image file: $!");# produce thumbnail from full-size image$err = $img->BlobToImage ($full);error ("Can't convert image data: $err") if $err;$err = $img->Scale (geometry => "64x64");error ("Can't scale image file: $err") if $err;$thumb = $img->ImageToBlob ();return ($full, $thumb);}sub error {my $msg = shift;print $h->p ({ class=>"error" }, "Error: $msg");print $h->close("html");exit (0);}sub formField {my $name = shift;my $value = shift // '';my $type = $fieldType{$name} // "button";if ($type eq "image") {return $h->input ({name => $name,class => "inputfile",type => "file",id => "file",size => 60}) . $h->label ({ for=>"file", class=>"top" }, $h->span ("Choose File..."));} elsif ($type eq "button") {if ($name eq "Cancel") {return $h->input ({ type=>"submit", value => "Cancel", onClick=>"history.back();" })} else {return $h->input ({ type=>"submit", value => $value, name=>$name })}} elsif ($type eq "textarea") {return $h->tag ("textarea", {name => $name,override => 1,cols => 30,rows => 4}, $value);} else {return $h->input ({name => $name,type => $type,value => $value,required => [],override => 1,size => 30});}}sub printJavascript {print<<JSCRIPT;<SCRIPT language="JavaScript"><!--var inputs = document.querySelectorAll( '.inputfile' );Array.prototype.forEach.call( inputs, function( input ){var label = input.nextElementSibling,labelVal = label.innerHTML;input.addEventListener( 'change', function( e ){var fileName = e.target.value.split( '\\\\' ).pop();if( fileName )label.querySelector( 'span' ).innerHTML = fileName;elselabel.innerHTML = labelVal;});});//--></SCRIPT>JSCRIPT}