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.
Have you tried Searching this site?
Unix/Linux/Mac OS X support by phone, email or on-site: Support Rates
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. We appreciate comments and article submissions.
Many of the products and books I review are things I purchased for my own use. Some were given to me specifically for the purpose of reviewing them. I resell or can earn commissions from the sale of some of these items. Links within these pages may be affiliate links that pay me for referring you to them. That's mostly insignificant amounts of money; whenever it is not I have made my relationship plain. I also may own stock in companies mentioned here. If you have any question, please do feel free to contact me.
Specific links that take you to pages that allow you to purchase the item I reviewed are very likely to pay me a commission. Many of the books I review were given to me by the publishers specifically for the purpose of writing a review. These gifts and referral fees do not affect my opinions; I often give bad reviews anyway.
We use Google third-party advertising companies to serve ads when you visit our website. These companies may use information (not including your name, address, email address, or telephone number) about your visits to this and other websites in order to provide advertisements about goods and services of interest to you. If you would like more information about this practice and to know your choices about not having this information used by these companies, click here.
Click here to add your comments
Sun Feb 26 22:53:29 2006: Subject: dhart
...or you could use www.ezminders.com
Sun Feb 26 22:59:04 2006: Subject: 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.
Don't miss responses! Subscribe to Comments by RSS or by Email
Click here to add your comments
If you want a picture to show with your comment, go get a Gravatar