#!/usr/bin/perl -T ########################### # # MarlboroClassSchedule.cgi # is a web .cgi script to display an editable # Marlboro College class schedule. # The documentation is at the end of this file in POD format. # # $Id: MarlboroClassSchedule.cgi,v 1.3 2002/04/12 09:19:20 msie Exp $ ########################### package MarlboroClassSchedule; # -== initialization ============================================- # I'd rather define globals with the "our" keyword, # but on akbar we're still stuck at perl 5.005 ... use vars qw( $VERSION $cgi $title1 $title2 $contact $datafilename $lastmodified $blockdata $schedulehtml ); $VERSION = "0.1"; use CGI; use CGI::Carp qw(fatalsToBrowser); # -== main ======================================================- defineGlobals(); readData(); # Define $blockdata from the disk file $datafilename . # If the user has clicked "Save Changes", if ($cgi->param('saveChanges')) { my $whichBlock = $cgi->param('whichBlock'); my $text = $cgi->param('text'); $blockdata->{ $whichBlock } = $text; writeData(); } # When accessed through the internet, via apache .cgi, caller() is false. # Under mod_perl, caller() is 'Apache::Registry'. # If we're invoked either of these ways, output a web page. # (Otherwise, another file such as test.pl is executing this file.) if ( not caller() or caller() eq 'Apache::Registry' ) { print $cgi->header(); if (my $whichBlock = $cgi->param('edit')) { print htmlEdit($whichBlock); } else { print htmlSchedule(); } } # -== define various global parameters ==========================- sub defineGlobals { $cgi = new CGI; $title1 = 'Marlboro College - Fall 2002 Class Schedule'; $title2 = 'Marlboro College
Fall 2002 Class Schedule'; $contact = 'Jim Mahoney (mahoney@marlboro.edu)'; # I don't think this is really necessary - I put it in to have short # keys for the hash which stores the text for each time block, but it # would probably be cleaner to just uses the longer, full names everywhere. %timeblocks = ( mon830 => "Monday 8:30am", wed830 => "Wednesday 8:30am", fri830 => "Friday 8:30am", mon930 => "Monday 9:30am", wed930 => "Wednesday 9:30am", fri930 => "Friday 9:30am", mon1030 => "Monday 10:30am", wed1030 => "Wednesday 10:30am", fri1030 => "Friday 10:30am", tues830 => "Tuesday 8:30am", thurs830 => "Thursday 8:30am", tues1000 => "Tuesday 10:00am", thurs1000 => "Thursday 10:00am", mon1130 => "Monday 11:30am", tues1130 => "Tuesday 11:30am", wed1130 => "Wednesday 11:30am", thurs1130 => "Thursday 11:30am", fri1130 => "Friday 11:30am", mon130 => "Monday 1:30pm", tues130 => "Tuesday 1:30pm", thurs130 => "Thursday 1:30pm", fri130 => "Friday 1:30pm", mon330 => "Monday 3:30pm", tues330 => "Tuesday 3:30pm", thurs330 => "Thursday 3:30pm", fri330 => "Friday 3:30pm", tues630 => "Tuesday 6:30pm", wed630 => "Wednesday 6:30pm", thurs630 => "Thursday 6:30pm", fri630 => "Friday 6:30pm", ); # The web server must have read/write access to this file. $datafilename = "datafile.txt"; } # -== data persistence routines ==========================================- # Storable reports errors by throwing exceptions which are caught with eval{}. # See http://theoryx5.uwinnipeg.ca/CPAN/data/Storable/Storable.html use Storable; # Since this routine creates the file $datafilename # and sets its privileges, whoever runs it must have # write access to the directory where $datafilename lives. sub initData { $blockdata = {}; unlink $datafilename; writeData(); chmod 0666, $datafilename; } sub readData { initData() unless -e $datafilename; $lastmodified = -M $datafilename; $lastmodified = scalar localtime( time() - 24*3600*$lastmodified ); $lastmodified =~ s/\d+:\d+:\d+ //; eval { $blockdata = Storable::lock_retrieve( $datafilename ) }; if ($@) { die "couldn't read data : $@"; } } sub writeData { # nstore is "network store" - uses file format compatible across platforms eval { Storable::lock_nstore( $blockdata, $datafilename ) }; if ($@) { die "couldn't write data : $@"; } } # -== html string for edit page ==================================- sub htmlEdit { my ($whichBlock) = @_; return <<"END_EDIT_HTML"; $title1

$title2


Editing $timeblocks{$whichBlock}


END_EDIT_HTML } # -== html string for schedule page ==================================- sub htmlSchedule { return <<"END_SCHEDULE_HTML"; $title1

$title2

Monday Tuesday Wednesday Thursday Friday
8:30

$blockdata->{mon830}

$blockdata->{tues830}

$blockdata->{wed830}

$blockdata->{thurs830}

$blockdata->{fri830}

9:00

9:30

$blockdata->{mon930}

$blockdata->{wed930}

$blockdata->{fri930}

10:00

$blockdata->{tues1000}

$blockdata->{thurs1000}

10:30

$blockdata->{mon1030}

$blockdata->{wed1030}

$blockdata->{fri1030}

11:00

11:30

$blockdata->{mon1130}

$blockdata->{tues1130}

$blockdata->{wed1130}

$blockdata->{thurs1130}

$blockdata->{fri1130}

12:00

12:30

1:00



Dedicated
Hour


1:30

$blockdata->{mon130}

$blockdata->{tues130}

$blockdata->{thurs130}

$blockdata->{fri130}

2:00

Town / Faculty
Meeting
2:30

3:00

3:30

$blockdata->{mon330}

$blockdata->{tues330}

$blockdata->{thurs330}

$blockdata->{fri330}

4:00

4:30

5:00

5:30




6:00
6:30
$blockdata->{tues630}

$blockdata->{wed630}

$blockdata->{thurs630}

$blockdata->{fri630}

7:00
7:30
8:00
8:30

Notes:
$contact
Last modified $lastmodified
END_SCHEDULE_HTML } 1; # -== Documentation ==============================================- =head1 NAME MarlboroClassSchedule - Perl cgi script for an editable weekly class schedule, using the time blocks typical at Marlboro College. =head1 SYNOPSIS (1) Run install.pl to define the datafile name and copy the script to your cgi-bin directory. Or, to install it by hand, put MarlboroClassSchedule.cgi in a cgi enabled web directory, and edit its global parameters at the start of the file, particularly $datafilename. Make sure the web server can create and edit the data file. (2) (Optional) Run test.pl to see if everything is working. (3) To use it, point your browser at wherever you installed it (i.e. http://..../MarlboroClassSchedule.cgi) and click away. =head1 DESCRIPTION MarlboroClassSchedule.cgi is a web script which displays a class schedule, and let's you edit it by clicking on links with each time block. A test suite, test.pl, may be used to exercise the various subroutines with the script, as well as fetch and interact with the installed web script. =head1 AUTHOR Jim Mahoney , Marlboro College =head1 COPYRIGHT Copyright 2002, Jim Mahoney. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See http://www.perl.com/perl/misc/Artistic.html =cut