The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
What I've Been Up To Of Late - A new Ruby iCalendar Library

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Rick DeNatale

Posts: 269
Nickname: rdenatale
Registered: Sep, 2007

Rick DeNatale is a consultant with over three decades of experience in OO technology.
What I've Been Up To Of Late - A new Ruby iCalendar Library Posted: Jan 23, 2009 7:19 PM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Rick DeNatale.
Original Post: What I've Been Up To Of Late - A new Ruby iCalendar Library
Feed Title: Talk Like A Duck
Feed URL: http://talklikeaduck.denhaven2.com/articles.atom
Feed Description: Musings on Ruby, Rails, and other topics by an experienced object technologist.
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Rick DeNatale
Latest Posts From Talk Like A Duck

Advertisement

Instead of blogging much of late, apart from the odd twitter tweet, and playing with alpha versions of Maglev as they come out, I’ve been spending most of my time working on a new implementation of RFC 2445 “Internet Calendaring and Scheduling Core Object Specification (iCalendar)”, in Ruby.

My previous employer wanted to implement iCalendar recurring events to allow their customers to import and export events from their favorite calendar application, be that MS Outlook, the Mac iCal app, Google calendar, or whatever. RFC 2445 is the “linqua franca” for calendar applications. Unfortunately there wasn’t enough in the budget to do this given the technical challenges which I’ll describe shortly. Since I’ve had a lot of free time on my hands since late November when the budget for anything seemed to sublimate along with the company because of the financial crisis, I’ve been chipping away at it anyway.

Although there are several extant ruby implementations of iCalendar, the most popular being the icalendar and vPim gems, which do a reasonable job parsing and generating icalendar files, none of them provide an implementation of the harder aspects of iCalendar: time zone representation and recurring events.

You have to understand that RFC 2445 is the demon spawn of IBM (via Lotus) and Microsoft, and like many such standards, appears to be a camel with humps full of the quirks of the proprietary products from the author’s companies, and when those companies are IBM and Microsoft, and it’s the late 1990s, the standards don’t always conform to todays practices.

Does Anybody Know What Time Zone It Is?

While Ruby has libraries which deal with time zones (TZInfo), and recurring events (Runt, and TExp) in both cases they aren’t usable out of the box to support iCalendar.

TZInfo, like most of the computing world, uses the Zoneinfo (a.k.a. Olsen) database of time zone information, which allows referencing time zones by standard names. RFC 2445 requires each iCalendar file or datastream to contain a definition of each time zone referenced within the file. The time zone definitions name the time zone, give an initial offset from utc, and either a list of transition times between standard and daylight saving time, or recurrence rules defining those times.

So one of my goals is to allow Ruby applications to import iCalendar files containing time zone definitions and make use of those definitions with the contents of the imported calendar, and to allow calendars produced by Ruby applications to properly produce valid iCalendar time zone definition components.

Right now, I’ve done most of the groundwork for the second goal. I can generate a time zone definition (technically a VTIMEZONE component) from a ZoneInfo time zone name and a starting and ending time, the component is tagged with an extended attribute so that if I import a file produced by this library I can use TZInfo to do the time zone mappings for the calendar.

I put the second goal for time zone components off for the time being while I’ve been working on the other major problem area, if for no other reason that iCalendar time zone components make use of some of the same machinery as recurring events.

Recurring Events, or Deja Vu, All Over Again

Runt and TExp are both based on Martin Fowler’s paper on a pattern for implementing recurring events. Martin’s approach is quite elegant. Unfortunately, it’s rather inadequate to implement iCalendar’s notion of recurring events.

The primary component of a recurring event definition in iCalendar is a ‘recur’ value, which describes how to enumerate a set of occurrences given a starting time. The actual definition is quite complex and hard to understand. A ‘recur’ val has a basic frequency, like MONTHLY, or WEEKLY, or MINUTELY, and an interval. The frequency and interval can be used to express a recurrence pattern like, “every 3 days”. Then there are optional parts like, BYMINUTE, BYYEAR, BYWEEKDAY, which if they represent a period of time the same as or longer than the frequency act as filters, for example “FREQ=MONTHLY;BYMONTH=1,2” represents an event which happens every January and February at the given time. If a BYxxx part represents a shorter period than the frequency, it adds additional occurences, so “FREQ=DAILY;BYHOUR=11,14” represents an event which recurs every day at both 11:mm a.m. and 2:mm p.m. where the mm is taken from the separately provided start time.

A second way to represent a list of occurrences is explicitly with a list of date or date-time values.

That’s all complicated enough, but a given event can have multiple ‘recur’ values and lists, each of which can either add (RRULE, RDATE) or prevent (EXRULE, EXDATE) occurrences from being included in the final event.

While I’m pretty sure that a lot of this capability never gets used in the real world, it’s hard to determine what subsets the various calendar applications actually use. The complexity of iCalendar has led to efforts like and Calsifywhich is chartered by the Internet Engineering Task Force with simplfying RFC 2445 ””, along with the related RFC 2446 “iCalendar Transport-Independent Interoperability Protoco (iTIP)”, RFC 2447 ” iCalendar Message-Based Interoperability Protocol (iMIP)”, and RFC 3283 “Guide to Internet Calendaring” and CalConnect a consortium working on usage standards to aid interoperability of applications the existing versions of those standards

In the spirit of Postel’s Law I’ve decided to take on accepting everything that RFC 2445 allows.

Where Things Stand

First I considered doing this as an extension to either the iCalendar or vPim gems, each has it’s advantages and disadvantages. After considerable thought I decided to start afresh, and build a behavior-driven implementation as much as possible. I’ve found myself taking a slight detour from strict test-first design in the case of the implementation of enumerating ‘recur’ values. Since there the specification is so convoluted, it was more natural to try to ponder the overall problem, and write ‘black-box’ specs directly from the RFC. It took me several days of pondering all of the examples in RFC 2445, and a few ‘shower thoughts’ before I got the general approach to enumerating occurrences. In either case, I’ve been using RSpec as my specification/behavior driving/acceptance testing tool, with great pleasure.

So far, I’ve got specs and code for:

  1. Parsing a calendar envelope
  2. Parsing an event
  3. Producing a VTIMEZONE calendar component for a given time range from a TZInfo::Timezone
  4. Parsing ‘recur’ values
  5. Attribute reading and writing for ‘recur’ values
  6. Enumerating occurrences for a ‘recur’ value given a starting time

Having just completed the last of these and passing all of the example use cases given in section 4.8.5.4 of RFC 2445, I feel like I’m over a big hump, with a few, hopefully smaller, humps to go like the merging of RRULEs, EXRULEs, RDATEs and EXDATEs; and giving imported VTIMEZONE components the ability to actually do time conversions. Other that that I think it’s just a series of several smaller tasks. One of the reasons for posting this is to give myself some incentive to keep at it by going public!

It’s not quite ready to foist on the world just yet, but I hope to do that soon. My inclination is to release this as open source. I must say that since I’ve been without paying work for several months now, and this has been a self funded project, I’d like to figure out how to generate some revenue from what has been a considerable amount of work. I’d welcome any ideas to that end.

Read: What I've Been Up To Of Late - A new Ruby iCalendar Library

Topic: A Dark Colour Scheme For ActionScript, Ruby, MXML and Rails Previous Topic   Next Topic Topic: Binary search an array in JavaScript

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use