Monthly Archives: June 2015

Using Ruby To Make iCal Events, Part 2

Earlier I discussed creating calendar events with Ruby to take the pain out of creating a lot of events. I just finished up a script that created 126 events in seconds. Here are the relevant bits (in addition to the earlier post).

Input

My input CSV looks like this (below). It’s Hal Higdon’s Intermediate 1 plan.

Date,Week,Day,Description
6/8/2015,1,MON,Cross
6/9/2015,1,TUE,3 miles
6/10/2015,1,WED,5 miles
6/11/2015,1,THU,3 miles
6/12/2015,1,FRI,Rest
6/13/2015,1,SAT,5 miles (pace)
6/14/2015,1,SUN,8 miles
6/15/2015,2,MON,Cross
6/16/2015,2,TUE,3 miles

I copied the grid at the bottom and pasted it into Excel. I created another tab to handle the ETL. You can highlight a row and paste special (right click shows you this option) to transpose the cells. That allows you to take a row and paste it as a column. Yes, I can Excel pretty good. Excel sucks at regex though, so I let Ruby handle teasing out the meaning of each of the workouts.

The Code

  def read_input(infile)
    CSV.foreach(infile, :headers => true) do |row|
      m, d, y     = row['Date'].split(/\//).map(&:to_i)
      date        = DateTime.civil(y, m, d, 7, 0, 0)
      description = row['Description']
      next if description == "Rest"
      minutes = if description.match(/^\d{1,2}/)
                  description.match(/^\d{1,2}/)[0].to_i * 10
                else
                  30
                end
      event = Icalendar::Event.new
      event.dtstart  = date
      event.duration = "P#{minutes}M"
      event.summary  = description
      event.comment  = "Event created with Ruby script"
      @cal.add_event(event)
    end
  end

It’s not pretty. That method is doing a lot. The event comment isn’t saved either. That’s OK. I still got what I need — a whole lot of events that I didn’t have to type myself, and a script (and process) that I can use moving forward.

Win-win.

Leave a Comment

Filed under programming, ruby

Using Ruby To Create iCal Events

Calendars can be so tedious, so I hacked mine.

Anytime we have a new season begin, or I start a new running training plan, I have a bunch of events that need to be created. Usually you just sit down and take the half hour (or whatever) to bang all the events out. You can copy and paste events in iCal from day to day, which helps. But it still sucks.

So I finally sat down and figured out how to script it.

Gemfile:

# A sample Gemfile
source "https://rubygems.org"
ruby '2.2.2'

gem "icalendar"

Script (make_events.rb):

require "rubygems"
require "bundler"
require "csv"
require "date"
Bundler.require

### Create iCal ics file with multiple events
class EventCreator
  attr_reader :cal

  def initialize
    @cal = Icalendar::Calendar.new
    make_events
  end

  def make_events
    dt = DateTime.civil(2015, 6, 6, 0, 7, 0)
    3.times do |i|
      event          = Icalendar::Event.new
      event.dtstart  = dt + i
      event.duration = "P30M"
      event.summary  = "Test Event #{i}!"
      @cal.add_event(event)
    end
  end

  def to_ics
    File.open("scripted.ics", "w") { |f| f.write @cal.to_ical }
  end
end

if __FILE__ == $0
  calendar = EventCreator.new
  calendar.to_ics
end

So all you have to do from the command line, after you’ve run bundle install is ruby make_events.rb. It will create a single ics file that you can import into iCal. When you open the file you will be asked what calendar you want to import the events into.

Note: The gem does not appear to support “full day” events. That’s ok. Next up for me is to create a running training plan given a CSV file. I’ll post that next.

4 Comments

Filed under programming, ruby