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.