From d2bfbfd2810fbee673e43b2515db8bac527b3441 Mon Sep 17 00:00:00 2001 From: hukl Date: Mon, 16 Mar 2009 20:58:49 +0100 Subject: Refactored Chaos Calendar by wrapping libical and introducing event and occurrence model. More improvements to come. Enables us to create events with reoccurrence and intervals etc. --- app/models/event.rb | 27 ++++++++++++++++++++++ app/models/node.rb | 1 + app/models/occurrence.rb | 60 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+) create mode 100644 app/models/event.rb create mode 100644 app/models/occurrence.rb (limited to 'app/models') diff --git a/app/models/event.rb b/app/models/event.rb new file mode 100644 index 0000000..60b8521 --- /dev/null +++ b/app/models/event.rb @@ -0,0 +1,27 @@ +class Event < ActiveRecord::Base + + # Associations + + has_many :occurrences + belongs_to :node + + # Callbacks + + after_save :generate_occurences + + # Instance Methods + + def occurrences_in_range start_time, end_time + self.occurrences.find( + :all, :conditions => [ + "start_time > ? AND end_time < ?", + start_time, end_time + ] + ) + end + + private + def generate_occurences + Occurrence.generate self + end +end diff --git a/app/models/node.rb b/app/models/node.rb index d2db4ba..da26164 100644 --- a/app/models/node.rb +++ b/app/models/node.rb @@ -7,6 +7,7 @@ class Node < ActiveRecord::Base belongs_to :head, :class_name => "Page", :foreign_key => :head_id belongs_to :draft, :class_name => "Page", :foreign_key => :draft_id has_many :permissions + has_one :event # Callbacks after_create :initialize_empty_page diff --git a/app/models/occurrence.rb b/app/models/occurrence.rb new file mode 100644 index 0000000..6205618 --- /dev/null +++ b/app/models/occurrence.rb @@ -0,0 +1,60 @@ +# TODO Make a gem out of the c wrapper +require 'lib/chaos_calendar/ical_occurrences' + +class Occurrence < ActiveRecord::Base + + # Associations + + belongs_to :node + belongs_to :event + + # Class Methods + + def self.find_in_range start_time, end_time + find( + :all, :conditions => [ + "start_time > ? AND end_time < ?", start_time, end_time + ] + ) + end + + # Deletes all Occurrences which belong to the given event. Afterwards a few + # variables are set to save repetitive queries. The occurrences of the given + # event are then calculated and created. + def self.generate event + self.delete_all(:event_id => event.id) + + node = event.node + summary = node.head.title + duration = (event.end_time - event.start_time) + occurrences = self.generate_dates(event) + + occurrences.each do |occurrence| + self.create( + :summary => summary, + :start_time => occurrence, + :end_time => (occurrence + duration), + :node_id => node.id, + :event_id => event.id + ) + end + end + + # Calculates the start_time of all occurrences for a given event if a proper + # RRule is provided. An ArgumentError is thrown from within the libical + # wrapper if the RRule is malformed. If the rrule attribute of an event is + # nil, it simply returns the event start_time as only occurrence. + # Return value is always an array of Time objects. + def self.generate_dates event + if event.rrule + Ical_occurrences::occurrences( + event.start_time.utc.iso8601, + (Time.now + 5.years).utc.iso8601, + event.rrule + ) + else + [event.start_time] + end + + end +end -- cgit v1.3