At the Forge - Dynamically Generated Calendars
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.
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:
BEGIN:VCALENDAR VERSION :2.0 PRODID :-//Mozilla.org/NONSGML Mozilla Calendar V1.0//EN BEGIN:VEVENT UID :05e55cc2-1dd2-11b2-8818-f578cbb4b77d SUMMARY :LJ deadline STATUS :TENTATIVE CLASS :PRIVATE X-MOZILLA-ALARM-DEFAULT-LENGTH :0 DTSTART :20050211T140000 DTEND :20050211T150000 DTSTAMP :20050209T132231Z END:VEVENT END:VCALENDAR
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.
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.
Listing 1. static-calendar.py, a simple CGI program in Python to open an iCalendar file and send it by HTTP.
#!/usr/bin/python # Grab the CGI module import cgi # Log any problems that we might have import cgitb cgitb.enable(display=0, logdir="/tmp") # Where is our calendar file? calendar_directory = '/usr/local/apache2/calendars/' calendar_file = calendar_directory + 'test.ics' # Send a content-type header to the user's browser print "Content-type: text/calendar\n\n" # Send the contents of the file to the browser calendar_filehandle = open(calendar_file, "rb") print calendar_filehandle.read() calendar_filehandle.close()
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.
|Non-Linux FOSS: libnotify, OS X Style||Jun 18, 2013|
|Containers—Not Virtual Machines—Are the Future Cloud||Jun 17, 2013|
|Lock-Free Multi-Producer Multi-Consumer Queue on Ring Buffer||Jun 12, 2013|
|Weechat, Irssi's Little Brother||Jun 11, 2013|
|One Tail Just Isn't Enough||Jun 07, 2013|
|Introduction to MapReduce with Hadoop on Linux||Jun 05, 2013|
- Containers—Not Virtual Machines—Are the Future Cloud
- Non-Linux FOSS: libnotify, OS X Style
- Lock-Free Multi-Producer Multi-Consumer Queue on Ring Buffer
- Linux Systems Administrator
- RSS Feeds
- Introduction to MapReduce with Hadoop on Linux
- Validate an E-Mail Address with PHP, the Right Way
- New Products
- Weechat, Irssi's Little Brother
- Tech Tip: Really Simple HTTP Server with Python
- Poul-Henning Kamp: welcome to
25 min 23 sec ago
- This has already been done
26 min 23 sec ago
- Reply to comment | Linux Journal
1 hour 11 min ago
- Welcome to 1998
2 hours 7 sec ago
- notifier shortcomings
2 hours 23 min ago
4 hours 40 sec ago
- Android User
4 hours 2 min ago
- Reply to comment | Linux Journal
5 hours 55 min ago
8 hours 44 min ago
- This is a good post. This
13 hours 57 min ago
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?