From 0740cac0afa46fbc87062eef7003ff653bd5208a Mon Sep 17 00:00:00 2001 From: Lars Henrik Mai Date: Sun, 21 Sep 2014 18:18:21 +0200 Subject: make Event and Occurrence sortable and adds some convenience --- README.md | 23 +++++++++++++++------- lib/sublab_calendar/calendar.rb | 41 +++++++++++++++++++++++++++++++++------ lib/sublab_calendar/event.rb | 23 +++++++++++++++++----- lib/sublab_calendar/occurrence.rb | 28 ++++++++++++++++++++++---- 4 files changed, 93 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 11c1879..7892fdd 100644 --- a/README.md +++ b/README.md @@ -11,16 +11,25 @@ You'll need ruby and ruby bundler (http://bundler.io). bundle install # start a REPL - pry -r ./sublab_calendar + pry -Ilib -r sublab_calendar - cal = SublabCalendar.load + cal = SublabCalendar::Calendar.load - cal.events # all events - cal.future # future events - cal.past # past events + cal.events # all events + cal.future_events # future events + cal.past_events # past events + + # get all events & occurrences this month + + list = cal.everything_this_month + # => SublabCalendar::EventList + + puts list.to_json + # => + # {"summary":"lounge","start":"2014-09-11 19:00:00 UTC","end":"2014-09-11 21:00:00 UTC"} + # {"summary":"lounge","start":"2014-09-25 19:00:00 UTC","end":"2014-09-25 21:00:00 UTC"} + # {"summary":"September Event","start":"2014-09-26 18:00:00 +0200","end":"2014-09-26 21:00:00 +0200"} - # dump future events as JSON - puts JSON.pretty_generate(cal.future) == Vagrant diff --git a/lib/sublab_calendar/calendar.rb b/lib/sublab_calendar/calendar.rb index e136ff5..0f95816 100644 --- a/lib/sublab_calendar/calendar.rb +++ b/lib/sublab_calendar/calendar.rb @@ -4,6 +4,15 @@ module SublabCalendar attr_reader :calendar + PERIODS = { + future: ->(ev) { ev.dtstart >= DateTime.now }, + past: ->(ev) { ev.dtstart < DateTime.now }, + this_month: ->(ev) { + ev.dtstart >= DateTime.now.beginning_of_month && + ev.dtstart < DateTime.now.end_of_month + } + } + def initialize(ical) @calendar = Icalendar.parse(ical).first end @@ -23,16 +32,24 @@ module SublabCalendar calendar.events.map(&method(:readable)) end - def future - calendar.events.select {|ev| ev.dtstart >= DateTime.now}.map(&method(:readable)) + PERIODS.each do |name, selector| + define_method "#{name}_events" do # def future_events + calendar.events. # calendar.events. + select(&selector). # select(&PERIODS[:future]). + map(&method(:readable)) # map(&method(:readable)) + end # end end - def past - calendar.events.select {|ev| ev.dtstart < DateTime.now}.map(&method(:readable)) + def recurring + events.select(&:recurring?) end - def recurring - events.select(&:"recurring?") + def non_recurring + events.reject(&:recurring?) + end + + def all_day + events.select(&:all_day?) end def next(count=1) @@ -43,6 +60,18 @@ module SublabCalendar SublabCalendar::Event.new(event) end + def everything_this_month + normal = events. + select(&PERIODS[:this_month]). + reject(&:recurring?). + map(&method(:readable)). + flatten + + occs = recurring.map(&:occurrences_this_month).flatten + + EventList.new(normal + occs) + end + end end diff --git a/lib/sublab_calendar/event.rb b/lib/sublab_calendar/event.rb index d350d51..e5042d8 100644 --- a/lib/sublab_calendar/event.rb +++ b/lib/sublab_calendar/event.rb @@ -2,10 +2,12 @@ module SublabCalendar class Event < SimpleDelegator - BASIC_ATTRIBUTES = [:summary, :dtstart, :dtend] - def to_h - BASIC_ATTRIBUTES.inject({}) {|hsh, attr| hsh[attr] = send(attr).to_s; hsh } + { + summary: summary, + start: dtstart, + end: dtend + } end def to_json(*args) @@ -15,15 +17,26 @@ module SublabCalendar def to_s "<#{self.class} #{self.to_h}>" end + alias_method :inspect, :to_s + + def <=>(other) + self.dtstart.to_datetime <=> other.dtstart.to_datetime + end - def inspect - to_s + def ==(other) + self.uid == other.uid end + alias_method :eql?, :== def recurring? ! rrule.empty? end + def all_day? + # all day events do not have a time, and get parsed to a Icalendar::Values:Date class + dtstart.is_a? Icalendar::Values::Date + end + def occurrences_this_month return nil unless recurring? occurrences_between(*this_month).map {|occ| Occurrence.new(occ, self) } diff --git a/lib/sublab_calendar/occurrence.rb b/lib/sublab_calendar/occurrence.rb index fad58a8..085a814 100644 --- a/lib/sublab_calendar/occurrence.rb +++ b/lib/sublab_calendar/occurrence.rb @@ -17,10 +17,24 @@ module SublabCalendar } end - def inspect - to_s + def to_json(*args) + to_h.to_json(*args) end + def to_s + "<#{self.class} #{self.to_h}>" + end + alias_method :inspect, :to_s + + def <=>(other) + self.dtstart.to_datetime <=> other.dtstart.to_datetime + end + + def ==(o) + o.class == self.class && o.state == state + end + alias_method :eql?, :== + def summary event.summary end @@ -29,8 +43,14 @@ module SublabCalendar event.description end - def to_s - "<#{self.class} #{self.to_h}>" + def dtstart + start_time.to_datetime + end + + protected + + def state + [event.uid, start_time, end_time] end end -- cgit v1.2.1