From d540092bfcc7b02b8c8346570fbef7848320d1b7 Mon Sep 17 00:00:00 2001 From: Sasi Olin Date: Sun, 14 Feb 2021 22:56:45 +0100 Subject: [PATCH] Add icalendar files (fixes #2147) --- Gemfile | 2 ++ Gemfile.lock | 4 +++ app/controllers/conferences_controller.rb | 39 +++++++++++++++++++++++ app/controllers/schedules_controller.rb | 6 ++++ app/helpers/conference_helper.rb | 27 ++++++++++++++++ config/routes.rb | 2 ++ 6 files changed, 80 insertions(+) diff --git a/Gemfile b/Gemfile index c7867eb2..8059b258 100644 --- a/Gemfile +++ b/Gemfile @@ -219,6 +219,8 @@ gem 'nokogiri', '>= 1.8.1' # memcached binary connector gem 'dalli' +gem 'icalendar' + # Use guard and spring for testing in development group :development do # to launch specs when files are modified diff --git a/Gemfile.lock b/Gemfile.lock index ea8191f6..eeb82f76 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -241,6 +241,9 @@ GEM image_processing (1.12.1) mini_magick (>= 4.9.5, < 5) ruby-vips (>= 2.0.17, < 3) + icalendar (2.7.0) + ice_cube (~> 0.16) + ice_cube (0.16.3) io-like (0.3.0) iso-639 (0.2.8) jaro_winkler (1.5.3) @@ -652,6 +655,7 @@ DEPENDENCIES guard-rspec haml-rails haml_lint + icalendar iso-639 jquery-datatables-rails jquery-rails diff --git a/app/controllers/conferences_controller.rb b/app/controllers/conferences_controller.rb index 90d1274b..41e43bfa 100644 --- a/app/controllers/conferences_controller.rb +++ b/app/controllers/conferences_controller.rb @@ -67,6 +67,45 @@ class ConferencesController < ApplicationController end end + def calendar + respond_to do |format| + format.ics do + calendar = Icalendar::Calendar.new + Conference.all.each do |conf| + if params[:full] + event_schedules = conf.program.selected_event_schedules( + includes: [{ event: %i[event_type speakers submitter] }] + ) + calendar = icalendar_proposals(calendar, event_schedules.map(&:event), conf) + else + calendar.event do |e| + e.dtstart = conf.start_date + e.dtstart.ical_params = { 'VALUE'=>'DATE' } + e.dtend = conf.end_date + e.dtend.ical_params = { 'VALUE'=>'DATE' } + e.duration = "P#{(conf.end_date - conf.start_date + 1).floor}D" + e.created = conf.created_at + e.last_modified = conf.updated_at + e.summary = conf.title + e.description = conf.description + e.uid = conf.guid + e.url = conference_url(conf.short_title) + v = conf.venue + e.geo = v.latitude, v.longitude if v.latitude && v.longitude + location = '' + location += "#{v.street}, " if v.street + location += "#{v.postalcode} #{v.city}, " if v.postalcode && v.city + location += v.country_name if v.country_name + e.location = location if location + end + end + end + calendar.publish + render inline: calendar.to_ical + end + end + end + private def conference_finder_conditions diff --git a/app/controllers/schedules_controller.rb b/app/controllers/schedules_controller.rb index 2d3f22ef..f7ff69eb 100644 --- a/app/controllers/schedules_controller.rb +++ b/app/controllers/schedules_controller.rb @@ -21,6 +21,12 @@ class SchedulesController < ApplicationController format.xml do @events_xml = event_schedules.map(&:event).group_by{ |event| event.time.to_date } if event_schedules end + format.ics do + cal = Icalendar::Calendar.new + cal = icalendar_proposals(cal, event_schedules.map(&:event), @conference) + cal.publish + render inline: cal.to_ical + end format.html do @rooms = @conference.venue.rooms if @conference.venue diff --git a/app/helpers/conference_helper.rb b/app/helpers/conference_helper.rb index a48bed54..6ec2449c 100644 --- a/app/helpers/conference_helper.rb +++ b/app/helpers/conference_helper.rb @@ -21,4 +21,31 @@ module ConferenceHelper '%20Sponsorship' ].join end + + # adds events to icalendar for proposals in a conference + def icalendar_proposals(calendar, proposals, conference) + proposals.each do |proposal| + calendar.event do |e| + e.dtstart = proposal.time + e.dtend = proposal.time + proposal.event_type.length * 60 + e.duration = "PT#{proposal.event_type.length}M" + e.created = proposal.created_at + e.last_modified = proposal.updated_at + e.summary = proposal.title + e.description = proposal.abstract + e.uid = proposal.guid + e.url = conference_program_proposal_url(conference.short_title, proposal.id) + v = conference.venue + e.geo = v.latitude, v.longitude if v.latitude && v.longitude + location = '' + location += "#{proposal.room.name} - " if proposal.room.name + location += " - #{v.street}, " if v.street + location += "#{v.postalcode} #{v.city}, " if v.postalcode && v.city + location += "#{v.country_name}, " if v.country_name + e.location = location + e.categories = conference.title, "Difficulty: #{proposal.difficulty_level.title}", "Track: #{proposal.track.name}" + end + end + calendar + end end diff --git a/config/routes.rb b/config/routes.rb index 57bfa630..f6c4566d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -219,6 +219,8 @@ Osem::Application.routes.draw do get '/admin' => redirect('/admin/conferences') + get '/calendar' => 'conferences#calendar' + unless ENV['OSEM_ROOT_CONFERENCE'].blank? root to: redirect("/conferences/#{ENV['OSEM_ROOT_CONFERENCE']}") else