At the Forge - Dynamically Generated Calendars

Want to remind your Web site's users about upcoming events or get the whole company synced on a common calendar? Get started creating iCalendar files with Python.

Last column, we looked at Sunbird, a standalone application from the Mozilla Foundation for tracking calendars. As we saw, Sunbird is able to work with calendars in the iCalendar format. These calendars may be on the local filesystem or retrieved by HTTP from a remote server. We also saw how easy Sunbird makes it to use a calendar that a remote server has made available. We simply enter the URL into a dialog box, and after waiting for Sunbird to retrieve the iCalendar file, the new events are added to our calendar display.

A variety of remote calendars already exist on the Internet in iCalendar format, and you can find and subscribe to them without too much trouble. But doing so is helpful only if you want to subscribe to a calendar that already exists or is available publicly. What if your organization wants to standardize on iCalendar for exchanging event information? How can you create and distribute iCalendar files, such that others can keep track of the events they must attend?

This month, we look at the server side of iCalendar files and create calendars designed to be retrieved by calendar applications, such as Sunbird, within an organization.

iCalendar Files

If two computers are going to exchange calendars, we obviously need to have a standard that defines how those calendars should be formatted. The protocol over which they are exchanged is not defined, although both standards and daily use seem to indicate that HTTP is the overwhelming favorite for such transactions. The format for calendar exchange, defined in RFC 2445, reflects its age. Whereas a new calendar format would undoubtedly be defined to use XML, this RFC, dated November 1998, uses a set of name-value pairs, with some primitive nesting of elements within a hierarchy. For example, here is the the iCalendar file that we examined last month, when we first looked at Sunbird:

 :-// Mozilla Calendar V1.0//EN
 :LJ deadline

As you can see, the file begins and ends with BEGIN:VCALENDAR and END:VCALENDAR tags. There is some calendar-wide data at the top of the file, VERSION and PRODID, but then the first and only event is defined, bracketed by BEGIN:VEVENT and END:VEVENT entries. You can imagine how a file could have many more entries than this single one.

iCalendar makes it possible for an event to recur at regular intervals. You thus could have a single VEVENT entry reminding you about the weekly Monday-afternoon meeting or reminding you to put out the trash every Tuesday and Friday morning. Each event also has a beginning and ending time, DTSTART and DTEND, allowing for different lengths.

Although it is not obvious from the above example, iCalendar also allows us to make exceptions to recurring events. So, if your Monday-afternoon meeting is not going to take place during a holiday week, you can insert an EXDATE entry. The application that displays your calendar then ignores the recurring event on that date.

Publishing iCalendar Files

Assuming that we already have an iCalendar file on our system, making it available on the Web is quite easy. Listing 1 contains a simple CGI program that I wrote in Python; it looks for an iCalendar file in a particular directory and returns the contents of that file to the requesting calendar application.

If you haven't written a CGI program in Python before, this example should demonstrate how straightforward it is. Load the CGI module for some basic CGI functionality. Then, load the cgitb, for CGI traceback, module, which allows us to put debugging information in a file, if and when a problem occurs.

We then send a text/calendar Content-type header. It's probably safe to assume that most content on the Web is sent with a Content-type of text/html (for HTML-formatted text), text/plain (for plain-text files), with many of types image/jpeg, image/png and image/gif thrown in for good measure. The iCalendar standard indicates that the appropriate Content-type to associate with calendar files is text/calendar, even if programs such as Sunbird are forgiving enough to accept the text/plain format as well. Finally, we end the program by sending the contents of the calendar file, which we read from the local filesystem.

If you have been doing Web programming for any length of time, this example should be raising all sorts of red flags. The idea that we would use a program to return a static file seems somewhat silly, although this does have the slight advantage of letting us hide the true location of the calendar file from outside users. There are undoubtedly better ways to accomplish this, however, including the Apache Alias directive. We could improve this program somewhat by passing the calendar's filename as a parameter, but that still would require that we have a set of statically generated files.



Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

The webpage for this module s

ewindisch's picture

The webpage for this module seems to have been moved to where there are much more current releases available than reviewed here. Amongst other things, it now supports installation via the command "python install"

The old webpage still exists and makes no acknowledgement of the new site, thus I understand the author's confusion.


Anonymous's picture

I really liked the article, and I like where it's going. I'm a member of more than one non-profit org that would benefit greatly from a calendar system like the one proposed.

Unfortunately, MS Outlook, the calendar used by most of the members, does not seem to like iCalendar files generated by Mozilla. I don't know if MSO's iCalendar/vCalendar import works at all.

On MSO 2000, it just says it can't read the file. On MSO 2003, it displays the message

"This error can appear if you have attempted to save a recurring Lunar appointment in iCalendar format.
To avoid this error, set the appointment option to Gregorian instead of Lunar."

So I tried a file that had only 2 appointments, both non-recurring. Still got the same message. Configuring Mozilla to store universal time didn't help either.
MSO will not export an .ics/.vcs file, so it's difficult to see what it thinks is a good example.

I think this problem will somehow have to be resolved to make this idea really useful, since unfortunately I can't dictate to the other members what calendar app they should use. Any ideas?

--Jeff in Austin, TX

MSO exports icalendar files j

Anonymous's picture

MSO exports icalendar files just fine. Just send an appointment using internet format or drag and drop an appointment on an email after setting the default format to iCalendar. Then you can examine the format of a MSO iCalendar file.

One Click, Universal Protection: Implementing Centralized Security Policies on Linux Systems

As Linux continues to play an ever increasing role in corporate data centers and institutions, ensuring the integrity and protection of these systems must be a priority. With 60% of the world's websites and an increasing share of organization's mission-critical workloads running on Linux, failing to stop malware and other advanced threats on Linux can increasingly impact an organization's reputation and bottom line.

Learn More

Sponsored by Bit9

Linux Backup and Recovery Webinar

Most companies incorporate backup procedures for critical data, which can be restored quickly if a loss occurs. However, fewer companies are prepared for catastrophic system failures, in which they lose all data, the entire operating system, applications, settings, patches and more, reducing their system(s) to “bare metal.” After all, before data can be restored to a system, there must be a system to restore it to.

In this one hour webinar, learn how to enhance your existing backup strategies for better disaster recovery preparedness using Storix System Backup Administrator (SBAdmin), a highly flexible bare-metal recovery solution for UNIX and Linux systems.

Learn More

Sponsored by Storix