VRFS-3276 : Calendar manager
* Streamline logic * Enable recurring sessions through rrule * Implement method to create ics feed for user * Extract a type-safe scheduled duration method on music_session for external and internal use.
This commit is contained in:
parent
b71ad3a4cd
commit
92a2524c65
|
|
@ -1,43 +1,59 @@
|
||||||
module JamRuby
|
module JamRuby
|
||||||
class CalendarManager
|
class CalendarManager < BaseManager
|
||||||
class << self
|
DATE_FORMAT="%Y%m%dT%H%M%SZ"
|
||||||
def ics_from_music_session(music_session, delete=false)
|
def initialize(options={})
|
||||||
uid = "#{music_session.user_id}_#{music_session.id}@JamKazam"
|
super(options)
|
||||||
text = "JamKazam Session #{music_session.description}"
|
@log = Logging.logger[self]
|
||||||
case music_session.recurring_mode
|
|
||||||
when NO_RECURRING
|
|
||||||
create_ics_event(uid, text, scheduled_start, scheduled_start+scheduled_duration, delete)
|
|
||||||
when RECURRING_WEEKLY
|
|
||||||
create_ics_event(uid, text, scheduled_start, scheduled_start+scheduled_duration, delete)
|
|
||||||
else
|
|
||||||
raise ArgumentError("Recurring mode not supported: #{music_session.recurring_mode}")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# @return calendar (as ICS string) for specified user
|
|
||||||
def create_ics_feed(user)
|
|
||||||
end
|
|
||||||
|
|
||||||
def create_ics_event(uuid, summary, start_at, end_at, delete=false, sequence=0)
|
|
||||||
uuid ||= UUID.timestamp_create
|
|
||||||
event = "BEGIN:VEVENT\r\n"
|
|
||||||
event << "UID:#{uuid}\r\n"
|
|
||||||
event << "DTSTAMP:#{Time.now.utc().strftime(DATE_FORMAT)}\r\n"
|
|
||||||
event << "DTSTART:#{start_at.utc().strftime(DATE_FORMAT)}\r\n"
|
|
||||||
event << "DTEND:#{end_at.utc().strftime(DATE_FORMAT)}\r\n"
|
|
||||||
event << "SUMMARY:#{summary}\r\n"
|
|
||||||
if delete
|
|
||||||
event << "METHOD:CANCEL\r\n"
|
|
||||||
event << "STATUS:CANCELLED\r\n"
|
|
||||||
end
|
|
||||||
event << "SEQUENCE:#{sequence}\r\n" if sequence
|
|
||||||
event << "END:VEVENT"
|
|
||||||
end
|
|
||||||
|
|
||||||
def create_ics_cal(ics_events)
|
|
||||||
"BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:JamKazam\r\n#{ics_events}\r\nEND:VCALENDAR"
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
|
||||||
end
|
# @return event (as ICS string) for a given music session
|
||||||
|
def ics_event_from_music_session(music_session, delete=false)
|
||||||
|
# Determine properties of calendar event and create:
|
||||||
|
uid = "#{music_session.id}@JamKazam"
|
||||||
|
text = "JamKazam Session #{music_session.description}"
|
||||||
|
rrule = nil
|
||||||
|
start_at = music_session.scheduled_start
|
||||||
|
stop_at = music_session.scheduled_start+music_session.safe_scheduled_duration
|
||||||
|
if !delete && music_session.recurring_mode==MusicSession::RECURRING_WEEKLY
|
||||||
|
rrule = "FREQ=WEEKLY;INTERVAL=1"
|
||||||
|
end
|
||||||
|
create_ics_event(uid, text, start_at, stop_at, delete, rrule)
|
||||||
|
end
|
||||||
|
|
||||||
|
# @return calendar (as ICS string) for specified user
|
||||||
|
def create_ics_feed(user)
|
||||||
|
ics_events = ""
|
||||||
|
MusicSession.scheduled_rsvp(user, true).each_with_index do |music_session, i|
|
||||||
|
ics_events << "\r\n" if(i > 0)
|
||||||
|
ics_events << ics_event_from_music_session(music_session)
|
||||||
|
end
|
||||||
|
create_ics_cal(ics_events)
|
||||||
|
end
|
||||||
|
|
||||||
|
# @return event (as ICS string) for given arguments
|
||||||
|
def create_ics_event(uuid, summary, start_at, end_at, delete=false, rrule=nil, sequence=nil)
|
||||||
|
uuid ||= UUID.timestamp_create
|
||||||
|
event = "BEGIN:VEVENT\r\n"
|
||||||
|
event << "UID:#{uuid}\r\n"
|
||||||
|
event << "DTSTAMP:#{Time.now.utc().strftime(DATE_FORMAT)}\r\n"
|
||||||
|
event << "DTSTART:#{start_at.utc().strftime(DATE_FORMAT)}\r\n"
|
||||||
|
event << "DTEND:#{end_at.utc().strftime(DATE_FORMAT)}\r\n"
|
||||||
|
event << "SUMMARY:#{summary}\r\n"
|
||||||
|
if delete
|
||||||
|
event << "METHOD:CANCEL\r\n"
|
||||||
|
event << "STATUS:CANCELLED\r\n"
|
||||||
|
end
|
||||||
|
if rrule
|
||||||
|
event << "RRULE:#{rrule}\r\n"
|
||||||
|
end
|
||||||
|
event << "SEQUENCE:#{sequence}\r\n" if sequence
|
||||||
|
event << "END:VEVENT"
|
||||||
|
end
|
||||||
|
|
||||||
|
# @return calendar (as ICS string) for specified events
|
||||||
|
def create_ics_cal(ics_events)
|
||||||
|
"BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:JamKazam\r\n#{ics_events}\r\nEND:VCALENDAR"
|
||||||
|
end
|
||||||
|
|
||||||
|
end # class
|
||||||
|
end # module
|
||||||
|
|
@ -880,6 +880,21 @@ SQL
|
||||||
end
|
end
|
||||||
result
|
result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def safe_scheduled_duration
|
||||||
|
duration = scheduled_duration
|
||||||
|
# you can put seconds into the scheduled_duration field, but once stored, it comes back out as a string
|
||||||
|
if scheduled_duration.class == String
|
||||||
|
begin
|
||||||
|
bits = scheduled_duration.split(':')
|
||||||
|
duration = bits[0].to_i.hours + bits[1].to_i.minutes + bits[2].to_i.seconds
|
||||||
|
rescue Exception => e
|
||||||
|
duration = 1.hours
|
||||||
|
@@log.error("unable to parse duration #{scheduled_duration}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
duration
|
||||||
|
end
|
||||||
# should create a timestamp like:
|
# should create a timestamp like:
|
||||||
#
|
#
|
||||||
# with_timezone = TRUE
|
# with_timezone = TRUE
|
||||||
|
|
@ -910,17 +925,7 @@ SQL
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
duration = scheduled_duration
|
duration = safe_scheduled_duration
|
||||||
# you can put seconds into the scheduled_duration field, but once stored, it comes back out as a string
|
|
||||||
if scheduled_duration.class == String
|
|
||||||
begin
|
|
||||||
bits = scheduled_duration.split(':')
|
|
||||||
duration = bits[0].to_i.hours + bits[1].to_i.minutes + bits[2].to_i.seconds
|
|
||||||
rescue Exception => e
|
|
||||||
duration = 1.hours
|
|
||||||
@@log.error("unable to parse duration #{scheduled_duration}")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end_time = start_time + duration
|
end_time = start_time + duration
|
||||||
if with_timezone
|
if with_timezone
|
||||||
"#{start_time.strftime("%A, %B %e")}, #{start_time.strftime("%l:%M").strip}-#{end_time.strftime("%l:%M %p").strip} #{timezone_display}"
|
"#{start_time.strftime("%A, %B %e")}, #{start_time.strftime("%l:%M").strip}-#{end_time.strftime("%l:%M %p").strip} #{timezone_display}"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue