[Zope] Calendar (was: Portal idea)

Phillip J. Eby pje@telecommunity.com
Sun, 05 Sep 1999 11:34:56 -0500


At 07:41 AM 9/5/99 +1000, Robert Leftwich wrote:
>You might be able to leverage the following, which I remembered seeing
>in a (relatively) recent Python announcement list :
>
>
>a Python class to handle recurring dates; needs mxDateTime
>module.  (06-Aug-99)
>

Yep, it could be used to help with Schedule's generation of
CalendarEntries.  I've previously looked over the module with that thought
in mind, but it's a relatively small part of the overall Schedule concept.

The interesting design bits at present are things like, how do you manage
presentation?  Should Schedule/CalendarEntry provide information like
colors, icons, and link targets, or should these be handled solely by the
calendar that displays them?  Perhaps there should be an API consisting of
methods for certain standard calendar formats, called on the CalendarEntry
or its Schedule by the displaying calendar.  The displaying calendar could
call the one it wants, or override it and go for certain attributes.  The
API needs to be fairly robust to allow for the wide range of possible
'calendar' interfaces as well as the wide range of things that go on
schedules.  Think about:

* Employee shift calendars
* Appointment calendars
* Conference/class schedules
* Project timelines
* e-Meeting schedules for people scattered around the globe
* The schedule of a person who's constantly time-zone hopping

And there are probably other things I haven't thought of to go on this
list.  Additions are welcome!

Some of these sound like jobs for CalendarEntry subclasses, or specialized
objects which contain CalendarEntries.  Like for example, a Deadline
object, which changes its rendering as the time approaches, or perhaps
contains the deadline as a CalendarEntry and automatically sets reminder
entries X amount of time in advance.


The other tricky bit is co-ordinating Schedules, whether it's of the people
or the other resources that are needed to get a meeting or some other event
off the ground.  For example, I may need a room, a projector, and a bunch
of people at the same time.  It seems there is a need for a CalendarEntry
to be able to reference a set of other objects with Schedules, and make
tentative entries, allowing the other objects to accept/decline.  The
'original' entry needs to know accept/decline statuses of the other
Scheduled objects and possibly fire off an event higher up the food chain
as these statuses change.  (E.g., my room reservation for a class gets
overridden by an emergency need of the sales department to make an
important presentation that just came up.  Or a key person in my meeting
has to cancel.)

It would seem that the ability for someone to request to add themselves
onto a CalendarEntry's resource list would also be valuable, e.g. to
register for a class and have it show up on one's own Schedule as reserved
time, and be notified of changes, as well as for conflicts with other
potential uses of my time.

At this point it begins to be clear that there are really two kinds of
schedules: plans and commitments.  I can *plan* to have a meeting at such
and such a time, but it is meaningless without scheduled resource
commitments.  Similarly, if I cancel or change the plan, the previous
commitments evaporate.

It would appear then, that the fundamental objects are an Event (a thing
you plan, which knows what resources are required for it to occur), a
Schedule (that manages a resource's commitments and allows the resource or
its owner to accept/reject), and a CalendarEntry (which is used by both
Events and Schedules to position themselves in time and provide an access
point for calendar displays to find them).


We find next that Events need nesting and relative time, so that a
'Conference' Event may contain 'Class' and 'Meal' events which float
relative to the overall conference date.  Similarly, Schedules need to
understand Event nesting, so that booking a room all day for a conference
doesn't interfere with co-ordinating the schedule for what classes will
occur in that room!  Event nesting on the Event side is easy -- or at least
conceptually straightforward -- but it's not clear how to do it on the
Schedule side.  Unless you can nest either Schedules or CalendarEntries,
that is, and that thought makes my head hurt right now.

Just to complicate things further, you may not wish to schedule a
*specific* resource, but rather a class of resource.  I need a math teacher
to teach Algebra I, but I don't care which one.  (Or an employee for this
shift, or a projector for my presentation, or...) I just want to be sure X
quantity of some resource is available during the time or times my Event is
planned for, so I need to schedule a generic resource, and be given back
the specifics, if needed.

This doesn't complicate things *too* much, as long as the Event-to-Schedule
API allows that a more specific subclass, say, 'ResourcePool' might be
what's being scheduled.  A ResourcePool keeps track of some class of
resources and either individually schedules them, or simply ensures it has
enough instances to do the job.  Interestingly, this latter can be
accomplished simply by changing the way a Schedule evaluates the definition
of a conflict.  For a single resource, two things at once is a conflict,
but for any other number, it requires N+1 to be a conflict.  So an ordinary
Schedule works for scheduling any number of interchangeable resources, as
long as the number is constant, and a ResourcePool Schedule also passes
through commitments to the individual resources contained (referenced?)
within it.

Now the idea of nesting Schedules within CalendarEntries (maybe we should
now call them ScheduleEntries) doesn't make my head hurt as much.  It also
appears to make sense to have some sort of 'TimeGrid' schedule that can be
used within an Event or Schedule to block out time in discrete units.  For
example, classes in both schools and conferences are usually blocked out on
a distinct time grid.  This could make planning easier at the UI level -
just pick from a dropdown or click on a grid square to schedule that class
period.

Actually, nesting Events would make that pretty simple to do, now that I
think of it.  Picture this:

Event - Three day conference 8:30-5:30, X/XX-X/XX
    Event - Classes, 8:30-12:30, 1:30-5:30 each day
        Event - Class Periods, 8:30-9:15, 9:30-10:15, etc.
            Event - specific class 1
            Event - specific class 2, etc.
    Event - Lunch, 12:00-1:30 each day

And so on.  The key is that a nested event has to take place within the
date windows of its parent, but it is contained in the Event, rather than a
specific CalendarEntry for that Event.  Relative time now makes sense, as
does the ability to have times 'snap to grid' against the higher level of
Event.  At each level of Event, it makes sense to get Schedule commitments:
schedule the hotel for the conference, the meeting rooms for the classes,
the instructors for the specific classes, and so on.  You could do this for
an entire university's semester scheduling, although it would surely
involve many thousands of automatically generated CalendarEntries on the
part of the various Events and Schedules.

Whew! That was quite a little ride.  It's pretty amazing what you can do
with Zope, when you get to thinking about the possibilities of its ODB and
scripting environment.  This type of scheduling toolkit would be orders of
magnitude more difficult to attempt in a relational database (or anything
else, for that matter).  The key is going to be to get the base
classes/interfaces *just so*, so that you can build all the other fancy
stuff on top of it without it falling over as you reach the heights of
capability.