class EventParser
Public Class Methods
new(calendar_content)
click to toggle source
# File lib/event_parser.rb, line 5 def initialize(calendar_content) @calendar_content = calendar_content end
Public Instance Methods
events()
click to toggle source
# File lib/event_parser.rb, line 9 def events events = [] get_events_in_calendar.each do |event| summary = parse_summary event starts_at = parse_starts_at event ends_at = parse_ends_at event if recurring_event? event recurring_dates = parse_recurring_dates(event) recurring_dates.each do |recurring_starts_at, recurring_ends_at| events << new_event(summary, recurring_starts_at, recurring_ends_at) end else events << new_event(summary, starts_at, ends_at) end end events end
Private Instance Methods
add_days_to_time(time, days)
click to toggle source
# File lib/event_parser.rb, line 118 def add_days_to_time(time, days) new_time = time + (days * 24 * 60 * 60) # required to keep the same hour after summer/winter time change if time.hour > new_time.hour new_time + 60 * 60 elsif time.hour < new_time.hour new_time - 60 * 60 else new_time end end
get_events_in_calendar()
click to toggle source
# File lib/event_parser.rb, line 43 def get_events_in_calendar beginnings = @calendar_content.split('BEGIN:VEVENT') events = [] beginnings.each do |event_beginning| next unless event_beginning.include? 'END:VEVENT' events << event_beginning.split('END:VEVENT').first end events end
is_date_excluded?(date, event)
click to toggle source
# File lib/event_parser.rb, line 112 def is_date_excluded?(date, event) date_str = date.strftime '%Y%m%dT%I%M%S' not_excluded = /EXDATE[\w\/=;]*:#{date_str}/.match(event).nil? !not_excluded end
new_event(summary, starts_at, ends_at)
click to toggle source
# File lib/event_parser.rb, line 37 def new_event(summary, starts_at, ends_at) OpenStruct.new(summary: summary, starts_at: starts_at, ends_at: ends_at) end
parse_ends_at(event)
click to toggle source
# File lib/event_parser.rb, line 64 def parse_ends_at(event) Time.parse(/DTEND[\w\/=;\s]*:(\d+T\d+)/.match(event)[1]) end
parse_recurring_dates(event)
click to toggle source
# File lib/event_parser.rb, line 72 def parse_recurring_dates(event) recurring_dates = {} starts_at = parse_starts_at event ends_at = parse_ends_at event summary = parse_summary event if event.include? 'RRULE:FREQ=WEEKLY;COUNT=' count = /RRULE:FREQ=WEEKLY;COUNT=(\d+)/.match(event)[1].to_i count.times do |i| recurring_starts_at = add_days_to_time(starts_at, i * 7) recurring_ends_at = add_days_to_time(ends_at, i * 7) unless is_date_excluded?(recurring_starts_at, event) recurring_dates[recurring_starts_at] = recurring_ends_at end end elsif event.include? 'RRULE:FREQ=WEEKLY;UNTIL=' until_time = Time.parse(/RRULE:FREQ=WEEKLY;UNTIL=(\d+T\d+)/.match(event)[1]) last_starts_at = starts_at last_ends_at = ends_at while last_starts_at <= until_time unless is_date_excluded?(last_starts_at, event) recurring_dates[last_starts_at] = last_ends_at end last_starts_at = add_days_to_time(last_starts_at, 7) last_ends_at = add_days_to_time(last_ends_at, 7) end else raise "Unsupported recurring event type: #{summary}" end recurring_dates end
parse_starts_at(event)
click to toggle source
# File lib/event_parser.rb, line 60 def parse_starts_at(event) Time.parse(/DTSTART[\w\/=;\s]*:(\d+T\d+)/.match(event)[1]) end
parse_summary(event)
click to toggle source
# File lib/event_parser.rb, line 56 def parse_summary(event) /SUMMARY:(.*)/.match(event)[1].strip end
recurring_event?(event)
click to toggle source
# File lib/event_parser.rb, line 68 def recurring_event?(event) event.include? 'RRULE:FREQ=WEEKLY;' end