Subversion Repositories CoffeeCatalog

Rev

Rev 7 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
7 - 1
#!/usr/bin/perl -w
2
 
3
use strict;
4
use HTML::Tiny;
9 - 5
use CGI qw/param header start_html url uploadInfo/;
7 - 6
my $h = HTML::Tiny->new( mode => 'html' );
7
 
8
 
9
my $pageTitle = "CC Manage Roaster";
10
my $homeURL = "/";
9 - 11
my $DBTable = "roasters";
7 - 12
my %FIELDS = (
9 - 13
	roaster   =>  [qw(Roaster                       1		text			required)],
14
	url       =>  [qw(URL                           2		text			required)],
15
	location  =>  ['Location (City, State)',   3,	'text',			'required'],
16
	note      =>  [qw(Notes                         4		textarea)],
17
	logo      =>  [qw(Logo                          5		image)]
7 - 18
);
9 - 19
 
7 - 20
my %fieldDisplayName = map  { $_ => $FIELDS{$_}->[0]   } keys %FIELDS;
21
my %fieldType        = map  { $_ => $FIELDS{$_}->[2]   } keys %FIELDS;
22
my @requiredFields   = sort fieldOrder grep { defined $FIELDS{$_}->[3] } keys %FIELDS;
9 - 23
my @DBFields   = sort fieldOrder grep { $fieldType{$_} =~ /^text/ } keys %FIELDS;
24
my $primary = $DBFields[0];
7 - 25
 
26
sub fieldOrder {
27
	$FIELDS{$a}->[1] <=> $FIELDS{$b}->[1];
28
}
29
 
9 - 30
sub saveForm {
31
  my $FTS = shift;
32
 
33
  use WebDB;
34
  my $dbh = WebDB::connect ();
35
  if ($FTS->{logo}) {
36
    use Image::Magick;
37
    my $mime_type = uploadInfo ($FTS->{logo})->{'Content-Type'};
38
    my ($full, $thumb) = read_image_file ($FTS->{logo});
39
    $dbh->do (
40
  		  "INSERT INTO $DBTable
41
		    (roaster,url,logo,thumbnail,location,note,mime_type,date_added)
42
		    VALUES(?,?,?,?,?,?,?,now())
43
		    ON DUPLICATE KEY UPDATE url = ?, logo = ?, thumbnail = ?, location = ?, note = ?, mime_type = ?",
44
			   undef,
45
			   $FTS->{roaster}, $FTS->{url}, $full, $thumb, $FTS->{location}, $FTS->{note}, $mime_type,
46
			                    $FTS->{url}, $full, $thumb, $FTS->{location}, $FTS->{note}, $mime_type);
47
  } else {
48
    $dbh->do (
49
  		  "INSERT INTO $DBTable
50
		    (roaster,url,location,note,date_added)
51
		    VALUES(?,?,?,?,now())
52
		    ON DUPLICATE KEY UPDATE url = ?, location = ?, note = ?",
53
			   undef,
54
			   $FTS->{roaster}, $FTS->{url}, $FTS->{location}, $FTS->{note}, $FTS->{url}, $FTS->{location}, $FTS->{note});
55
  }
56
	$dbh->disconnect ();	 # Image was stored into database successfully.
57
}
58
 
59
 
60
 
61
 
7 - 62
print header (),
9 - 63
			start_html (-title => "Add / Update ".ucfirst ($primary), -style => {'src' => "style.css"} );
7 - 64
 
65
print $h->div ({ class => "accent pageheader" }, [
66
  $h->h1 ($pageTitle),
67
  $h->div ({ class=>"sp0" }, [
68
    $h->div ({ class=>"spLeft" }, [
69
    ]),
70
    $h->div ({ class=>"spRight" }, [
71
      $h->input ({ type=>"button", value=>"Home", onClick=>"window.location.href='$homeURL'" }),
72
    ]),
73
  ]),
74
]);
75
 
76
my $choice = param ("choice") // "";
77
if ($choice eq "Save") {
78
	process_form ();
9 - 79
} elsif (defined (param ($primary))) {
80
  my $thing = param ($primary);
81
	display_form ($thing, $choice);
7 - 82
} else {
83
	display_form (); # blank form
84
}
85
 
86
print $h->close ("html");
87
 
88
sub display_form  {
89
  my $R = shift;
90
  my $view = shift // "";
9 - 91
  my %F;
7 - 92
  my $hiddenR = "";
93
	my $actionbutton;
94
 
9 - 95
	my ($I, $logo);
96
 
7 - 97
  if ($R) {
9 - 98
    # we're dealing with an existing thing.  Get the current values out of the DB...
7 - 99
    use WebDB;
100
    my $dbh = WebDB::connect ();
9 - 101
 
102
	  @F{@DBFields} = $dbh->selectrow_array (
103
                     "SELECT ". join (", ", @DBFields) ." FROM $DBTable WHERE $primary = ?",
7 - 104
                      undef, $R);
105
	  $dbh->disconnect ();
106
 
9 - 107
	  my $i = "serve_image.pl" . sprintf ("?roaster=%s", $h->url_encode ($R));
108
	  $I = $h->img ({ src => "$i;thumbnail=1", class=>"show", alt => $R });
109
	  $I .= $h->img ({ src => "$i", class=>"hide", alt => $R });
110
 
7 - 111
	  # did we find a record?
9 - 112
	  error ("Cannot find a database entry for '$R'") unless defined $F{$DBFields[0]};
7 - 113
 
114
    if ($view eq "Update") {
9 - 115
      # We'd like the update that thing, give the user a form...
116
      print $h->p ("Updating ".ucfirst ($primary).": $R...");
117
 
118
      foreach (@DBFields) {
119
        $F{$_} = formField ($_, $F{$_});
120
      }
7 - 121
      $logo = $I.'&nbsp;&nbsp;&nbsp;' . formField ('logo');
122
 
123
      $actionbutton = formField ("choice", "Save");
9 - 124
      $actionbutton .= formField ("Cancel");
7 - 125
    } else {
9 - 126
      # We're just looking at it...
127
      print $h->p ("Viewing ".ucfirst ($primary).": $R...");
7 - 128
      $logo = $I;
9 - 129
      $F{$DBFields[0]} .= $h->input ({ type=>"hidden", name=>$DBFields[0], value=> $F{$DBFields[0]} });
7 - 130
      $actionbutton = formField ("choice", "Update");
9 - 131
      $actionbutton .= formField ("Cancel", "Back");
7 - 132
    }
133
  } else {
9 - 134
    print $h->p ("Adding a new ".ucfirst ($primary)."...");
7 - 135
 
9 - 136
    foreach (@DBFields) {
137
      $F{$_} = formField ($_);
138
    }
7 - 139
    $logo = formField ('logo');
140
 
141
    $actionbutton = formField ("choice", "Save");
9 - 142
    $actionbutton .= formField ("Cancel");
7 - 143
  }
144
 
145
 
146
	print $h->open ("form", { action => url (), method=>"POST", enctype=>"multipart/form-data" });
9 - 147
	print $h->div ({ class=>"sp0" },
148
	  $h->div ({ class=>"rTable" }, [ map ({
149
      $h->div ({ class=>"rTableRow" }, [
150
        $h->div ({ class=>"rTableCell right top" }, "$fieldDisplayName{$_}: "),
151
        $h->div ({ class=>"rTableCell" }, $F{$_})
152
      ])
153
      } @DBFields),
154
      $h->div ({ class=>"rTableRow" }, [
155
        $h->div ({ class=>"rTableCell right top" }, "$fieldDisplayName{'logo'}: "),
156
        $h->div ({ class=>"rTableCell" }, $logo)
157
      ]),
158
    ])
159
  );
7 - 160
 
161
  print $actionbutton;
162
  print $h->close ("form");
163
 
164
  printJavascript ();
165
 
166
}
167
 
168
sub process_form  {
169
  use WebDB;
170
 
171
  my %FORM;
172
  foreach (keys %FIELDS) {
173
  	if ($fieldType{$_} =~ /^text/) {
174
  		$FORM{$_} = WebDB::trim param ($_) // "";
175
  	} else {
176
	  	$FORM{$_} = param ($_) // "";
177
  	}
178
  }
179
 
180
  	 # check for required fields
181
	my @errors = ();
182
	foreach (@requiredFields) {
183
		push @errors, "$fieldDisplayName{$_} is missing." if $FORM{$_} eq "";
184
	}
185
 
186
  if (@errors)	 {
187
    print $h->div ({ class=>"error" }, [
188
  	  $h->p ("The following errors occurred:"),
189
  	  $h->ul ($h->li (@errors)),
190
  	  $h->p ("Please click your Browser's Back button to\n"
191
  	  	   . "return to the previous page and correct the problem.")
192
  	]);
193
  	return;
194
  }	 # Form was okay;  get image type and contents and create new record.
9 - 195
 
196
  saveForm (\%FORM);
7 - 197
 
9 - 198
	print $h->p ({ class=>"success" }, ucfirst ($primary)." successfully saved.");
7 - 199
 
200
  display_form ($FORM{roaster});
201
}
202
 
203
sub read_image_file {
204
	my $fh = shift;             # filename/file handle
205
	my $img = new Image::Magick;
9 - 206
	my $fullimg = new Image::Magick;
7 - 207
	my ($full, $thumb);
208
	my $err;
209
	# read full-size image directly from upload file
210
	(read ($fh, $full, (stat ($fh))[7]) == (stat ($fh))[7])
211
          or error ("Can't read image file: $!");
212
	# produce thumbnail from full-size image
213
	$err = $img->BlobToImage ($full);
214
	error ("Can't convert image data: $err") if $err;
9 - 215
	$err = $fullimg->BlobToImage ($full);
216
	error ("Can't convert image data: $err") if $err;
217
 
218
 	if ($fullimg->Get("width") > 300 or $fullimg->Get("height") > 300) {
219
	  $err = $fullimg->Scale (geometry => "300x300");
220
	  error ("Can't scale image file: $err") if $err;
221
 	}
222
 
7 - 223
	$err = $img->Scale (geometry => "64x64");
224
	error ("Can't scale image file: $err") if $err;
225
	$thumb = $img->ImageToBlob ();
9 - 226
	$full  = $fullimg->ImageToBlob ();
7 - 227
	return ($full, $thumb);
228
}
229
 
230
sub error {
231
	my $msg = shift;
232
	print $h->p ({ class=>"error" }, "Error: $msg");
233
  print $h->close("html");
234
	exit (0);
235
}
236
 
237
sub formField {
238
	my $name  = shift;
239
	my $value = shift // '';
240
	my $type = $fieldType{$name} // "button";
241
 
242
	if ($type eq "image") {
243
		return $h->input ({
244
        name => $name,
245
        class => "inputfile",
246
        type => "file",
247
        id   => "file",
248
        size => 60
249
      }) . $h->label ({ for=>"file", class=>"top" }, $h->span ("Choose File..."));
250
 
251
	} elsif ($type eq "button") {
252
		if ($name eq "Cancel") {
9 - 253
			return $h->input ({ type=>"button", value => $value ne '' ? $value : "Cancel" , onClick=>"history.back(); return false;" })
7 - 254
		} else {
255
			return $h->input ({ type=>"submit", value => $value, name=>$name })
256
		}
257
 
258
	} elsif ($type eq "textarea") {
259
	  return $h->tag ("textarea", {
260
	    name => $name,
261
	    override => 1,
262
			cols => 30,
263
			rows => 4
264
	  }, $value);
265
 
266
	}	else {
267
	  return $h->input ({
268
	    name => $name,
269
	    type => $type,
270
	    value => $value,
271
	    required => [],
272
	    override => 1,
273
	    size => 30
274
	  });
275
	}
276
}
277
 
278
sub printJavascript {
279
    print<<JSCRIPT;
280
 
281
 
282
<SCRIPT language="JavaScript">
283
<!--
284
 
285
var inputs = document.querySelectorAll( '.inputfile' );
286
Array.prototype.forEach.call( inputs, function( input )
287
{
288
	var label	 = input.nextElementSibling,
289
		labelVal = label.innerHTML;
290
 
291
	input.addEventListener( 'change', function( e )
292
	{
293
		var fileName = e.target.value.split( '\\\\' ).pop();
294
		if( fileName )
295
			label.querySelector( 'span' ).innerHTML = fileName;
296
		else
297
			label.innerHTML = labelVal;
298
	});
299
});
300
 
301
//-->
302
</SCRIPT>
303
 
304
 
305
JSCRIPT
306
 
307
}
308