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="https://aplawrence.com/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.
Got something to add? Send me email.
More Articles by Anthony Lawrence © 2011-06-30 Anthony Lawrence
I think there is a world market for maybe five computers. (Thomas Watson, Chairman of IBM, 1943)
Sun Feb 26 22:53:29 2006: 1712 dhart
...or you could use a reminder service.
Sun Feb 26 22:59:04 2006: 1713 TonyLawrence
Well, that's a reminder service, which isn't quite the same thing - or at least isn't when you add features to base code like this. For example, I have versions of this that accept input from "printed" POS forms and allow a scheduling department to sort delivery or installation schedules by town, assign technicians, and do other functions. Your imagination is the only limit.
------------------------
Printer Friendly Version
Simple Schedule Copyright © February 2006 Tony Lawrence
Have you tried Searching this site?
This is a Unix/Linux resource website. It contains technical articles about Unix, Linux and general computing related subjects, opinion, news, help files, how-to's, tutorials and more.
Contact us
Printer Friendly Version