
Schedule::Oncall - Methods for managing an on-call schedule

use Schedule::Oncall;

Schedule::Oncall provides methods to manipulate an on-call schedule.
One or more tables of schedules can be maintained, loaded, and
searched. An on-call table is composed of seven days, where each
day has a list of minute ranges which correspond to a particular person.
Information such as email address, pager number, etc. may be stored in
the schedule configuration file. Simple variable assignments may also
be made. Other textual information may be stored in the schedule in
order to assist other applications (e.g., html headers or email body
text), and variables substitution may occur within the text blocks.
Schedule files may be chosen based on weekly or monthly rotations,
relative to the first week or month of the year. Weekly schedules
begin on a Monday and end on a Sunday, the same as strftime(3)'s
"%W" format. Each rotation is stored in a separate file, and the
appropriate rotation is chosen at load time.

my $sched = new Schedule::Oncall;
Returns a new Schedule::Oncall object.
my $error = $sched->error;
The error string as returned by the last method invoked. An empty
string ("") means no error.
$sched->load (
"dir" => "/path",
"file" => "filename",
"date" => num,
"week" => num,
"month" => num,
);
if ($sched->error ne "")
{
print STDERR "error loading schedule: " . $sched->error . "\n";
}
Load a schedule into a schedule object. This may be called multiple
consecutive times, and the schedules will be overlayed.
"dir" is the path to the schedule files. If unspecified it defaults to
"./".
"file" is the filename of a schedule to load. If it is an absolute path,
then that path overrides "dir". If it is a simple filename or a relative
path, it is appended to "dir".
"date" is the time (as integer seconds since the Epoch (00:00:00 UTC,
January 1, 1970). If unspecified it defaults to the current time.
"month" is an integer which is used to control which monthly schedule to
load. The month number is the month of the year (jan is 0) modulo "month".
"file" is appended with ".monthN" where "N" is the result of the modulo.
"week" is the week version of "month". Calculations are performed with the
week number instead of the month number. The first week of the year is
numbered "1" and begins on the first monday of the year. Days prior to
that reside in week 0. For example, Jan 1-3 1999 are week 0, and jan 4 1999
begins week 1. See "cal 1 1999".
Both monthly and weekly schedule rotations are supported if both "week" and
"month" are supplied. The resulting filename will resemble
"filename.month5.week2".
undef is returned if there is an error, and the description of the error is
stored in $sched->error.
If this method is called successive times to load different schedules, the
schedules are overlayed.
The format of the schedule file is somewhat free-form. Blank
lines and lines beginning with a "#" are ignored. It consists
of person definitions, text definitions, variable assignments,
and schedule definitions, in any order. It is recommended to
keep the schedule definition at the end of the file for readability
purposes.
A person definition looks like this:
begin person doej
fullname John Doe
pager 408-555-1212
cell 555-555-1212
email doej@domain.com
email doej@otherdomain.com
end person
Indentation is not significant, but it helps readability.
There can be any number of contact types ("email", "pager",
etc.) and each type can have multiple entries. There are
no pre-defined contact types, but as a convention there
should be "email", "pager", "fullname", "cell", "workphone",
and "homephone".
Text definitions are used to store configuration data for
applications based on
A text definition looks like this:
begin text email-response
From: mis@domain.com
To: __SUBMITTER__
We have received your submittion to the oncall alias.
Someone will respond soon.
end text
Variable definitions are also used to store configuration
information, and may only span one line, like this:
VARIABLE = value
Text definitions may undergo variable substitutions.
Substitions are invoked by ${variable}. The B<substitute_text>
method performs the actual substitutions.
Schedule definitions show who is on call at what times.
The format is vaguely compatible with a comma-separated-values
file, like this:
,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday
08:00,joe,jon,jon,jon,fred,bob
09:00,phil,marty,pat,jon,jon,jon,jon
This allows schedules to be imported into spreadsheet applications
and edited there. The above example shows that "pat" is oncall from
09:00-09:59 on Wednesday morning. Empty entries are ignored rather than
inserting a null string for the corresponding time slot. This allows
multiple schedules to be overlayed for the purpose of implementing
temporary "substitute" schedules.
If during the parsing of the schedule files this routine finds a variable
definition "override = (begin date) through (end date)", and the date
argument passed to this method falls within those two override dates, then
parsing of the file is terminated at the point where the variable is
defined. This allows the specification of temporary schedules which are
applicable to only a particular time frame. One application is for modified
schedules when individuals go on vacation.
The first line with a blank first column and day names is considered
the title line, and it defines the day order in which the following
rows are in.
Hours are in 24-hour format. They may be a single hour (such as "08:00"
or "08:30"), which implies the entry begins at the time listed and
continues until the last minute of that hour, e.g. 08:00 through 08:59.
Ranges are also acceptable, like this:
08:00-08:29,joe,joe,joe,...
08:30-08:59,fred,fred,fred,...
Ranges must begin and end on the same day. The second time of the
range must be later than the first part (i.e. a range like
"23:30-00:30" is invalid).
One "schedule" may be broken up into separate files for
convenience, and each file can be loaded separately. For example,
it might be a good idea to keep the people, text, and variable
definitions in their own file, and the actual schedule in its
own file for easier editing.
my $person = $sched->oncall (time);
Returns the name of the person who is on call at "time", given
the currently loaded schedule. "time" is seconds since the Epoch,
or the current time if unspecified.
The $sref->{"oncall-now"} structure is also initialized with
all of the personal data for that username collected in the
configuration file. If the on-call person is found to be a null
string, $sref->{"oncall->now"}->{"username"} is set to "nobody",
otherwise it is set to the username from the schedule. Variables
with multiple values (e.g. two email addresses specified) will be
joined with ",".
undef is returned if there is an error or if nobody is on call.
$sched->error is set to the error description.
return info about a person
for each person some personal info is stored returns:
( "pager" => ["pager1", "pager2", ...], "email" => ["email1", "email2", ...], "cell" => ["cell1", "cell2", ...], "fullname" => "full name", "etc" => "etc", ...)
returns undef on error.
my $val = $sched->var ("varname");
Returns the value of "varname" which was set in the configuration
file, or undef if the variable does not exist.
my ($week, $month) = $sched->rotation (
"week" => 4,
"month" => 4,
);
returns the current week and month rotation
Returns the currently loaded schedule as an array with each element
representing the hourly schedule for that day, in list form. The
first element is Sunday. For example:
([[0, 59, "person1"], [60, 119, "person2"], ...], [[0, 59, "person3"], ...], ...)
describes a schedule where "person1" is on call Sunday from midnight
until 1am, "person2" is on call from 1am until 2am, "person3" is on
on call from midnight until 1am on Monday, etc.
Given a minute of the day, returns a formatted time
such as hh:mm.
Perform variable expansion on the text collected from
a config file. All the variables defined in the config
file are substituted, along with any settings of
$self->{"oncall-now"} set by invoking the B<oncall> method,
"date" (set to localtime(time)), and "files" set to a
comma-separated list of files read by the B<load> method.
Variables located in the text sections which have no
definition are substituted with "n/a".

time(2)

none.