-----Original Message----- From: chas <panda@skinnyhippo.com> To: Itamar Shtull-Trauring <itamars@ibm.net>; Zope-l <zope@zope.org> Date: Saturday, September 04, 1999 3:40 PM Subject: Re: [Zope] Calendar (was: Portal idea)
At 07:27 PM 9/4/99 +0200, Itamar Shtull-Trauring wrote:
chas wrote:
just as a side note, you might want to think about the nature of the events. i've found that it's better to stick with rdb for events-listings because my events fall into 3 categories when it comes to the dates/times :
a) one-off events. eg. you specify the dates. eg. 19 oct 1999, 2 nov 1999 for event A 1 nov 1999 for event B .... which results in a one-to-many relationship
I don't think there are many applications where an rdb is really going to be much cleaner than the ZODB. (Though I think there may be a number of situations where the ZODB is cleaner, but maybe I'm just an object bigot :) The really straightforward thing to do would be something like this: Event ZClass (inherits from CatalogAware, ObjectManager) - EventDate ZClass (may inherit from CatalogAware for doing date-range manipulation) Event could have a function, as Itamar suggested, that zips through the EventDate objects (<dtml-in "objectValues('EventDate')">) and sees if there is a match. Or, you could grab all matching EventDate objects (through the Catalog) and then use parent[1] to get the Event info. This is a one-to-many relationship with no redundancy, and it should perform pretty well, I think. You could, of course, use a list property instead of an EventDate ZClass... but I don't think you would get the same Catalog benefit then. Kevin
a) one-off events. eg. you specify the dates. eg. 19 oct 1999, 2 nov 1999 for event A 1 nov 1999 for event B .... which results in a one-to-many relationship
I don't think there are many applications where an rdb is really going to be much cleaner than the ZODB. (Though I think there may be a number of situations where the ZODB is cleaner, but maybe I'm just an object bigot :)
The really straightforward thing to do would be something like this:
Event ZClass (inherits from CatalogAware, ObjectManager) - EventDate ZClass (may inherit from CatalogAware for doing date-range manipulation)
Event could have a function, as Itamar suggested, that zips through the EventDate objects (<dtml-in "objectValues('EventDate')">) and sees if there is a match.
Or, you could grab all matching EventDate objects (through the Catalog) and then use parent[1] to get the Event info.
This is a one-to-many relationship with no redundancy, and it should perform pretty well, I think.
ok, i'll give that a shot then if only to get my head around odb's. gotta admit that a lot of my bias towards the rdb is based on the fact that mysql (our weapon of choice) has proven itself to be an incredible speed daemon (i mean, they sacrifice transactions, which i don't need, in the name of speed). but don't worry, i'll go into this with an open mind... and thanks for setting me straight :) chas
At 04:37 AM 9/5/99 +0900, somebody wrote:
Event ZClass (inherits from CatalogAware, ObjectManager) - EventDate ZClass (may inherit from CatalogAware for doing date-range manipulation)
Event could have a function, as Itamar suggested, that zips through the EventDate objects (<dtml-in "objectValues('EventDate')">) and sees if there is a match.
Or, you could grab all matching EventDate objects (through the Catalog) and then use parent[1] to get the Event info.
This is a one-to-many relationship with no redundancy, and it should perform pretty well, I think.
I've given the subject of events quite a bit of thought. In addition to the one-up, recurring, and range problems, there is also the small matter of timezones, and efficient searching for what items should be displayed on what 'day', even though what constitutes a 'day' differs for different timezones. My thoughts go like this: * Events, Meetings, and the like may have a 'Schedule' object associated with them. The Schedule contains zero or more CalendarEntry objects. * CalendarEntry objects model a single UTC timespan - i.e. a start and stop timestamp. They provide a (multivalued) calendar_date attribute which can be cataloged. calendar_date is a list of all the dates (in UTC terms) which the event intersects. (Note that this requires ZCatalog to support a 'MultiValueIndex', which it doesn't yet. I say 'yet' because it's something I want to code up when I get around to it. It looks like a pretty trivial addition.) * When displaying a calendar, search for CalendarEntries with calendar_date values for both the desired day, and either one day forward or one day back from the desired day, depending on your relative timezone to UTC. Then look at the start/stop timestamps of the entries to weed out items which aren't really a match. * Because CalendarEntries (and the Schedules that contain them) acquire attributes and methods from their containing Event, Meeting, or whatever, they do not need to contain any other data, unless there are more specific notes. If a particular calendar wants to work its way upward through the acquisition tree to provide a broader view of an event, with many scheduled items for the same day (e.g. a seminar with lots of classes), it can do so. * To handle recurring events, give Schedules the ability to generate recurring CalendarEntries by way of a dialog that asks for a highest and lowest date to generate, and the parameters for recurrence. This method would just create the requisite CalendarEntries, and perhaps store the data used to generate them to be used as a default for the next time the generation needs to be run. Ideally, it would save the next value that should be used for a start date. * If Schedules are ObjectManager derivatives, it should be possible to easily view/add/edit/delete individual CalendarEntries from the Schedule. I think that about covers it. Notice, by the way, that it really doesn't matter where you put a Schedule object. It could be attached to anything that needs a schedule, like a room, a person, a project... If Schedules have a property that determines whether conflicts are allowed, so much the better. Schedules could also provide some basic views to display themselves nicely. The only other thing I can think of, is to allow CalendarEntries to be crosslinked between different Schedules, and changed as one. This would allow, say a Meeting or Conference's Schedule to have a CalendarEntry which also appears in a MeetingRoom's Schedule. This is technically possible in the ZODB, but in practice, the issue of asking all the Schedules to approve a change before committing, is a bit tricky. If it could be done, however, it would be a *way* cool thing. Not that all the preceding isn't pretty cool on its own.
gotta admit that a lot of my bias towards the rdb is based on the fact that mysql (our weapon of choice) has proven itself to be an incredible speed daemon (i mean, they sacrifice transactions, which i don't need, in the name of speed).
Interestingly, you *can* do transactions in MySQL, if you do them at a higher semantic level. For example, you could build a ZODB Storage implementation based on MySQL that supported Zope versioning and undo as well as transactions, all without MySQL needing transactions. Of course, arguably what you'd have when you did that would not really be a relational database at all... :)
You might be able to leverage the following, which I remembered seeing in a (relatively) recent Python announcement list : Robert Leftwich Subject: simple module to manipulate recurring dates Date: Sat, 07 Aug 99 01:03:40 GMT From: Skip Montanaro <skip@mojam.com> Organization: RHRZ - University of Bonn (Germany) To: python-announce-list@python.org Newsgroups: comp.lang.python.announce Followup-To: comp.lang.python In Musi-Cal I frequently need to deal with recurring dates such as "every Monday from 1pm to 3pm". The fact that I can't easily process recurring dates has been an ongoing problem. After one of my partners posed a question about recurring dates for another project a couple days ago, I decided it was time to start thinking seriously about it. The result is a small module, recur.py, which you can get to through my Python Bits page at http://www.musi-cal.com/~skip/python/ The module implements a single class, Recurrence. You can intersect two recurrences to get a new one or generate a finite series of absolute dates from an infinite recurrence. It doesn't yet do unions (my feeble brain hasn't figured that out), nor can it parse limited English phrases such as the one above into a Recurrence object. Also, it can only represent simple recurrences. More complex recurrences like "Easter", "every other Friday" or "the third Thursday of the month" are beyond it. Marc-Andre Lemburg's mxDateTime module: http://starship.python.net/crew/lemburg/mxDateTime.html is required. I'd very much like to get some feedback on this, especially on the stuff it can't do. It's an area where I have virtually no past programming experience (literature references would be most welcome!). If I'm hiking down the wrong trail I'd like to find out before I run into a lot of grizzly bears (or even the occasional snake... ;-) Thanks, Skip Montanaro | http://www.mojam.com/ skip@mojam.com | http://www.musi-cal.com/~skip/ 847-971-7098 <P><A HREF="http://www.musi-cal.com/~skip/python/recur.py">recur.py</A> - a Python class to handle recurring dates; needs mxDateTime module. (06-Aug-99)
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.
participants (4)
-
chas -
Kevin Dangoor -
Phillip J. Eby -
Robert Leftwich