#!/opt/perl/bin/perl
#
#       This script will take a student's quote for bananas and create
#       a web page for the results of the highest and lowest of the week.
#
#               James Judd juddjam@eng.auburn.edu 960729
#       for Auburn University's Political Science Department
#               under the MCI grant for U102 Online
#

$datafile = "/home/duc1/juddjam/public_html/banana/banana.pits";
$lockfile = "/home/duc1/juddjam/public_html/banana/banana.pits.lock";
$expiry = 60;		# seconds before lockfile invalidated

$later = "<H3>Busy.. please try again a little later.\n</H3>";
$error = "<H3>Unexpected error.. notify your instructor.\n</H3>";

print "Content-type: text/html\n\n";
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/, $buffer);
foreach $pair (@pairs)
{
    ($name, $value) = split(/=/, $pair);

    # Un-Webify plus signs and %-encoding
    $value =~ tr/+/ /;
    $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

    # Stop people from using subshells to execute commands
    $value =~ s/~!/ ~!/g; 

    $FORM{$name} = $value;
}

($store = $FORM{'store'}) =~ y/_/ /;
($price = $FORM{'price'}) =~ s#(\.\d\d)\d+#$1#;
$week = $FORM{'weeknum'};

print <<EOT;
<HTML>
<HEAD>
<TITLE>Banana Page</TITLE>
</HEAD>
<BODY BACKGROUND="/pict/backgrounds/white.gif" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#FF0000" ALINK="#FFCC00" VLINK="#0000FF">
<CENTER><H2>Banana Price Page</H2></CENTER>
<P>
<BR>
EOT

&result_generation() if $FORM{'store'} && $FORM{'price'};
&show_data();
$week++;

print <<EOT;
<CENTER><P><BR>You may now review the<P>
<FORM method=POST action="http://www.auburn.edu/cgi-bin/bprice.pl">
<INPUT TYPE="hidden" name="weeknum" value="$week">
<INPUT TYPE="submit" VALUE="Previous Week's Prices">
</FORM>
<P>
or you may<P>
<A HREF="http://www.auburn.edu/~juddjam/banana/index.html">Go Back</A>
<P>
to the main banana page
EOT

sub show_data {
	local($_,$earliest,$latest,$highest,$lowest,@stuff);
	local($average,$sum,$number,$store,$price,$time);
	
	unless (open F, $datafile) {
		print $error;
		exit;
	}
	@stuff = <F>;
	close F;

	## determine bounds

	local($week_length) = 3600 * 24 * 7;
	$earliest = ($latest = time()) - $week_length;
	$earliest -= $week * $week_length;
	$latest   -= $week * $week_length;

	foreach (@stuff) {
		($store,$price,$time) = split(/\t/);
		next unless $time >= $earliest && $time <= $latest;
		if ($highest < $price || $highest eq "") {
			$highest = $price;
			$highstore = $store;
		}
		if ($lowest > $price || $lowest eq "") {
			$lowest = $price;
			$lowstore = $store;
		}
		@data = (@data, "<TR>\n<TD>",
		     scalar localtime($time),
		     "</TD> <TD><FONT COLOR=#00CC00>$price&#162</FONT></TD> <TD><FONT COLOR=#000099>$store</FONT></TD>\n");
		$sum += $price;
		$number++;
	}
	unless ($number) {
		if ($week == 0) {
		  print "<CENTER>No prices have been entered for this week.</CENTER><P>\n";
		}
		elsif ($week == 1) {
		  print "<CENTER>No prices were entered for last week.</CENTER><P>\n";
		}
		else
		{
		  print "<CENTER>No prices were entered for the week starting $week weeks ago.</CENTER><P>\n";
		}
		return;
	}
	($average = $sum / $number) =~ s#(\.\d\d)\d+#$1#;
	print "<CENTER><P><FONT SIZE=5>H</FONT><FONT SIZE=4>ighest of the week: <FONT COLOR=#FF0000>$highest&#162;</FONT> per pound at $highstore</B></FONT><P> <FONT SIZE=5>L</FONT><FONT SIZE=4>owest of the week: <FONT COLOR=#0000FF>$lowest&#162; </FONT> per pound at $lowstore</B></FONT><P><B>Average</B> for this week: <B>$average&#162;</B> per pound<P>\n";
	print "<P><I> ", scalar localtime($earliest), " through " , scalar localtime($latest), ":</I><P>\n";
	print "<TABLE BORDER>\n";
	print "<TR>";
	print "<TH>Entry Date/Time</TH> <TH>Price</TH> <TH>Store</TH>";
	print "</TR>\n";
	print "@data";
	print "\n";
	print "</TABLE>\n";
	print "</CENTER>\n";
}


sub result_generation {
	local($winks);
	if (-e $lockfile) {
		unlink $lockfile
			if (time() - (stat $lockfile)[9] > $expiry);
	}
	sleep 1 while (-e $lockfile && $winks++ < 5);
	if (-e $lockfile) {
		print $later;
		exit;
	}

	symlink("lockfile", $lockfile);
	unless (open F, ">>$datafile") {
		print "$error: $!";
		exit;
	}
	print F "$store\t$price\t", time(), "\n";
	close F;
	unlink $lockfile;
}
