I often get asked for web-based scheduling programs. I’ve done quite a few of them over the years, sometimes using scripts available from the web, but more often writing my own simply because I don’t like modifying other people’s code.
All of the calendar based schedules I’ve done start with the very simple files presented here. This base version doesn’t have much flexibility: it lets you put in one note per day, and anyone who can access the schedule can overwrite that with new information. Obviously most businesses need additional features like multiple items, control of access, and probably much more. But this is the starting point we can build from.
As shown here, your web server needs to support SSI (Server Side Includes). Nowadays most of us would do this with php instead, but I still use the Perl methods because I’m old and stuck in my ways. Maybe I’ll show a php version later.
The entire scheduling program consists of one web page. You can call it whatever you want, but the cgi-bin perl script needs to know where it can find it in your filesystem. The cgi script uses a Perl database to store scheduled events; that can be located anywhere also but of course has to be accessible by the user Apache is running as.
Note that the script serves two purposes: it is called to add items to the schedule and as a server side include to display scheduled events. In this version we have no pretty formatting or other niceties that almost certainly would be needed in a production version.
The script reads the web page and displays it when it is called for a specific day; this could have been done differently with a basically empty web page depending on a cgi script to provide the contents. However, this design lets unskilled people edit the web page without affecting the script.
The web page and associated script follow:
# sched.html
<html><head><title>Schedule</title></head><body bgcolor="lightgreen">
<h2>Schedule</h2>
<script language="JavaScript">
<!-- yes this should look like this
function calendar() {
var now=today.getDate();
var tmonth=today.getMonth();
var tyear=today.getYear();
if (tyear < 1000) { tyear += 1900};
var d=new Date(year,month,"1");
var dd=new Date(year,nextmonth,"1");
var aday=(1000 * 60 * 60 * 24);
var ms=dd.getTime();
ms -= aday;
dd.setTime(ms);
var lastday=dd.getDate();
var sd=d.getDay();
pmonth=month-1;
pyear=year;
nmonth=month+1;
nyear=year;
if (pmonth < 0) { pmonth=11; pyear--;}
if (nmonth > 11) {nmonth=0; nyear++;}
dnmonth=nmonth+1;
dpmonth=pmonth+1;
document.write("<h2>Calendar for ");
document.write(names[month] + " " + year);
document.write("</h2>");
document.write("<TABLE BORDER width=\"50%\" cellwidth=\"14%\" CELLpadding=8>");
var y=1;
document.write("<TR>");
document.write("<td>S</td><td>M</td><td>T</td><td>W</td>
<td>T</td><td>F</td><td>S</td></tr><tr>");
for ( x=0; x < sd ; x++) {
document.write("<TD></TD>");
}
t=sd;
var prinmonth=month+1;
for ( x=sd; x < lastday + sd; x++) {
document.write("<TD width=\"100\" >" + "<a href=\"/cgi-bin/sched.pl?" +
prinmonth + "/" + y + "/" + year + "\">" + y + "</a>" + "</td>");
y++;t++;
if ((t % 7) == 0) { document.write("</TR><tr>")};
}
document.write("</TR><TR>");
document.write("</table>");
}
var argstr=location.search.substring(1,location.search.length);
var args= argstr.split('/');
var today=new Date();
if ( args[0] != "" ) {
var rmonth=args[0];
rmonth--;
today=new Date(args[2],rmonth,args[1]);
}
var month=today.getMonth();
var nextmonth=month+1;
var nxmonth=month+2;
var prmonth=month;
var year=today.getYear();
if (year < 1000) { year += 1900};
var nxyear=year;
var pryear=year;
if (nextmonth > 12) {nextmonth=1};
if (nxmonth > 12) {nxmonth=1;nxyear++};
if (prmonth < 1) {prmonth=12;pryear--};
$bstart="";
$bend="";
names=new Array("January","February","March","April","May","June","July",
"August","September","October","November","December");
var x=0;
calendar();
document.write("<p><a href=\"/sched.html?");
document.write(prmonth + "/" + "01/" + pryear + "\">Previous</a>");
document.write("<---------><a href=\"/sched.html?");
document.write(nxmonth + "/" + "01/" + nxyear + "\">Next</a>");
// and this should look like this -->
</script>
<p>
<!--#include virtual="/cgi-bin/sched.pl" -->
</body></html>
-----------------
#!/usr/bin/perl
use CGI qw(:standard);
use Time::Local;
$posting=param('posting');
$date=shift @ARGV;
$date=param('date') if not $date;
print "Content-TYPE: text/html\n\n";
if ($date) {
open(I,"/var/www/html/sched.html");
@stuff=<I>;
foreach (@stuff) {
print if not /<.body><.html>/;
}
}
$today=time();
$delete=$today;
$delete -= (3600 * 24 * 90);
@d=split /\//,$date;
eval {$filedate=timelocal(0,0,0,$d[1],$d[0]-1,$d[2]-1900);} ;
dbmopen(%sched,"/home/schedules/schedules",0666) or print $!;
$lastdate=$filedate;
$firstdate=$filedate;
if (not $date ) {
@d=localtime($today);
eval {$firstdate=timelocal(0,0,0,1,$d[4],$d[5]);} ;
eval {$lastdate=timelocal(0,0,0,1,$d[4]+1,$d[5]+1);} ;
print "<hr>";
}
$schedule=param('schedule');
$sched{$firstdate}=$schedule if $schedule;
print "<p>Listings for $date</p>";
foreach(sort keys %sched) {
delete $sched{$_} if $_ < $delete;
#delete $sched{$_};
next if $_ < $firstdate;
next if $_ > $lastdate;
$now=localtime($_) if not $date;
$now=~ s/00:00:00//;
print "<br> $now $sched{$_}";
}
dbmclose %sched;
if ($date) {
print <<EOF;
<p><a href="/sched.html">Return to Full
Calendar</a></p>
<form method=post action="/cgi-bin/sched.pl">
<p>Add note for $date: <input type=text size=60 name="schedule">
<input type=hidden name="date" value="$date">
<p><input type=submit name="posting" value="Add">
</form>
EOF
}
print "</body></html>" if ($date);
That’s all of it. It’s simple, but can actually be easily expanded to much more complexity without a great deal of effort.
*Originally published at APLawrence.com
Add to document.write(“Del.icio.us”) | DiggThis | Yahoo! My Web
Technorati:
A.P. Lawrence provides SCO Unix and Linux consulting services http://www.pcunix.com