Subversion Repositories CoffeeCatalog

Rev

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