Move calendar scraping to a model method

This commit is contained in:
Joshua Coles 2023-10-04 14:41:15 +01:00
parent ef3642678d
commit 0e0d26d06d
5 changed files with 67 additions and 82 deletions

View File

@ -1,71 +0,0 @@
class ScrapeCalendarJob < ApplicationJob
queue_as :default
def clean_up_lecture_title(unit_code, short_lecture_title) end
def perform(*args)
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
unit_codes = Course.all.map(&:unit_code)
events = calendar.events.map do |event|
summary = event.summary
match = summary.split('-')
# Handle odd events we don't care about
next if match.length != 2
unit_code = match[0]
short_lecture_title = match[1]
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.in?(unit_codes)
{
unit_code:,
short_lecture_title:,
start_time:,
event_uuid:,
}
end
events
.compact
.filter { |attrs| attrs[:unit_code].in? unit_codes }
.group_by { |attrs| attrs[:unit_code] }
.map do |unit_code, course_events|
course = Course.find_by(unit_code: unit_code)
lecture_counter = 0
course_events.each do |event|
# Naive check to see if we've already created this lecture
if course.lectures.find_by(event_uuid: event[:event_uuid]).present? || course.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
course.lectures.create!(
title: title,
start_time: event[:start_time],
event_uuid: event[:event_uuid],
)
end
end
end
end

View File

@ -4,4 +4,68 @@ class Course < ApplicationRecord
# A course has a standalone connection to its recordings. To be shown they must be associated with a lecture but we
# track those not associated with a lecture to avoid duplication.
has_many :recordings, dependent: :destroy
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|
summary = event.summary
match = summary.split('-')
# Handle odd events we don't care about
next if match.length != 2
unit_code = match[0]
short_lecture_title = match[1]
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
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

View File

@ -1,7 +1,7 @@
class Lecture < ApplicationRecord
belongs_to :course
has_one :attendance
has_one :recording
has_one :attendance, dependent: :destroy
has_one :recording, dependent: :nullify
enum :kind, [
:lecture,

View File

@ -24,10 +24,9 @@
<th colspan="4" scope="colgroup" class="bg-gray-50 py-2 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Week <%= week_number %></th>
</tr>
<% lectures.each do |lecture| %>
<% lectures.reject(&:cancelled).each do |lecture| %>
<tr class="<%= class_names({
'lecture-future': lecture.start_time.future?,
'bg-slate-200': lecture.cancelled,
'bg-green-100': lecture.attendance.present?,
}) %>">
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6">

View File

@ -1,7 +0,0 @@
require "test_helper"
class ScrapeCalendarJobTest < ActiveJob::TestCase
# test "the truth" do
# assert true
# end
end