lecture-attendance-manager/app/models/course.rb
Joshua Coles f0b458f6a1 Improve event summary parsing in course model
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.
2024-02-04 14:03:13 +00:00

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