require 'rubygems' require 'bundler/setup' require 'date' require 'active_support/core_ext/date_and_time/calculations' require 'icalendar/recurrence' require 'open-uri' require 'json' class SublabCalendar URL = "https://sublab.org:5232/calendars/events" class Event < SimpleDelegator BASIC_ATTRIBUTES = [:summary, :dtstart, :dtend] def to_h BASIC_ATTRIBUTES.inject({}) {|hsh, attr| hsh[attr] = send(attr).to_s; hsh } end def to_json(*args) to_h.to_json(*args) end def to_s "<#{self.class} #{self.to_h}>" end def inspect to_s end def recurring? ! rrule.empty? end def occurrences_this_month return nil unless recurring? occurrences_between(*this_month).map {|occ| Occurrence.new(occ, self) } end private def this_month [Date.today.beginning_of_month, Date.today.end_of_month] end end class Occurrence < SimpleDelegator attr_reader :event def initialize(occurrence, event) @event = event super(occurrence) end def to_h { summary: summary, start: start_time, end: end_time } end def inspect to_s end def summary event.summary end def description event.description end def to_s "<#{self.class} #{self.to_h}>" end end attr_reader :calendar def initialize(ical) @calendar = Icalendar.parse(ical).first end def self.load(url=URL) ical = open(url, {ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE}) new(ical) end def events calendar.events.map(&method(:readable)) end def future calendar.events.select {|ev| ev.dtstart >= DateTime.now}.map(&method(:readable)) end def past calendar.events.select {|ev| ev.dtstart < DateTime.now}.map(&method(:readable)) end def recurring events.select(&:"recurring?") end def next(count=1) future.take(count) end def readable(event) Event.new(event) end end