This commit refines event summary parsing in the course model. Instead of splitting the summary, it uses regular expressions to extract the unit code and short lecture title more accurately. The update also includes better handling of events that don't match this format.
81 lines
2.5 KiB
Ruby
81 lines
2.5 KiB
Ruby
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:,
|
|
}
|
|
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],
|
|
)
|
|
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
|
|
end
|