Creating iCalendar files in Ruby

Using the iCalendar ruby library (gem install icalendar):

From the Show model, I added a method to create an event:

1
2
3
4
5
6
7
8
9
10
11
class Show < ActiveRecord::Base
...
  def to_ical_event
    event = Icalendar::Event.new    
    event.dtstart = time ? time.to_datetime : date
    event.dtstamp = created_at.to_datetime
    event.summary = "The title"
    event.description = "The description"
    event.uid = "show-#{id}"   
  end
end
  • dtstart takes a Date or DateTime object (see Ruby cookbook recipe chapter 3.9 for to_datetime method).

From the Venue model, I added a method to create the calendar and add all the show events:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Venue < ActiveRecord::Base
  has_many :shows  
...
  def to_ical
    ical = Icalendar::Calendar.new
    ical.product_id = "-//dclicio.us//iCal 1.0//EN"
    ical.custom_property("X-WR-CALNAME;VALUE=TEXT", name)
    ical.custom_property("X-WR-TIMEZONE;VALUE=TEXT", "US/Eastern")
    shows.each do |show|
      event = show.to_ical_event
      ical.add_event(event)
    end
    ical
  end
end
  • The X-WR custom properties are read by iCal and by google calendar.

Then a task to iterate through the venues creating the ics files:

1
2
3
4
5
6
Venue.find(:all, :include => [ :shows ]).each do |venue|
  ical = venue.to_ical       
  file = File.new("/tmp/#{venue.name}.ics", "w")
  file.write(ical.to_ical) # Allow myself to ... introduce ... myself :/
  file.close
end

An ics file looks like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
BEGIN:VCALENDAR
X-WR-CALNAME;VALUE=TEXT:Black cat
VERSION:2.0
CALSCALE:GREGORIAN
PRODID:-//dclicio.us//iCal 1.0//EN
X-WR-TIMEZONE;VALUE=TEXT:US/Eastern
BEGIN:VEVENT
UID:dclicio.us-243
DESCRIPTION:with \nhttp://dclicio.us
SUMMARY:
DTSTART:20070117
DTSTAMP:040425
SEQ:0
END:VEVENT
END:VCALENDAR

I then surface these files in public/ical/ and add a ProxyPass /ical ! so apache can serve em up straight without hitting mongrel.

Check out dclicio.us to see it in action.

Tags: , , , ,

Leave a Reply