class Course < ApplicationRecord has_many :lectures, dependent: :destroy has_many :work_items, dependent: :destroy # A course has a standalone connection to its recordings. To be displayed they must be associated with a lecture but # we them independently to avoid re-importing lectures. has_many :recordings, dependent: :destroy scope :active, -> { where(archived: false) } def lectures_and_work_items (lectures + work_items).sort_by(&:start_time) end def import_from_calendar! ics_file = HTTParty.get("https://mytimetable.bath.ac.uk/ical?6519757b&group=false&timetable=!MjAyMyFzdHVkZW50c2V0ITRDRjQ5MjlGRTg1M0Q4N0MyMDZENTVDNUQ3QTJFNzk0&eu=amMzMDkxQGJhdGguYWMudWs=&h=MiuDbRiudE_Yf7B25v2SfEuFCtmYGkFb5sAUI3yGmtY=") calendars = Icalendar::Calendar.parse(ics_file) calendar = calendars.first events = calendar.events.map do |event| # Example title include: PH40065B-Lab, PH40112-Lecc (Wk 19-25, 29-32), MA40049-Leca (LOIL), MA40049-Lecb summary = event.summary match = /(^\w\w\d{5})-(\w+)/.match(summary) # Handle odd events we don't care about next if match.nil? unit_code = match[1] short_lecture_title = match[2] start_time = event.dtstart.to_time event_uuid = event.uid.to_s next if unit_code.nil? || short_lecture_title.nil? || event_uuid.nil? || start_time.nil? || unit_code != self.unit_code { unit_code:, short_lecture_title:, start_time:, event_uuid:, online: summary.include?("LOIL"), } end lecture_counter = 0 events.compact.each do |event| # Naive check to see if we've already created this lecture if lectures.find_by(event_uuid: event[:event_uuid]).present? || lectures.find_by( start_time: (event[:start_time].beginning_of_hour + 5.minutes)..(event[:start_time].beginning_of_hour + 1.hour + 5.minutes) ).present? next end if event[:short_lecture_title].starts_with? "Lec" lecture_counter += 1 title = "Lecture #{lecture_counter}" else title = event[:short_lecture_title] end lectures.create!( title: title, start_time: event[:start_time], event_uuid: event[:event_uuid], online: event[:online], live_video_url: if event[:online] self.default_live_video_url else nil end, ) end end # What should this do for existing attendances? def renumber_lectures! lectures.group_by(&:kind).each do |kind, lectures| lectures.sort_by(&:start_time).each_with_index do |lecture, index| lecture.update!(title: "#{kind.to_s.humanize} #{index + 1}") end end end def fill_in_default_live_video_url! raise "No default live video URL set" if self.default_live_video_url.nil? lectures.where(live_video_url: nil).update_all!(live_video_url: self.default_live_video_url) end end